@webex/contact-center 3.12.0-llmrefactor.2 → 3.12.0-llmrefactor.3

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 (187) hide show
  1. package/.sdd/manifest.json +5 -4
  2. package/ai-docs/ARCHITECTURE.md +1 -1
  3. package/ai-docs/CONTRACTS.md +5 -1
  4. package/ai-docs/SECURITY.md +1 -1
  5. package/ai-docs/contact-center-spec.md +22 -4
  6. package/ai-docs/features/consult-transfer-list-policy/spec/feature-spec.md +362 -0
  7. package/dist/cc.js +440 -10
  8. package/dist/cc.js.map +1 -1
  9. package/dist/config.js +7 -0
  10. package/dist/config.js.map +1 -1
  11. package/dist/constants.js +10 -2
  12. package/dist/constants.js.map +1 -1
  13. package/dist/index.js.map +1 -1
  14. package/dist/metrics/behavioral-events.js +13 -0
  15. package/dist/metrics/behavioral-events.js.map +1 -1
  16. package/dist/metrics/constants.js +2 -0
  17. package/dist/metrics/constants.js.map +1 -1
  18. package/dist/services/AddressBook.js +18 -15
  19. package/dist/services/AddressBook.js.map +1 -1
  20. package/dist/services/AnswerCallOnWebexService.js +174 -0
  21. package/dist/services/AnswerCallOnWebexService.js.map +1 -0
  22. package/dist/services/EntryPoint.js +46 -68
  23. package/dist/services/EntryPoint.js.map +1 -1
  24. package/dist/services/Queue.js +27 -22
  25. package/dist/services/Queue.js.map +1 -1
  26. package/dist/services/WebexCrossClientService.js +171 -0
  27. package/dist/services/WebexCrossClientService.js.map +1 -0
  28. package/dist/services/WxAppTelephonyMercurySync.js +93 -0
  29. package/dist/services/WxAppTelephonyMercurySync.js.map +1 -0
  30. package/dist/services/config/Util.js +3 -0
  31. package/dist/services/config/Util.js.map +1 -1
  32. package/dist/services/config/constants.js +10 -6
  33. package/dist/services/config/constants.js.map +1 -1
  34. package/dist/services/config/types.js +4 -0
  35. package/dist/services/config/types.js.map +1 -1
  36. package/dist/services/core/Err.js.map +1 -1
  37. package/dist/services/core/WebexRequest.js +6 -2
  38. package/dist/services/core/WebexRequest.js.map +1 -1
  39. package/dist/services/core/aqm-reqs.js +28 -14
  40. package/dist/services/core/aqm-reqs.js.map +1 -1
  41. package/dist/services/core/types.js.map +1 -1
  42. package/dist/services/task/Task.js +73 -7
  43. package/dist/services/task/Task.js.map +1 -1
  44. package/dist/services/task/TaskFactory.js +8 -4
  45. package/dist/services/task/TaskFactory.js.map +1 -1
  46. package/dist/services/task/TaskManager.js +176 -20
  47. package/dist/services/task/TaskManager.js.map +1 -1
  48. package/dist/services/task/WebexCallingUtils.js +70 -0
  49. package/dist/services/task/WebexCallingUtils.js.map +1 -0
  50. package/dist/services/task/constants.js +4 -1
  51. package/dist/services/task/constants.js.map +1 -1
  52. package/dist/services/task/contact.js +29 -0
  53. package/dist/services/task/contact.js.map +1 -1
  54. package/dist/services/task/digital/Digital.js +3 -2
  55. package/dist/services/task/digital/Digital.js.map +1 -1
  56. package/dist/services/task/state-machine/TaskStateMachine.js +135 -37
  57. package/dist/services/task/state-machine/TaskStateMachine.js.map +1 -1
  58. package/dist/services/task/state-machine/actions.js +6 -1
  59. package/dist/services/task/state-machine/actions.js.map +1 -1
  60. package/dist/services/task/state-machine/guards.js +38 -11
  61. package/dist/services/task/state-machine/guards.js.map +1 -1
  62. package/dist/services/task/state-machine/types.js.map +1 -1
  63. package/dist/services/task/state-machine/uiControlsComputer.js +118 -18
  64. package/dist/services/task/state-machine/uiControlsComputer.js.map +1 -1
  65. package/dist/services/task/types.js +16 -1
  66. package/dist/services/task/types.js.map +1 -1
  67. package/dist/services/task/voice/Voice.js +350 -14
  68. package/dist/services/task/voice/Voice.js.map +1 -1
  69. package/dist/services/task/voice/WebRTC.js +4 -1
  70. package/dist/services/task/voice/WebRTC.js.map +1 -1
  71. package/dist/services/task/voice/wxAppVoiceMethods.js +201 -0
  72. package/dist/services/task/voice/wxAppVoiceMethods.js.map +1 -0
  73. package/dist/services/wxAppTelephonyUtils.js +19 -0
  74. package/dist/services/wxAppTelephonyUtils.js.map +1 -0
  75. package/dist/types/cc.d.ts +77 -4
  76. package/dist/types/config.d.ts +7 -0
  77. package/dist/types/constants.d.ts +8 -0
  78. package/dist/types/index.d.ts +3 -1
  79. package/dist/types/metrics/constants.d.ts +2 -0
  80. package/dist/types/services/AddressBook.d.ts +2 -1
  81. package/dist/types/services/AnswerCallOnWebexService.d.ts +37 -0
  82. package/dist/types/services/EntryPoint.d.ts +7 -5
  83. package/dist/types/services/Queue.d.ts +5 -3
  84. package/dist/types/services/WebexCrossClientService.d.ts +28 -0
  85. package/dist/types/services/WxAppTelephonyMercurySync.d.ts +28 -0
  86. package/dist/types/services/config/constants.d.ts +8 -5
  87. package/dist/types/services/config/types.d.ts +17 -4
  88. package/dist/types/services/core/Err.d.ts +2 -0
  89. package/dist/types/services/core/WebexRequest.d.ts +1 -0
  90. package/dist/types/services/core/types.d.ts +2 -0
  91. package/dist/types/services/task/Task.d.ts +20 -2
  92. package/dist/types/services/task/TaskFactory.d.ts +2 -1
  93. package/dist/types/services/task/WebexCallingUtils.d.ts +11 -0
  94. package/dist/types/services/task/constants.d.ts +3 -0
  95. package/dist/types/services/task/contact.d.ts +4 -0
  96. package/dist/types/services/task/digital/Digital.d.ts +2 -2
  97. package/dist/types/services/task/state-machine/TaskStateMachine.d.ts +260 -56
  98. package/dist/types/services/task/state-machine/guards.d.ts +6 -5
  99. package/dist/types/services/task/state-machine/types.d.ts +9 -1
  100. package/dist/types/services/task/types.d.ts +81 -4
  101. package/dist/types/services/task/voice/Voice.d.ts +48 -9
  102. package/dist/types/services/task/voice/WebRTC.d.ts +2 -2
  103. package/dist/types/services/task/voice/wxAppVoiceMethods.d.ts +52 -0
  104. package/dist/types/services/wxAppTelephonyUtils.d.ts +5 -0
  105. package/dist/types/types.d.ts +14 -8
  106. package/dist/types/utils/PageCache.d.ts +20 -3
  107. package/dist/types.js +7 -2
  108. package/dist/types.js.map +1 -1
  109. package/dist/utils/PageCache.js +19 -5
  110. package/dist/utils/PageCache.js.map +1 -1
  111. package/dist/webex.js +1 -1
  112. package/package.json +1 -1
  113. package/src/cc.ts +506 -9
  114. package/src/config.ts +7 -0
  115. package/src/constants.ts +8 -0
  116. package/src/index.ts +2 -0
  117. package/src/metrics/ai-docs/metrics-spec.md +9 -3
  118. package/src/metrics/behavioral-events.ts +14 -0
  119. package/src/metrics/constants.ts +2 -0
  120. package/src/services/AddressBook.ts +17 -6
  121. package/src/services/AnswerCallOnWebexService.ts +206 -0
  122. package/src/services/EntryPoint.ts +59 -60
  123. package/src/services/Queue.ts +29 -12
  124. package/src/services/WebexCrossClientService.ts +212 -0
  125. package/src/services/WxAppTelephonyMercurySync.ts +115 -0
  126. package/src/services/ai-docs/AGENTS.md +10 -10
  127. package/src/services/ai-docs/services-spec.md +6 -1
  128. package/src/services/config/Util.ts +3 -0
  129. package/src/services/config/ai-docs/AGENTS.md +1 -1
  130. package/src/services/config/ai-docs/ARCHITECTURE.md +2 -2
  131. package/src/services/config/ai-docs/config-spec.md +6 -0
  132. package/src/services/config/constants.ts +10 -6
  133. package/src/services/config/types.ts +16 -4
  134. package/src/services/core/Err.ts +1 -0
  135. package/src/services/core/WebexRequest.ts +3 -1
  136. package/src/services/core/ai-docs/core-spec.md +5 -1
  137. package/src/services/core/aqm-reqs.ts +30 -15
  138. package/src/services/core/types.ts +2 -0
  139. package/src/services/task/Task.ts +79 -8
  140. package/src/services/task/TaskFactory.ts +8 -3
  141. package/src/services/task/TaskManager.ts +254 -15
  142. package/src/services/task/WebexCallingUtils.ts +136 -0
  143. package/src/services/task/ai-docs/ARCHITECTURE.md +1 -0
  144. package/src/services/task/ai-docs/task-spec.md +117 -2
  145. package/src/services/task/constants.ts +3 -0
  146. package/src/services/task/contact.ts +30 -0
  147. package/src/services/task/digital/Digital.ts +4 -2
  148. package/src/services/task/state-machine/TaskStateMachine.ts +210 -63
  149. package/src/services/task/state-machine/actions.ts +5 -2
  150. package/src/services/task/state-machine/ai-docs/AGENTS.md +8 -4
  151. package/src/services/task/state-machine/ai-docs/ARCHITECTURE.md +17 -8
  152. package/src/services/task/state-machine/ai-docs/task-state-machine-spec.md +46 -22
  153. package/src/services/task/state-machine/guards.ts +64 -11
  154. package/src/services/task/state-machine/types.ts +16 -1
  155. package/src/services/task/state-machine/uiControlsComputer.ts +206 -32
  156. package/src/services/task/types.ts +114 -4
  157. package/src/services/task/voice/Voice.ts +462 -12
  158. package/src/services/task/voice/WebRTC.ts +5 -1
  159. package/src/services/task/voice/wxAppVoiceMethods.ts +307 -0
  160. package/src/services/wxAppTelephonyUtils.ts +14 -0
  161. package/src/types.ts +33 -9
  162. package/src/utils/AGENTS.md +21 -10
  163. package/src/utils/PageCache.ts +38 -5
  164. package/src/utils/ai-docs/utils-spec.md +21 -11
  165. package/test/unit/spec/cc.ts +1274 -0
  166. package/test/unit/spec/metrics/behavioral-events.ts +18 -0
  167. package/test/unit/spec/services/AddressBook.ts +37 -6
  168. package/test/unit/spec/services/AnswerCallOnWebexService.ts +223 -0
  169. package/test/unit/spec/services/EntryPoint.ts +87 -40
  170. package/test/unit/spec/services/Queue.ts +123 -12
  171. package/test/unit/spec/services/WebexCrossClientService.ts +261 -0
  172. package/test/unit/spec/services/WxAppTelephonyMercurySync.ts +113 -0
  173. package/test/unit/spec/services/config/Util.ts +85 -0
  174. package/test/unit/spec/services/core/WebexRequest.ts +3 -1
  175. package/test/unit/spec/services/core/aqm-reqs.ts +113 -1
  176. package/test/unit/spec/services/task/Task.ts +200 -0
  177. package/test/unit/spec/services/task/TaskFactory.ts +39 -2
  178. package/test/unit/spec/services/task/TaskManager.ts +653 -1
  179. package/test/unit/spec/services/task/WebexCallingUtils.ts +153 -0
  180. package/test/unit/spec/services/task/contact.ts +33 -0
  181. package/test/unit/spec/services/task/state-machine/TaskStateMachine.ts +854 -72
  182. package/test/unit/spec/services/task/state-machine/guards.ts +210 -8
  183. package/test/unit/spec/services/task/state-machine/uiControlsComputer.ts +445 -7
  184. package/test/unit/spec/services/task/voice/Voice.ts +874 -0
  185. package/test/unit/spec/services/task/voice/wxAppVoiceMethods.ts +459 -0
  186. package/umd/contact-center.min.js +2 -2
  187. package/umd/contact-center.min.js.map +1 -1
