@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.
Files changed (146) hide show
  1. package/dist/aiEnableRequest/index.js +184 -0
  2. package/dist/aiEnableRequest/index.js.map +1 -0
  3. package/dist/aiEnableRequest/utils.js +36 -0
  4. package/dist/aiEnableRequest/utils.js.map +1 -0
  5. package/dist/annotation/index.js +3 -3
  6. package/dist/annotation/index.js.map +1 -1
  7. package/dist/breakouts/breakout.js +1 -1
  8. package/dist/breakouts/index.js +1 -1
  9. package/dist/config.js +5 -1
  10. package/dist/config.js.map +1 -1
  11. package/dist/constants.js +26 -6
  12. package/dist/constants.js.map +1 -1
  13. package/dist/hashTree/constants.js +3 -1
  14. package/dist/hashTree/constants.js.map +1 -1
  15. package/dist/hashTree/hashTree.js +18 -0
  16. package/dist/hashTree/hashTree.js.map +1 -1
  17. package/dist/hashTree/hashTreeParser.js +709 -380
  18. package/dist/hashTree/hashTreeParser.js.map +1 -1
  19. package/dist/hashTree/types.js +4 -2
  20. package/dist/hashTree/types.js.map +1 -1
  21. package/dist/hashTree/utils.js +10 -0
  22. package/dist/hashTree/utils.js.map +1 -1
  23. package/dist/index.js +11 -2
  24. package/dist/index.js.map +1 -1
  25. package/dist/interceptors/constant.js +12 -0
  26. package/dist/interceptors/constant.js.map +1 -0
  27. package/dist/interceptors/dataChannelAuthToken.js +233 -0
  28. package/dist/interceptors/dataChannelAuthToken.js.map +1 -0
  29. package/dist/interceptors/index.js +7 -0
  30. package/dist/interceptors/index.js.map +1 -1
  31. package/dist/interpretation/index.js +2 -2
  32. package/dist/interpretation/index.js.map +1 -1
  33. package/dist/interpretation/siLanguage.js +1 -1
  34. package/dist/locus-info/controlsUtils.js +5 -3
  35. package/dist/locus-info/controlsUtils.js.map +1 -1
  36. package/dist/locus-info/index.js +125 -68
  37. package/dist/locus-info/index.js.map +1 -1
  38. package/dist/locus-info/selfUtils.js +1 -0
  39. package/dist/locus-info/selfUtils.js.map +1 -1
  40. package/dist/locus-info/types.js.map +1 -1
  41. package/dist/media/MediaConnectionAwaiter.js +57 -1
  42. package/dist/media/MediaConnectionAwaiter.js.map +1 -1
  43. package/dist/media/properties.js +4 -2
  44. package/dist/media/properties.js.map +1 -1
  45. package/dist/meeting/in-meeting-actions.js +7 -1
  46. package/dist/meeting/in-meeting-actions.js.map +1 -1
  47. package/dist/meeting/index.js +209 -90
  48. package/dist/meeting/index.js.map +1 -1
  49. package/dist/meeting/request.js +50 -0
  50. package/dist/meeting/request.js.map +1 -1
  51. package/dist/meeting/request.type.js.map +1 -1
  52. package/dist/meeting/util.js +128 -2
  53. package/dist/meeting/util.js.map +1 -1
  54. package/dist/meetings/index.js +78 -36
  55. package/dist/meetings/index.js.map +1 -1
  56. package/dist/member/index.js +10 -0
  57. package/dist/member/index.js.map +1 -1
  58. package/dist/member/util.js +10 -0
  59. package/dist/member/util.js.map +1 -1
  60. package/dist/metrics/constants.js +2 -1
  61. package/dist/metrics/constants.js.map +1 -1
  62. package/dist/multistream/mediaRequestManager.js +1 -1
  63. package/dist/multistream/mediaRequestManager.js.map +1 -1
  64. package/dist/multistream/remoteMediaManager.js +11 -0
  65. package/dist/multistream/remoteMediaManager.js.map +1 -1
  66. package/dist/reactions/reactions.type.js.map +1 -1
  67. package/dist/types/aiEnableRequest/index.d.ts +5 -0
  68. package/dist/types/aiEnableRequest/utils.d.ts +2 -0
  69. package/dist/types/config.d.ts +3 -0
  70. package/dist/types/constants.d.ts +21 -1
  71. package/dist/types/hashTree/constants.d.ts +1 -0
  72. package/dist/types/hashTree/hashTree.d.ts +7 -0
  73. package/dist/types/hashTree/hashTreeParser.d.ts +99 -14
  74. package/dist/types/hashTree/types.d.ts +3 -0
  75. package/dist/types/hashTree/utils.d.ts +6 -0
  76. package/dist/types/index.d.ts +1 -0
  77. package/dist/types/interceptors/constant.d.ts +5 -0
  78. package/dist/types/interceptors/dataChannelAuthToken.d.ts +35 -0
  79. package/dist/types/interceptors/index.d.ts +2 -1
  80. package/dist/types/locus-info/index.d.ts +9 -2
  81. package/dist/types/locus-info/types.d.ts +1 -0
  82. package/dist/types/media/MediaConnectionAwaiter.d.ts +10 -1
  83. package/dist/types/media/properties.d.ts +2 -1
  84. package/dist/types/meeting/in-meeting-actions.d.ts +6 -0
  85. package/dist/types/meeting/index.d.ts +24 -2
  86. package/dist/types/meeting/request.d.ts +16 -1
  87. package/dist/types/meeting/request.type.d.ts +5 -0
  88. package/dist/types/meeting/util.d.ts +31 -0
  89. package/dist/types/meetings/index.d.ts +4 -2
  90. package/dist/types/member/index.d.ts +1 -0
  91. package/dist/types/member/util.d.ts +5 -0
  92. package/dist/types/metrics/constants.d.ts +1 -0
  93. package/dist/types/reactions/reactions.type.d.ts +1 -0
  94. package/dist/webinar/index.js +1 -1
  95. package/package.json +22 -22
  96. package/src/aiEnableRequest/README.md +84 -0
  97. package/src/aiEnableRequest/index.ts +170 -0
  98. package/src/aiEnableRequest/utils.ts +25 -0
  99. package/src/annotation/index.ts +7 -4
  100. package/src/config.ts +3 -0
  101. package/src/constants.ts +26 -1
  102. package/src/hashTree/constants.ts +1 -0
  103. package/src/hashTree/hashTree.ts +17 -0
  104. package/src/hashTree/hashTreeParser.ts +627 -249
  105. package/src/hashTree/types.ts +4 -0
  106. package/src/hashTree/utils.ts +9 -0
  107. package/src/index.ts +8 -1
  108. package/src/interceptors/constant.ts +6 -0
  109. package/src/interceptors/dataChannelAuthToken.ts +142 -0
  110. package/src/interceptors/index.ts +2 -1
  111. package/src/interpretation/index.ts +2 -2
  112. package/src/locus-info/controlsUtils.ts +11 -0
  113. package/src/locus-info/index.ts +146 -58
  114. package/src/locus-info/selfUtils.ts +1 -0
  115. package/src/locus-info/types.ts +1 -0
  116. package/src/media/MediaConnectionAwaiter.ts +41 -1
  117. package/src/media/properties.ts +3 -1
  118. package/src/meeting/in-meeting-actions.ts +12 -0
  119. package/src/meeting/index.ts +127 -17
  120. package/src/meeting/request.ts +42 -0
  121. package/src/meeting/request.type.ts +6 -0
  122. package/src/meeting/util.ts +156 -1
  123. package/src/meetings/index.ts +94 -9
  124. package/src/member/index.ts +10 -0
  125. package/src/member/util.ts +12 -0
  126. package/src/metrics/constants.ts +1 -0
  127. package/src/multistream/mediaRequestManager.ts +1 -1
  128. package/src/multistream/remoteMediaManager.ts +13 -0
  129. package/src/reactions/reactions.type.ts +1 -0
  130. package/test/unit/spec/aiEnableRequest/index.ts +981 -0
  131. package/test/unit/spec/aiEnableRequest/utils.ts +130 -0
  132. package/test/unit/spec/hashTree/hashTree.ts +66 -0
  133. package/test/unit/spec/hashTree/hashTreeParser.ts +1869 -189
  134. package/test/unit/spec/interceptors/dataChannelAuthToken.ts +141 -0
  135. package/test/unit/spec/locus-info/controlsUtils.js +29 -0
  136. package/test/unit/spec/locus-info/index.js +201 -45
  137. package/test/unit/spec/media/MediaConnectionAwaiter.ts +41 -1
  138. package/test/unit/spec/media/properties.ts +12 -3
  139. package/test/unit/spec/meeting/in-meeting-actions.ts +8 -2
  140. package/test/unit/spec/meeting/index.js +441 -75
  141. package/test/unit/spec/meeting/request.js +64 -0
  142. package/test/unit/spec/meeting/utils.js +433 -22
  143. package/test/unit/spec/meetings/index.js +550 -10
  144. package/test/unit/spec/member/index.js +28 -4
  145. package/test/unit/spec/member/util.js +65 -27
  146. package/test/unit/spec/multistream/remoteMediaManager.ts +30 -0
