@webex/plugin-meetings 3.11.0-next.4 → 3.11.0-next.41
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/aiEnableRequest/index.js +184 -0
- package/dist/aiEnableRequest/index.js.map +1 -0
- package/dist/aiEnableRequest/utils.js +36 -0
- package/dist/aiEnableRequest/utils.js.map +1 -0
- package/dist/annotation/index.js +3 -3
- package/dist/annotation/index.js.map +1 -1
- package/dist/breakouts/breakout.js +1 -1
- package/dist/breakouts/index.js +1 -1
- package/dist/config.js +5 -1
- package/dist/config.js.map +1 -1
- package/dist/constants.js +26 -6
- package/dist/constants.js.map +1 -1
- package/dist/hashTree/constants.js +3 -1
- package/dist/hashTree/constants.js.map +1 -1
- package/dist/hashTree/hashTree.js +18 -0
- package/dist/hashTree/hashTree.js.map +1 -1
- package/dist/hashTree/hashTreeParser.js +709 -380
- package/dist/hashTree/hashTreeParser.js.map +1 -1
- package/dist/hashTree/types.js +4 -2
- package/dist/hashTree/types.js.map +1 -1
- package/dist/hashTree/utils.js +10 -0
- package/dist/hashTree/utils.js.map +1 -1
- package/dist/index.js +11 -2
- package/dist/index.js.map +1 -1
- package/dist/interceptors/constant.js +12 -0
- package/dist/interceptors/constant.js.map +1 -0
- package/dist/interceptors/dataChannelAuthToken.js +233 -0
- package/dist/interceptors/dataChannelAuthToken.js.map +1 -0
- package/dist/interceptors/index.js +7 -0
- package/dist/interceptors/index.js.map +1 -1
- package/dist/interpretation/index.js +2 -2
- package/dist/interpretation/index.js.map +1 -1
- package/dist/interpretation/siLanguage.js +1 -1
- package/dist/locus-info/controlsUtils.js +5 -3
- package/dist/locus-info/controlsUtils.js.map +1 -1
- package/dist/locus-info/index.js +125 -68
- package/dist/locus-info/index.js.map +1 -1
- package/dist/locus-info/selfUtils.js +1 -0
- package/dist/locus-info/selfUtils.js.map +1 -1
- package/dist/locus-info/types.js.map +1 -1
- package/dist/media/MediaConnectionAwaiter.js +57 -1
- package/dist/media/MediaConnectionAwaiter.js.map +1 -1
- package/dist/media/properties.js +4 -2
- package/dist/media/properties.js.map +1 -1
- package/dist/meeting/in-meeting-actions.js +7 -1
- package/dist/meeting/in-meeting-actions.js.map +1 -1
- package/dist/meeting/index.js +209 -90
- package/dist/meeting/index.js.map +1 -1
- package/dist/meeting/request.js +50 -0
- package/dist/meeting/request.js.map +1 -1
- package/dist/meeting/request.type.js.map +1 -1
- package/dist/meeting/util.js +128 -2
- package/dist/meeting/util.js.map +1 -1
- package/dist/meetings/index.js +78 -36
- package/dist/meetings/index.js.map +1 -1
- package/dist/member/index.js +10 -0
- package/dist/member/index.js.map +1 -1
- package/dist/member/util.js +10 -0
- package/dist/member/util.js.map +1 -1
- package/dist/metrics/constants.js +2 -1
- package/dist/metrics/constants.js.map +1 -1
- package/dist/multistream/mediaRequestManager.js +1 -1
- package/dist/multistream/mediaRequestManager.js.map +1 -1
- package/dist/multistream/remoteMediaManager.js +11 -0
- package/dist/multistream/remoteMediaManager.js.map +1 -1
- package/dist/reactions/reactions.type.js.map +1 -1
- package/dist/types/aiEnableRequest/index.d.ts +5 -0
- package/dist/types/aiEnableRequest/utils.d.ts +2 -0
- package/dist/types/config.d.ts +3 -0
- package/dist/types/constants.d.ts +21 -1
- package/dist/types/hashTree/constants.d.ts +1 -0
- package/dist/types/hashTree/hashTree.d.ts +7 -0
- package/dist/types/hashTree/hashTreeParser.d.ts +99 -14
- package/dist/types/hashTree/types.d.ts +3 -0
- package/dist/types/hashTree/utils.d.ts +6 -0
- package/dist/types/index.d.ts +1 -0
- package/dist/types/interceptors/constant.d.ts +5 -0
- package/dist/types/interceptors/dataChannelAuthToken.d.ts +35 -0
- package/dist/types/interceptors/index.d.ts +2 -1
- package/dist/types/locus-info/index.d.ts +9 -2
- package/dist/types/locus-info/types.d.ts +1 -0
- package/dist/types/media/MediaConnectionAwaiter.d.ts +10 -1
- package/dist/types/media/properties.d.ts +2 -1
- package/dist/types/meeting/in-meeting-actions.d.ts +6 -0
- package/dist/types/meeting/index.d.ts +24 -2
- package/dist/types/meeting/request.d.ts +16 -1
- package/dist/types/meeting/request.type.d.ts +5 -0
- package/dist/types/meeting/util.d.ts +31 -0
- package/dist/types/meetings/index.d.ts +4 -2
- package/dist/types/member/index.d.ts +1 -0
- package/dist/types/member/util.d.ts +5 -0
- package/dist/types/metrics/constants.d.ts +1 -0
- package/dist/types/reactions/reactions.type.d.ts +1 -0
- package/dist/webinar/index.js +1 -1
- package/package.json +22 -22
- package/src/aiEnableRequest/README.md +84 -0
- package/src/aiEnableRequest/index.ts +170 -0
- package/src/aiEnableRequest/utils.ts +25 -0
- package/src/annotation/index.ts +7 -4
- package/src/config.ts +3 -0
- package/src/constants.ts +26 -1
- package/src/hashTree/constants.ts +1 -0
- package/src/hashTree/hashTree.ts +17 -0
- package/src/hashTree/hashTreeParser.ts +627 -249
- package/src/hashTree/types.ts +4 -0
- package/src/hashTree/utils.ts +9 -0
- package/src/index.ts +8 -1
- package/src/interceptors/constant.ts +6 -0
- package/src/interceptors/dataChannelAuthToken.ts +142 -0
- package/src/interceptors/index.ts +2 -1
- package/src/interpretation/index.ts +2 -2
- package/src/locus-info/controlsUtils.ts +11 -0
- package/src/locus-info/index.ts +146 -58
- package/src/locus-info/selfUtils.ts +1 -0
- package/src/locus-info/types.ts +1 -0
- package/src/media/MediaConnectionAwaiter.ts +41 -1
- package/src/media/properties.ts +3 -1
- package/src/meeting/in-meeting-actions.ts +12 -0
- package/src/meeting/index.ts +127 -17
- package/src/meeting/request.ts +42 -0
- package/src/meeting/request.type.ts +6 -0
- package/src/meeting/util.ts +156 -1
- package/src/meetings/index.ts +94 -9
- package/src/member/index.ts +10 -0
- package/src/member/util.ts +12 -0
- package/src/metrics/constants.ts +1 -0
- package/src/multistream/mediaRequestManager.ts +1 -1
- package/src/multistream/remoteMediaManager.ts +13 -0
- package/src/reactions/reactions.type.ts +1 -0
- package/test/unit/spec/aiEnableRequest/index.ts +981 -0
- package/test/unit/spec/aiEnableRequest/utils.ts +130 -0
- package/test/unit/spec/hashTree/hashTree.ts +66 -0
- package/test/unit/spec/hashTree/hashTreeParser.ts +1869 -189
- package/test/unit/spec/interceptors/dataChannelAuthToken.ts +141 -0
- package/test/unit/spec/locus-info/controlsUtils.js +29 -0
- package/test/unit/spec/locus-info/index.js +201 -45
- package/test/unit/spec/media/MediaConnectionAwaiter.ts +41 -1
- package/test/unit/spec/media/properties.ts +12 -3
- package/test/unit/spec/meeting/in-meeting-actions.ts +8 -2
- package/test/unit/spec/meeting/index.js +441 -75
- package/test/unit/spec/meeting/request.js +64 -0
- package/test/unit/spec/meeting/utils.js +433 -22
- package/test/unit/spec/meetings/index.js +550 -10
- package/test/unit/spec/member/index.js +28 -4
- package/test/unit/spec/member/util.js +65 -27
- package/test/unit/spec/multistream/remoteMediaManager.ts +30 -0
|
@@ -5,6 +5,11 @@ declare const MemberUtil: {
|
|
|
5
5
|
* @returns {Boolean}
|
|
6
6
|
*/
|
|
7
7
|
canReclaimHost: (participant: any) => any;
|
|
8
|
+
/**
|
|
9
|
+
* @param {Object} participant - The locus participant object.
|
|
10
|
+
* @returns {Boolean}
|
|
11
|
+
*/
|
|
12
|
+
canApproveAIEnablement: (participant: any) => boolean;
|
|
8
13
|
/**
|
|
9
14
|
* @param {Object} participant - The locus participant object.
|
|
10
15
|
* @returns {[ServerRoleShape]}
|
package/dist/webinar/index.js
CHANGED
package/package.json
CHANGED
|
@@ -41,14 +41,15 @@
|
|
|
41
41
|
"@types/jsdom": "^21",
|
|
42
42
|
"@webex/babel-config-legacy": "0.0.0",
|
|
43
43
|
"@webex/eslint-config-legacy": "0.0.0",
|
|
44
|
+
"@webex/event-dictionary-ts": "^1.0.2073",
|
|
44
45
|
"@webex/jest-config-legacy": "0.0.0",
|
|
45
46
|
"@webex/legacy-tools": "0.0.0",
|
|
46
|
-
"@webex/plugin-rooms": "3.11.0-next.
|
|
47
|
-
"@webex/test-helper-chai": "3.
|
|
48
|
-
"@webex/test-helper-mocha": "3.
|
|
49
|
-
"@webex/test-helper-mock-webex": "3.
|
|
50
|
-
"@webex/test-helper-retry": "3.
|
|
51
|
-
"@webex/test-helper-test-users": "3.
|
|
47
|
+
"@webex/plugin-rooms": "3.11.0-next.10",
|
|
48
|
+
"@webex/test-helper-chai": "3.11.0-next.1",
|
|
49
|
+
"@webex/test-helper-mocha": "3.11.0-next.1",
|
|
50
|
+
"@webex/test-helper-mock-webex": "3.11.0-next.1",
|
|
51
|
+
"@webex/test-helper-retry": "3.11.0-next.1",
|
|
52
|
+
"@webex/test-helper-test-users": "3.11.0-next.1",
|
|
52
53
|
"chai": "^4.3.4",
|
|
53
54
|
"chai-as-promised": "^7.1.1",
|
|
54
55
|
"eslint": "^8.24.0",
|
|
@@ -60,23 +61,22 @@
|
|
|
60
61
|
"typescript": "^4.7.4"
|
|
61
62
|
},
|
|
62
63
|
"dependencies": {
|
|
63
|
-
"@webex/common": "3.
|
|
64
|
-
"@webex/
|
|
65
|
-
"@webex/internal-
|
|
66
|
-
"@webex/internal-plugin-
|
|
67
|
-
"@webex/internal-plugin-
|
|
68
|
-
"@webex/internal-plugin-
|
|
69
|
-
"@webex/internal-plugin-
|
|
70
|
-
"@webex/internal-plugin-
|
|
71
|
-
"@webex/internal-plugin-
|
|
72
|
-
"@webex/internal-plugin-
|
|
73
|
-
"@webex/
|
|
74
|
-
"@webex/
|
|
75
|
-
"@webex/plugin-
|
|
76
|
-
"@webex/plugin-rooms": "3.11.0-next.1",
|
|
64
|
+
"@webex/common": "3.11.0-next.1",
|
|
65
|
+
"@webex/internal-media-core": "2.22.1",
|
|
66
|
+
"@webex/internal-plugin-conversation": "3.11.0-next.10",
|
|
67
|
+
"@webex/internal-plugin-device": "3.11.0-next.7",
|
|
68
|
+
"@webex/internal-plugin-llm": "3.11.0-next.10",
|
|
69
|
+
"@webex/internal-plugin-mercury": "3.11.0-next.9",
|
|
70
|
+
"@webex/internal-plugin-metrics": "3.11.0-next.7",
|
|
71
|
+
"@webex/internal-plugin-support": "3.11.0-next.10",
|
|
72
|
+
"@webex/internal-plugin-user": "3.11.0-next.7",
|
|
73
|
+
"@webex/internal-plugin-voicea": "3.11.0-next.10",
|
|
74
|
+
"@webex/media-helpers": "3.11.0-next.3",
|
|
75
|
+
"@webex/plugin-people": "3.11.0-next.9",
|
|
76
|
+
"@webex/plugin-rooms": "3.11.0-next.10",
|
|
77
77
|
"@webex/ts-sdp": "^1.8.1",
|
|
78
78
|
"@webex/web-capabilities": "^1.9.0",
|
|
79
|
-
"@webex/webex-core": "3.11.0-next.
|
|
79
|
+
"@webex/webex-core": "3.11.0-next.7",
|
|
80
80
|
"ampersand-collection": "^2.0.2",
|
|
81
81
|
"bowser": "^2.11.0",
|
|
82
82
|
"btoa": "^1.2.1",
|
|
@@ -93,5 +93,5 @@
|
|
|
93
93
|
"//": [
|
|
94
94
|
"TODO: upgrade jwt-decode when moving to node 18"
|
|
95
95
|
],
|
|
96
|
-
"version": "3.11.0-next.
|
|
96
|
+
"version": "3.11.0-next.41"
|
|
97
97
|
}
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
# AI Assistant Enable Request
|
|
2
|
+
|
|
3
|
+
The AI Assistant Enable Request feature provides support for requesting and approving the enablement of AI assistant capabilities during a meeting. This feature implements a permission-based workflow where one participant can request to enable the AI assistant, and another participant (typically the host or a cohost) can accept or decline that request.
|
|
4
|
+
|
|
5
|
+
### Structure
|
|
6
|
+
|
|
7
|
+
The AI Enable Request plugin manages the approval workflow for enabling AI assistant functionality in meetings. It handles sending requests, receiving approval events, and processing responses.
|
|
8
|
+
|
|
9
|
+
### Events
|
|
10
|
+
|
|
11
|
+
The plugin emits events when approval requests are received:
|
|
12
|
+
|
|
13
|
+
```javascript
|
|
14
|
+
// Listen for approval request events
|
|
15
|
+
meeting.aiEnableRequest.on('approval-request-arrived', (event) => {
|
|
16
|
+
const {actionType, isApprover, isInitiator, initiatorId, approverId, url} = event;
|
|
17
|
+
|
|
18
|
+
if (isApprover) {
|
|
19
|
+
// This participant received a request
|
|
20
|
+
console.log(`Received ${actionType} from ${initiatorId}`);
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
if (isInitiator) {
|
|
24
|
+
// This participant sent a request that was processed
|
|
25
|
+
console.log(`Your ${actionType} request was processed`);
|
|
26
|
+
}
|
|
27
|
+
});
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
### Initiator (requester) functionality
|
|
31
|
+
|
|
32
|
+
The following method is available to participants who want to request AI assistant enablement:
|
|
33
|
+
|
|
34
|
+
```javascript
|
|
35
|
+
// Request to enable AI assistant, specifying the approver's participant ID
|
|
36
|
+
meeting.aiEnableRequest.requestEnableAIAssistant({
|
|
37
|
+
approverId: 'approver-participant-id',
|
|
38
|
+
});
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
### Approver functionality
|
|
42
|
+
|
|
43
|
+
The following methods are available to participants who receive AI assistant enable requests:
|
|
44
|
+
|
|
45
|
+
```javascript
|
|
46
|
+
// Accept an AI assistant enable request
|
|
47
|
+
// url and initiatorId come from the 'approval-request-arrived' event
|
|
48
|
+
meeting.aiEnableRequest.acceptEnableAIAssistantRequest({
|
|
49
|
+
url: approvalUrl,
|
|
50
|
+
initiatorId,
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
// Decline an AI assistant enable request
|
|
54
|
+
meeting.aiEnableRequest.declineEnableAIAssistantRequest({
|
|
55
|
+
url: approvalUrl,
|
|
56
|
+
initiatorId,
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
// Decline all pending AI assistant enable requests
|
|
60
|
+
meeting.aiEnableRequest.declineAllEnableAIAssistantRequests({
|
|
61
|
+
url: approvalUrl,
|
|
62
|
+
initiatorId,
|
|
63
|
+
});
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
### Example workflow
|
|
67
|
+
|
|
68
|
+
```javascript
|
|
69
|
+
// Participant A requests to enable AI assistant
|
|
70
|
+
await meeting.aiEnableRequest.requestEnableAIAssistant({
|
|
71
|
+
approverId: participantB.id,
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
// Participant B receives the request via event
|
|
75
|
+
meeting.aiEnableRequest.on('approval-request-arrived', async (event) => {
|
|
76
|
+
if (event.isApprover && event.actionType === 'REQUESTED') {
|
|
77
|
+
// User can now choose to accept or decline
|
|
78
|
+
await meeting.aiEnableRequest.acceptEnableAIAssistantRequest({
|
|
79
|
+
url: event.url,
|
|
80
|
+
initiatorId: event.initiatorId,
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
|
+
});
|
|
84
|
+
```
|
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
/*!
|
|
2
|
+
* Copyright (c) 2015-2026 Cisco Systems, Inc. See LICENSE file.
|
|
3
|
+
*/
|
|
4
|
+
import {WebexPlugin} from '@webex/webex-core';
|
|
5
|
+
import {AI_ENABLE_REQUEST, HTTP_VERBS, LOCUSEVENT, MEETINGS} from '../constants';
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* @class AIEnableRequest
|
|
9
|
+
*/
|
|
10
|
+
const AIEnableRequest = WebexPlugin.extend({
|
|
11
|
+
namespace: MEETINGS,
|
|
12
|
+
|
|
13
|
+
props: {
|
|
14
|
+
approvalUrl: 'string',
|
|
15
|
+
selfParticipantId: 'string',
|
|
16
|
+
hasSubscribedToEvents: 'boolean',
|
|
17
|
+
},
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Update the approval url for handoff
|
|
21
|
+
* @param {string} approvalUrl
|
|
22
|
+
* @returns {void}
|
|
23
|
+
*/
|
|
24
|
+
approvalUrlUpdate(approvalUrl) {
|
|
25
|
+
this.set('approvalUrl', approvalUrl);
|
|
26
|
+
},
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Update the self participant id
|
|
30
|
+
* @param {string} selfParticipantId
|
|
31
|
+
* @returns {void}
|
|
32
|
+
*/
|
|
33
|
+
selfParticipantIdUpdate(selfParticipantId) {
|
|
34
|
+
this.set('selfParticipantId', selfParticipantId);
|
|
35
|
+
|
|
36
|
+
if (!this.hasSubscribedToEvents) {
|
|
37
|
+
this.listenToApprovalRequests();
|
|
38
|
+
this.set('hasSubscribedToEvents', true);
|
|
39
|
+
}
|
|
40
|
+
},
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Listen to locus approval request events and trigger a new event with necessary details when an AI enablement approval request is received
|
|
44
|
+
* @returns {void}
|
|
45
|
+
*/
|
|
46
|
+
listenToApprovalRequests() {
|
|
47
|
+
this.listenTo(this.webex.internal.mercury, `event:${LOCUSEVENT.APPROVAL_REQUEST}`, (event) => {
|
|
48
|
+
if (event?.data?.approval?.resourceType === AI_ENABLE_REQUEST.RESOURCE_TYPE) {
|
|
49
|
+
const {receivers, initiator, actionType, url} = event.data.approval;
|
|
50
|
+
const approverId = receivers?.[0]?.participantId;
|
|
51
|
+
const isApprover = !!approverId && approverId === this.selfParticipantId;
|
|
52
|
+
const initiatorId = initiator?.participantId;
|
|
53
|
+
const isInitiator = !!initiatorId && initiatorId === this.selfParticipantId;
|
|
54
|
+
if (
|
|
55
|
+
!isApprover &&
|
|
56
|
+
!isInitiator &&
|
|
57
|
+
// Not just the initiator needs to know about declined all because
|
|
58
|
+
// all future requests will be rejected if the meeting is in the declined all state
|
|
59
|
+
actionType !== AI_ENABLE_REQUEST.ACTION_TYPE.DECLINED_ALL
|
|
60
|
+
) {
|
|
61
|
+
return;
|
|
62
|
+
}
|
|
63
|
+
this.trigger(AI_ENABLE_REQUEST.EVENTS.APPROVAL_REQUEST_ARRIVED, {
|
|
64
|
+
actionType,
|
|
65
|
+
isApprover,
|
|
66
|
+
isInitiator,
|
|
67
|
+
initiatorId,
|
|
68
|
+
approverId,
|
|
69
|
+
url,
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
});
|
|
73
|
+
},
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* Helper method to send AI assistant request
|
|
77
|
+
* @param {Object} params
|
|
78
|
+
* @param {string} params.url approval url
|
|
79
|
+
* @param {string} params.actionType the type of action (REQUESTED, ACCEPTED, DECLINED, DECLINED_ALL)
|
|
80
|
+
* @param {string} params.initiatorId
|
|
81
|
+
* @param {string} params.approverId
|
|
82
|
+
* @param {string} params.method HTTP method to use for the request
|
|
83
|
+
* @returns {Promise}
|
|
84
|
+
*/
|
|
85
|
+
sendApprovalRequest({url, actionType, initiatorId, approverId, method}) {
|
|
86
|
+
return this.request({
|
|
87
|
+
method,
|
|
88
|
+
uri: url,
|
|
89
|
+
body: {
|
|
90
|
+
actionType,
|
|
91
|
+
resourceType: AI_ENABLE_REQUEST.RESOURCE_TYPE,
|
|
92
|
+
initiator: {
|
|
93
|
+
participantId: initiatorId,
|
|
94
|
+
},
|
|
95
|
+
approver: {
|
|
96
|
+
participantId: approverId,
|
|
97
|
+
},
|
|
98
|
+
},
|
|
99
|
+
});
|
|
100
|
+
},
|
|
101
|
+
|
|
102
|
+
/**
|
|
103
|
+
* Sends a request to enable the AI assistant
|
|
104
|
+
* @param {Object} params
|
|
105
|
+
* @param {string} params.approverId
|
|
106
|
+
* @returns {Promise}
|
|
107
|
+
*/
|
|
108
|
+
requestEnableAIAssistant({approverId}) {
|
|
109
|
+
return this.sendApprovalRequest({
|
|
110
|
+
url: this.approvalUrl,
|
|
111
|
+
actionType: AI_ENABLE_REQUEST.ACTION_TYPE.REQUESTED,
|
|
112
|
+
initiatorId: this.selfParticipantId,
|
|
113
|
+
approverId,
|
|
114
|
+
method: HTTP_VERBS.POST,
|
|
115
|
+
});
|
|
116
|
+
},
|
|
117
|
+
|
|
118
|
+
/**
|
|
119
|
+
* Sends a request to accept the AI assistant enablement
|
|
120
|
+
* @param {Object} params
|
|
121
|
+
* @param {string} params.url approval url
|
|
122
|
+
* @param {string} params.initiatorId
|
|
123
|
+
* @returns {Promise}
|
|
124
|
+
*/
|
|
125
|
+
acceptEnableAIAssistantRequest({url, initiatorId}) {
|
|
126
|
+
return this.sendApprovalRequest({
|
|
127
|
+
url,
|
|
128
|
+
actionType: AI_ENABLE_REQUEST.ACTION_TYPE.ACCEPTED,
|
|
129
|
+
initiatorId,
|
|
130
|
+
approverId: this.selfParticipantId,
|
|
131
|
+
method: HTTP_VERBS.PUT,
|
|
132
|
+
});
|
|
133
|
+
},
|
|
134
|
+
|
|
135
|
+
/**
|
|
136
|
+
* Sends a request to decline the AI assistant enablement
|
|
137
|
+
* @param {Object} params
|
|
138
|
+
* @param {string} params.url approval url
|
|
139
|
+
* @param {string} params.initiatorId
|
|
140
|
+
* @returns {Promise}
|
|
141
|
+
*/
|
|
142
|
+
declineEnableAIAssistantRequest({url, initiatorId}) {
|
|
143
|
+
return this.sendApprovalRequest({
|
|
144
|
+
url,
|
|
145
|
+
actionType: AI_ENABLE_REQUEST.ACTION_TYPE.DECLINED,
|
|
146
|
+
initiatorId,
|
|
147
|
+
approverId: this.selfParticipantId,
|
|
148
|
+
method: HTTP_VERBS.PUT,
|
|
149
|
+
});
|
|
150
|
+
},
|
|
151
|
+
|
|
152
|
+
/**
|
|
153
|
+
* Sends a request to decline all AI assistant enablement requests
|
|
154
|
+
* @param {Object} params
|
|
155
|
+
* @param {string} params.url approval url
|
|
156
|
+
* @param {string} params.initiatorId
|
|
157
|
+
* @returns {Promise}
|
|
158
|
+
*/
|
|
159
|
+
declineAllEnableAIAssistantRequests({url, initiatorId}) {
|
|
160
|
+
return this.sendApprovalRequest({
|
|
161
|
+
url,
|
|
162
|
+
actionType: AI_ENABLE_REQUEST.ACTION_TYPE.DECLINED_ALL,
|
|
163
|
+
initiatorId,
|
|
164
|
+
approverId: this.selfParticipantId,
|
|
165
|
+
method: HTTP_VERBS.PUT,
|
|
166
|
+
});
|
|
167
|
+
},
|
|
168
|
+
});
|
|
169
|
+
|
|
170
|
+
export default AIEnableRequest;
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/* eslint-disable import/prefer-default-export */
|
|
2
|
+
import Meeting from '../meeting';
|
|
3
|
+
|
|
4
|
+
export const getAIEnablementApprover = (meeting: Meeting) => {
|
|
5
|
+
const members = Object.values(meeting.members.membersCollection.members);
|
|
6
|
+
|
|
7
|
+
// find the host, if the host has the capability, return the host id
|
|
8
|
+
const host = members.find((member) => member.roles.moderator && member.canApproveAIEnablement);
|
|
9
|
+
|
|
10
|
+
if (host) {
|
|
11
|
+
return host.id;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
// find the cohosts, if the host has the capability, return the host id
|
|
15
|
+
const cohosts = members
|
|
16
|
+
.filter((member) => member.roles.cohost && member.canApproveAIEnablement)
|
|
17
|
+
.sort((a, b) => a.id.localeCompare(b.id));
|
|
18
|
+
|
|
19
|
+
if (cohosts.length > 0) {
|
|
20
|
+
return cohosts[0].id;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
// if no cohost has the capability, return null
|
|
24
|
+
return null;
|
|
25
|
+
};
|
package/src/annotation/index.ts
CHANGED
|
@@ -13,7 +13,7 @@ import {
|
|
|
13
13
|
} from './constants';
|
|
14
14
|
|
|
15
15
|
import {StrokeData, RequestData, IAnnotationChannel, CommandRequestBody} from './annotation.types';
|
|
16
|
-
import {HTTP_VERBS} from '../constants';
|
|
16
|
+
import {HTTP_VERBS, LOCUSEVENT} from '../constants';
|
|
17
17
|
|
|
18
18
|
/**
|
|
19
19
|
* @description Annotation to handle LLM and Mercury message and locus API
|
|
@@ -69,7 +69,7 @@ class AnnotationChannel extends WebexPlugin implements IAnnotationChannel {
|
|
|
69
69
|
*/
|
|
70
70
|
private eventCommandProcessor(e) {
|
|
71
71
|
if (
|
|
72
|
-
e?.data?.eventType ===
|
|
72
|
+
e?.data?.eventType === LOCUSEVENT.APPROVAL_REQUEST &&
|
|
73
73
|
e?.data?.approval?.resourceType === ANNOTATION_RESOURCE_TYPE &&
|
|
74
74
|
e?.data?.approval?.actionType
|
|
75
75
|
) {
|
|
@@ -110,7 +110,7 @@ class AnnotationChannel extends WebexPlugin implements IAnnotationChannel {
|
|
|
110
110
|
if (!this.hasSubscribedToEvents) {
|
|
111
111
|
// @ts-ignore
|
|
112
112
|
this.webex.internal.mercury.on(
|
|
113
|
-
|
|
113
|
+
`event:${LOCUSEVENT.APPROVAL_REQUEST}`,
|
|
114
114
|
this.eventCommandProcessor,
|
|
115
115
|
this
|
|
116
116
|
);
|
|
@@ -127,7 +127,10 @@ class AnnotationChannel extends WebexPlugin implements IAnnotationChannel {
|
|
|
127
127
|
public deregisterEvents() {
|
|
128
128
|
if (this.hasSubscribedToEvents) {
|
|
129
129
|
// @ts-ignore
|
|
130
|
-
this.webex.internal.mercury.off(
|
|
130
|
+
this.webex.internal.mercury.off(
|
|
131
|
+
`event:${LOCUSEVENT.APPROVAL_REQUEST}`,
|
|
132
|
+
this.eventCommandProcessor
|
|
133
|
+
);
|
|
131
134
|
|
|
132
135
|
// @ts-ignore
|
|
133
136
|
this.webex.internal.llm.off('event:relay.event', this.eventDataProcessor);
|
package/src/config.ts
CHANGED
|
@@ -101,5 +101,8 @@ export default {
|
|
|
101
101
|
stopIceGatheringAfterFirstRelayCandidate: false,
|
|
102
102
|
enableAudioTwccForMultistream: false,
|
|
103
103
|
enablePerUdpUrlReachability: false, // true: separate peer connection per each UDP URL; false: single peer connection for all URLs
|
|
104
|
+
locus: {
|
|
105
|
+
excludedDataSets: ['attendees'], // attendees data set only applies to webinar attendees and we never really need that
|
|
106
|
+
},
|
|
104
107
|
},
|
|
105
108
|
};
|
package/src/constants.ts
CHANGED
|
@@ -364,6 +364,8 @@ export const EVENT_TRIGGERS = {
|
|
|
364
364
|
MEETING_CONTROLS_VIEW_THE_PARTICIPANTS_LIST_UPDATED:
|
|
365
365
|
'meeting:controls:view-the-participants-list:updated',
|
|
366
366
|
MEETING_CONTROLS_RAISE_HAND_UPDATED: 'meeting:controls:raise-hand:updated',
|
|
367
|
+
MEETING_CONTROLS_AI_SUMMARY_NOTIFICATION_UPDATED:
|
|
368
|
+
'meeting:controls:ai-summary-notification:updated',
|
|
367
369
|
MEETING_CONTROLS_VIDEO_UPDATED: 'meeting:controls:video:updated',
|
|
368
370
|
MEETING_CONTROLS_STAGE_VIEW_UPDATED: 'meeting:controls:stage-view:updated',
|
|
369
371
|
MEETING_CONTROLS_WEBCAST_UPDATED: 'meeting:controls:webcast:updated',
|
|
@@ -387,6 +389,7 @@ export const EVENT_TRIGGERS = {
|
|
|
387
389
|
MEETING_MANUAL_CAPTION_UPDATED: 'meeting:manualCaptionControl:updated',
|
|
388
390
|
MEETING_CAPTION_RECEIVED: 'meeting:caption-received',
|
|
389
391
|
MEETING_PARTICIPANT_REASON_CHANGED: 'meeting:participant-reason-changed',
|
|
392
|
+
MEETING_AI_ENABLE_REQUEST: 'meeting:aiEnableRequest',
|
|
390
393
|
};
|
|
391
394
|
|
|
392
395
|
export const EVENT_TYPES = {
|
|
@@ -413,7 +416,6 @@ export const HEADERS = {
|
|
|
413
416
|
// Meeting actually ended
|
|
414
417
|
export const MEETING_REMOVED_REASON = {
|
|
415
418
|
SELF_REMOVED: 'SELF_REMOVED', // server or host removed you from the meeting
|
|
416
|
-
FULLSTATE_REMOVED: 'FULLSTATE_REMOVED', // meeting got dropped ? not sure
|
|
417
419
|
MEETING_INACTIVE_TERMINATING: 'MEETING_INACTIVE_TERMINATING', // Meeting got ended or everyone left the meeting
|
|
418
420
|
CLIENT_LEAVE_REQUEST: 'CLIENT_LEAVE_REQUEST', // You triggered leave meeting
|
|
419
421
|
CLIENT_LEAVE_REQUEST_TAB_CLOSED: 'CLIENT_LEAVE_REQUEST_TAB_CLOSED', // You triggered leave meeting, such as closing the browser tab directly
|
|
@@ -704,6 +706,7 @@ export const LOCUSINFO = {
|
|
|
704
706
|
CONTROLS_MEETING_LAYOUT_UPDATED: 'CONTROLS_MEETING_LAYOUT_UPDATED',
|
|
705
707
|
CONTROLS_RECORDING_UPDATED: 'CONTROLS_RECORDING_UPDATED',
|
|
706
708
|
CONTROLS_MEETING_TRANSCRIBE_UPDATED: 'CONTROLS_MEETING_TRANSCRIBE_UPDATED',
|
|
709
|
+
CONTROLS_AI_SUMMARY_NOTIFICATION_UPDATED: 'CONTROLS_AI_SUMMARY_NOTIFICATION_UPDATED',
|
|
707
710
|
CONTROLS_MEETING_TRANSCRIPTION_SPOKEN_LANGUAGE_UPDATED:
|
|
708
711
|
'CONTROLS_MEETING_TRANSCRIPTION_SPOKEN_LANGUAGE_UPDATED',
|
|
709
712
|
CONTROLS_MEETING_MANUAL_CAPTION_UPDATED: 'CONTROLS_MEETING_MANUAL_CAPTION_UPDATED',
|
|
@@ -750,6 +753,7 @@ export const LOCUSINFO = {
|
|
|
750
753
|
SELF_IS_SHARING_BLOCKED_CHANGE: 'SELF_IS_SHARING_BLOCKED_CHANGE',
|
|
751
754
|
SELF_MEETING_BREAKOUTS_CHANGED: 'SELF_MEETING_BREAKOUTS_CHANGED',
|
|
752
755
|
SELF_MEETING_INTERPRETATION_CHANGED: 'SELF_MEETING_INTERPRETATION_CHANGED',
|
|
756
|
+
SELF_ID_CHANGED: 'SELF_ID_CHANGED',
|
|
753
757
|
SELF_MEETING_BRB_CHANGED: 'SELF_MEETING_BRB_CHANGED',
|
|
754
758
|
MEDIA_INACTIVITY: 'MEDIA_INACTIVITY',
|
|
755
759
|
LINKS_SERVICES: 'LINKS_SERVICES',
|
|
@@ -797,6 +801,8 @@ export const LOCUSEVENT = {
|
|
|
797
801
|
|
|
798
802
|
HASH_TREE_DATA_UPDATED: 'locus.state_message',
|
|
799
803
|
|
|
804
|
+
APPROVAL_REQUEST: 'locus.approval_request',
|
|
805
|
+
|
|
800
806
|
// events generated internally by SDK
|
|
801
807
|
SDK_LOCUS_FROM_SYNC_MEETINGS: 'jsSdk.locus_from_sync_meetings', // generated for each meeting from response to GET /loci Locus API call
|
|
802
808
|
SDK_NO_EVENT: 'jsSdk.no_event', // used in cases where eventType is irrelevant
|
|
@@ -977,6 +983,8 @@ export const DISPLAY_HINTS = {
|
|
|
977
983
|
LOWER_SOMEONE_ELSES_HAND: 'LOWER_SOMEONE_ELSES_HAND',
|
|
978
984
|
LEAVE_TRANSFER_HOST_END_MEETING: 'LEAVE_TRANSFER_HOST_END_MEETING',
|
|
979
985
|
LEAVE_END_MEETING: 'LEAVE_END_MEETING',
|
|
986
|
+
END_MEETING: 'END_MEETING',
|
|
987
|
+
REQUIRE_HOST_END_MEETING_BEFORE_LEAVE: 'REQUIRE_HOST_END_MEETING_BEFORE_LEAVE',
|
|
980
988
|
STREAMING_STATUS_STARTED: 'STREAMING_STATUS_STARTED',
|
|
981
989
|
STREAMING_STATUS_STOPPED: 'STREAMING_STATUS_STOPPED',
|
|
982
990
|
CAPTION_START: 'CAPTION_START',
|
|
@@ -1080,6 +1088,10 @@ export const DISPLAY_HINTS = {
|
|
|
1080
1088
|
// Polling QA
|
|
1081
1089
|
ENABLE_ATTENDEE_START_POLLING_QA: 'ENABLE_ATTENDEE_START_POLLING_QA',
|
|
1082
1090
|
DISABLE_ATTENDEE_START_POLLING_QA: 'DISABLE_ATTENDEE_START_POLLING_QA',
|
|
1091
|
+
|
|
1092
|
+
// AI
|
|
1093
|
+
ATTENDEE_REQUEST_AI_ASSISTANT_ENABLED: 'ATTENDEE_REQUEST_AI_ASSISTANT_ENABLED',
|
|
1094
|
+
ATTENDEE_REQUEST_AI_ASSISTANT_DECLINED_ALL: 'ATTENDEE_REQUEST_AI_ASSISTANT_DECLINED_ALL',
|
|
1083
1095
|
};
|
|
1084
1096
|
|
|
1085
1097
|
export const INTERSTITIAL_DISPLAY_HINTS = [DISPLAY_HINTS.VOIP_IS_ENABLED];
|
|
@@ -1403,3 +1415,16 @@ export const STAGE_MANAGER_TYPE = {
|
|
|
1403
1415
|
};
|
|
1404
1416
|
|
|
1405
1417
|
export const DEFAULT_LARGE_SCALE_WEBINAR_ATTENDEE_SEARCH_LIMIT = 50;
|
|
1418
|
+
|
|
1419
|
+
export const AI_ENABLE_REQUEST = {
|
|
1420
|
+
EVENTS: {
|
|
1421
|
+
APPROVAL_REQUEST_ARRIVED: 'APPROVAL_REQUEST_ARRIVED',
|
|
1422
|
+
},
|
|
1423
|
+
ACTION_TYPE: {
|
|
1424
|
+
REQUESTED: 'REQUESTED',
|
|
1425
|
+
ACCEPTED: 'ACCEPTED',
|
|
1426
|
+
DECLINED: 'DECLINED',
|
|
1427
|
+
DECLINED_ALL: 'DECLINED_ALL',
|
|
1428
|
+
},
|
|
1429
|
+
RESOURCE_TYPE: 'AiAssistant',
|
|
1430
|
+
};
|
|
@@ -6,4 +6,5 @@ export const DataSetNames = {
|
|
|
6
6
|
ATD_ACTIVE: 'atd-active', // only sent to panelists, over LLM; the attendees that have their hands raised or are allowed to unmute themselves
|
|
7
7
|
ATD_UNMUTED: 'atd-unmuted', // sent to web client, over LLM, not sent to panelists; the attendees that are unmuted
|
|
8
8
|
SELF: 'self', // sent to web client, over Mercury
|
|
9
|
+
UNJOINED: 'unjoined', // sent when you are not joined, but can still see some stuff from the meeting (mutually exclusive with "main")
|
|
9
10
|
};
|
package/src/hashTree/hashTree.ts
CHANGED
|
@@ -371,6 +371,23 @@ class HashTree {
|
|
|
371
371
|
return items;
|
|
372
372
|
}
|
|
373
373
|
|
|
374
|
+
/**
|
|
375
|
+
* Retrieves the version of a specific item by its id and type.
|
|
376
|
+
* @param {number} id The ID of the item.
|
|
377
|
+
* @param {ObjectType} type The type of the item.
|
|
378
|
+
* @returns {number | undefined} The version of the item if found, undefined otherwise.
|
|
379
|
+
*/
|
|
380
|
+
getItemVersion(id: number, type: ObjectType): number | undefined {
|
|
381
|
+
if (this.numLeaves === 0) {
|
|
382
|
+
return undefined;
|
|
383
|
+
}
|
|
384
|
+
|
|
385
|
+
const index = id % this.numLeaves;
|
|
386
|
+
const item = this.leaves[index]?.[type]?.[id];
|
|
387
|
+
|
|
388
|
+
return item?.version;
|
|
389
|
+
}
|
|
390
|
+
|
|
374
391
|
/**
|
|
375
392
|
* Resizes the HashTree to have a new number of leaf nodes, redistributing all existing items.
|
|
376
393
|
* @param {number} newNumLeaves The new number of leaf nodes (must be 0 or a power of 2).
|