package/dist/cc.js CHANGED
@@ -19,6 +19,9 @@ var _Utils = require("./services/core/Utils");
19
19
  var _types3 = require("./services/config/types");
20
20
  var _TaskManager = _interopRequireDefault(require("./services/task/TaskManager"));
21
21
  var _WebCallingService = _interopRequireDefault(require("./services/WebCallingService"));
22
+ var _AnswerCallOnWebexService = _interopRequireDefault(require("./services/AnswerCallOnWebexService"));
23
+ var _WebexCrossClientService = _interopRequireDefault(require("./services/WebexCrossClientService"));
24
+ var _WxAppTelephonyMercurySync = _interopRequireDefault(require("./services/WxAppTelephonyMercurySync"));
22
25
  var _types4 = require("./services/task/types");
23
26
  var _MetricsManager = _interopRequireDefault(require("./metrics/MetricsManager"));
24
27
  var _constants4 = require("./metrics/constants");
@@ -185,6 +188,29 @@ class ContactCenter extends _webexCore.WebexPlugin {
185
188
  * @private
186
189
  */
187
190
 
191
+ /**
192
+ * REST telephony for wxApp thick-client answer (WXCC-6026)
193
+ * @private
194
+ */
195
+
196
+ /**
197
+ * usersub cross-client state for Webex App toast suppression
198
+ * @private
199
+ */
200
+
201
+ /**
202
+ * Mercury telephony mute sync for wxApp thick-client answer
203
+ * @private
204
+ */
205
+
206
+ /** True when wxApp mute sync opened Mercury (Extension/DN-only profiles). */
207
+ wxAppMercuryConnectedByCc = false;
208
+
209
+ /** True when wxApp mute sync registered the Webex device. */
210
+ wxAppDeviceRegisteredByCc = false;
211
+ static WXAPP_FALSE_PUBLISH_RETRY_DELAY_MS = 30_000;
212
+ static WXAPP_FALSE_PUBLISH_MAX_RETRIES = 3;
213
+
188
214
  /**
189
215
  * Core service managers for Contact Center operations
190
216
  * Includes agent, connection, and configuration services
@@ -345,11 +371,15 @@ class ContactCenter extends _webexCore.WebexPlugin {
345
371
  connectionConfig: this.getConnectionConfig()
346
372
  });
347
373
  this.webCallingService = new _WebCallingService.default(this.$webex);
374
+ this.answerCallOnWebexService = new _AnswerCallOnWebexService.default(this.$webex);
375
+ this.webexCrossClientService = new _WebexCrossClientService.default(this.$webex);
376
+ this.wxAppTelephonyMercurySync = new _WxAppTelephonyMercurySync.default(this.$webex);
348
377
  this.apiAIAssistant = new _ApiAiAssistant.ApiAIAssistant(this.$webex);
349
378
  this.metricsManager = _MetricsManager.default.getInstance({
350
379
  webex: this.$webex
351
380
  });
352
381
  this.taskManager = _TaskManager.default.getTaskManager(this.apiAIAssistant, this.services.contact, this.webCallingService, this.services.webSocketManager, this.services.rtdWebSocketManager);
382
+ this.taskManager.setAnswerCallOnWebexService(this.answerCallOnWebexService);
353
383
  this.incomingTaskListener();
354
384
 
355
385
  // Initialize API instances
@@ -541,6 +571,11 @@ class ContactCenter extends _webexCore.WebexPlugin {
541
571
  this.services.webSocketManager.off('message', this.handleWebsocketMessage);
542
572
  this.services.rtdWebSocketManager.off('message', this.handleRTDWebsocketMessage);
543
573
  this.services.connectionService.off('connectionLost', this.handleConnectionLost);
574
+ const {
575
+ publishError: wxAppPublishError
576
+ } = await this.teardownWxAppLocalState({
577
+ clearInitFlag: true
578
+ });
544
579
  if (this.agentConfig.webRtcEnabled && this.agentConfig.loginVoiceOptions.includes(_types.LoginOption.BROWSER)) {
545
580
  if (this.$webex.internal.mercury.connected) {
546
581
  this.$webex.internal.mercury.off('online');
@@ -566,6 +601,9 @@ class ContactCenter extends _webexCore.WebexPlugin {
566
601
 
567
602
  // Clear any cached agent configuration
568
603
  this.agentConfig = null;
604
+ if (wxAppPublishError) {
605
+ throw wxAppPublishError;
606
+ }
569
607
  _loggerProxy.default.log('Deregistered successfully', {
570
608
  module: _constants.CC_FILE,
571
609
  method: _constants.METHODS.DEREGISTER
@@ -619,6 +657,12 @@ class ContactCenter extends _webexCore.WebexPlugin {
619
657
  * ```
620
658
  */
621
659
  async getBuddyAgents(data) {
660
+ const {
661
+ action,
662
+ state,
663
+ mediaType = 'telephony'
664
+ } = data;
665
+ const buddyAgentState = state ?? (action === 'Transfer' ? _constants2.AGENT_STATE_AVAILABLE : undefined);
622
666
  _loggerProxy.default.info('Fetching buddy agents', {
623
667
  module: _constants.CC_FILE,
624
668
  method: _constants.METHODS.GET_BUDDY_AGENTS
@@ -628,13 +672,16 @@ class ContactCenter extends _webexCore.WebexPlugin {
628
672
  const resp = await this.services.agent.buddyAgents({
629
673
  data: {
630
674
  agentProfileId: this.agentConfig.agentProfileID,
631
- ...data
675
+ mediaType,
676
+ ...(buddyAgentState ? {
677
+ state: buddyAgentState
678
+ } : {})
632
679
  }
633
680
  });
634
681
  this.metricsManager.trackEvent(_constants4.METRIC_EVENT_NAMES.FETCH_BUDDY_AGENTS_SUCCESS, {
635
682
  ..._MetricsManager.default.getCommonTrackingFieldForAQMResponse(resp),
636
- mediaType: data.mediaType,
637
- buddyAgentState: data.state,
683
+ mediaType,
684
+ buddyAgentState,
638
685
  buddyAgentCount: resp.data.agentList.length
639
686
  }, ['operational']);
640
687
  _loggerProxy.default.log(`Successfully retrieved ${resp.data.agentList.length} buddy agents`, {
@@ -647,8 +694,8 @@ class ContactCenter extends _webexCore.WebexPlugin {
647
694
  const failureResp = error.details;
648
695
  this.metricsManager.trackEvent(_constants4.METRIC_EVENT_NAMES.FETCH_BUDDY_AGENTS_FAILED, {
649
696
  ..._MetricsManager.default.getCommonTrackingFieldForAQMResponseFailed(failureResp),
650
- mediaType: data.mediaType,
651
- buddyAgentState: data.state
697
+ mediaType,
698
+ buddyAgentState
652
699
  }, ['operational']);
653
700
  const {
654
701
  error: detailedError
@@ -685,7 +732,14 @@ class ContactCenter extends _webexCore.WebexPlugin {
685
732
  isEndConsultEnabled: this.agentConfig.isEndConsultEnabled,
686
733
  webRtcEnabled: this.agentConfig.webRtcEnabled,
687
734
  autoWrapup: this.agentConfig.wrapUpData?.wrapUpProps?.autoWrapup ?? false,
688
- aiFeature: this.agentConfig.aiFeature
735
+ aiFeature: this.agentConfig.aiFeature,
736
+ consultTransfer: {
737
+ allowConsultToQueue: this.agentConfig.allowConsultToQueue,
738
+ accessQueue: this.agentConfig.accessQueue,
739
+ accessEntryPoint: this.agentConfig.accessEntryPoint,
740
+ accessBuddyTeam: this.agentConfig.accessBuddyTeam
741
+ },
742
+ enableWxBetterTogether: this.isWxBetterTogetherEnabled()
689
743
  };
690
744
  this.taskManager.setConfigFlags(configFlags);
691
745
  // TODO: Make profile a singleton to make it available throughout app/sdk so we dont need to inject info everywhere
@@ -846,6 +900,13 @@ class ContactCenter extends _webexCore.WebexPlugin {
846
900
  notifsTrackingId: resp.trackingId
847
901
  };
848
902
  this.webCallingService.setLoginOption(data.loginOption);
903
+ if (this.agentConfig) {
904
+ this.agentConfig.deviceType = data.loginOption;
905
+ if (data.loginOption === _types.LoginOption.AGENT_DN || data.loginOption === _types.LoginOption.EXTENSION) {
906
+ this.agentConfig.defaultDn = data.dialNumber;
907
+ this.agentConfig.dn = data.dialNumber;
908
+ }
909
+ }
849
910
  this.metricsManager.trackEvent(_constants4.METRIC_EVENT_NAMES.STATION_LOGIN_SUCCESS, {
850
911
  ..._MetricsManager.default.getCommonTrackingFieldForAQMResponse(resp),
851
912
  loginType: data.loginOption,
@@ -858,6 +919,7 @@ class ContactCenter extends _webexCore.WebexPlugin {
858
919
  method: _constants.METHODS.STATION_LOGIN,
859
920
  trackingId: resp.trackingId
860
921
  });
922
+ await this.ensureWxAppPostStationLogin();
861
923
  return response;
862
924
  } catch (error) {
863
925
  const failure = error.details;
@@ -912,6 +974,7 @@ class ContactCenter extends _webexCore.WebexPlugin {
912
974
  if (this.webCallingService) {
913
975
  this.webCallingService.deregisterWebCallingLine();
914
976
  }
977
+ await this.teardownWxAppLocalState();
915
978
  _loggerProxy.default.log(`Agent station logout completed successfully`, {
916
979
  module: _constants.CC_FILE,
917
980
  method: _constants.METHODS.STATION_LOGOUT,
@@ -1170,6 +1233,372 @@ class ContactCenter extends _webexCore.WebexPlugin {
1170
1233
  }
1171
1234
  }
1172
1235
 
1236
+ /**
1237
+ * Whether wxApp thick-client answer is enabled for this SDK instance.
1238
+ * @public
1239
+ */
1240
+ isWxBetterTogetherEnabled() {
1241
+ return this.$config?.enableWxBetterTogether === true;
1242
+ }
1243
+
1244
+ /**
1245
+ * Current station login option (Extension, Dial Number, or Browser/Desktop).
1246
+ * Prefer webCallingService — updated on every stationLogin before wxApp hooks run.
1247
+ * @private
1248
+ */
1249
+ getCurrentStationLoginOption() {
1250
+ return this.webCallingService?.loginOption ?? this.agentConfig?.deviceType;
1251
+ }
1252
+
1253
+ /**
1254
+ * wxApp thick-client answer is supported for Extension and Dial Number station login only —
1255
+ * not Browser/Desktop (WebRTC) login.
1256
+ * @private
1257
+ */
1258
+ assertWxAppStationLoginSupportedForEnable() {
1259
+ const loginOption = this.getCurrentStationLoginOption();
1260
+ if (loginOption !== _types.LoginOption.EXTENSION && loginOption !== _types.LoginOption.AGENT_DN) {
1261
+ throw new Error('setManageWebexCallingInWxcc requires EXTENSION or AGENT_DN station login. Complete station login before enabling.');
1262
+ }
1263
+ }
1264
+
1265
+ /**
1266
+ * Clears runtime wxApp config after logout/deregister so stale flags do not apply on relogin.
1267
+ * @private
1268
+ */
1269
+ resetEnableWxBetterTogetherConfig() {
1270
+ if (this.$config) {
1271
+ this.$config.enableWxBetterTogether = false;
1272
+ }
1273
+ this.taskManager.applyEnableWxBetterTogether(false);
1274
+ }
1275
+
1276
+ /**
1277
+ * Runtime enable/disable for wxApp Better Together (toast suppression + Mercury mute sync).
1278
+ *
1279
+ * **Phase 1 (WXCC-6026 / MMT): NOT part of the public host contract.**
1280
+ * Hosts must set `webexConfig.cc.enableWxBetterTogether` before `webex.init()` / `cc.register()`.
1281
+ * To change the flag after the SDK is initialized, re-init the SDK with the updated config.
1282
+ *
1283
+ * **Supported public read API:** {@link isWxBetterTogetherEnabled}.
1284
+ * **Supported telephony API:** unified `task.accept()`, `task.decline()`, `task.toggleMute()`,
1285
+ * `task.transmitDtmf()` — SDK routes wxApp calls internally when the init flag is active.
1286
+ *
1287
+ * **Production lifecycle does not call this method.** Station login, silent relogin, logout,
1288
+ * and deregister use {@link ensureWxAppPostStationLogin} and {@link teardownWxAppLocalState}
1289
+ * (usersub publish + Mercury subscribe/unsubscribe based on the init flag).
1290
+ *
1291
+ * This setter remains as a **private implementation** for Phase 2 runtime toggle and unit tests.
1292
+ * It updates `$config.enableWxBetterTogether`, TaskManager flags, cross-client usersub
1293
+ * (`answer-calls-on-wxcc`), and Mercury mute sync; rolls back config on publish/connect failure.
1294
+ *
1295
+ * @param enabled - `true` to enable wxApp answer + usersub suppression; `false` to disable and tear down.
1296
+ * @throws When enabling without login, on unsupported BROWSER station login, or when usersub/Mercury init fails.
1297
+ * @internal
1298
+ * @see enableWxBetterTogether (CCPluginConfig init flag)
1299
+ * @see ensureWxAppPostStationLogin
1300
+ * @see teardownWxAppLocalState
1301
+ */
1302
+ async setManageWebexCallingInWxcc(enabled) {
1303
+ if (enabled && !this.$webex.internal.device?.userId) {
1304
+ throw new Error('Cannot publish answer-calls-on-wxcc: user is not logged in');
1305
+ }
1306
+ if (enabled) {
1307
+ this.assertWxAppStationLoginSupportedForEnable();
1308
+ }
1309
+ const previousEnabled = this.isWxBetterTogetherEnabled();
1310
+ if (this.$config) {
1311
+ this.$config.enableWxBetterTogether = enabled;
1312
+ }
1313
+ this.taskManager.applyEnableWxBetterTogether(enabled);
1314
+ let publishedEnable = false;
1315
+ try {
1316
+ if (enabled) {
1317
+ await this.ensureWxAppMercuryAndSubscribe();
1318
+ await this.publishAnswerOnWebexCrossClientState(true);
1319
+ publishedEnable = true;
1320
+ this.taskManager.syncWxAppMuteFromCallDetailsForAllTasks();
1321
+ } else {
1322
+ await this.publishAnswerOnWebexCrossClientState(false);
1323
+ this.wxAppTelephonyMercurySync.unsubscribe();
1324
+ await this.releaseWxAppMercuryResources();
1325
+ }
1326
+ } catch (error) {
1327
+ if (publishedEnable) {
1328
+ await this.revertWxAppCrossClientPublish();
1329
+ } else if (enabled) {
1330
+ this.wxAppTelephonyMercurySync.unsubscribe();
1331
+ await this.releaseWxAppMercuryResources();
1332
+ }
1333
+ if (this.$config) {
1334
+ this.$config.enableWxBetterTogether = previousEnabled;
1335
+ }
1336
+ this.taskManager.applyEnableWxBetterTogether(previousEnabled);
1337
+ throw error;
1338
+ }
1339
+ }
1340
+ async ensureWxAppPostStationLogin() {
1341
+ if (this.getCurrentStationLoginOption() === _types.LoginOption.BROWSER) {
1342
+ return;
1343
+ }
1344
+ let publishedEnable = false;
1345
+ try {
1346
+ if (this.isWxBetterTogetherEnabled()) {
1347
+ await this.ensureWxAppMercuryAndSubscribe();
1348
+ await this.publishAnswerOnWebexCrossClientState(true);
1349
+ publishedEnable = true;
1350
+ this.taskManager.syncWxAppMuteFromCallDetailsForAllTasks();
1351
+ } else {
1352
+ await this.ensureWxAppDeviceRegistered();
1353
+ await this.publishAnswerOnWebexCrossClientState(false, {
1354
+ force: true
1355
+ });
1356
+ this.webexCrossClientService.teardown();
1357
+ this.wxAppTelephonyMercurySync.unsubscribe();
1358
+ await this.releaseWxAppMercuryResources();
1359
+ }
1360
+ } catch (error) {
1361
+ _loggerProxy.default.error(`Failed to initialize wxApp post-station-login: ${error}`, {
1362
+ module: _constants.CC_FILE,
1363
+ method: _constants.METHODS.STATION_LOGIN
1364
+ });
1365
+ if (this.isWxBetterTogetherEnabled()) {
1366
+ if (publishedEnable) {
1367
+ await this.revertWxAppCrossClientPublish();
1368
+ } else {
1369
+ this.wxAppTelephonyMercurySync.unsubscribe();
1370
+ await this.releaseWxAppMercuryResources();
1371
+ }
1372
+ this.resetEnableWxBetterTogetherConfig();
1373
+ } else {
1374
+ this.scheduleForcedFalsePublishRetry();
1375
+ }
1376
+ }
1377
+ }
1378
+ clearWxAppFalsePublishRetryTimer() {
1379
+ if (this.wxAppFalsePublishRetryTimer) {
1380
+ clearTimeout(this.wxAppFalsePublishRetryTimer);
1381
+ this.wxAppFalsePublishRetryTimer = undefined;
1382
+ }
1383
+ }
1384
+ scheduleForcedFalsePublishRetry(retryAttempt = 0) {
1385
+ this.scheduleFalsePublishRetry(retryAttempt, {
1386
+ requireDisabled: true
1387
+ });
1388
+ }
1389
+
1390
+ /**
1391
+ * Retries compensating false publish after rollback failure, regardless of enabled flag.
1392
+ * @private
1393
+ */
1394
+ scheduleCompensatingFalsePublishRetry(retryAttempt = 0) {
1395
+ this.scheduleFalsePublishRetry(retryAttempt);
1396
+ }
1397
+ scheduleFalsePublishRetry(retryAttempt = 0, options = {}) {
1398
+ if (retryAttempt >= ContactCenter.WXAPP_FALSE_PUBLISH_MAX_RETRIES) {
1399
+ return;
1400
+ }
1401
+ if (options?.requireDisabled && this.isWxBetterTogetherEnabled()) {
1402
+ return;
1403
+ }
1404
+ this.clearWxAppFalsePublishRetryTimer();
1405
+ this.wxAppFalsePublishRetryTimer = setTimeout(async () => {
1406
+ this.wxAppFalsePublishRetryTimer = undefined;
1407
+ if (options?.requireDisabled && this.isWxBetterTogetherEnabled()) {
1408
+ return;
1409
+ }
1410
+ if (!options?.requireDisabled && this.isWxBetterTogetherEnabled() && this.webexCrossClientService.isAnswerCallsStateActive()) {
1411
+ return;
1412
+ }
1413
+ try {
1414
+ await this.ensureWxAppDeviceRegistered();
1415
+ await this.publishAnswerOnWebexCrossClientState(false, {
1416
+ force: true
1417
+ });
1418
+ this.webexCrossClientService.teardown();
1419
+ this.wxAppTelephonyMercurySync.unsubscribe();
1420
+ await this.releaseWxAppMercuryResources();
1421
+ } catch (retryError) {
1422
+ _loggerProxy.default.error(`Failed to retry forced answer-calls-on-wxcc false publish: ${retryError}`, {
1423
+ module: _constants.CC_FILE,
1424
+ method: _constants.METHODS.SET_MANAGE_WEBEX_CALLING_IN_WXCC
1425
+ });
1426
+ this.scheduleFalsePublishRetry(retryAttempt + 1, options);
1427
+ }
1428
+ }, ContactCenter.WXAPP_FALSE_PUBLISH_RETRY_DELAY_MS);
1429
+ }
1430
+
1431
+ /**
1432
+ * Best-effort rollback when usersub true was published but wxApp setup did not complete.
1433
+ * @private
1434
+ */
1435
+ async revertWxAppCrossClientPublish() {
1436
+ try {
1437
+ await this.publishAnswerOnWebexCrossClientState(false, {
1438
+ force: true
1439
+ });
1440
+ } catch (error) {
1441
+ _loggerProxy.default.error(`Failed to publish compensating answer-calls-on-wxcc false during wxApp rollback: ${error}`, {
1442
+ module: _constants.CC_FILE,
1443
+ method: _constants.METHODS.SET_MANAGE_WEBEX_CALLING_IN_WXCC
1444
+ });
1445
+ this.scheduleCompensatingFalsePublishRetry();
1446
+ }
1447
+ this.webexCrossClientService.teardown();
1448
+ this.wxAppTelephonyMercurySync.unsubscribe();
1449
+ await this.releaseWxAppMercuryResources();
1450
+ }
1451
+ async ensureWxAppDeviceRegistered() {
1452
+ const device = this.$webex.internal.device;
1453
+ if (device && !device.registered && device.register) {
1454
+ await device.register();
1455
+ this.wxAppDeviceRegisteredByCc = true;
1456
+ _loggerProxy.default.log('WxApp: device registered for cross-client publish', {
1457
+ module: _constants.CC_FILE,
1458
+ method: _constants.METHODS.ENSURE_WXAPP_MERCURY_CONNECTED
1459
+ });
1460
+ }
1461
+ }
1462
+ async ensureWxAppMercuryConnected() {
1463
+ const mercury = this.$webex.internal.mercury;
1464
+ await this.ensureWxAppDeviceRegistered();
1465
+ if (mercury && !mercury.connected) {
1466
+ await mercury.connect();
1467
+ this.wxAppMercuryConnectedByCc = true;
1468
+ _loggerProxy.default.log('WxApp mute sync: mercury connected', {
1469
+ module: _constants.CC_FILE,
1470
+ method: _constants.METHODS.ENSURE_WXAPP_MERCURY_CONNECTED
1471
+ });
1472
+ }
1473
+ }
1474
+
1475
+ /**
1476
+ * Disconnects Mercury and unregisters the device when wxApp mute sync opened them.
1477
+ * @private
1478
+ */
1479
+ async releaseWxAppMercuryResources() {
1480
+ const mercury = this.$webex.internal.mercury;
1481
+ const device = this.$webex.internal.device;
1482
+ if (this.wxAppMercuryConnectedByCc && mercury?.connected) {
1483
+ try {
1484
+ await mercury.disconnect();
1485
+ this.wxAppMercuryConnectedByCc = false;
1486
+ _loggerProxy.default.log('WxApp mute sync: mercury disconnected', {
1487
+ module: _constants.CC_FILE,
1488
+ method: _constants.METHODS.ENSURE_WXAPP_MERCURY_CONNECTED
1489
+ });
1490
+ } catch (error) {
1491
+ _loggerProxy.default.error(`Failed to disconnect wxApp Mercury: ${error}`, {
1492
+ module: _constants.CC_FILE,
1493
+ method: _constants.METHODS.ENSURE_WXAPP_MERCURY_CONNECTED
1494
+ });
1495
+ }
1496
+ }
1497
+ if (this.wxAppDeviceRegisteredByCc && device?.registered && device.unregister) {
1498
+ try {
1499
+ // @ts-ignore
1500
+ await device.unregister();
1501
+ this.wxAppDeviceRegisteredByCc = false;
1502
+ _loggerProxy.default.log('WxApp mute sync: device unregistered', {
1503
+ module: _constants.CC_FILE,
1504
+ method: _constants.METHODS.ENSURE_WXAPP_MERCURY_CONNECTED
1505
+ });
1506
+ } catch (error) {
1507
+ _loggerProxy.default.error(`Failed to unregister wxApp device: ${error}`, {
1508
+ module: _constants.CC_FILE,
1509
+ method: _constants.METHODS.ENSURE_WXAPP_MERCURY_CONNECTED
1510
+ });
1511
+ }
1512
+ } else if (this.wxAppDeviceRegisteredByCc) {
1513
+ this.wxAppDeviceRegisteredByCc = false;
1514
+ }
1515
+ }
1516
+
1517
+ /**
1518
+ * Clears wxApp runtime state and feature-owned resources. Publish failures are logged;
1519
+ * optional rethrow for deregister when callers need to surface usersub errors.
1520
+ * @private
1521
+ */
1522
+ async teardownWxAppLocalState(options) {
1523
+ this.clearWxAppFalsePublishRetryTimer();
1524
+ let publishError;
1525
+ try {
1526
+ const shouldForceFalsePublish = this.isWxBetterTogetherEnabled() || this.webexCrossClientService.isAnswerCallsStateActive();
1527
+ await this.publishAnswerOnWebexCrossClientState(false, {
1528
+ force: shouldForceFalsePublish
1529
+ });
1530
+ } catch (error) {
1531
+ publishError = error;
1532
+ _loggerProxy.default.error(`Failed to publish answer-calls-on-wxcc false during wxApp teardown: ${error}`, {
1533
+ module: _constants.CC_FILE,
1534
+ method: _constants.METHODS.SET_MANAGE_WEBEX_CALLING_IN_WXCC
1535
+ });
1536
+ }
1537
+ this.webexCrossClientService.teardown();
1538
+ this.wxAppTelephonyMercurySync.unsubscribe();
1539
+ await this.releaseWxAppMercuryResources();
1540
+ if (options?.clearInitFlag) {
1541
+ this.resetEnableWxBetterTogetherConfig();
1542
+ }
1543
+ if (publishError) {
1544
+ this.scheduleCompensatingFalsePublishRetry();
1545
+ }
1546
+ if (options?.rethrowPublishError && publishError) {
1547
+ throw publishError;
1548
+ }
1549
+ return {
1550
+ publishError: publishError ?? undefined
1551
+ };
1552
+ }
1553
+ async ensureWxAppMercuryAndSubscribe() {
1554
+ if (!this.isWxBetterTogetherEnabled()) {
1555
+ return;
1556
+ }
1557
+ if (this.getCurrentStationLoginOption() === _types.LoginOption.BROWSER) {
1558
+ return;
1559
+ }
1560
+ const agentId = this.agentConfig?.agentId;
1561
+ if (!agentId) {
1562
+ _loggerProxy.default.error('Cannot subscribe wxApp mute sync: agentId unavailable', {
1563
+ module: _constants.CC_FILE,
1564
+ method: _constants.METHODS.SYNC_WXAPP_MUTE_FROM_MERCURY
1565
+ });
1566
+ return;
1567
+ }
1568
+ try {
1569
+ await this.ensureWxAppMercuryConnected();
1570
+ this.wxAppTelephonyMercurySync.subscribe(agentId, (callId, muted) => {
1571
+ this.taskManager.applyWxAppMuteStateFromSync(callId, muted);
1572
+ });
1573
+ } catch (error) {
1574
+ _loggerProxy.default.error(`Failed to ensure wxApp Mercury mute sync: ${error}`, {
1575
+ module: _constants.CC_FILE,
1576
+ method: _constants.METHODS.SYNC_WXAPP_MUTE_FROM_MERCURY
1577
+ });
1578
+ this.wxAppTelephonyMercurySync.unsubscribe();
1579
+ await this.releaseWxAppMercuryResources();
1580
+ throw error;
1581
+ }
1582
+ }
1583
+ async publishAnswerOnWebexCrossClientState(enable, options) {
1584
+ if (enable && !this.isWxBetterTogetherEnabled()) {
1585
+ return;
1586
+ }
1587
+ if (!enable && !options?.force && !this.webexCrossClientService.isAnswerCallsStateActive()) {
1588
+ return;
1589
+ }
1590
+ const userId = this.$webex.internal.device?.userId;
1591
+ if (!userId) {
1592
+ return;
1593
+ }
1594
+ await this.webexCrossClientService.setManageWebexCallingInWxcc(enable, {
1595
+ userId
1596
+ });
1597
+ if (enable) {
1598
+ this.clearWxAppFalsePublishRetryTimer();
1599
+ }
1600
+ }
1601
+
1173
1602
  /**
1174
1603
  * Initializes event listeners for the Contact Center service
1175
1604
  * Sets up handlers for connection state changes and other core events
@@ -1268,6 +1697,7 @@ class ContactCenter extends _webexCore.WebexPlugin {
1268
1697
  }
1269
1698
  this.agentConfig.lastStateAuxCodeId = auxCodeId;
1270
1699
  this.agentConfig.isAgentLoggedIn = true;
1700
+ await this.ensureWxAppPostStationLogin();
1271
1701
  _loggerProxy.default.log(`Silent relogin process completed successfully with login Option: ${reLoginResponse.data.deviceType} teamId: ${reLoginResponse.data.teamId}`, {
1272
1702
  module: _constants.CC_FILE,
1273
1703
  method: _constants.METHODS.SILENT_RELOGIN,
@@ -1884,8 +2314,8 @@ class ContactCenter extends _webexCore.WebexPlugin {
1884
2314
  }
1885
2315
 
1886
2316
  /**
1887
- * Returns paginated entry points for the organization.
1888
- * Thin wrapper around internal EntryPoint instance.
2317
+ * Returns paginated entry points using the EntryPoint service defaults.
2318
+ * Existing request parameters can override those defaults.
1889
2319
  * @public
1890
2320
  */
1891
2321
  async getEntryPoints(params = {}) {
@@ -1893,8 +2323,8 @@ class ContactCenter extends _webexCore.WebexPlugin {
1893
2323
  }
1894
2324
 
1895
2325
  /**
1896
- * Returns paginated contact service queues for the organization.
1897
- * Thin wrapper around internal Queue instance.
2326
+ * Returns paginated contact service queues using the Queue service defaults.
2327
+ * Existing request parameters can override those defaults.
1898
2328
  * @public
1899
2329
  */
1900
2330
  async getQueues(params = {}) {