@@ -6,6 +6,7 @@ export type MemberId = string;
6
6
  export default class Member {
7
7
  associatedUser: MemberId | null;
8
8
  associatedUsers: Set<MemberId>;
9
+ canApproveAIEnablement: boolean;
9
10
  canReclaimHost: boolean;
10
11
  id: MemberId;
11
12
  isAudioMuted: any;
@@ -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]}
@@ -87,5 +87,6 @@ declare const BEHAVIORAL_METRICS: {
87
87
  MEDIA_ISSUE_DETECTED: string;
88
88
  LOCUS_CLASSIC_VS_HASH_TREE_MISMATCH: string;
89
89
  LOCUS_HASH_TREE_UNSUPPORTED_OPERATION: string;
90
+ MEDIA_STILL_NOT_CONNECTED: string;
90
91
  };
91
92
  export { BEHAVIORAL_METRICS as default };
@@ -32,6 +32,7 @@ export declare enum SkinToneType {
32
32
  dark = "dark"
33
33
  }
34
34
  export type Sender = {
35
+ displayName: string;
35
36
  participantId: string;
36
37
  };
37
38
  export type ProcessedReaction = {
@@ -506,7 +506,7 @@ var Webinar = _webexCore.WebexPlugin.extend({
506
506
  }, _callee8);
507
507
  }))();
