@webex/plugin-meetings 3.12.0-next.9 → 3.12.0-task-refactor.1
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/annotation/index.js +5 -14
- 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 +2 -8
- package/dist/config.js.map +1 -1
- package/dist/constants.js +6 -29
- package/dist/constants.js.map +1 -1
- package/dist/hashTree/hashTreeParser.js +29 -1563
- package/dist/hashTree/hashTreeParser.js.map +1 -1
- package/dist/hashTree/types.js +3 -13
- package/dist/hashTree/types.js.map +1 -1
- package/dist/index.js +2 -11
- package/dist/index.js.map +1 -1
- package/dist/interceptors/index.js +0 -7
- package/dist/interceptors/index.js.map +1 -1
- package/dist/interceptors/locusRouteToken.js +5 -27
- package/dist/interceptors/locusRouteToken.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 +3 -7
- package/dist/locus-info/controlsUtils.js.map +1 -1
- package/dist/locus-info/index.js +247 -642
- package/dist/locus-info/index.js.map +1 -1
- package/dist/locus-info/selfUtils.js +0 -1
- package/dist/locus-info/selfUtils.js.map +1 -1
- package/dist/locus-info/types.js.map +1 -1
- package/dist/media/MediaConnectionAwaiter.js +1 -57
- package/dist/media/MediaConnectionAwaiter.js.map +1 -1
- package/dist/media/properties.js +2 -4
- package/dist/media/properties.js.map +1 -1
- package/dist/meeting/in-meeting-actions.js +1 -7
- package/dist/meeting/in-meeting-actions.js.map +1 -1
- package/dist/meeting/index.js +1036 -1481
- package/dist/meeting/index.js.map +1 -1
- package/dist/meeting/request.js +0 -50
- package/dist/meeting/request.js.map +1 -1
- package/dist/meeting/request.type.js.map +1 -1
- package/dist/meeting/util.js +3 -133
- package/dist/meeting/util.js.map +1 -1
- package/dist/meetings/index.js +59 -142
- package/dist/meetings/index.js.map +1 -1
- package/dist/meetings/util.js +7 -11
- package/dist/meetings/util.js.map +1 -1
- package/dist/member/index.js +0 -10
- package/dist/member/index.js.map +1 -1
- package/dist/member/util.js +0 -10
- package/dist/member/util.js.map +1 -1
- package/dist/metrics/constants.js +1 -7
- package/dist/metrics/constants.js.map +1 -1
- package/dist/multistream/mediaRequestManager.js +60 -9
- package/dist/multistream/mediaRequestManager.js.map +1 -1
- package/dist/multistream/remoteMediaManager.js +0 -11
- package/dist/multistream/remoteMediaManager.js.map +1 -1
- package/dist/multistream/sendSlotManager.js +2 -116
- package/dist/multistream/sendSlotManager.js.map +1 -1
- package/dist/reachability/clusterReachability.js +18 -171
- package/dist/reachability/clusterReachability.js.map +1 -1
- package/dist/reachability/index.js +11 -21
- package/dist/reachability/index.js.map +1 -1
- package/dist/reachability/reachabilityPeerConnection.js +1 -1
- package/dist/reachability/reachabilityPeerConnection.js.map +1 -1
- package/dist/reactions/reactions.type.js.map +1 -1
- package/dist/reconnection-manager/index.js +1 -0
- package/dist/reconnection-manager/index.js.map +1 -1
- package/dist/types/common/browser-detection.d.ts +0 -1
- package/dist/types/common/events/events-scope.d.ts +0 -1
- package/dist/types/common/events/events.d.ts +0 -1
- package/dist/types/config.d.ts +0 -5
- package/dist/types/constants.d.ts +1 -24
- package/dist/types/hashTree/hashTreeParser.d.ts +11 -260
- package/dist/types/hashTree/types.d.ts +0 -20
- package/dist/types/index.d.ts +0 -1
- package/dist/types/interceptors/index.d.ts +1 -2
- package/dist/types/interceptors/locusRouteToken.d.ts +0 -2
- package/dist/types/locus-info/index.d.ts +47 -68
- package/dist/types/locus-info/types.d.ts +12 -28
- package/dist/types/media/MediaConnectionAwaiter.d.ts +1 -10
- package/dist/types/media/properties.d.ts +1 -2
- package/dist/types/meeting/in-meeting-actions.d.ts +0 -6
- package/dist/types/meeting/index.d.ts +7 -86
- package/dist/types/meeting/request.d.ts +1 -16
- package/dist/types/meeting/request.type.d.ts +0 -5
- package/dist/types/meeting/util.d.ts +0 -31
- package/dist/types/meeting-info/util.d.ts +0 -1
- package/dist/types/meeting-info/utilv2.d.ts +0 -1
- package/dist/types/meetings/index.d.ts +2 -4
- package/dist/types/member/index.d.ts +0 -1
- package/dist/types/member/types.d.ts +4 -4
- package/dist/types/member/util.d.ts +0 -5
- package/dist/types/metrics/constants.d.ts +0 -6
- package/dist/types/multistream/mediaRequestManager.d.ts +23 -0
- package/dist/types/multistream/sendSlotManager.d.ts +1 -23
- package/dist/types/reachability/clusterReachability.d.ts +3 -30
- package/dist/types/reactions/reactions.type.d.ts +0 -1
- package/dist/types/recording-controller/util.d.ts +5 -5
- package/dist/types/roap/index.d.ts +1 -1
- package/dist/webinar/index.js +163 -438
- package/dist/webinar/index.js.map +1 -1
- package/package.json +24 -26
- package/src/annotation/index.ts +7 -27
- package/src/config.ts +0 -5
- package/src/constants.ts +1 -30
- package/src/hashTree/hashTreeParser.ts +25 -1523
- package/src/hashTree/types.ts +1 -24
- package/src/index.ts +1 -8
- package/src/interceptors/index.ts +1 -2
- package/src/interceptors/locusRouteToken.ts +5 -22
- package/src/interpretation/index.ts +2 -2
- package/src/locus-info/controlsUtils.ts +0 -17
- package/src/locus-info/index.ts +213 -707
- package/src/locus-info/selfUtils.ts +0 -1
- package/src/locus-info/types.ts +12 -27
- package/src/media/MediaConnectionAwaiter.ts +1 -41
- package/src/media/properties.ts +1 -3
- package/src/meeting/in-meeting-actions.ts +0 -12
- package/src/meeting/index.ts +84 -461
- package/src/meeting/request.ts +0 -42
- package/src/meeting/request.type.ts +0 -6
- package/src/meeting/util.ts +2 -160
- package/src/meetings/index.ts +60 -180
- package/src/meetings/util.ts +9 -10
- package/src/member/index.ts +0 -10
- package/src/member/util.ts +0 -12
- package/src/metrics/constants.ts +0 -7
- package/src/multistream/mediaRequestManager.ts +54 -4
- package/src/multistream/remoteMediaManager.ts +0 -13
- package/src/multistream/sendSlotManager.ts +3 -97
- package/src/reachability/clusterReachability.ts +27 -153
- package/src/reachability/index.ts +1 -15
- package/src/reachability/reachabilityPeerConnection.ts +1 -3
- package/src/reactions/reactions.type.ts +0 -1
- package/src/reconnection-manager/index.ts +1 -0
- package/src/webinar/index.ts +6 -265
- package/test/unit/spec/annotation/index.ts +7 -69
- package/test/unit/spec/interceptors/locusRouteToken.ts +0 -44
- package/test/unit/spec/locus-info/controlsUtils.js +1 -56
- package/test/unit/spec/locus-info/index.js +90 -1457
- package/test/unit/spec/media/MediaConnectionAwaiter.ts +1 -41
- package/test/unit/spec/media/properties.ts +3 -12
- package/test/unit/spec/meeting/in-meeting-actions.ts +2 -8
- package/test/unit/spec/meeting/index.js +128 -981
- package/test/unit/spec/meeting/request.js +0 -70
- package/test/unit/spec/meeting/utils.js +26 -438
- package/test/unit/spec/meetings/index.js +33 -845
- package/test/unit/spec/meetings/utils.js +1 -51
- package/test/unit/spec/member/index.js +4 -28
- package/test/unit/spec/member/util.js +27 -65
- package/test/unit/spec/multistream/mediaRequestManager.ts +85 -2
- package/test/unit/spec/multistream/remoteMediaManager.ts +0 -30
- package/test/unit/spec/multistream/sendSlotManager.ts +36 -135
- package/test/unit/spec/reachability/clusterReachability.ts +1 -125
- package/test/unit/spec/reachability/index.ts +3 -26
- package/test/unit/spec/reconnection-manager/index.js +8 -4
- package/test/unit/spec/webinar/index.ts +37 -534
- package/dist/aiEnableRequest/index.js +0 -184
- package/dist/aiEnableRequest/index.js.map +0 -1
- package/dist/aiEnableRequest/utils.js +0 -36
- package/dist/aiEnableRequest/utils.js.map +0 -1
- package/dist/hashTree/constants.js +0 -22
- package/dist/hashTree/constants.js.map +0 -1
- package/dist/hashTree/hashTree.js +0 -533
- package/dist/hashTree/hashTree.js.map +0 -1
- package/dist/hashTree/utils.js +0 -69
- package/dist/hashTree/utils.js.map +0 -1
- package/dist/interceptors/constant.js +0 -12
- package/dist/interceptors/constant.js.map +0 -1
- package/dist/interceptors/dataChannelAuthToken.js +0 -290
- package/dist/interceptors/dataChannelAuthToken.js.map +0 -1
- package/dist/interceptors/utils.js +0 -27
- package/dist/interceptors/utils.js.map +0 -1
- package/dist/types/aiEnableRequest/index.d.ts +0 -5
- package/dist/types/aiEnableRequest/utils.d.ts +0 -2
- package/dist/types/hashTree/constants.d.ts +0 -9
- package/dist/types/hashTree/hashTree.d.ts +0 -136
- package/dist/types/hashTree/utils.d.ts +0 -22
- package/dist/types/interceptors/constant.d.ts +0 -5
- package/dist/types/interceptors/dataChannelAuthToken.d.ts +0 -43
- package/dist/types/interceptors/utils.d.ts +0 -1
- package/dist/types/webinar/utils.d.ts +0 -6
- package/dist/webinar/utils.js +0 -25
- package/dist/webinar/utils.js.map +0 -1
- package/src/aiEnableRequest/README.md +0 -84
- package/src/aiEnableRequest/index.ts +0 -170
- package/src/aiEnableRequest/utils.ts +0 -25
- package/src/hashTree/constants.ts +0 -10
- package/src/hashTree/hashTree.ts +0 -480
- package/src/hashTree/utils.ts +0 -62
- package/src/interceptors/constant.ts +0 -6
- package/src/interceptors/dataChannelAuthToken.ts +0 -170
- package/src/interceptors/utils.ts +0 -16
- package/src/webinar/utils.ts +0 -16
- package/test/unit/spec/aiEnableRequest/index.ts +0 -981
- package/test/unit/spec/aiEnableRequest/utils.ts +0 -130
- package/test/unit/spec/hashTree/hashTree.ts +0 -721
- package/test/unit/spec/hashTree/hashTreeParser.ts +0 -3670
- package/test/unit/spec/hashTree/utils.ts +0 -140
- package/test/unit/spec/interceptors/dataChannelAuthToken.ts +0 -210
- package/test/unit/spec/interceptors/utils.ts +0 -75
- package/test/unit/spec/webinar/utils.ts +0 -39
package/src/meeting/index.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import uuid from 'uuid';
|
|
2
|
-
import {cloneDeep, isEqual, isEmpty
|
|
2
|
+
import {cloneDeep, isEqual, isEmpty} from 'lodash';
|
|
3
3
|
import jwtDecode from 'jwt-decode';
|
|
4
4
|
// @ts-ignore - Fix this
|
|
5
5
|
import {StatelessWebexPlugin} from '@webex/webex-core';
|
|
@@ -13,7 +13,7 @@ import {
|
|
|
13
13
|
CALL_DIAGNOSTIC_CONFIG,
|
|
14
14
|
RtcMetrics,
|
|
15
15
|
} from '@webex/internal-plugin-metrics';
|
|
16
|
-
import
|
|
16
|
+
import {ClientEvent as RawClientEvent} from '@webex/event-dictionary-ts';
|
|
17
17
|
|
|
18
18
|
import {
|
|
19
19
|
ConnectionState,
|
|
@@ -22,7 +22,6 @@ import {
|
|
|
22
22
|
MediaConnectionEventNames,
|
|
23
23
|
MediaContent,
|
|
24
24
|
MediaType,
|
|
25
|
-
MediaCodecMimeType,
|
|
26
25
|
RemoteTrackType,
|
|
27
26
|
RoapMessage,
|
|
28
27
|
StatsAnalyzer,
|
|
@@ -34,8 +33,6 @@ import {
|
|
|
34
33
|
InboundAudioIssueSubTypes,
|
|
35
34
|
} from '@webex/internal-media-core';
|
|
36
35
|
|
|
37
|
-
import {DataChannelTokenType} from '@webex/internal-plugin-llm';
|
|
38
|
-
|
|
39
36
|
import {
|
|
40
37
|
LocalStream,
|
|
41
38
|
LocalCameraStream,
|
|
@@ -53,12 +50,6 @@ import {
|
|
|
53
50
|
type MeetingTranscriptPayload,
|
|
54
51
|
} from '@webex/internal-plugin-voicea';
|
|
55
52
|
|
|
56
|
-
import {
|
|
57
|
-
getBrowserMediaErrorCode,
|
|
58
|
-
isBrowserMediaError,
|
|
59
|
-
isBrowserMediaErrorName,
|
|
60
|
-
} from '@webex/internal-plugin-metrics/src/call-diagnostic/call-diagnostic-metrics.util';
|
|
61
|
-
import {CapabilityState, WebCapabilities} from '@webex/web-capabilities';
|
|
62
53
|
import {processNewCaptions} from './voicea-meeting';
|
|
63
54
|
|
|
64
55
|
import {
|
|
@@ -182,15 +173,12 @@ import JoinForbiddenError from '../common/errors/join-forbidden-error';
|
|
|
182
173
|
import {ReachabilityMetrics} from '../reachability/reachability.types';
|
|
183
174
|
import {SetStageOptions, SetStageVideoLayout, UnsetStageVideoLayout} from './request.type';
|
|
184
175
|
import {Invitee} from './type';
|
|
185
|
-
import {DataSet
|
|
176
|
+
import {DataSet} from '../hashTree/hashTreeParser';
|
|
186
177
|
import {LocusDTO} from '../locus-info/types';
|
|
187
|
-
import AIEnableRequest from '../aiEnableRequest';
|
|
188
178
|
|
|
189
179
|
// default callback so we don't call an undefined function, but in practice it should never be used
|
|
190
180
|
const DEFAULT_ICE_PHASE_CALLBACK = () => 'JOIN_MEETING_FINAL';
|
|
191
181
|
|
|
192
|
-
const LLM_HEALTHCHECK_TIMER_MS = 3 * 60 * 1000;
|
|
193
|
-
|
|
194
182
|
const logRequest = (request: any, {logText = ''}) => {
|
|
195
183
|
LoggerProxy.logger.info(`${logText} - sending request`);
|
|
196
184
|
|
|
@@ -254,7 +242,6 @@ export type AddMediaOptions = {
|
|
|
254
242
|
remoteMediaManagerConfig?: RemoteMediaManagerConfiguration; // applies only to multistream meetings
|
|
255
243
|
bundlePolicy?: BundlePolicy; // applies only to multistream meetings
|
|
256
244
|
allowMediaInLobby?: boolean; // allows adding media when in the lobby
|
|
257
|
-
allowPublishMediaInLobby?: boolean; // allows publishing media when in the lobby, if not specified, default value false is used
|
|
258
245
|
additionalMediaOptions?: AdditionalMediaOptions; // allows adding additional options like send/receive audio/video
|
|
259
246
|
};
|
|
260
247
|
|
|
@@ -569,34 +556,6 @@ type MediaReachabilityMetrics = ReachabilityMetrics & {
|
|
|
569
556
|
* @memberof Meeting
|
|
570
557
|
*/
|
|
571
558
|
|
|
572
|
-
/**
|
|
573
|
-
* Stores an event so all events can be later retrieved via a console command for debugging.
|
|
574
|
-
* @param {string} type
|
|
575
|
-
* @param {Object} data
|
|
576
|
-
* @returns {void}
|
|
577
|
-
*/
|
|
578
|
-
export function storeEventForDebugging(
|
|
579
|
-
type: string,
|
|
580
|
-
data: {
|
|
581
|
-
eventType: any;
|
|
582
|
-
stateElementsMessage?: HashTreeMessage;
|
|
583
|
-
}
|
|
584
|
-
) {
|
|
585
|
-
if ((window as any)?.locusEvents) {
|
|
586
|
-
// only store non-heartbeat hash tree messages
|
|
587
|
-
if (
|
|
588
|
-
data.eventType === LOCUSEVENT.HASH_TREE_DATA_UPDATED &&
|
|
589
|
-
data.stateElementsMessage?.locusStateElements
|
|
590
|
-
) {
|
|
591
|
-
(window as any).locusEvents.push({
|
|
592
|
-
...data,
|
|
593
|
-
timestamp: new Date().toLocaleString(),
|
|
594
|
-
type,
|
|
595
|
-
});
|
|
596
|
-
}
|
|
597
|
-
}
|
|
598
|
-
}
|
|
599
|
-
|
|
600
559
|
/**
|
|
601
560
|
* @description Meeting is the crux of the plugin
|
|
602
561
|
* @export
|
|
@@ -608,7 +567,6 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
608
567
|
breakouts: any;
|
|
609
568
|
simultaneousInterpretation: any;
|
|
610
569
|
annotation: any;
|
|
611
|
-
aiEnableRequest: any;
|
|
612
570
|
webinar: any;
|
|
613
571
|
conversationUrl: string;
|
|
614
572
|
callStateForMetrics: CallStateForMetrics;
|
|
@@ -657,13 +615,6 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
657
615
|
keepAliveTimerId: NodeJS.Timeout;
|
|
658
616
|
lastVideoLayoutInfo: any;
|
|
659
617
|
locusInfo: any;
|
|
660
|
-
// this group of properties is populated via updateMeetingObject() that's registered as a callback with LocusInfo
|
|
661
|
-
isUserUnadmitted?: boolean;
|
|
662
|
-
joinedWith?: any;
|
|
663
|
-
selfId?: string;
|
|
664
|
-
roles: any[];
|
|
665
|
-
// ... there is more ... see SelfUtils.parse()
|
|
666
|
-
// end of the group
|
|
667
618
|
locusMediaRequest?: LocusMediaRequest;
|
|
668
619
|
mediaProperties: MediaProperties;
|
|
669
620
|
mediaRequestManagers: {
|
|
@@ -698,6 +649,7 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
698
649
|
endCallInitJoinReq: any;
|
|
699
650
|
endJoinReqResp: any;
|
|
700
651
|
endLocalSDPGenRemoteSDPRecvDelay: any;
|
|
652
|
+
joinedWith: any;
|
|
701
653
|
locusId: any;
|
|
702
654
|
startCallInitJoinReq: any;
|
|
703
655
|
startJoinReqResp: any;
|
|
@@ -712,11 +664,12 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
712
664
|
permissionTokenReceivedLocalTime: number;
|
|
713
665
|
resourceId: any;
|
|
714
666
|
resourceUrl: string;
|
|
667
|
+
selfId: string;
|
|
715
668
|
state: any;
|
|
716
669
|
localAudioStreamMuteStateHandler: () => void;
|
|
717
670
|
localVideoStreamMuteStateHandler: () => void;
|
|
718
671
|
localOutputTrackChangeHandler: () => void;
|
|
719
|
-
|
|
672
|
+
roles: any[];
|
|
720
673
|
environment: string;
|
|
721
674
|
namespace = MEETINGS;
|
|
722
675
|
allowMediaInLobby: boolean;
|
|
@@ -798,7 +751,6 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
798
751
|
private uploadLogsTimer?: ReturnType<typeof setTimeout>;
|
|
799
752
|
private logUploadIntervalIndex: number;
|
|
800
753
|
private mediaServerIp: string;
|
|
801
|
-
private llmHealthCheckTimer?: ReturnType<typeof setTimeout>;
|
|
802
754
|
|
|
803
755
|
/**
|
|
804
756
|
* @param {Object} attrs
|
|
@@ -933,10 +885,6 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
933
885
|
*/
|
|
934
886
|
// @ts-ignore
|
|
935
887
|
this.simultaneousInterpretation = new SimultaneousInterpretation({}, {parent: this.webex});
|
|
936
|
-
|
|
937
|
-
// @ts-ignore
|
|
938
|
-
this.aiEnableRequest = new AIEnableRequest({}, {parent: this.webex});
|
|
939
|
-
|
|
940
888
|
/**
|
|
941
889
|
* @instance
|
|
942
890
|
* @type {Annotation}
|
|
@@ -1586,12 +1534,6 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
1586
1534
|
}
|
|
1587
1535
|
};
|
|
1588
1536
|
|
|
1589
|
-
this.localConstraintsChangeHandler = () => {
|
|
1590
|
-
if (!this.isMultistream) {
|
|
1591
|
-
this.mediaProperties.webrtcMediaConnection?.updatePreferredBitrateKbps();
|
|
1592
|
-
}
|
|
1593
|
-
};
|
|
1594
|
-
|
|
1595
1537
|
/**
|
|
1596
1538
|
* Promise that exists if SDP offer has been generated, and resolves once sdp answer is received.
|
|
1597
1539
|
* @instance
|
|
@@ -2901,13 +2843,6 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
2901
2843
|
);
|
|
2902
2844
|
});
|
|
2903
2845
|
|
|
2904
|
-
this.locusInfo.on(LOCUSINFO.EVENTS.CONTROLS_MEETING_HESIOD_LLM_ID_UPDATED, ({hesiodLlmId}) => {
|
|
2905
|
-
if (hesiodLlmId) {
|
|
2906
|
-
// @ts-ignore
|
|
2907
|
-
this.webex.internal.voicea.onCaptionServiceIdUpdate(hesiodLlmId);
|
|
2908
|
-
}
|
|
2909
|
-
});
|
|
2910
|
-
|
|
2911
2846
|
this.locusInfo.on(LOCUSINFO.EVENTS.CONTROLS_MEETING_BREAKOUT_UPDATED, ({breakout}) => {
|
|
2912
2847
|
this.breakouts.updateBreakout(breakout);
|
|
2913
2848
|
Trigger.trigger(
|
|
@@ -3001,18 +2936,6 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
3001
2936
|
);
|
|
3002
2937
|
});
|
|
3003
2938
|
|
|
3004
|
-
this.locusInfo.on(
|
|
3005
|
-
LOCUSINFO.EVENTS.CONTROLS_AI_SUMMARY_NOTIFICATION_UPDATED,
|
|
3006
|
-
({aiSummaryNotification}) => {
|
|
3007
|
-
Trigger.trigger(
|
|
3008
|
-
this,
|
|
3009
|
-
{file: 'meeting/index', function: 'setupLocusControlsListener'},
|
|
3010
|
-
EVENT_TRIGGERS.MEETING_CONTROLS_AI_SUMMARY_NOTIFICATION_UPDATED,
|
|
3011
|
-
{aiSummaryNotification}
|
|
3012
|
-
);
|
|
3013
|
-
}
|
|
3014
|
-
);
|
|
3015
|
-
|
|
3016
2939
|
this.locusInfo.on(LOCUSINFO.EVENTS.CONTROLS_WEBCAST_CHANGED, ({state}) => {
|
|
3017
2940
|
Trigger.trigger(
|
|
3018
2941
|
this,
|
|
@@ -3464,8 +3387,6 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
3464
3387
|
this.recordingController.setLocusUrl(this.locusUrl);
|
|
3465
3388
|
this.controlsOptionsManager.setLocusUrl(this.locusUrl, !!isMainLocus);
|
|
3466
3389
|
this.webinar.locusUrlUpdate(url);
|
|
3467
|
-
// @ts-ignore
|
|
3468
|
-
this.webex.internal.llm.setRefreshHandler(() => this.refreshDataChannelToken());
|
|
3469
3390
|
|
|
3470
3391
|
Trigger.trigger(
|
|
3471
3392
|
this,
|
|
@@ -3496,7 +3417,6 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
3496
3417
|
this.breakouts.breakoutServiceUrlUpdate(payload?.services?.breakout?.url);
|
|
3497
3418
|
this.annotation.approvalUrlUpdate(payload?.services?.approval?.url);
|
|
3498
3419
|
this.simultaneousInterpretation.approvalUrlUpdate(payload?.services?.approval?.url);
|
|
3499
|
-
this.aiEnableRequest.approvalUrlUpdate(payload?.services?.approval?.url);
|
|
3500
3420
|
});
|
|
3501
3421
|
}
|
|
3502
3422
|
|
|
@@ -3594,9 +3514,6 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
3594
3514
|
// @ts-ignore - config coming from registerPlugin
|
|
3595
3515
|
if (datachannelUrl && this.config.enableAutomaticLLM) {
|
|
3596
3516
|
this.updateLLMConnection();
|
|
3597
|
-
if (this.webinar.isJoinPracticeSessionDataChannel()) {
|
|
3598
|
-
this.webinar.updatePSDataChannel();
|
|
3599
|
-
}
|
|
3600
3517
|
}
|
|
3601
3518
|
}
|
|
3602
3519
|
|
|
@@ -3734,7 +3651,7 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
3734
3651
|
});
|
|
3735
3652
|
this.updateLLMConnection();
|
|
3736
3653
|
});
|
|
3737
|
-
this.locusInfo.on(LOCUSINFO.EVENTS.SELF_ADMITTED_GUEST, (payload) => {
|
|
3654
|
+
this.locusInfo.on(LOCUSINFO.EVENTS.SELF_ADMITTED_GUEST, async (payload) => {
|
|
3738
3655
|
this.stopKeepAlive();
|
|
3739
3656
|
|
|
3740
3657
|
if (payload) {
|
|
@@ -3760,15 +3677,6 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
3760
3677
|
});
|
|
3761
3678
|
}
|
|
3762
3679
|
this.rtcMetrics?.sendNextMetrics();
|
|
3763
|
-
|
|
3764
|
-
this.ensureDefaultDatachannelTokenAfterAdmit().catch((error) => {
|
|
3765
|
-
LoggerProxy.logger.warn(
|
|
3766
|
-
`Meeting:index#setUpLocusInfoSelfListener --> failed post-admit token prefetch flow: ${
|
|
3767
|
-
error?.message || String(error)
|
|
3768
|
-
}`
|
|
3769
|
-
);
|
|
3770
|
-
});
|
|
3771
|
-
|
|
3772
3680
|
this.updateLLMConnection();
|
|
3773
3681
|
});
|
|
3774
3682
|
|
|
@@ -3838,10 +3746,6 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
3838
3746
|
);
|
|
3839
3747
|
});
|
|
3840
3748
|
|
|
3841
|
-
this.locusInfo.on(LOCUSINFO.EVENTS.SELF_ID_CHANGED, (payload) => {
|
|
3842
|
-
this.aiEnableRequest.selfParticipantIdUpdate(payload.selfId);
|
|
3843
|
-
});
|
|
3844
|
-
|
|
3845
3749
|
this.locusInfo.on(LOCUSINFO.EVENTS.SELF_MEETING_INTERPRETATION_CHANGED, (payload) => {
|
|
3846
3750
|
const targetChanged = this.simultaneousInterpretation.updateSelfInterpretation(payload);
|
|
3847
3751
|
Trigger.trigger(
|
|
@@ -4344,9 +4248,6 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
4344
4248
|
bothLeaveAndEndMeetingAvailable: MeetingUtil.bothLeaveAndEndMeetingAvailable(
|
|
4345
4249
|
this.userDisplayHints
|
|
4346
4250
|
),
|
|
4347
|
-
requireHostEndMeetingBeforeLeave: MeetingUtil.requireHostEndMeetingBeforeLeave(
|
|
4348
|
-
this.userDisplayHints
|
|
4349
|
-
),
|
|
4350
4251
|
canEnableClosedCaption: MeetingUtil.canEnableClosedCaption(this.userDisplayHints),
|
|
4351
4252
|
canStartTranscribing: MeetingUtil.canStartTranscribing(this.userDisplayHints),
|
|
4352
4253
|
canStopTranscribing: MeetingUtil.canStopTranscribing(this.userDisplayHints),
|
|
@@ -4605,12 +4506,6 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
4605
4506
|
requiredHints: [DISPLAY_HINTS.DISABLE_ATTENDEE_START_POLLING_QA],
|
|
4606
4507
|
displayHints: this.userDisplayHints,
|
|
4607
4508
|
}),
|
|
4608
|
-
canAttendeeRequestAiAssistantEnabled: MeetingUtil.canAttendeeRequestAiAssistantEnabled(
|
|
4609
|
-
this.userDisplayHints,
|
|
4610
|
-
this.roles
|
|
4611
|
-
),
|
|
4612
|
-
isAttendeeRequestAiAssistantDeclinedAll:
|
|
4613
|
-
MeetingUtil.attendeeRequestAiAssistantDeclinedAll(this.userDisplayHints),
|
|
4614
4509
|
}) || changed;
|
|
4615
4510
|
}
|
|
4616
4511
|
if (changed) {
|
|
@@ -4682,8 +4577,7 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
4682
4577
|
mediaId: string;
|
|
4683
4578
|
host: object;
|
|
4684
4579
|
selfId: string;
|
|
4685
|
-
dataSets: DataSet[];
|
|
4686
|
-
metadata: Metadata; // only sent by Locus when hash trees are used
|
|
4580
|
+
dataSets: DataSet[];
|
|
4687
4581
|
}) {
|
|
4688
4582
|
const mtgLocus: any = data.locus;
|
|
4689
4583
|
|
|
@@ -4699,7 +4593,6 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
4699
4593
|
trigger: 'join-response',
|
|
4700
4594
|
locus: mtgLocus,
|
|
4701
4595
|
dataSets: data.dataSets,
|
|
4702
|
-
metadata: data.metadata,
|
|
4703
4596
|
});
|
|
4704
4597
|
}
|
|
4705
4598
|
|
|
@@ -4909,7 +4802,6 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
4909
4802
|
this.localVideoStreamMuteStateHandler
|
|
4910
4803
|
);
|
|
4911
4804
|
oldStream?.off(LocalStreamEventNames.OutputTrackChange, this.localOutputTrackChangeHandler);
|
|
4912
|
-
oldStream?.off(LocalStreamEventNames.ConstraintsChange, this.localConstraintsChangeHandler);
|
|
4913
4805
|
|
|
4914
4806
|
// we don't update this.mediaProperties.mediaDirection.sendVideo, because we always keep it as true to avoid extra SDP exchanges
|
|
4915
4807
|
this.mediaProperties.setLocalVideoStream(localStream);
|
|
@@ -4925,7 +4817,6 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
4925
4817
|
this.localVideoStreamMuteStateHandler
|
|
4926
4818
|
);
|
|
4927
4819
|
localStream?.on(LocalStreamEventNames.OutputTrackChange, this.localOutputTrackChangeHandler);
|
|
4928
|
-
localStream?.on(LocalStreamEventNames.ConstraintsChange, this.localConstraintsChangeHandler);
|
|
4929
4820
|
|
|
4930
4821
|
if (!this.isMultistream || !localStream) {
|
|
4931
4822
|
// for multistream WCME automatically un-publishes the old stream when we publish a new one
|
|
@@ -5060,7 +4951,6 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
5060
4951
|
this.localVideoStreamMuteStateHandler
|
|
5061
4952
|
);
|
|
5062
4953
|
videoStream?.off(LocalStreamEventNames.OutputTrackChange, this.localOutputTrackChangeHandler);
|
|
5063
|
-
videoStream?.off(LocalStreamEventNames.ConstraintsChange, this.localConstraintsChangeHandler);
|
|
5064
4954
|
|
|
5065
4955
|
shareAudioStream?.off(StreamEventNames.Ended, this.handleShareAudioStreamEnded);
|
|
5066
4956
|
shareAudioStream?.off(
|
|
@@ -5474,18 +5364,6 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
5474
5364
|
let joined = false;
|
|
5475
5365
|
let joinResponse = prevJoinResponse;
|
|
5476
5366
|
|
|
5477
|
-
/* Before we do anything, check if RTCPeerConnection is available. Normally this is checked
|
|
5478
|
-
by addMediaInternal() itself when creating the media connection, but since joinWithMedia()
|
|
5479
|
-
is a convenience method that does both join() and addMedia(), we want to fail fast here
|
|
5480
|
-
in case WebRTC is not available at all.
|
|
5481
|
-
*/
|
|
5482
|
-
if (WebCapabilities.supportsRTCPeerConnection() === CapabilityState.NOT_CAPABLE) {
|
|
5483
|
-
// throw the same error that would be thrown by addMediaInternal()
|
|
5484
|
-
throw new Errors.WebrtcApiNotAvailableError(
|
|
5485
|
-
'RTCPeerConnection API is not available in this environment'
|
|
5486
|
-
);
|
|
5487
|
-
}
|
|
5488
|
-
|
|
5489
5367
|
try {
|
|
5490
5368
|
let turnServerInfo;
|
|
5491
5369
|
let turnDiscoverySkippedReason;
|
|
@@ -5556,29 +5434,12 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
5556
5434
|
// if this was the first attempt, let's do a retry
|
|
5557
5435
|
let shouldRetry = !isRetry;
|
|
5558
5436
|
|
|
5559
|
-
if (
|
|
5560
|
-
CallDiagnosticUtils.isSdpOfferCreationError(error) ||
|
|
5561
|
-
CallDiagnosticUtils.isWebrtcApiNotAvailableError(error)
|
|
5562
|
-
) {
|
|
5437
|
+
if (CallDiagnosticUtils.isSdpOfferCreationError(error)) {
|
|
5563
5438
|
// errors related to offer creation (for example missing H264 codec) will happen again no matter how many times we try,
|
|
5564
5439
|
// so there is no point doing a retry
|
|
5565
5440
|
shouldRetry = false;
|
|
5566
5441
|
}
|
|
5567
5442
|
|
|
5568
|
-
if (CallDiagnosticUtils.isBrowserMediaError(error)) {
|
|
5569
|
-
shouldRetry = false;
|
|
5570
|
-
// eslint-disable-next-line no-ex-assign
|
|
5571
|
-
error = merge({
|
|
5572
|
-
error: {
|
|
5573
|
-
body: {
|
|
5574
|
-
errorCode: CallDiagnosticUtils.getBrowserMediaErrorCode(error),
|
|
5575
|
-
message: error?.message,
|
|
5576
|
-
name: error?.name,
|
|
5577
|
-
},
|
|
5578
|
-
},
|
|
5579
|
-
});
|
|
5580
|
-
}
|
|
5581
|
-
|
|
5582
5443
|
// we only want to call leave if join was successful and this was a retry or we won't be doing any more retries
|
|
5583
5444
|
if (joined && (isRetry || !shouldRetry)) {
|
|
5584
5445
|
try {
|
|
@@ -5852,11 +5713,6 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
5852
5713
|
*/
|
|
5853
5714
|
private processLocusLLMEvent = (event: LocusLLMEvent): void => {
|
|
5854
5715
|
if (event.data.eventType === LOCUSEVENT.HASH_TREE_DATA_UPDATED) {
|
|
5855
|
-
// @ts-ignore
|
|
5856
|
-
if (this.config.experimental.storeLocusHashTreeEventsForDebugging) {
|
|
5857
|
-
storeEventForDebugging('llm', event.data);
|
|
5858
|
-
}
|
|
5859
|
-
|
|
5860
5716
|
this.locusInfo.parse(this, event.data);
|
|
5861
5717
|
} else {
|
|
5862
5718
|
LoggerProxy.logger.warn(
|
|
@@ -5880,7 +5736,7 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
5880
5736
|
this.isReactionsSupported()
|
|
5881
5737
|
) {
|
|
5882
5738
|
const member = this.members.membersCollection.get(e.data.sender.participantId);
|
|
5883
|
-
if (!member
|
|
5739
|
+
if (!member) {
|
|
5884
5740
|
// @ts-ignore -- fix type
|
|
5885
5741
|
LoggerProxy.logger.warn(
|
|
5886
5742
|
`Meeting:index#processRelayEvent --> Skipping handling of ${REACTION_RELAY_TYPES.REACTION} for ${this.id}. participantId ${e.data.sender.participantId} does not exist in membersCollection.`
|
|
@@ -5888,7 +5744,7 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
5888
5744
|
break;
|
|
5889
5745
|
}
|
|
5890
5746
|
|
|
5891
|
-
const name =
|
|
5747
|
+
const {name} = member;
|
|
5892
5748
|
const processedReaction: ProcessedReaction = {
|
|
5893
5749
|
reaction: e.data.reaction,
|
|
5894
5750
|
sender: {
|
|
@@ -5917,35 +5773,37 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
5917
5773
|
* @returns {void}
|
|
5918
5774
|
*/
|
|
5919
5775
|
stopTranscription() {
|
|
5920
|
-
|
|
5921
|
-
|
|
5922
|
-
|
|
5923
|
-
|
|
5924
|
-
|
|
5776
|
+
if (this.transcription) {
|
|
5777
|
+
// @ts-ignore
|
|
5778
|
+
this.webex.internal.voicea.off(
|
|
5779
|
+
VOICEAEVENTS.VOICEA_ANNOUNCEMENT,
|
|
5780
|
+
this.voiceaListenerCallbacks[VOICEAEVENTS.VOICEA_ANNOUNCEMENT]
|
|
5781
|
+
);
|
|
5925
5782
|
|
|
5926
|
-
|
|
5927
|
-
|
|
5928
|
-
|
|
5929
|
-
|
|
5930
|
-
|
|
5783
|
+
// @ts-ignore
|
|
5784
|
+
this.webex.internal.voicea.off(
|
|
5785
|
+
VOICEAEVENTS.CAPTIONS_TURNED_ON,
|
|
5786
|
+
this.voiceaListenerCallbacks[VOICEAEVENTS.CAPTIONS_TURNED_ON]
|
|
5787
|
+
);
|
|
5931
5788
|
|
|
5932
|
-
|
|
5933
|
-
|
|
5934
|
-
|
|
5935
|
-
|
|
5936
|
-
|
|
5789
|
+
// @ts-ignore
|
|
5790
|
+
this.webex.internal.voicea.off(
|
|
5791
|
+
VOICEAEVENTS.EVA_COMMAND,
|
|
5792
|
+
this.voiceaListenerCallbacks[VOICEAEVENTS.EVA_COMMAND]
|
|
5793
|
+
);
|
|
5937
5794
|
|
|
5938
|
-
|
|
5939
|
-
|
|
5940
|
-
|
|
5941
|
-
|
|
5942
|
-
|
|
5795
|
+
// @ts-ignore
|
|
5796
|
+
this.webex.internal.voicea.off(
|
|
5797
|
+
VOICEAEVENTS.NEW_CAPTION,
|
|
5798
|
+
this.voiceaListenerCallbacks[VOICEAEVENTS.NEW_CAPTION]
|
|
5799
|
+
);
|
|
5943
5800
|
|
|
5944
|
-
|
|
5945
|
-
|
|
5801
|
+
// @ts-ignore
|
|
5802
|
+
this.webex.internal.voicea.deregisterEvents();
|
|
5946
5803
|
|
|
5947
|
-
|
|
5948
|
-
|
|
5804
|
+
this.areVoiceaEventsSetup = false;
|
|
5805
|
+
this.triggerStopReceivingTranscriptionEvent();
|
|
5806
|
+
}
|
|
5949
5807
|
}
|
|
5950
5808
|
|
|
5951
5809
|
/**
|
|
@@ -5969,30 +5827,6 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
5969
5827
|
);
|
|
5970
5828
|
}
|
|
5971
5829
|
|
|
5972
|
-
/**
|
|
5973
|
-
* Restores LLM subchannel subscriptions after reconnect when captions are active.
|
|
5974
|
-
* @returns {void}
|
|
5975
|
-
*/
|
|
5976
|
-
private restoreLLMSubscriptionsIfNeeded(): void {
|
|
5977
|
-
try {
|
|
5978
|
-
// @ts-ignore
|
|
5979
|
-
const isCaptionBoxOn = this.webex.internal.voicea?.getIsCaptionBoxOn?.();
|
|
5980
|
-
|
|
5981
|
-
if (!isCaptionBoxOn) {
|
|
5982
|
-
return;
|
|
5983
|
-
}
|
|
5984
|
-
|
|
5985
|
-
// @ts-ignore
|
|
5986
|
-
this.webex.internal.voicea.updateSubchannelSubscriptions({subscribe: ['transcription']});
|
|
5987
|
-
} catch (error) {
|
|
5988
|
-
const msg = error?.message || String(error);
|
|
5989
|
-
|
|
5990
|
-
LoggerProxy.logger.warn(
|
|
5991
|
-
`Meeting:index#restoreLLMSubscriptionsIfNeeded --> failed to restore subscriptions after LLM online: ${msg}`
|
|
5992
|
-
);
|
|
5993
|
-
}
|
|
5994
|
-
}
|
|
5995
|
-
|
|
5996
5830
|
/**
|
|
5997
5831
|
* This is a callback for the LLM event that is triggered when it comes online
|
|
5998
5832
|
* This method in turn will trigger an event to the developers that the LLM is connected
|
|
@@ -6001,8 +5835,8 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
6001
5835
|
* @returns {null}
|
|
6002
5836
|
*/
|
|
6003
5837
|
private handleLLMOnline = (): void => {
|
|
6004
|
-
|
|
6005
|
-
|
|
5838
|
+
// @ts-ignore
|
|
5839
|
+
this.webex.internal.llm.off('online', this.handleLLMOnline);
|
|
6006
5840
|
Trigger.trigger(
|
|
6007
5841
|
this,
|
|
6008
5842
|
{
|
|
@@ -6230,11 +6064,8 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
6230
6064
|
return Promise.reject(error);
|
|
6231
6065
|
})
|
|
6232
6066
|
.then((join) => {
|
|
6233
|
-
this.saveDataChannelToken(join);
|
|
6234
6067
|
// @ts-ignore - config coming from registerPlugin
|
|
6235
6068
|
if (this.config.enableAutomaticLLM) {
|
|
6236
|
-
// @ts-ignore
|
|
6237
|
-
this.webex.internal.llm.off('online', this.handleLLMOnline);
|
|
6238
6069
|
// @ts-ignore
|
|
6239
6070
|
this.webex.internal.llm.on('online', this.handleLLMOnline);
|
|
6240
6071
|
this.updateLLMConnection()
|
|
@@ -6261,186 +6092,23 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
6261
6092
|
});
|
|
6262
6093
|
}
|
|
6263
6094
|
|
|
6264
|
-
/** starts a timer that after a few minutes checks if
|
|
6265
|
-
* the LLM connection is connected, if not it sends a metric
|
|
6266
|
-
* @private
|
|
6267
|
-
* @returns {void}
|
|
6268
|
-
*/
|
|
6269
|
-
private startLLMHealthCheckTimer() {
|
|
6270
|
-
// first cancel any existing timer
|
|
6271
|
-
this.clearLLMHealthCheckTimer();
|
|
6272
|
-
|
|
6273
|
-
this.llmHealthCheckTimer = setTimeout(() => {
|
|
6274
|
-
// @ts-ignore
|
|
6275
|
-
const isConnected = this.webex.internal.llm.isConnected();
|
|
6276
|
-
|
|
6277
|
-
if (!isConnected) {
|
|
6278
|
-
// @ts-ignore
|
|
6279
|
-
const {hasEverConnected} = this.webex.internal.llm;
|
|
6280
|
-
|
|
6281
|
-
// only send metric if not connected - to avoid too many metrics
|
|
6282
|
-
Metrics.sendBehavioralMetric(BEHAVIORAL_METRICS.LLM_HEALTHCHECK_FAILURE, {
|
|
6283
|
-
correlation_id: this.correlationId,
|
|
6284
|
-
hasEverConnected,
|
|
6285
|
-
});
|
|
6286
|
-
}
|
|
6287
|
-
|
|
6288
|
-
this.llmHealthCheckTimer = undefined;
|
|
6289
|
-
}, LLM_HEALTHCHECK_TIMER_MS);
|
|
6290
|
-
}
|
|
6291
|
-
|
|
6292
|
-
/**
|
|
6293
|
-
* Clears the LLM health check timer
|
|
6294
|
-
* @private
|
|
6295
|
-
* @returns {void}
|
|
6296
|
-
*/
|
|
6297
|
-
private clearLLMHealthCheckTimer() {
|
|
6298
|
-
if (this.llmHealthCheckTimer) {
|
|
6299
|
-
clearTimeout(this.llmHealthCheckTimer);
|
|
6300
|
-
this.llmHealthCheckTimer = undefined;
|
|
6301
|
-
}
|
|
6302
|
-
}
|
|
6303
|
-
|
|
6304
|
-
/**
|
|
6305
|
-
* Disconnects and cleans up the default LLM session listeners/timers.
|
|
6306
|
-
* @param {Object} options
|
|
6307
|
-
* @param {boolean} [options.removeOnlineListener=true] removes the one-time online listener
|
|
6308
|
-
* @param {boolean} [options.throwOnError=true] rethrows disconnect errors when true
|
|
6309
|
-
* @returns {Promise<void>}
|
|
6310
|
-
*/
|
|
6311
|
-
private cleanupLLMConneciton = async ({
|
|
6312
|
-
removeOnlineListener = true,
|
|
6313
|
-
throwOnError = true,
|
|
6314
|
-
}: {
|
|
6315
|
-
removeOnlineListener?: boolean;
|
|
6316
|
-
throwOnError?: boolean;
|
|
6317
|
-
} = {}): Promise<void> => {
|
|
6318
|
-
try {
|
|
6319
|
-
// @ts-ignore - Fix type
|
|
6320
|
-
await this.webex.internal.llm.disconnectLLM({
|
|
6321
|
-
code: 3050,
|
|
6322
|
-
reason: 'done (permanent)',
|
|
6323
|
-
});
|
|
6324
|
-
} catch (error) {
|
|
6325
|
-
LoggerProxy.logger.error(
|
|
6326
|
-
'Meeting:index#cleanupLLMConneciton --> Failed to disconnect default LLM session',
|
|
6327
|
-
error
|
|
6328
|
-
);
|
|
6329
|
-
|
|
6330
|
-
if (throwOnError) {
|
|
6331
|
-
throw error;
|
|
6332
|
-
}
|
|
6333
|
-
} finally {
|
|
6334
|
-
if (removeOnlineListener) {
|
|
6335
|
-
// @ts-ignore - Fix type
|
|
6336
|
-
this.webex.internal.llm.off('online', this.handleLLMOnline);
|
|
6337
|
-
}
|
|
6338
|
-
// @ts-ignore - fix types
|
|
6339
|
-
this.webex.internal.llm.off('event:relay.event', this.processRelayEvent);
|
|
6340
|
-
// @ts-ignore - Fix type
|
|
6341
|
-
this.webex.internal.llm.off(LOCUS_LLM_EVENT, this.processLocusLLMEvent);
|
|
6342
|
-
|
|
6343
|
-
this.clearLLMHealthCheckTimer();
|
|
6344
|
-
}
|
|
6345
|
-
};
|
|
6346
|
-
|
|
6347
|
-
/**
|
|
6348
|
-
* Clears all data channel tokens stored in LLM.
|
|
6349
|
-
* Called during meeting cleanup to ensure stale tokens are not reused.
|
|
6350
|
-
* @returns {void}
|
|
6351
|
-
*/
|
|
6352
|
-
clearDataChannelToken(): void {
|
|
6353
|
-
// @ts-ignore
|
|
6354
|
-
this.webex.internal.llm.resetDatachannelTokens();
|
|
6355
|
-
}
|
|
6356
|
-
|
|
6357
|
-
/**
|
|
6358
|
-
* Saves the data channel tokens from the join response into LLM so that
|
|
6359
|
-
* updateLLMConnection / updatePSDataChannel don't need to fetch them from locusInfo.
|
|
6360
|
-
* @param {Object} join - The parsed join response (from MeetingUtil.parseLocusJoin)
|
|
6361
|
-
* @returns {void}
|
|
6362
|
-
*/
|
|
6363
|
-
saveDataChannelToken(join: any): void {
|
|
6364
|
-
const datachannelToken = join?.locus?.self?.datachannelToken;
|
|
6365
|
-
const practiceSessionDatachannelToken = join?.locus?.self?.practiceSessionDatachannelToken;
|
|
6366
|
-
|
|
6367
|
-
if (datachannelToken) {
|
|
6368
|
-
// @ts-ignore
|
|
6369
|
-
this.webex.internal.llm.setDatachannelToken(datachannelToken, DataChannelTokenType.Default);
|
|
6370
|
-
}
|
|
6371
|
-
|
|
6372
|
-
if (practiceSessionDatachannelToken) {
|
|
6373
|
-
// @ts-ignore
|
|
6374
|
-
this.webex.internal.llm.setDatachannelToken(
|
|
6375
|
-
practiceSessionDatachannelToken,
|
|
6376
|
-
DataChannelTokenType.PracticeSession
|
|
6377
|
-
);
|
|
6378
|
-
}
|
|
6379
|
-
}
|
|
6380
|
-
|
|
6381
|
-
/**
|
|
6382
|
-
* Ensures default-session data channel token exists after lobby admission.
|
|
6383
|
-
* Some lobby users do not receive a token until they are admitted.
|
|
6384
|
-
* @returns {Promise<boolean>} true when a new token is fetched and cached
|
|
6385
|
-
*/
|
|
6386
|
-
private async ensureDefaultDatachannelTokenAfterAdmit(): Promise<boolean> {
|
|
6387
|
-
try {
|
|
6388
|
-
// @ts-ignore
|
|
6389
|
-
const datachannelToken = this.webex.internal.llm.getDatachannelToken();
|
|
6390
|
-
// @ts-ignore
|
|
6391
|
-
const isDataChannelTokenEnabled = await this.webex.internal.llm.isDataChannelTokenEnabled();
|
|
6392
|
-
|
|
6393
|
-
if (!isDataChannelTokenEnabled || datachannelToken) {
|
|
6394
|
-
return false;
|
|
6395
|
-
}
|
|
6396
|
-
|
|
6397
|
-
const response = await this.meetingRequest.fetchDatachannelToken({
|
|
6398
|
-
locusUrl: this.locusUrl,
|
|
6399
|
-
requestingParticipantId: this.members.selfId,
|
|
6400
|
-
isPracticeSession: false,
|
|
6401
|
-
});
|
|
6402
|
-
const fetchedDatachannelToken = response?.body?.datachannelToken;
|
|
6403
|
-
|
|
6404
|
-
if (!fetchedDatachannelToken) {
|
|
6405
|
-
return false;
|
|
6406
|
-
}
|
|
6407
|
-
|
|
6408
|
-
// @ts-ignore
|
|
6409
|
-
this.webex.internal.llm.setDatachannelToken(
|
|
6410
|
-
fetchedDatachannelToken,
|
|
6411
|
-
DataChannelTokenType.Default
|
|
6412
|
-
);
|
|
6413
|
-
|
|
6414
|
-
return true;
|
|
6415
|
-
} catch (error) {
|
|
6416
|
-
const msg = error?.message || String(error);
|
|
6417
|
-
|
|
6418
|
-
LoggerProxy.logger.warn(
|
|
6419
|
-
`Meeting:index#ensureDefaultDatachannelTokenAfterAdmit --> failed to proactively fetch default data channel token after admit: ${msg}`,
|
|
6420
|
-
{statusCode: error?.statusCode}
|
|
6421
|
-
);
|
|
6422
|
-
|
|
6423
|
-
return false;
|
|
6424
|
-
}
|
|
6425
|
-
}
|
|
6426
|
-
|
|
6427
6095
|
/**
|
|
6428
6096
|
* Connects to low latency mercury and reconnects if the address has changed
|
|
6429
6097
|
* It will also disconnect if called when the meeting has ended
|
|
6098
|
+
* @param {String} datachannelUrl
|
|
6430
6099
|
* @returns {Promise}
|
|
6431
6100
|
*/
|
|
6432
6101
|
async updateLLMConnection() {
|
|
6433
6102
|
// @ts-ignore - Fix type
|
|
6434
|
-
const {url
|
|
6103
|
+
const {url, info: {datachannelUrl, practiceSessionDatachannelUrl} = {}} = this.locusInfo;
|
|
6435
6104
|
|
|
6436
6105
|
const isJoined = this.isJoined();
|
|
6437
6106
|
|
|
6438
|
-
//
|
|
6439
|
-
const
|
|
6440
|
-
|
|
6441
|
-
|
|
6442
|
-
|
|
6443
|
-
const dataChannelUrl = datachannelUrl;
|
|
6107
|
+
// webinar panelist should use new data channel in practice session
|
|
6108
|
+
const dataChannelUrl =
|
|
6109
|
+
this.webinar.isJoinPracticeSessionDataChannel() && practiceSessionDatachannelUrl
|
|
6110
|
+
? practiceSessionDatachannelUrl
|
|
6111
|
+
: datachannelUrl;
|
|
6444
6112
|
|
|
6445
6113
|
// @ts-ignore - Fix type
|
|
6446
6114
|
if (this.webex.internal.llm.isConnected()) {
|
|
@@ -6453,7 +6121,19 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
6453
6121
|
) {
|
|
6454
6122
|
return undefined;
|
|
6455
6123
|
}
|
|
6456
|
-
|
|
6124
|
+
// @ts-ignore - Fix type
|
|
6125
|
+
await this.webex.internal.llm.disconnectLLM(
|
|
6126
|
+
isJoined
|
|
6127
|
+
? {
|
|
6128
|
+
code: 3050,
|
|
6129
|
+
reason: 'done (permanent)',
|
|
6130
|
+
}
|
|
6131
|
+
: undefined
|
|
6132
|
+
);
|
|
6133
|
+
// @ts-ignore - Fix type
|
|
6134
|
+
this.webex.internal.llm.off('event:relay.event', this.processRelayEvent);
|
|
6135
|
+
// @ts-ignore - Fix type
|
|
6136
|
+
this.webex.internal.llm.off(LOCUS_LLM_EVENT, this.processLocusLLMEvent);
|
|
6457
6137
|
}
|
|
6458
6138
|
|
|
6459
6139
|
if (!isJoined) {
|
|
@@ -6462,7 +6142,7 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
6462
6142
|
|
|
6463
6143
|
// @ts-ignore - Fix type
|
|
6464
6144
|
return this.webex.internal.llm
|
|
6465
|
-
.registerAndConnect(url, dataChannelUrl
|
|
6145
|
+
.registerAndConnect(url, dataChannelUrl)
|
|
6466
6146
|
.then((registerAndConnectResult) => {
|
|
6467
6147
|
// @ts-ignore - Fix type
|
|
6468
6148
|
this.webex.internal.llm.off('event:relay.event', this.processRelayEvent);
|
|
@@ -6476,8 +6156,6 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
6476
6156
|
'Meeting:index#updateLLMConnection --> enabled to receive relay events!'
|
|
6477
6157
|
);
|
|
6478
6158
|
|
|
6479
|
-
this.startLLMHealthCheckTimer();
|
|
6480
|
-
|
|
6481
6159
|
return Promise.resolve(registerAndConnectResult);
|
|
6482
6160
|
});
|
|
6483
6161
|
}
|
|
@@ -7666,7 +7344,7 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
7666
7344
|
*/
|
|
7667
7345
|
private async waitForMediaConnectionConnected(): Promise<void> {
|
|
7668
7346
|
try {
|
|
7669
|
-
await this.mediaProperties.waitForMediaConnectionConnected(
|
|
7347
|
+
await this.mediaProperties.waitForMediaConnectionConnected();
|
|
7670
7348
|
} catch (error) {
|
|
7671
7349
|
const {iceConnected} = error;
|
|
7672
7350
|
|
|
@@ -8259,7 +7937,6 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
8259
7937
|
remoteMediaManagerConfig,
|
|
8260
7938
|
bundlePolicy = 'max-bundle',
|
|
8261
7939
|
additionalMediaOptions = {},
|
|
8262
|
-
allowPublishMediaInLobby = false,
|
|
8263
7940
|
} = options;
|
|
8264
7941
|
|
|
8265
7942
|
const {
|
|
@@ -8280,6 +7957,7 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
8280
7957
|
const ipver = MeetingUtil.getIpVersion(this.webex); // used just for metrics
|
|
8281
7958
|
|
|
8282
7959
|
// If the user is unjoined or guest waiting in lobby dont allow the user to addMedia
|
|
7960
|
+
// @ts-ignore - isUserUnadmitted coming from SelfUtil
|
|
8283
7961
|
if (this.isUserUnadmitted && !this.wirelessShare && !this.allowMediaInLobby) {
|
|
8284
7962
|
throw new UserInLobbyError();
|
|
8285
7963
|
}
|
|
@@ -8324,13 +8002,7 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
8324
8002
|
this.brbState = createBrbState(this, false);
|
|
8325
8003
|
|
|
8326
8004
|
try {
|
|
8327
|
-
|
|
8328
|
-
// setup local streams for publishing, because if we ever end up admitted to the meeting
|
|
8329
|
-
// but Locus event about it for us is delayed or missed, others could see/hear our user's video/audio
|
|
8330
|
-
// while the user would still think they're in the lobby
|
|
8331
|
-
if (allowPublishMediaInLobby || !this.isUserUnadmitted) {
|
|
8332
|
-
await this.setUpLocalStreamReferences(localStreams);
|
|
8333
|
-
}
|
|
8005
|
+
await this.setUpLocalStreamReferences(localStreams);
|
|
8334
8006
|
|
|
8335
8007
|
this.setMercuryListener();
|
|
8336
8008
|
|
|
@@ -8798,12 +8470,12 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
8798
8470
|
LoggerProxy.logger.log('Meeting:index#leave --> Leaving a meeting');
|
|
8799
8471
|
|
|
8800
8472
|
return MeetingUtil.leaveMeeting(this, options)
|
|
8801
|
-
.then(
|
|
8473
|
+
.then((leave) => {
|
|
8802
8474
|
// CA team recommends submitting this *after* locus /leave
|
|
8803
8475
|
submitLeaveMetric();
|
|
8804
8476
|
|
|
8805
8477
|
this.meetingFiniteStateMachine.leave();
|
|
8806
|
-
|
|
8478
|
+
this.clearMeetingData();
|
|
8807
8479
|
|
|
8808
8480
|
// upload logs on leave irrespective of meeting delete
|
|
8809
8481
|
Trigger.trigger(
|
|
@@ -9662,10 +9334,10 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
9662
9334
|
});
|
|
9663
9335
|
|
|
9664
9336
|
return MeetingUtil.endMeetingForAll(this)
|
|
9665
|
-
.then(
|
|
9337
|
+
.then((end) => {
|
|
9666
9338
|
this.meetingFiniteStateMachine.end();
|
|
9667
9339
|
|
|
9668
|
-
|
|
9340
|
+
this.clearMeetingData();
|
|
9669
9341
|
// upload logs on leave irrespective of meeting delete
|
|
9670
9342
|
Trigger.trigger(
|
|
9671
9343
|
this,
|
|
@@ -9713,7 +9385,7 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
9713
9385
|
* @public
|
|
9714
9386
|
* @memberof Meeting
|
|
9715
9387
|
*/
|
|
9716
|
-
clearMeetingData =
|
|
9388
|
+
clearMeetingData = () => {
|
|
9717
9389
|
this.audio = null;
|
|
9718
9390
|
this.video = null;
|
|
9719
9391
|
this.screenShareFloorState = ScreenShareFloorStatus.RELEASED;
|
|
@@ -9722,13 +9394,17 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
9722
9394
|
}
|
|
9723
9395
|
this.queuedMediaUpdates = [];
|
|
9724
9396
|
|
|
9725
|
-
this.
|
|
9726
|
-
|
|
9397
|
+
if (this.transcription) {
|
|
9398
|
+
this.stopTranscription();
|
|
9399
|
+
this.transcription = undefined;
|
|
9400
|
+
}
|
|
9727
9401
|
|
|
9728
9402
|
this.annotation.deregisterEvents();
|
|
9729
9403
|
|
|
9730
|
-
|
|
9731
|
-
|
|
9404
|
+
// @ts-ignore - fix types
|
|
9405
|
+
this.webex.internal.llm.off('event:relay.event', this.processRelayEvent);
|
|
9406
|
+
// @ts-ignore - Fix type
|
|
9407
|
+
this.webex.internal.llm.off(LOCUS_LLM_EVENT, this.processLocusLLMEvent);
|
|
9732
9408
|
};
|
|
9733
9409
|
|
|
9734
9410
|
/**
|
|
@@ -9921,20 +9597,15 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
9921
9597
|
}
|
|
9922
9598
|
|
|
9923
9599
|
if (shouldEnableMusicMode) {
|
|
9924
|
-
await this.sendSlotManager.
|
|
9925
|
-
|
|
9926
|
-
|
|
9927
|
-
|
|
9928
|
-
maxaveragebitrate: '64000',
|
|
9929
|
-
maxplaybackrate: '48000',
|
|
9930
|
-
}
|
|
9931
|
-
);
|
|
9600
|
+
await this.sendSlotManager.setCodecParameters(MediaType.AudioMain, {
|
|
9601
|
+
maxaveragebitrate: '64000',
|
|
9602
|
+
maxplaybackrate: '48000',
|
|
9603
|
+
});
|
|
9932
9604
|
} else {
|
|
9933
|
-
await this.sendSlotManager.
|
|
9934
|
-
|
|
9935
|
-
|
|
9936
|
-
|
|
9937
|
-
);
|
|
9605
|
+
await this.sendSlotManager.deleteCodecParameters(MediaType.AudioMain, [
|
|
9606
|
+
'maxaveragebitrate',
|
|
9607
|
+
'maxplaybackrate',
|
|
9608
|
+
]);
|
|
9938
9609
|
}
|
|
9939
9610
|
}
|
|
9940
9611
|
|
|
@@ -10433,52 +10104,4 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
10433
10104
|
cancelSipCallOut(participantId: string) {
|
|
10434
10105
|
return this.meetingRequest.cancelSipCallOut(participantId);
|
|
10435
10106
|
}
|
|
10436
|
-
|
|
10437
|
-
/**
|
|
10438
|
-
* Method to get new data
|
|
10439
|
-
* @returns {Promise}
|
|
10440
|
-
*/
|
|
10441
|
-
public async refreshDataChannelToken() {
|
|
10442
|
-
const isPracticeSession = this.webinar.isJoinPracticeSessionDataChannel();
|
|
10443
|
-
const dataChannelTokenType = this.getDataChannelTokenType();
|
|
10444
|
-
|
|
10445
|
-
try {
|
|
10446
|
-
const res = await this.meetingRequest.fetchDatachannelToken({
|
|
10447
|
-
locusUrl: this.locusUrl,
|
|
10448
|
-
requestingParticipantId: this.members.selfId,
|
|
10449
|
-
isPracticeSession,
|
|
10450
|
-
});
|
|
10451
|
-
|
|
10452
|
-
return {
|
|
10453
|
-
body: {
|
|
10454
|
-
datachannelToken: res.body.datachannelToken,
|
|
10455
|
-
dataChannelTokenType,
|
|
10456
|
-
},
|
|
10457
|
-
};
|
|
10458
|
-
} catch (e) {
|
|
10459
|
-
const msg = e?.message || String(e);
|
|
10460
|
-
|
|
10461
|
-
LoggerProxy.logger.warn(
|
|
10462
|
-
`Meeting:index#refreshDataChannelToken --> DataChannel token refresh failed (likely locus changed or participant left): ${msg}`,
|
|
10463
|
-
{statusCode: e?.statusCode}
|
|
10464
|
-
);
|
|
10465
|
-
|
|
10466
|
-
return null;
|
|
10467
|
-
}
|
|
10468
|
-
}
|
|
10469
|
-
|
|
10470
|
-
/**
|
|
10471
|
-
* Determines the current data channel token type based on the meeting state.
|
|
10472
|
-
*
|
|
10473
|
-
* variant should be used when connecting to the LLM data channel.
|
|
10474
|
-
*
|
|
10475
|
-
* @returns {DataChannelTokenType} The token type representing the current session mode.
|
|
10476
|
-
*/
|
|
10477
|
-
public getDataChannelTokenType(): DataChannelTokenType {
|
|
10478
|
-
if (this.webinar.isJoinPracticeSessionDataChannel()) {
|
|
10479
|
-
return DataChannelTokenType.PracticeSession;
|
|
10480
|
-
}
|
|
10481
|
-
|
|
10482
|
-
return DataChannelTokenType.Default;
|
|
10483
|
-
}
|
|
10484
10107
|
}
|