@webex/internal-plugin-ai-assistant 0.0.0-next.24 → 0.0.0-next.25
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/README.md +43 -0
- package/dist/ai-assistant.js +21 -12
- package/dist/ai-assistant.js.map +1 -1
- package/dist/types.js.map +1 -1
- package/package.json +1 -1
- package/src/ai-assistant.ts +20 -11
- package/src/types.ts +4 -1
- package/test/unit/spec/ai-assistant.ts +319 -0
package/README.md
CHANGED
|
@@ -123,8 +123,51 @@ webex.internal.aiAssistant.askMeAnything({
|
|
|
123
123
|
}
|
|
124
124
|
});
|
|
125
125
|
});
|
|
126
|
+
|
|
127
|
+
// Advanced: Use the common makeAiAssistantRequest method for custom requests
|
|
128
|
+
webex.internal.aiAssistant.makeAiAssistantRequest({
|
|
129
|
+
sessionId: '<session-id>', // Optional for first request
|
|
130
|
+
encryptionKeyUrl: '<encryption-key-url>',
|
|
131
|
+
contextResources: [{
|
|
132
|
+
id: '<meeting-instance-id>',
|
|
133
|
+
type: 'meeting',
|
|
134
|
+
url: 'company.webex.com'
|
|
135
|
+
}],
|
|
136
|
+
contentType: 'message', // 'action' or 'message'
|
|
137
|
+
contentValue: 'What were the key takeaways?',
|
|
138
|
+
requestId: 'custom-id', // Optional
|
|
139
|
+
locale: 'en_US', // Optional
|
|
140
|
+
assistant: 'meeting-assistant' // Optional
|
|
141
|
+
}).then((response) => {
|
|
142
|
+
const { requestId, sessionId, streamEventName } = response;
|
|
143
|
+
|
|
144
|
+
// Listen for streaming responses
|
|
145
|
+
webex.internal.aiAssistant.on(streamEventName, (data) => {
|
|
146
|
+
console.log('Custom AI Response:', data.message);
|
|
147
|
+
});
|
|
148
|
+
});
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
### Optional Parameters
|
|
152
|
+
|
|
153
|
+
All AI Assistant methods support an optional `requestId` parameter that allows you to specify a custom request identifier:
|
|
154
|
+
|
|
155
|
+
```js
|
|
156
|
+
// Example with custom requestId
|
|
157
|
+
webex.internal.aiAssistant.summarizeMeeting({
|
|
158
|
+
meetingInstanceId: '<meeting-instance-id>',
|
|
159
|
+
meetingSite: 'company.webex.com',
|
|
160
|
+
sessionId: '<session-id>',
|
|
161
|
+
encryptionKeyUrl: '<encryption-key-url>',
|
|
162
|
+
requestId: 'my-custom-request-id' // Optional: specify your own request ID
|
|
163
|
+
}).then((response) => {
|
|
164
|
+
// The response will contain your custom requestId
|
|
165
|
+
console.log('Request ID:', response.requestId); // 'my-custom-request-id'
|
|
166
|
+
});
|
|
126
167
|
```
|
|
127
168
|
|
|
169
|
+
If `requestId` is not provided, a new UUID will be automatically generated for each request.
|
|
170
|
+
|
|
128
171
|
### Response Format
|
|
129
172
|
|
|
130
173
|
All AI Assistant methods return a Promise that resolves with:
|
package/dist/ai-assistant.js
CHANGED
|
@@ -194,7 +194,7 @@ var AIAssistant = _webexCore.WebexPlugin.extend({
|
|
|
194
194
|
var resource = options.resource,
|
|
195
195
|
params = options.params;
|
|
196
196
|
var timeout = this.config.requestTimeout;
|
|
197
|
-
var requestId = _uuid.default.v4();
|
|
197
|
+
var requestId = options.requestId || _uuid.default.v4();
|
|
198
198
|
var eventName = this._getResultEventName(requestId);
|
|
199
199
|
var streamEventName = this._getStreamEventName(requestId);
|
|
200
200
|
|
|
@@ -264,16 +264,16 @@ var AIAssistant = _webexCore.WebexPlugin.extend({
|
|
|
264
264
|
body: _objectSpread({
|
|
265
265
|
clientRequestId: requestId
|
|
266
266
|
}, params)
|
|
267
|
-
}).catch(function (error) {
|
|
268
|
-
reject(error);
|
|
269
267
|
}).then(function (_ref2) {
|
|
270
268
|
var body = _ref2.body;
|
|
271
269
|
resolve(_objectSpread(_objectSpread({}, body), {}, {
|
|
272
270
|
requestId: requestId,
|
|
273
271
|
streamEventName: streamEventName
|
|
274
272
|
}));
|
|
275
|
-
|
|
273
|
+
}).catch(function (error) {
|
|
274
|
+
reject(error);
|
|
276
275
|
});
|
|
276
|
+
timer.start();
|
|
277
277
|
});
|
|
278
278
|
},
|
|
279
279
|
/**
|
|
@@ -287,9 +287,12 @@ var AIAssistant = _webexCore.WebexPlugin.extend({
|
|
|
287
287
|
* @param {Object} options.parameters optional parameters to include in the request (for action type only)
|
|
288
288
|
* @param {Object} options.assistant optional parameter to specify the assistant to use
|
|
289
289
|
* @param {Object} options.locale optional locale to use for the request, defaults to 'en_US'
|
|
290
|
+
* @param {string} options.requestId optional request ID to use for this request, if not provided a new UUID will be generated
|
|
290
291
|
* @returns {Promise<Object>} Resolves with an object containing the requestId, sessionId and streamEventName
|
|
292
|
+
* @public
|
|
293
|
+
* @memberof AIAssistant
|
|
291
294
|
*/
|
|
292
|
-
|
|
295
|
+
makeAiAssistantRequest: function makeAiAssistantRequest(options) {
|
|
293
296
|
var _this6 = this;
|
|
294
297
|
return (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee3() {
|
|
295
298
|
var value, content;
|
|
@@ -320,7 +323,7 @@ var AIAssistant = _webexCore.WebexPlugin.extend({
|
|
|
320
323
|
if (options.parameters) {
|
|
321
324
|
content.parameters = options.parameters;
|
|
322
325
|
}
|
|
323
|
-
return _context3.abrupt("return", _this6._request({
|
|
326
|
+
return _context3.abrupt("return", _this6._request(_objectSpread({
|
|
324
327
|
resource: options.sessionId ? "sessions/".concat(options.sessionId, "/messages") : 'sessions/messages',
|
|
325
328
|
params: _objectSpread({
|
|
326
329
|
async: 'chunked',
|
|
@@ -329,7 +332,9 @@ var AIAssistant = _webexCore.WebexPlugin.extend({
|
|
|
329
332
|
}, options.assistant ? {
|
|
330
333
|
assistant: options.assistant
|
|
331
334
|
} : {})
|
|
332
|
-
}
|
|
335
|
+
}, options.requestId ? {
|
|
336
|
+
requestId: options.requestId
|
|
337
|
+
} : {})));
|
|
333
338
|
case 8:
|
|
334
339
|
case "end":
|
|
335
340
|
return _context3.stop();
|
|
@@ -345,10 +350,11 @@ var AIAssistant = _webexCore.WebexPlugin.extend({
|
|
|
345
350
|
* @param {string} options.sessionId the session ID for subsequent requests, not required for the first request
|
|
346
351
|
* @param {string} options.encryptionKeyUrl the encryption key URL for this meeting summary
|
|
347
352
|
* @param {number} options.lastMinutes Optional number of minutes to summarize from the end of the meeting. If not included, summarizes from the start.
|
|
353
|
+
* @param {string} options.requestId optional request ID to use for this request, if not provided a new UUID will be generated
|
|
348
354
|
* @returns {Promise<Object>} Resolves with an object containing the requestId, sessionId and streamEventName
|
|
349
355
|
*/
|
|
350
356
|
summarizeMeeting: function summarizeMeeting(options) {
|
|
351
|
-
return this.
|
|
357
|
+
return this.makeAiAssistantRequest(_objectSpread(_objectSpread({}, options), {}, {
|
|
352
358
|
contentType: _constants.CONTENT_TYPES.ACTION,
|
|
353
359
|
contentValue: _constants.ACTION_TYPES.SUMMARIZE_FOR_ME,
|
|
354
360
|
contextResources: [{
|
|
@@ -369,10 +375,11 @@ var AIAssistant = _webexCore.WebexPlugin.extend({
|
|
|
369
375
|
* @param {string} options.meetingSite the name.webex.com site for the meeting
|
|
370
376
|
* @param {string} options.sessionId the session ID for subsequent requests, not required for the first request
|
|
371
377
|
* @param {string} options.encryptionKeyUrl the encryption key URL for this meeting summary
|
|
378
|
+
* @param {string} options.requestId optional request ID to use for this request, if not provided a new UUID will be generated
|
|
372
379
|
* @returns {Promise<Object>} Resolves with an object containing the requestId, sessionId and streamEventName
|
|
373
380
|
*/
|
|
374
381
|
wasMyNameMentioned: function wasMyNameMentioned(options) {
|
|
375
|
-
return this.
|
|
382
|
+
return this.makeAiAssistantRequest(_objectSpread(_objectSpread({}, options), {}, {
|
|
376
383
|
contextResources: [{
|
|
377
384
|
id: options.meetingInstanceId,
|
|
378
385
|
type: _constants.CONTEXT_RESOURCE_TYPES.MEETING,
|
|
@@ -389,10 +396,11 @@ var AIAssistant = _webexCore.WebexPlugin.extend({
|
|
|
389
396
|
* @param {string} options.meetingSite the name.webex.com site for the meeting
|
|
390
397
|
* @param {string} options.sessionId the session ID for subsequent requests, not required for the first request
|
|
391
398
|
* @param {string} options.encryptionKeyUrl the encryption key URL for this meeting summary
|
|
399
|
+
* @param {string} options.requestId optional request ID to use for this request, if not provided a new UUID will be generated
|
|
392
400
|
* @returns {Promise<Object>} Resolves with an object containing the requestId, sessionId and streamEventName
|
|
393
401
|
*/
|
|
394
402
|
showAllActionItems: function showAllActionItems(options) {
|
|
395
|
-
return this.
|
|
403
|
+
return this.makeAiAssistantRequest(_objectSpread(_objectSpread({}, options), {}, {
|
|
396
404
|
contextResources: [{
|
|
397
405
|
id: options.meetingInstanceId,
|
|
398
406
|
type: _constants.CONTEXT_RESOURCE_TYPES.MEETING,
|
|
@@ -437,10 +445,11 @@ var AIAssistant = _webexCore.WebexPlugin.extend({
|
|
|
437
445
|
* @param {string} options.sessionId the session ID for subsequent requests, not required for the first request
|
|
438
446
|
* @param {string} options.encryptionKeyUrl the encryption key URL for this meeting summary
|
|
439
447
|
* @param {string} options.question the question to ask about the meeting content
|
|
448
|
+
* @param {string} options.requestId optional request ID to use for this request, if not provided a new UUID will be generated
|
|
440
449
|
* @returns {Promise<Object>} Resolves with an object containing the requestId, sessionId and streamEventName
|
|
441
450
|
*/
|
|
442
451
|
askMeAnything: function askMeAnything(options) {
|
|
443
|
-
return this.
|
|
452
|
+
return this.makeAiAssistantRequest(_objectSpread(_objectSpread({}, options), {}, {
|
|
444
453
|
contextResources: [{
|
|
445
454
|
id: options.meetingInstanceId,
|
|
446
455
|
type: _constants.CONTEXT_RESOURCE_TYPES.MEETING,
|
|
@@ -450,7 +459,7 @@ var AIAssistant = _webexCore.WebexPlugin.extend({
|
|
|
450
459
|
contentValue: options.question
|
|
451
460
|
}));
|
|
452
461
|
},
|
|
453
|
-
version: "0.0.0-next.
|
|
462
|
+
version: "0.0.0-next.25"
|
|
454
463
|
});
|
|
455
464
|
var _default = exports.default = AIAssistant;
|
|
456
465
|
//# sourceMappingURL=ai-assistant.js.map
|
package/dist/ai-assistant.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["_uuid","_interopRequireDefault","require","_webexCore","_lodash","_commonTimers","_constants","_utils","ownKeys","e","r","t","_Object$keys","_Object$getOwnPropertySymbols","o","filter","_Object$getOwnPropertyDescriptor","enumerable","push","apply","_objectSpread","arguments","length","Object","forEach","_defineProperty2","default","_Object$getOwnPropertyDescriptors","_Object$defineProperties","_Object$defineProperty","AIAssistant","WebexPlugin","extend","namespace","registered","initialize","_len","args","Array","_key","_apply","prototype","register","_this","webex","canAuthorize","logger","error","_promise","reject","Error","info","resolve","internal","mercury","connect","then","listenForEvents","trigger","AI_ASSISTANT_REGISTERED","catch","concat","message","unregister","_this2","stopListeningForEvents","disconnect","AI_ASSISTANT_UNREGISTERED","_this3","on","ASSISTANT_API_RESPONSE_EVENT","envelope","_handleEvent","data","off","_getResultEventName","requestId","AI_ASSISTANT_RESULT","_getStreamEventName","AI_ASSISTANT_STREAM","clientRequestId","_decryptContent","responseContent","_this4","_asyncToGenerator2","_regenerator","mark","_callee","wrap","_callee$","_context","prev","next","t0","name","RESPONSE_NAMES","MESSAGE","CITED_ANSWER","TOOL_RESULT","TOOL_USE","WORKSPACE","decryptMessage","abrupt","decryptCitedAnswer","decryptToolUse","decryptWorkspace","stop","_request","options","_this5","resource","params","timeout","config","requestTimeout","uuid","v4","eventName","streamEventName","timer","Timer","stopListening","finished","errorMessage","AI_ASSISTANT_ERRORS","AI_ASSISTANT_TIMEOUT","errorCode","AI_ASSISTANT_ERROR_CODES","listenTo","_ref","_callee2","resultData","responseType","decryptErrorMessage","_callee2$","_context2","reset","get","cancel","merge","response","_x","request","service","AI_ASSISTANT_SERVICE_NAME","method","contentType","body","_ref2","start","_makeMeetingRequest","_this6","_callee3","value","content","_callee3$","_context3","contentValue","_encryptData","text","encryptionKeyUrl","sent","context","resources","contextResources","type","parameters","sessionId","async","locale","assistant","summarizeMeeting","CONTENT_TYPES","ACTION","ACTION_TYPES","SUMMARIZE_FOR_ME","id","meetingInstanceId","CONTEXT_RESOURCE_TYPES","MEETING","url","meetingSite","lastMinutes","wasMyNameMentioned","WAS_MY_NAME_MENTIONED","showAllActionItems","SHOW_ALL_ACTION_ITEMS","_ref3","_this7","_callee4","result","_callee4$","_context4","encryption","encryptText","askMeAnything","question","version","_default","exports"],"sources":["ai-assistant.ts"],"sourcesContent":["/*!\n * Copyright (c) 2015-2022 Cisco Systems, Inc. See LICENSE file.\n */\nimport uuid from 'uuid';\nimport {WebexPlugin} from '@webex/webex-core';\nimport '@webex/internal-plugin-mercury';\nimport {get, merge} from 'lodash';\nimport {Timer} from '@webex/common-timers';\n\nimport {\n MakeMeetingRequestOptions,\n RequestOptions,\n RequestResponse,\n SummarizeMeetingOptions,\n} from './types';\nimport {\n AI_ASSISTANT_ERROR_CODES,\n AI_ASSISTANT_ERRORS,\n AI_ASSISTANT_REGISTERED,\n AI_ASSISTANT_RESULT,\n AI_ASSISTANT_STREAM,\n AI_ASSISTANT_UNREGISTERED,\n AI_ASSISTANT_SERVICE_NAME,\n ASSISTANT_API_RESPONSE_EVENT,\n ACTION_TYPES,\n CONTENT_TYPES,\n CONTEXT_RESOURCE_TYPES,\n RESPONSE_NAMES,\n} from './constants';\nimport {decryptCitedAnswer, decryptMessage, decryptToolUse, decryptWorkspace} from './utils';\n\nconst AIAssistant = WebexPlugin.extend({\n namespace: 'AIAssistant',\n\n /**\n * registered value indicating events registration is successful\n * @instance\n * @type {Boolean}\n * @memberof AIAssistant\n */\n registered: false,\n\n /**\n * Initializer\n * @private\n * @param {Object} attrs\n * @param {Object} options\n * @returns {undefined}\n */\n initialize(...args) {\n Reflect.apply(WebexPlugin.prototype.initialize, this, args);\n },\n\n /**\n * Explicitly sets up the AI assistant plugin by connecting to mercury, and listening for AI assistant events.\n * @returns {Promise}\n * @public\n * @memberof AIAssistant\n */\n register() {\n if (!this.webex.canAuthorize) {\n this.logger.error('AI assistant->register#ERROR, Unable to register, SDK cannot authorize');\n\n return Promise.reject(new Error('SDK cannot authorize'));\n }\n\n if (this.registered) {\n this.logger.info('AI assistant->register#INFO, AI assistant plugin already registered');\n\n return Promise.resolve();\n }\n\n return this.webex.internal.mercury\n .connect()\n .then(() => {\n this.listenForEvents();\n this.trigger(AI_ASSISTANT_REGISTERED);\n this.registered = true;\n })\n .catch((error) => {\n this.logger.error(`AI assistant->register#ERROR, Unable to register, ${error.message}`);\n\n return Promise.reject(error);\n });\n },\n\n /**\n * Explicitly tears down the AI assistant plugin by disconnecting from mercury, and stops listening to AI assistant events\n * @returns {Promise}\n * @public\n * @memberof AIAssistant\n */\n unregister() {\n if (!this.registered) {\n this.logger.info('AI assistant->unregister#INFO, AI assistant plugin already unregistered');\n\n return Promise.resolve();\n }\n\n this.stopListeningForEvents();\n\n return this.webex.internal.mercury.disconnect().then(() => {\n this.trigger(AI_ASSISTANT_UNREGISTERED);\n this.registered = false;\n });\n },\n\n /**\n * registers for Assistant API events through mercury\n * @returns {undefined}\n * @private\n */\n listenForEvents() {\n this.webex.internal.mercury.on(ASSISTANT_API_RESPONSE_EVENT, (envelope) => {\n this._handleEvent(envelope.data);\n });\n },\n\n /**\n * unregisteres all the Assistant API events from mercury\n * @returns {undefined}\n * @private\n */\n stopListeningForEvents() {\n this.webex.internal.mercury.off(ASSISTANT_API_RESPONSE_EVENT);\n },\n\n /**\n * constructs the event name based on request id\n * This is used by the plugin to listen for the result of a particular request\n * @param {UUID} requestId the id of the request\n * @returns {string}\n */\n _getResultEventName(requestId: string) {\n return `${AI_ASSISTANT_RESULT}:${requestId}`;\n },\n\n /**\n * constructs the stream event name based on request id\n * This is used by the consumer to listen for the stream (i.e. the data) of a particular request\n * @param {UUID} requestId the id of the request\n * @returns {string}\n */\n _getStreamEventName(requestId: string) {\n return `${AI_ASSISTANT_STREAM}:${requestId}`;\n },\n\n /**\n * Takes incoming data and triggers correct events\n * @param {Object} data the event data\n * @returns {undefined}\n */\n _handleEvent(data) {\n this.trigger(this._getResultEventName(data.clientRequestId), data);\n },\n\n /**\n * Decrypts the response content in place\n * @param {any} responseContent the content object from the assistant-api response\n * @returns {Promise} resolves once decryption is complete\n */\n async _decryptContent(responseContent) {\n switch (responseContent.name) {\n case RESPONSE_NAMES.MESSAGE: {\n await decryptMessage(responseContent, this.webex);\n break;\n }\n case RESPONSE_NAMES.CITED_ANSWER: {\n await decryptCitedAnswer(responseContent, this.webex);\n break;\n }\n case RESPONSE_NAMES.TOOL_RESULT: {\n // No encrypted content in tool_result\n break;\n }\n case RESPONSE_NAMES.TOOL_USE: {\n await decryptToolUse(responseContent, this.webex);\n break;\n }\n case RESPONSE_NAMES.WORKSPACE: {\n await decryptWorkspace(responseContent, this.webex);\n break;\n }\n default:\n this.logger.error(\n `AI assistant->_decryptContent#ERROR, Unknown response content name: ${responseContent.name}`\n );\n }\n },\n\n /**\n * Makes the request to the AI assistant service\n * @param {Object} options\n * @param {string} options.resource the URL to query\n * @param {Mixed} options.params additional params for the body of the request\n * @returns {Promise<Object>} Resolves with an object containing the requestId, sessionId and streamEventName\n */\n _request(options: RequestOptions): Promise<RequestResponse> {\n const {resource, params} = options;\n\n const timeout = this.config.requestTimeout;\n const requestId = uuid.v4();\n const eventName = this._getResultEventName(requestId);\n const streamEventName = this._getStreamEventName(requestId);\n\n // eslint-disable-next-line no-async-promise-executor\n return new Promise((resolve, reject) => {\n const timer = new Timer(() => {\n this.stopListening(this, eventName);\n this.trigger(streamEventName, {\n requestId,\n finished: true,\n errorMessage: AI_ASSISTANT_ERRORS.AI_ASSISTANT_TIMEOUT,\n errorCode: AI_ASSISTANT_ERROR_CODES.AI_ASSISTANT_TIMEOUT,\n });\n }, timeout);\n\n this.listenTo(this, eventName, async (data) => {\n timer.reset();\n const resultData = get(data, 'response.content', {});\n const errorMessage = get(data, 'response.errorMessage');\n const errorCode = get(data, 'response.errorCode');\n const responseType = get(data, 'responseType');\n\n if (data.finished) {\n timer.cancel();\n this.stopListening(this, eventName);\n }\n\n let decryptErrorMessage;\n\n try {\n if (!errorCode) {\n await this._decryptContent(resultData);\n }\n } catch (decryptError) {\n decryptErrorMessage = decryptError.message;\n }\n\n this.trigger(\n streamEventName,\n merge({}, data.response, {\n responseType,\n requestId,\n finished: data.finished,\n errorMessage: errorMessage || decryptErrorMessage,\n errorCode,\n })\n );\n });\n\n this.webex\n .request({\n service: AI_ASSISTANT_SERVICE_NAME,\n resource,\n method: 'POST',\n contentType: 'application/json',\n body: {clientRequestId: requestId, ...params},\n })\n .catch((error) => {\n reject(error);\n })\n .then(({body}) => {\n resolve({...body, requestId, streamEventName});\n timer.start();\n });\n });\n },\n\n /**\n * Common method to make AI assistant requests for meeting analysis\n * @param {Object} options\n * @param {string} options.contextResources array of context resources to include in the request\n * @param {string} options.sessionId the session ID for subsequent requests, not required for the first request\n * @param {string} options.encryptionKeyUrl the encryption key URL for this meeting summary\n * @param {string} options.contentType the type of content ('action' or 'message')\n * @param {string} options.contentValue the value to use (action name or message text)\n * @param {Object} options.parameters optional parameters to include in the request (for action type only)\n * @param {Object} options.assistant optional parameter to specify the assistant to use\n * @param {Object} options.locale optional locale to use for the request, defaults to 'en_US'\n * @returns {Promise<Object>} Resolves with an object containing the requestId, sessionId and streamEventName\n */\n async _makeMeetingRequest(options: MakeMeetingRequestOptions): Promise<RequestResponse> {\n let value = options.contentValue;\n\n if (options.contentType === 'message') {\n value = await this._encryptData({\n text: options.contentValue,\n encryptionKeyUrl: options.encryptionKeyUrl,\n });\n }\n\n const content: any = {\n context: {\n resources: options.contextResources,\n },\n encryptionKeyUrl: options.encryptionKeyUrl,\n type: options.contentType,\n value,\n };\n\n if (options.parameters) {\n content.parameters = options.parameters;\n }\n\n return this._request({\n resource: options.sessionId ? `sessions/${options.sessionId}/messages` : 'sessions/messages',\n params: {\n async: 'chunked',\n locale: options.locale || 'en_US',\n content,\n ...(options.assistant ? {assistant: options.assistant} : {}),\n },\n });\n },\n\n /**\n * Returns the summary of a meeting\n * @param {Object} options\n * @param {string} options.meetingInstanceId the meeting instance ID for the meeting from locus\n * @param {string} options.meetingSite the name.webex.com site for the meeting\n * @param {string} options.sessionId the session ID for subsequent requests, not required for the first request\n * @param {string} options.encryptionKeyUrl the encryption key URL for this meeting summary\n * @param {number} options.lastMinutes Optional number of minutes to summarize from the end of the meeting. If not included, summarizes from the start.\n * @returns {Promise<Object>} Resolves with an object containing the requestId, sessionId and streamEventName\n */\n summarizeMeeting(options: SummarizeMeetingOptions): Promise<RequestResponse> {\n return this._makeMeetingRequest({\n ...options,\n contentType: CONTENT_TYPES.ACTION,\n contentValue: ACTION_TYPES.SUMMARIZE_FOR_ME,\n contextResources: [\n {\n id: options.meetingInstanceId,\n type: CONTEXT_RESOURCE_TYPES.MEETING,\n url: options.meetingSite,\n },\n ],\n ...(options.lastMinutes ? {parameters: {lastMinutes: options.lastMinutes}} : {}),\n });\n },\n\n /**\n * Checks if the user's name was mentioned in a meeting\n * @param {Object} options\n * @param {string} options.meetingInstanceId the meeting instance ID for the meeting from locus\n * @param {string} options.meetingSite the name.webex.com site for the meeting\n * @param {string} options.sessionId the session ID for subsequent requests, not required for the first request\n * @param {string} options.encryptionKeyUrl the encryption key URL for this meeting summary\n * @returns {Promise<Object>} Resolves with an object containing the requestId, sessionId and streamEventName\n */\n wasMyNameMentioned(options: SummarizeMeetingOptions): Promise<RequestResponse> {\n return this._makeMeetingRequest({\n ...options,\n contextResources: [\n {\n id: options.meetingInstanceId,\n type: CONTEXT_RESOURCE_TYPES.MEETING,\n url: options.meetingSite,\n },\n ],\n contentType: CONTENT_TYPES.ACTION,\n contentValue: ACTION_TYPES.WAS_MY_NAME_MENTIONED,\n });\n },\n\n /**\n * Returns all action items from a meeting\n * @param {Object} options\n * @param {string} options.meetingInstanceId the meeting instance ID for the meeting from locus\n * @param {string} options.meetingSite the name.webex.com site for the meeting\n * @param {string} options.sessionId the session ID for subsequent requests, not required for the first request\n * @param {string} options.encryptionKeyUrl the encryption key URL for this meeting summary\n * @returns {Promise<Object>} Resolves with an object containing the requestId, sessionId and streamEventName\n */\n showAllActionItems(options: SummarizeMeetingOptions): Promise<RequestResponse> {\n return this._makeMeetingRequest({\n ...options,\n contextResources: [\n {\n id: options.meetingInstanceId,\n type: CONTEXT_RESOURCE_TYPES.MEETING,\n url: options.meetingSite,\n },\n ],\n contentType: CONTENT_TYPES.ACTION,\n contentValue: ACTION_TYPES.SHOW_ALL_ACTION_ITEMS,\n });\n },\n\n /**\n * Helper method to encrypt text using the encryption key URL\n * @param {Object} options\n * @param {string} options.text the text to encrypt\n * @param {string} options.encryptionKeyUrl the encryption key URL to use for encryption\n * @returns {Promise<string>} returns a promise that resolves with the encrypted text\n */\n async _encryptData({text, encryptionKeyUrl}) {\n const result = await this.webex.internal.encryption.encryptText(encryptionKeyUrl, text);\n\n return result;\n },\n\n /**\n * Ask any question about the meeting content\n * @param {Object} options\n * @param {string} options.meetingInstanceId the meeting instance ID for the meeting from locus\n * @param {string} options.meetingSite the name.webex.com site for the meeting\n * @param {string} options.sessionId the session ID for subsequent requests, not required for the first request\n * @param {string} options.encryptionKeyUrl the encryption key URL for this meeting summary\n * @param {string} options.question the question to ask about the meeting content\n * @returns {Promise<Object>} Resolves with an object containing the requestId, sessionId and streamEventName\n */\n askMeAnything(options: SummarizeMeetingOptions & {question: string}): Promise<RequestResponse> {\n return this._makeMeetingRequest({\n ...options,\n contextResources: [\n {\n id: options.meetingInstanceId,\n type: CONTEXT_RESOURCE_TYPES.MEETING,\n url: options.meetingSite,\n },\n ],\n contentType: CONTENT_TYPES.MESSAGE,\n contentValue: options.question,\n });\n },\n});\n\nexport default AIAssistant;\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"names":["_uuid","_interopRequireDefault","require","_webexCore","_lodash","_commonTimers","_constants","_utils","ownKeys","e","r","t","_Object$keys","_Object$getOwnPropertySymbols","o","filter","_Object$getOwnPropertyDescriptor","enumerable","push","apply","_objectSpread","arguments","length","Object","forEach","_defineProperty2","default","_Object$getOwnPropertyDescriptors","_Object$defineProperties","_Object$defineProperty","AIAssistant","WebexPlugin","extend","namespace","registered","initialize","_len","args","Array","_key","_apply","prototype","register","_this","webex","canAuthorize","logger","error","_promise","reject","Error","info","resolve","internal","mercury","connect","then","listenForEvents","trigger","AI_ASSISTANT_REGISTERED","catch","concat","message","unregister","_this2","stopListeningForEvents","disconnect","AI_ASSISTANT_UNREGISTERED","_this3","on","ASSISTANT_API_RESPONSE_EVENT","envelope","_handleEvent","data","off","_getResultEventName","requestId","AI_ASSISTANT_RESULT","_getStreamEventName","AI_ASSISTANT_STREAM","clientRequestId","_decryptContent","responseContent","_this4","_asyncToGenerator2","_regenerator","mark","_callee","wrap","_callee$","_context","prev","next","t0","name","RESPONSE_NAMES","MESSAGE","CITED_ANSWER","TOOL_RESULT","TOOL_USE","WORKSPACE","decryptMessage","abrupt","decryptCitedAnswer","decryptToolUse","decryptWorkspace","stop","_request","options","_this5","resource","params","timeout","config","requestTimeout","uuid","v4","eventName","streamEventName","timer","Timer","stopListening","finished","errorMessage","AI_ASSISTANT_ERRORS","AI_ASSISTANT_TIMEOUT","errorCode","AI_ASSISTANT_ERROR_CODES","listenTo","_ref","_callee2","resultData","responseType","decryptErrorMessage","_callee2$","_context2","reset","get","cancel","merge","response","_x","request","service","AI_ASSISTANT_SERVICE_NAME","method","contentType","body","_ref2","start","makeAiAssistantRequest","_this6","_callee3","value","content","_callee3$","_context3","contentValue","_encryptData","text","encryptionKeyUrl","sent","context","resources","contextResources","type","parameters","sessionId","async","locale","assistant","summarizeMeeting","CONTENT_TYPES","ACTION","ACTION_TYPES","SUMMARIZE_FOR_ME","id","meetingInstanceId","CONTEXT_RESOURCE_TYPES","MEETING","url","meetingSite","lastMinutes","wasMyNameMentioned","WAS_MY_NAME_MENTIONED","showAllActionItems","SHOW_ALL_ACTION_ITEMS","_ref3","_this7","_callee4","result","_callee4$","_context4","encryption","encryptText","askMeAnything","question","version","_default","exports"],"sources":["ai-assistant.ts"],"sourcesContent":["/*!\n * Copyright (c) 2015-2022 Cisco Systems, Inc. See LICENSE file.\n */\nimport uuid from 'uuid';\nimport {WebexPlugin} from '@webex/webex-core';\nimport '@webex/internal-plugin-mercury';\nimport {get, merge} from 'lodash';\nimport {Timer} from '@webex/common-timers';\n\nimport {\n AiAssistantRequestOptions,\n RequestOptions,\n RequestResponse,\n SummarizeMeetingOptions,\n} from './types';\nimport {\n AI_ASSISTANT_ERROR_CODES,\n AI_ASSISTANT_ERRORS,\n AI_ASSISTANT_REGISTERED,\n AI_ASSISTANT_RESULT,\n AI_ASSISTANT_STREAM,\n AI_ASSISTANT_UNREGISTERED,\n AI_ASSISTANT_SERVICE_NAME,\n ASSISTANT_API_RESPONSE_EVENT,\n ACTION_TYPES,\n CONTENT_TYPES,\n CONTEXT_RESOURCE_TYPES,\n RESPONSE_NAMES,\n} from './constants';\nimport {decryptCitedAnswer, decryptMessage, decryptToolUse, decryptWorkspace} from './utils';\n\nconst AIAssistant = WebexPlugin.extend({\n namespace: 'AIAssistant',\n\n /**\n * registered value indicating events registration is successful\n * @instance\n * @type {Boolean}\n * @memberof AIAssistant\n */\n registered: false,\n\n /**\n * Initializer\n * @private\n * @param {Object} attrs\n * @param {Object} options\n * @returns {undefined}\n */\n initialize(...args) {\n Reflect.apply(WebexPlugin.prototype.initialize, this, args);\n },\n\n /**\n * Explicitly sets up the AI assistant plugin by connecting to mercury, and listening for AI assistant events.\n * @returns {Promise}\n * @public\n * @memberof AIAssistant\n */\n register() {\n if (!this.webex.canAuthorize) {\n this.logger.error('AI assistant->register#ERROR, Unable to register, SDK cannot authorize');\n\n return Promise.reject(new Error('SDK cannot authorize'));\n }\n\n if (this.registered) {\n this.logger.info('AI assistant->register#INFO, AI assistant plugin already registered');\n\n return Promise.resolve();\n }\n\n return this.webex.internal.mercury\n .connect()\n .then(() => {\n this.listenForEvents();\n this.trigger(AI_ASSISTANT_REGISTERED);\n this.registered = true;\n })\n .catch((error) => {\n this.logger.error(`AI assistant->register#ERROR, Unable to register, ${error.message}`);\n\n return Promise.reject(error);\n });\n },\n\n /**\n * Explicitly tears down the AI assistant plugin by disconnecting from mercury, and stops listening to AI assistant events\n * @returns {Promise}\n * @public\n * @memberof AIAssistant\n */\n unregister() {\n if (!this.registered) {\n this.logger.info('AI assistant->unregister#INFO, AI assistant plugin already unregistered');\n\n return Promise.resolve();\n }\n\n this.stopListeningForEvents();\n\n return this.webex.internal.mercury.disconnect().then(() => {\n this.trigger(AI_ASSISTANT_UNREGISTERED);\n this.registered = false;\n });\n },\n\n /**\n * registers for Assistant API events through mercury\n * @returns {undefined}\n * @private\n */\n listenForEvents() {\n this.webex.internal.mercury.on(ASSISTANT_API_RESPONSE_EVENT, (envelope) => {\n this._handleEvent(envelope.data);\n });\n },\n\n /**\n * unregisteres all the Assistant API events from mercury\n * @returns {undefined}\n * @private\n */\n stopListeningForEvents() {\n this.webex.internal.mercury.off(ASSISTANT_API_RESPONSE_EVENT);\n },\n\n /**\n * constructs the event name based on request id\n * This is used by the plugin to listen for the result of a particular request\n * @param {UUID} requestId the id of the request\n * @returns {string}\n */\n _getResultEventName(requestId: string) {\n return `${AI_ASSISTANT_RESULT}:${requestId}`;\n },\n\n /**\n * constructs the stream event name based on request id\n * This is used by the consumer to listen for the stream (i.e. the data) of a particular request\n * @param {UUID} requestId the id of the request\n * @returns {string}\n */\n _getStreamEventName(requestId: string) {\n return `${AI_ASSISTANT_STREAM}:${requestId}`;\n },\n\n /**\n * Takes incoming data and triggers correct events\n * @param {Object} data the event data\n * @returns {undefined}\n */\n _handleEvent(data) {\n this.trigger(this._getResultEventName(data.clientRequestId), data);\n },\n\n /**\n * Decrypts the response content in place\n * @param {any} responseContent the content object from the assistant-api response\n * @returns {Promise} resolves once decryption is complete\n */\n async _decryptContent(responseContent) {\n switch (responseContent.name) {\n case RESPONSE_NAMES.MESSAGE: {\n await decryptMessage(responseContent, this.webex);\n break;\n }\n case RESPONSE_NAMES.CITED_ANSWER: {\n await decryptCitedAnswer(responseContent, this.webex);\n break;\n }\n case RESPONSE_NAMES.TOOL_RESULT: {\n // No encrypted content in tool_result\n break;\n }\n case RESPONSE_NAMES.TOOL_USE: {\n await decryptToolUse(responseContent, this.webex);\n break;\n }\n case RESPONSE_NAMES.WORKSPACE: {\n await decryptWorkspace(responseContent, this.webex);\n break;\n }\n default:\n this.logger.error(\n `AI assistant->_decryptContent#ERROR, Unknown response content name: ${responseContent.name}`\n );\n }\n },\n\n /**\n * Makes the request to the AI assistant service\n * @param {Object} options\n * @param {string} options.resource the URL to query\n * @param {Mixed} options.params additional params for the body of the request\n * @returns {Promise<Object>} Resolves with an object containing the requestId, sessionId and streamEventName\n */\n _request(options: RequestOptions): Promise<RequestResponse> {\n const {resource, params} = options;\n\n const timeout = this.config.requestTimeout;\n const requestId = options.requestId || uuid.v4();\n const eventName = this._getResultEventName(requestId);\n const streamEventName = this._getStreamEventName(requestId);\n\n // eslint-disable-next-line no-async-promise-executor\n return new Promise((resolve, reject) => {\n const timer = new Timer(() => {\n this.stopListening(this, eventName);\n this.trigger(streamEventName, {\n requestId,\n finished: true,\n errorMessage: AI_ASSISTANT_ERRORS.AI_ASSISTANT_TIMEOUT,\n errorCode: AI_ASSISTANT_ERROR_CODES.AI_ASSISTANT_TIMEOUT,\n });\n }, timeout);\n\n this.listenTo(this, eventName, async (data) => {\n timer.reset();\n const resultData = get(data, 'response.content', {});\n const errorMessage = get(data, 'response.errorMessage');\n const errorCode = get(data, 'response.errorCode');\n const responseType = get(data, 'responseType');\n\n if (data.finished) {\n timer.cancel();\n this.stopListening(this, eventName);\n }\n\n let decryptErrorMessage;\n\n try {\n if (!errorCode) {\n await this._decryptContent(resultData);\n }\n } catch (decryptError) {\n decryptErrorMessage = decryptError.message;\n }\n\n this.trigger(\n streamEventName,\n merge({}, data.response, {\n responseType,\n requestId,\n finished: data.finished,\n errorMessage: errorMessage || decryptErrorMessage,\n errorCode,\n })\n );\n });\n\n this.webex\n .request({\n service: AI_ASSISTANT_SERVICE_NAME,\n resource,\n method: 'POST',\n contentType: 'application/json',\n body: {clientRequestId: requestId, ...params},\n })\n .then(({body}) => {\n resolve({...body, requestId, streamEventName});\n })\n .catch((error) => {\n reject(error);\n });\n\n timer.start();\n });\n },\n\n /**\n * Common method to make AI assistant requests for meeting analysis\n * @param {Object} options\n * @param {string} options.contextResources array of context resources to include in the request\n * @param {string} options.sessionId the session ID for subsequent requests, not required for the first request\n * @param {string} options.encryptionKeyUrl the encryption key URL for this meeting summary\n * @param {string} options.contentType the type of content ('action' or 'message')\n * @param {string} options.contentValue the value to use (action name or message text)\n * @param {Object} options.parameters optional parameters to include in the request (for action type only)\n * @param {Object} options.assistant optional parameter to specify the assistant to use\n * @param {Object} options.locale optional locale to use for the request, defaults to 'en_US'\n * @param {string} options.requestId optional request ID to use for this request, if not provided a new UUID will be generated\n * @returns {Promise<Object>} Resolves with an object containing the requestId, sessionId and streamEventName\n * @public\n * @memberof AIAssistant\n */\n async makeAiAssistantRequest(options: AiAssistantRequestOptions): Promise<RequestResponse> {\n let value = options.contentValue;\n\n if (options.contentType === 'message') {\n value = await this._encryptData({\n text: options.contentValue,\n encryptionKeyUrl: options.encryptionKeyUrl,\n });\n }\n\n const content: any = {\n context: {\n resources: options.contextResources,\n },\n encryptionKeyUrl: options.encryptionKeyUrl,\n type: options.contentType,\n value,\n };\n\n if (options.parameters) {\n content.parameters = options.parameters;\n }\n\n return this._request({\n resource: options.sessionId ? `sessions/${options.sessionId}/messages` : 'sessions/messages',\n params: {\n async: 'chunked',\n locale: options.locale || 'en_US',\n content,\n ...(options.assistant ? {assistant: options.assistant} : {}),\n },\n ...(options.requestId ? {requestId: options.requestId} : {}),\n });\n },\n\n /**\n * Returns the summary of a meeting\n * @param {Object} options\n * @param {string} options.meetingInstanceId the meeting instance ID for the meeting from locus\n * @param {string} options.meetingSite the name.webex.com site for the meeting\n * @param {string} options.sessionId the session ID for subsequent requests, not required for the first request\n * @param {string} options.encryptionKeyUrl the encryption key URL for this meeting summary\n * @param {number} options.lastMinutes Optional number of minutes to summarize from the end of the meeting. If not included, summarizes from the start.\n * @param {string} options.requestId optional request ID to use for this request, if not provided a new UUID will be generated\n * @returns {Promise<Object>} Resolves with an object containing the requestId, sessionId and streamEventName\n */\n summarizeMeeting(options: SummarizeMeetingOptions): Promise<RequestResponse> {\n return this.makeAiAssistantRequest({\n ...options,\n contentType: CONTENT_TYPES.ACTION,\n contentValue: ACTION_TYPES.SUMMARIZE_FOR_ME,\n contextResources: [\n {\n id: options.meetingInstanceId,\n type: CONTEXT_RESOURCE_TYPES.MEETING,\n url: options.meetingSite,\n },\n ],\n ...(options.lastMinutes ? {parameters: {lastMinutes: options.lastMinutes}} : {}),\n });\n },\n\n /**\n * Checks if the user's name was mentioned in a meeting\n * @param {Object} options\n * @param {string} options.meetingInstanceId the meeting instance ID for the meeting from locus\n * @param {string} options.meetingSite the name.webex.com site for the meeting\n * @param {string} options.sessionId the session ID for subsequent requests, not required for the first request\n * @param {string} options.encryptionKeyUrl the encryption key URL for this meeting summary\n * @param {string} options.requestId optional request ID to use for this request, if not provided a new UUID will be generated\n * @returns {Promise<Object>} Resolves with an object containing the requestId, sessionId and streamEventName\n */\n wasMyNameMentioned(options: SummarizeMeetingOptions): Promise<RequestResponse> {\n return this.makeAiAssistantRequest({\n ...options,\n contextResources: [\n {\n id: options.meetingInstanceId,\n type: CONTEXT_RESOURCE_TYPES.MEETING,\n url: options.meetingSite,\n },\n ],\n contentType: CONTENT_TYPES.ACTION,\n contentValue: ACTION_TYPES.WAS_MY_NAME_MENTIONED,\n });\n },\n\n /**\n * Returns all action items from a meeting\n * @param {Object} options\n * @param {string} options.meetingInstanceId the meeting instance ID for the meeting from locus\n * @param {string} options.meetingSite the name.webex.com site for the meeting\n * @param {string} options.sessionId the session ID for subsequent requests, not required for the first request\n * @param {string} options.encryptionKeyUrl the encryption key URL for this meeting summary\n * @param {string} options.requestId optional request ID to use for this request, if not provided a new UUID will be generated\n * @returns {Promise<Object>} Resolves with an object containing the requestId, sessionId and streamEventName\n */\n showAllActionItems(options: SummarizeMeetingOptions): Promise<RequestResponse> {\n return this.makeAiAssistantRequest({\n ...options,\n contextResources: [\n {\n id: options.meetingInstanceId,\n type: CONTEXT_RESOURCE_TYPES.MEETING,\n url: options.meetingSite,\n },\n ],\n contentType: CONTENT_TYPES.ACTION,\n contentValue: ACTION_TYPES.SHOW_ALL_ACTION_ITEMS,\n });\n },\n\n /**\n * Helper method to encrypt text using the encryption key URL\n * @param {Object} options\n * @param {string} options.text the text to encrypt\n * @param {string} options.encryptionKeyUrl the encryption key URL to use for encryption\n * @returns {Promise<string>} returns a promise that resolves with the encrypted text\n */\n async _encryptData({text, encryptionKeyUrl}) {\n const result = await this.webex.internal.encryption.encryptText(encryptionKeyUrl, text);\n\n return result;\n },\n\n /**\n * Ask any question about the meeting content\n * @param {Object} options\n * @param {string} options.meetingInstanceId the meeting instance ID for the meeting from locus\n * @param {string} options.meetingSite the name.webex.com site for the meeting\n * @param {string} options.sessionId the session ID for subsequent requests, not required for the first request\n * @param {string} options.encryptionKeyUrl the encryption key URL for this meeting summary\n * @param {string} options.question the question to ask about the meeting content\n * @param {string} options.requestId optional request ID to use for this request, if not provided a new UUID will be generated\n * @returns {Promise<Object>} Resolves with an object containing the requestId, sessionId and streamEventName\n */\n askMeAnything(options: SummarizeMeetingOptions & {question: string}): Promise<RequestResponse> {\n return this.makeAiAssistantRequest({\n ...options,\n contextResources: [\n {\n id: options.meetingInstanceId,\n type: CONTEXT_RESOURCE_TYPES.MEETING,\n url: options.meetingSite,\n },\n ],\n contentType: CONTENT_TYPES.MESSAGE,\n contentValue: options.question,\n });\n },\n});\n\nexport default AIAssistant;\n"],"mappings":"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"}
|
package/dist/types.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":[],"sources":["types.ts"],"sourcesContent":["export interface RequestResponse {\n sessionId: string;\n requestId: string;\n streamEventName: string;\n id: string;\n url: string;\n sessionUrl: string;\n creatorId: string;\n createdAt: string;\n}\n\nexport interface StreamEvent {\n message: string;\n requestId: string;\n finished: boolean;\n error: string | null;\n}\n\nexport interface RequestOptions {\n resource: string;\n dataPath: string;\n foundPath?: string;\n notFoundPath?: string;\n params?: Record<string, unknown>;\n}\n\nexport interface ContextResource {\n id: string;\n type: string;\n url: string;\n}\n\nexport interface SummarizeMeetingOptions {\n assistant?: string;\n meetingInstanceId: string;\n meetingSite: string;\n sessionId: string;\n encryptionKeyUrl: string;\n lastMinutes?: number;\n}\n\nexport interface
|
|
1
|
+
{"version":3,"names":[],"sources":["types.ts"],"sourcesContent":["export interface RequestResponse {\n sessionId: string;\n requestId: string;\n streamEventName: string;\n id: string;\n url: string;\n sessionUrl: string;\n creatorId: string;\n createdAt: string;\n}\n\nexport interface StreamEvent {\n message: string;\n requestId: string;\n finished: boolean;\n error: string | null;\n}\n\nexport interface RequestOptions {\n resource: string;\n dataPath: string;\n foundPath?: string;\n notFoundPath?: string;\n params?: Record<string, unknown>;\n requestId?: string;\n}\n\nexport interface ContextResource {\n id: string;\n type: string;\n url: string;\n}\n\nexport interface SummarizeMeetingOptions {\n assistant?: string;\n meetingInstanceId: string;\n meetingSite: string;\n sessionId: string;\n encryptionKeyUrl: string;\n lastMinutes?: number;\n requestId?: string;\n}\n\nexport interface AiAssistantRequestOptions {\n sessionId: string;\n encryptionKeyUrl: string;\n contextResources: ContextResource[];\n contentType: 'action' | 'message';\n contentValue: string;\n parameters?: any;\n assistant?: string;\n locale?: string;\n requestId?: string;\n}\n"],"mappings":""}
|
package/package.json
CHANGED
package/src/ai-assistant.ts
CHANGED
|
@@ -8,7 +8,7 @@ import {get, merge} from 'lodash';
|
|
|
8
8
|
import {Timer} from '@webex/common-timers';
|
|
9
9
|
|
|
10
10
|
import {
|
|
11
|
-
|
|
11
|
+
AiAssistantRequestOptions,
|
|
12
12
|
RequestOptions,
|
|
13
13
|
RequestResponse,
|
|
14
14
|
SummarizeMeetingOptions,
|
|
@@ -199,7 +199,7 @@ const AIAssistant = WebexPlugin.extend({
|
|
|
199
199
|
const {resource, params} = options;
|
|
200
200
|
|
|
201
201
|
const timeout = this.config.requestTimeout;
|
|
202
|
-
const requestId = uuid.v4();
|
|
202
|
+
const requestId = options.requestId || uuid.v4();
|
|
203
203
|
const eventName = this._getResultEventName(requestId);
|
|
204
204
|
const streamEventName = this._getStreamEventName(requestId);
|
|
205
205
|
|
|
@@ -257,13 +257,14 @@ const AIAssistant = WebexPlugin.extend({
|
|
|
257
257
|
contentType: 'application/json',
|
|
258
258
|
body: {clientRequestId: requestId, ...params},
|
|
259
259
|
})
|
|
260
|
-
.catch((error) => {
|
|
261
|
-
reject(error);
|
|
262
|
-
})
|
|
263
260
|
.then(({body}) => {
|
|
264
261
|
resolve({...body, requestId, streamEventName});
|
|
265
|
-
|
|
262
|
+
})
|
|
263
|
+
.catch((error) => {
|
|
264
|
+
reject(error);
|
|
266
265
|
});
|
|
266
|
+
|
|
267
|
+
timer.start();
|
|
267
268
|
});
|
|
268
269
|
},
|
|
269
270
|
|
|
@@ -278,9 +279,12 @@ const AIAssistant = WebexPlugin.extend({
|
|
|
278
279
|
* @param {Object} options.parameters optional parameters to include in the request (for action type only)
|
|
279
280
|
* @param {Object} options.assistant optional parameter to specify the assistant to use
|
|
280
281
|
* @param {Object} options.locale optional locale to use for the request, defaults to 'en_US'
|
|
282
|
+
* @param {string} options.requestId optional request ID to use for this request, if not provided a new UUID will be generated
|
|
281
283
|
* @returns {Promise<Object>} Resolves with an object containing the requestId, sessionId and streamEventName
|
|
284
|
+
* @public
|
|
285
|
+
* @memberof AIAssistant
|
|
282
286
|
*/
|
|
283
|
-
async
|
|
287
|
+
async makeAiAssistantRequest(options: AiAssistantRequestOptions): Promise<RequestResponse> {
|
|
284
288
|
let value = options.contentValue;
|
|
285
289
|
|
|
286
290
|
if (options.contentType === 'message') {
|
|
@@ -311,6 +315,7 @@ const AIAssistant = WebexPlugin.extend({
|
|
|
311
315
|
content,
|
|
312
316
|
...(options.assistant ? {assistant: options.assistant} : {}),
|
|
313
317
|
},
|
|
318
|
+
...(options.requestId ? {requestId: options.requestId} : {}),
|
|
314
319
|
});
|
|
315
320
|
},
|
|
316
321
|
|
|
@@ -322,10 +327,11 @@ const AIAssistant = WebexPlugin.extend({
|
|
|
322
327
|
* @param {string} options.sessionId the session ID for subsequent requests, not required for the first request
|
|
323
328
|
* @param {string} options.encryptionKeyUrl the encryption key URL for this meeting summary
|
|
324
329
|
* @param {number} options.lastMinutes Optional number of minutes to summarize from the end of the meeting. If not included, summarizes from the start.
|
|
330
|
+
* @param {string} options.requestId optional request ID to use for this request, if not provided a new UUID will be generated
|
|
325
331
|
* @returns {Promise<Object>} Resolves with an object containing the requestId, sessionId and streamEventName
|
|
326
332
|
*/
|
|
327
333
|
summarizeMeeting(options: SummarizeMeetingOptions): Promise<RequestResponse> {
|
|
328
|
-
return this.
|
|
334
|
+
return this.makeAiAssistantRequest({
|
|
329
335
|
...options,
|
|
330
336
|
contentType: CONTENT_TYPES.ACTION,
|
|
331
337
|
contentValue: ACTION_TYPES.SUMMARIZE_FOR_ME,
|
|
@@ -347,10 +353,11 @@ const AIAssistant = WebexPlugin.extend({
|
|
|
347
353
|
* @param {string} options.meetingSite the name.webex.com site for the meeting
|
|
348
354
|
* @param {string} options.sessionId the session ID for subsequent requests, not required for the first request
|
|
349
355
|
* @param {string} options.encryptionKeyUrl the encryption key URL for this meeting summary
|
|
356
|
+
* @param {string} options.requestId optional request ID to use for this request, if not provided a new UUID will be generated
|
|
350
357
|
* @returns {Promise<Object>} Resolves with an object containing the requestId, sessionId and streamEventName
|
|
351
358
|
*/
|
|
352
359
|
wasMyNameMentioned(options: SummarizeMeetingOptions): Promise<RequestResponse> {
|
|
353
|
-
return this.
|
|
360
|
+
return this.makeAiAssistantRequest({
|
|
354
361
|
...options,
|
|
355
362
|
contextResources: [
|
|
356
363
|
{
|
|
@@ -371,10 +378,11 @@ const AIAssistant = WebexPlugin.extend({
|
|
|
371
378
|
* @param {string} options.meetingSite the name.webex.com site for the meeting
|
|
372
379
|
* @param {string} options.sessionId the session ID for subsequent requests, not required for the first request
|
|
373
380
|
* @param {string} options.encryptionKeyUrl the encryption key URL for this meeting summary
|
|
381
|
+
* @param {string} options.requestId optional request ID to use for this request, if not provided a new UUID will be generated
|
|
374
382
|
* @returns {Promise<Object>} Resolves with an object containing the requestId, sessionId and streamEventName
|
|
375
383
|
*/
|
|
376
384
|
showAllActionItems(options: SummarizeMeetingOptions): Promise<RequestResponse> {
|
|
377
|
-
return this.
|
|
385
|
+
return this.makeAiAssistantRequest({
|
|
378
386
|
...options,
|
|
379
387
|
contextResources: [
|
|
380
388
|
{
|
|
@@ -409,10 +417,11 @@ const AIAssistant = WebexPlugin.extend({
|
|
|
409
417
|
* @param {string} options.sessionId the session ID for subsequent requests, not required for the first request
|
|
410
418
|
* @param {string} options.encryptionKeyUrl the encryption key URL for this meeting summary
|
|
411
419
|
* @param {string} options.question the question to ask about the meeting content
|
|
420
|
+
* @param {string} options.requestId optional request ID to use for this request, if not provided a new UUID will be generated
|
|
412
421
|
* @returns {Promise<Object>} Resolves with an object containing the requestId, sessionId and streamEventName
|
|
413
422
|
*/
|
|
414
423
|
askMeAnything(options: SummarizeMeetingOptions & {question: string}): Promise<RequestResponse> {
|
|
415
|
-
return this.
|
|
424
|
+
return this.makeAiAssistantRequest({
|
|
416
425
|
...options,
|
|
417
426
|
contextResources: [
|
|
418
427
|
{
|
package/src/types.ts
CHANGED
|
@@ -22,6 +22,7 @@ export interface RequestOptions {
|
|
|
22
22
|
foundPath?: string;
|
|
23
23
|
notFoundPath?: string;
|
|
24
24
|
params?: Record<string, unknown>;
|
|
25
|
+
requestId?: string;
|
|
25
26
|
}
|
|
26
27
|
|
|
27
28
|
export interface ContextResource {
|
|
@@ -37,9 +38,10 @@ export interface SummarizeMeetingOptions {
|
|
|
37
38
|
sessionId: string;
|
|
38
39
|
encryptionKeyUrl: string;
|
|
39
40
|
lastMinutes?: number;
|
|
41
|
+
requestId?: string;
|
|
40
42
|
}
|
|
41
43
|
|
|
42
|
-
export interface
|
|
44
|
+
export interface AiAssistantRequestOptions {
|
|
43
45
|
sessionId: string;
|
|
44
46
|
encryptionKeyUrl: string;
|
|
45
47
|
contextResources: ContextResource[];
|
|
@@ -48,4 +50,5 @@ export interface MakeMeetingRequestOptions {
|
|
|
48
50
|
parameters?: any;
|
|
49
51
|
assistant?: string;
|
|
50
52
|
locale?: string;
|
|
53
|
+
requestId?: string;
|
|
51
54
|
}
|
|
@@ -779,5 +779,324 @@ describe('plugin-ai-assistant', () => {
|
|
|
779
779
|
});
|
|
780
780
|
});
|
|
781
781
|
});
|
|
782
|
+
|
|
783
|
+
describe('#makeAiAssistantRequest', () => {
|
|
784
|
+
beforeEach(() => {
|
|
785
|
+
webex.request = sinon.stub().resolves({
|
|
786
|
+
body: {
|
|
787
|
+
id: 'test-message-id',
|
|
788
|
+
url: 'https://assistant-api-a.wbx2.com:443/assistant-api/api/v1/sessions/test-session-id/messages/test-message-id',
|
|
789
|
+
sessionId: 'test-session-id',
|
|
790
|
+
sessionUrl: 'https://assistant-api-a.wbx2.com:443/assistant-api/api/v1/sessions/test-session-id',
|
|
791
|
+
creatorId: 'test-creator-id',
|
|
792
|
+
createdAt: '2025-08-05T02:11:12.361Z',
|
|
793
|
+
},
|
|
794
|
+
});
|
|
795
|
+
|
|
796
|
+
// Mock encryption functions
|
|
797
|
+
webex.internal.encryption = {
|
|
798
|
+
encryptText: sinon.stub().callsFake(async (keyUrl, text) => {
|
|
799
|
+
return `encrypted-${text}`;
|
|
800
|
+
}),
|
|
801
|
+
};
|
|
802
|
+
});
|
|
803
|
+
|
|
804
|
+
it('makes a request with action content type without encryption', async () => {
|
|
805
|
+
const options = {
|
|
806
|
+
sessionId: 'test-session-id',
|
|
807
|
+
encryptionKeyUrl: 'test-key-url',
|
|
808
|
+
contextResources: [
|
|
809
|
+
{
|
|
810
|
+
id: 'meeting-123',
|
|
811
|
+
type: 'meeting',
|
|
812
|
+
url: 'company.webex.com',
|
|
813
|
+
},
|
|
814
|
+
],
|
|
815
|
+
contentType: 'action' as const,
|
|
816
|
+
contentValue: 'summarize_for_me',
|
|
817
|
+
locale: 'en_US',
|
|
818
|
+
assistant: 'meeting-assistant',
|
|
819
|
+
requestId: 'custom-request-id',
|
|
820
|
+
};
|
|
821
|
+
|
|
822
|
+
const result = await webex.internal.aiAssistant.makeAiAssistantRequest(options);
|
|
823
|
+
|
|
824
|
+
// Verify the request was made correctly
|
|
825
|
+
expect(webex.request.calledOnce).to.be.true;
|
|
826
|
+
const requestArgs = webex.request.getCall(0).args[0];
|
|
827
|
+
|
|
828
|
+
expect(requestArgs.service).to.equal('assistant-api');
|
|
829
|
+
expect(requestArgs.resource).to.equal('sessions/test-session-id/messages');
|
|
830
|
+
expect(requestArgs.method).to.equal('POST');
|
|
831
|
+
expect(requestArgs.contentType).to.equal('application/json');
|
|
832
|
+
expect(requestArgs.body).to.deep.equal({
|
|
833
|
+
clientRequestId: 'custom-request-id',
|
|
834
|
+
async: 'chunked',
|
|
835
|
+
locale: 'en_US',
|
|
836
|
+
content: {
|
|
837
|
+
context: {
|
|
838
|
+
resources: [
|
|
839
|
+
{
|
|
840
|
+
id: 'meeting-123',
|
|
841
|
+
type: 'meeting',
|
|
842
|
+
url: 'company.webex.com',
|
|
843
|
+
},
|
|
844
|
+
],
|
|
845
|
+
},
|
|
846
|
+
encryptionKeyUrl: 'test-key-url',
|
|
847
|
+
type: 'action',
|
|
848
|
+
value: 'summarize_for_me',
|
|
849
|
+
},
|
|
850
|
+
assistant: 'meeting-assistant',
|
|
851
|
+
});
|
|
852
|
+
|
|
853
|
+
// Verify encryption was not called for action content
|
|
854
|
+
expect(webex.internal.encryption.encryptText.notCalled).to.be.true;
|
|
855
|
+
|
|
856
|
+
// Verify return value
|
|
857
|
+
expect(result).to.deep.equal({
|
|
858
|
+
id: 'test-message-id',
|
|
859
|
+
url: 'https://assistant-api-a.wbx2.com:443/assistant-api/api/v1/sessions/test-session-id/messages/test-message-id',
|
|
860
|
+
sessionId: 'test-session-id',
|
|
861
|
+
sessionUrl: 'https://assistant-api-a.wbx2.com:443/assistant-api/api/v1/sessions/test-session-id',
|
|
862
|
+
creatorId: 'test-creator-id',
|
|
863
|
+
createdAt: '2025-08-05T02:11:12.361Z',
|
|
864
|
+
requestId: 'custom-request-id',
|
|
865
|
+
streamEventName: 'aiassistant:stream:custom-request-id',
|
|
866
|
+
});
|
|
867
|
+
});
|
|
868
|
+
|
|
869
|
+
it('makes a request with message content type and encrypts the content', async () => {
|
|
870
|
+
const options = {
|
|
871
|
+
sessionId: 'test-session-id',
|
|
872
|
+
encryptionKeyUrl: 'test-key-url',
|
|
873
|
+
contextResources: [
|
|
874
|
+
{
|
|
875
|
+
id: 'meeting-123',
|
|
876
|
+
type: 'meeting',
|
|
877
|
+
url: 'company.webex.com',
|
|
878
|
+
},
|
|
879
|
+
],
|
|
880
|
+
contentType: 'message' as const,
|
|
881
|
+
contentValue: 'What were the action items?',
|
|
882
|
+
};
|
|
883
|
+
|
|
884
|
+
const result = await webex.internal.aiAssistant.makeAiAssistantRequest(options);
|
|
885
|
+
|
|
886
|
+
// Verify encryption was called for message content
|
|
887
|
+
expect(webex.internal.encryption.encryptText.calledOnce).to.be.true;
|
|
888
|
+
expect(webex.internal.encryption.encryptText.getCall(0).args).to.deep.equal([
|
|
889
|
+
'test-key-url',
|
|
890
|
+
'What were the action items?',
|
|
891
|
+
]);
|
|
892
|
+
|
|
893
|
+
// Verify the request was made with encrypted content
|
|
894
|
+
const requestArgs = webex.request.getCall(0).args[0];
|
|
895
|
+
expect(requestArgs.body.content.value).to.equal('encrypted-What were the action items?');
|
|
896
|
+
expect(requestArgs.body.content.type).to.equal('message');
|
|
897
|
+
});
|
|
898
|
+
|
|
899
|
+
it('uses default locale when not provided', async () => {
|
|
900
|
+
const options = {
|
|
901
|
+
sessionId: 'test-session-id',
|
|
902
|
+
encryptionKeyUrl: 'test-key-url',
|
|
903
|
+
contextResources: [],
|
|
904
|
+
contentType: 'action' as const,
|
|
905
|
+
contentValue: 'test_action',
|
|
906
|
+
};
|
|
907
|
+
|
|
908
|
+
await webex.internal.aiAssistant.makeAiAssistantRequest(options);
|
|
909
|
+
|
|
910
|
+
const requestArgs = webex.request.getCall(0).args[0];
|
|
911
|
+
expect(requestArgs.body.locale).to.equal('en_US');
|
|
912
|
+
});
|
|
913
|
+
|
|
914
|
+
it('uses sessions/messages endpoint when no sessionId provided', async () => {
|
|
915
|
+
const options = {
|
|
916
|
+
sessionId: '',
|
|
917
|
+
encryptionKeyUrl: 'test-key-url',
|
|
918
|
+
contextResources: [],
|
|
919
|
+
contentType: 'action' as const,
|
|
920
|
+
contentValue: 'test_action',
|
|
921
|
+
};
|
|
922
|
+
|
|
923
|
+
await webex.internal.aiAssistant.makeAiAssistantRequest(options);
|
|
924
|
+
|
|
925
|
+
const requestArgs = webex.request.getCall(0).args[0];
|
|
926
|
+
expect(requestArgs.resource).to.equal('sessions/messages');
|
|
927
|
+
});
|
|
928
|
+
|
|
929
|
+
it('includes parameters when provided for action content type', async () => {
|
|
930
|
+
const options = {
|
|
931
|
+
sessionId: 'test-session-id',
|
|
932
|
+
encryptionKeyUrl: 'test-key-url',
|
|
933
|
+
contextResources: [],
|
|
934
|
+
contentType: 'action' as const,
|
|
935
|
+
contentValue: 'summarize_for_me',
|
|
936
|
+
parameters: {
|
|
937
|
+
lastMinutes: 30,
|
|
938
|
+
},
|
|
939
|
+
};
|
|
940
|
+
|
|
941
|
+
await webex.internal.aiAssistant.makeAiAssistantRequest(options);
|
|
942
|
+
|
|
943
|
+
const requestArgs = webex.request.getCall(0).args[0];
|
|
944
|
+
expect(requestArgs.body.content.parameters).to.deep.equal({
|
|
945
|
+
lastMinutes: 30,
|
|
946
|
+
});
|
|
947
|
+
});
|
|
948
|
+
|
|
949
|
+
it('generates UUID when requestId is not provided', async () => {
|
|
950
|
+
const options = {
|
|
951
|
+
sessionId: 'test-session-id',
|
|
952
|
+
encryptionKeyUrl: 'test-key-url',
|
|
953
|
+
contextResources: [],
|
|
954
|
+
contentType: 'action' as const,
|
|
955
|
+
contentValue: 'test_action',
|
|
956
|
+
};
|
|
957
|
+
|
|
958
|
+
const result = await webex.internal.aiAssistant.makeAiAssistantRequest(options);
|
|
959
|
+
|
|
960
|
+
// Should use the UUID stub
|
|
961
|
+
expect(result.requestId).to.equal('test-request-id');
|
|
962
|
+
expect(result.streamEventName).to.equal('aiassistant:stream:test-request-id');
|
|
963
|
+
|
|
964
|
+
const requestArgs = webex.request.getCall(0).args[0];
|
|
965
|
+
expect(requestArgs.body.clientRequestId).to.equal('test-request-id');
|
|
966
|
+
});
|
|
967
|
+
|
|
968
|
+
it('does not include assistant in request when not provided', async () => {
|
|
969
|
+
const options = {
|
|
970
|
+
sessionId: 'test-session-id',
|
|
971
|
+
encryptionKeyUrl: 'test-key-url',
|
|
972
|
+
contextResources: [],
|
|
973
|
+
contentType: 'action' as const,
|
|
974
|
+
contentValue: 'test_action',
|
|
975
|
+
};
|
|
976
|
+
|
|
977
|
+
await webex.internal.aiAssistant.makeAiAssistantRequest(options);
|
|
978
|
+
|
|
979
|
+
const requestArgs = webex.request.getCall(0).args[0];
|
|
980
|
+
expect(requestArgs.body.assistant).to.be.undefined;
|
|
981
|
+
});
|
|
982
|
+
|
|
983
|
+
it('handles request rejection', async () => {
|
|
984
|
+
webex.request.rejects(new Error('Network error'));
|
|
985
|
+
|
|
986
|
+
const options = {
|
|
987
|
+
sessionId: 'test-session-id',
|
|
988
|
+
encryptionKeyUrl: 'test-key-url',
|
|
989
|
+
contextResources: [],
|
|
990
|
+
contentType: 'action' as const,
|
|
991
|
+
contentValue: 'test_action',
|
|
992
|
+
};
|
|
993
|
+
|
|
994
|
+
await expect(
|
|
995
|
+
webex.internal.aiAssistant.makeAiAssistantRequest(options)
|
|
996
|
+
).to.be.rejectedWith('Network error');
|
|
997
|
+
});
|
|
998
|
+
|
|
999
|
+
it('starts timer when making a request', async () => {
|
|
1000
|
+
const options = {
|
|
1001
|
+
sessionId: 'test-session-id',
|
|
1002
|
+
encryptionKeyUrl: 'test-key-url',
|
|
1003
|
+
contextResources: [],
|
|
1004
|
+
contentType: 'action' as const,
|
|
1005
|
+
contentValue: 'test_action',
|
|
1006
|
+
};
|
|
1007
|
+
|
|
1008
|
+
await webex.internal.aiAssistant.makeAiAssistantRequest(options);
|
|
1009
|
+
|
|
1010
|
+
// Verify timer.start() was called
|
|
1011
|
+
expect(timerSpy.calledOnce).to.be.true;
|
|
1012
|
+
});
|
|
1013
|
+
|
|
1014
|
+
it('handles timeout when no streaming response comes back', async () => {
|
|
1015
|
+
const triggerSpy = sinon.spy(webex.internal.aiAssistant, 'trigger');
|
|
1016
|
+
|
|
1017
|
+
const options = {
|
|
1018
|
+
sessionId: 'test-session-id',
|
|
1019
|
+
encryptionKeyUrl: 'test-key-url',
|
|
1020
|
+
contextResources: [],
|
|
1021
|
+
contentType: 'action' as const,
|
|
1022
|
+
contentValue: 'test_action',
|
|
1023
|
+
};
|
|
1024
|
+
|
|
1025
|
+
await webex.internal.aiAssistant.makeAiAssistantRequest(options);
|
|
1026
|
+
|
|
1027
|
+
// Advance the clock past the timeout
|
|
1028
|
+
await clock.tickAsync(30001); // Default timeout + 1ms
|
|
1029
|
+
|
|
1030
|
+
await waitForAsync();
|
|
1031
|
+
|
|
1032
|
+
// Should trigger timeout event on the stream
|
|
1033
|
+
expect(triggerSpy.calledWith('aiassistant:stream:test-request-id')).to.be.true;
|
|
1034
|
+
const timeoutCall = triggerSpy.getCalls().find(call =>
|
|
1035
|
+
call.args[0] === 'aiassistant:stream:test-request-id' &&
|
|
1036
|
+
call.args[1].errorMessage === AI_ASSISTANT_ERRORS.AI_ASSISTANT_TIMEOUT
|
|
1037
|
+
);
|
|
1038
|
+
expect(timeoutCall).to.exist;
|
|
1039
|
+
expect(timeoutCall.args[1]).to.deep.include({
|
|
1040
|
+
requestId: 'test-request-id',
|
|
1041
|
+
finished: true,
|
|
1042
|
+
errorMessage: AI_ASSISTANT_ERRORS.AI_ASSISTANT_TIMEOUT,
|
|
1043
|
+
errorCode: AI_ASSISTANT_ERROR_CODES.AI_ASSISTANT_TIMEOUT,
|
|
1044
|
+
});
|
|
1045
|
+
});
|
|
1046
|
+
|
|
1047
|
+
it('resets timer when streaming responses are received', async () => {
|
|
1048
|
+
const timerResetSpy = sinon.spy(Timer.prototype, 'reset');
|
|
1049
|
+
const timerCancelSpy = sinon.spy(Timer.prototype, 'cancel');
|
|
1050
|
+
|
|
1051
|
+
const options = {
|
|
1052
|
+
sessionId: 'test-session-id',
|
|
1053
|
+
encryptionKeyUrl: 'test-key-url',
|
|
1054
|
+
contextResources: [],
|
|
1055
|
+
contentType: 'action' as const,
|
|
1056
|
+
contentValue: 'test_action',
|
|
1057
|
+
};
|
|
1058
|
+
|
|
1059
|
+
await webex.internal.aiAssistant.makeAiAssistantRequest(options);
|
|
1060
|
+
|
|
1061
|
+
// Simulate receiving a streaming response (not finished)
|
|
1062
|
+
await webex.internal.aiAssistant._handleEvent({
|
|
1063
|
+
clientRequestId: 'test-request-id',
|
|
1064
|
+
finished: false,
|
|
1065
|
+
response: {
|
|
1066
|
+
sessionId: 'test-session-id',
|
|
1067
|
+
messageId: 'test-message-id',
|
|
1068
|
+
content: {
|
|
1069
|
+
name: 'message',
|
|
1070
|
+
type: 'message',
|
|
1071
|
+
value: 'test-response',
|
|
1072
|
+
},
|
|
1073
|
+
},
|
|
1074
|
+
});
|
|
1075
|
+
|
|
1076
|
+
// Timer should be reset for intermediate responses
|
|
1077
|
+
expect(timerResetSpy.calledOnce).to.be.true;
|
|
1078
|
+
|
|
1079
|
+
// Simulate receiving a final response (finished)
|
|
1080
|
+
await webex.internal.aiAssistant._handleEvent({
|
|
1081
|
+
clientRequestId: 'test-request-id',
|
|
1082
|
+
finished: true,
|
|
1083
|
+
response: {
|
|
1084
|
+
sessionId: 'test-session-id',
|
|
1085
|
+
messageId: 'test-message-id',
|
|
1086
|
+
content: {
|
|
1087
|
+
name: 'message',
|
|
1088
|
+
type: 'message',
|
|
1089
|
+
value: 'final-response',
|
|
1090
|
+
},
|
|
1091
|
+
},
|
|
1092
|
+
});
|
|
1093
|
+
|
|
1094
|
+
// Timer should be cancelled for the final response
|
|
1095
|
+
expect(timerCancelSpy.calledOnce).to.be.true;
|
|
1096
|
+
|
|
1097
|
+
timerResetSpy.restore();
|
|
1098
|
+
timerCancelSpy.restore();
|
|
1099
|
+
});
|
|
1100
|
+
});
|
|
782
1101
|
});
|
|
783
1102
|
});
|