508
508
  },
509
- version: "3.11.0-next.4"
509
+ version: "3.11.0-next.41"
510
510
  });
511
511
  var _default = exports.default = Webinar;
512
512
  //# sourceMappingURL=index.js.map
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.1",
47
- "@webex/test-helper-chai": "3.10.0-next.1",
48
- "@webex/test-helper-mocha": "3.10.0-next.1",
49
- "@webex/test-helper-mock-webex": "3.10.0-next.1",
50
- "@webex/test-helper-retry": "3.10.0-next.1",
51
- "@webex/test-helper-test-users": "3.10.0-next.1",
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.10.0-next.1",
64
- "@webex/event-dictionary-ts": "^1.0.1930",
65
- "@webex/internal-media-core": "2.22.0",
66
- "@webex/internal-plugin-conversation": "3.11.0-next.1",
67
- "@webex/internal-plugin-device": "3.11.0-next.1",
68
- "@webex/internal-plugin-llm": "3.11.0-next.1",
69
- "@webex/internal-plugin-mercury": "3.11.0-next.1",
70
- "@webex/internal-plugin-metrics": "3.11.0-next.1",
71
- "@webex/internal-plugin-support": "3.11.0-next.1",
72
- "@webex/internal-plugin-user": "3.11.0-next.1",
73
- "@webex/internal-plugin-voicea": "3.11.0-next.1",
74
- "@webex/media-helpers": "3.11.0-next.1",
75
- "@webex/plugin-people": "3.11.0-next.1",
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.1",
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.4"
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
+ };
@@ -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 === 'locus.approval_request' &&
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
- 'event:locus.approval_request',
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('event:locus.approval_request', this.eventCommandProcessor);
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
  };
@@ -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).