@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.
- package/.sdd/manifest.json +5 -4
- package/ai-docs/ARCHITECTURE.md +1 -1
- package/ai-docs/CONTRACTS.md +5 -1
- package/ai-docs/SECURITY.md +1 -1
- package/ai-docs/contact-center-spec.md +22 -4
- package/ai-docs/features/consult-transfer-list-policy/spec/feature-spec.md +362 -0
- package/dist/cc.js +440 -10
- package/dist/cc.js.map +1 -1
- package/dist/config.js +7 -0
- package/dist/config.js.map +1 -1
- package/dist/constants.js +10 -2
- package/dist/constants.js.map +1 -1
- package/dist/index.js.map +1 -1
- package/dist/metrics/behavioral-events.js +13 -0
- package/dist/metrics/behavioral-events.js.map +1 -1
- package/dist/metrics/constants.js +2 -0
- package/dist/metrics/constants.js.map +1 -1
- package/dist/services/AddressBook.js +18 -15
- package/dist/services/AddressBook.js.map +1 -1
- package/dist/services/AnswerCallOnWebexService.js +174 -0
- package/dist/services/AnswerCallOnWebexService.js.map +1 -0
- package/dist/services/EntryPoint.js +46 -68
- package/dist/services/EntryPoint.js.map +1 -1
- package/dist/services/Queue.js +27 -22
- package/dist/services/Queue.js.map +1 -1
- package/dist/services/WebexCrossClientService.js +171 -0
- package/dist/services/WebexCrossClientService.js.map +1 -0
- package/dist/services/WxAppTelephonyMercurySync.js +93 -0
- package/dist/services/WxAppTelephonyMercurySync.js.map +1 -0
- package/dist/services/config/Util.js +3 -0
- package/dist/services/config/Util.js.map +1 -1
- package/dist/services/config/constants.js +10 -6
- package/dist/services/config/constants.js.map +1 -1
- package/dist/services/config/types.js +4 -0
- package/dist/services/config/types.js.map +1 -1
- package/dist/services/core/Err.js.map +1 -1
- package/dist/services/core/WebexRequest.js +6 -2
- package/dist/services/core/WebexRequest.js.map +1 -1
- package/dist/services/core/aqm-reqs.js +28 -14
- package/dist/services/core/aqm-reqs.js.map +1 -1
- package/dist/services/core/types.js.map +1 -1
- package/dist/services/task/Task.js +73 -7
- package/dist/services/task/Task.js.map +1 -1
- package/dist/services/task/TaskFactory.js +8 -4
- package/dist/services/task/TaskFactory.js.map +1 -1
- package/dist/services/task/TaskManager.js +176 -20
- package/dist/services/task/TaskManager.js.map +1 -1
- package/dist/services/task/WebexCallingUtils.js +70 -0
- package/dist/services/task/WebexCallingUtils.js.map +1 -0
- package/dist/services/task/constants.js +4 -1
- package/dist/services/task/constants.js.map +1 -1
- package/dist/services/task/contact.js +29 -0
- package/dist/services/task/contact.js.map +1 -1
- package/dist/services/task/digital/Digital.js +3 -2
- package/dist/services/task/digital/Digital.js.map +1 -1
- package/dist/services/task/state-machine/TaskStateMachine.js +135 -37
- package/dist/services/task/state-machine/TaskStateMachine.js.map +1 -1
- package/dist/services/task/state-machine/actions.js +6 -1
- package/dist/services/task/state-machine/actions.js.map +1 -1
- package/dist/services/task/state-machine/guards.js +38 -11
- package/dist/services/task/state-machine/guards.js.map +1 -1
- package/dist/services/task/state-machine/types.js.map +1 -1
- package/dist/services/task/state-machine/uiControlsComputer.js +118 -18
- package/dist/services/task/state-machine/uiControlsComputer.js.map +1 -1
- package/dist/services/task/types.js +16 -1
- package/dist/services/task/types.js.map +1 -1
- package/dist/services/task/voice/Voice.js +350 -14
- package/dist/services/task/voice/Voice.js.map +1 -1
- package/dist/services/task/voice/WebRTC.js +4 -1
- package/dist/services/task/voice/WebRTC.js.map +1 -1
- package/dist/services/task/voice/wxAppVoiceMethods.js +201 -0
- package/dist/services/task/voice/wxAppVoiceMethods.js.map +1 -0
- package/dist/services/wxAppTelephonyUtils.js +19 -0
- package/dist/services/wxAppTelephonyUtils.js.map +1 -0
- package/dist/types/cc.d.ts +77 -4
- package/dist/types/config.d.ts +7 -0
- package/dist/types/constants.d.ts +8 -0
- package/dist/types/index.d.ts +3 -1
- package/dist/types/metrics/constants.d.ts +2 -0
- package/dist/types/services/AddressBook.d.ts +2 -1
- package/dist/types/services/AnswerCallOnWebexService.d.ts +37 -0
- package/dist/types/services/EntryPoint.d.ts +7 -5
- package/dist/types/services/Queue.d.ts +5 -3
- package/dist/types/services/WebexCrossClientService.d.ts +28 -0
- package/dist/types/services/WxAppTelephonyMercurySync.d.ts +28 -0
- package/dist/types/services/config/constants.d.ts +8 -5
- package/dist/types/services/config/types.d.ts +17 -4
- package/dist/types/services/core/Err.d.ts +2 -0
- package/dist/types/services/core/WebexRequest.d.ts +1 -0
- package/dist/types/services/core/types.d.ts +2 -0
- package/dist/types/services/task/Task.d.ts +20 -2
- package/dist/types/services/task/TaskFactory.d.ts +2 -1
- package/dist/types/services/task/WebexCallingUtils.d.ts +11 -0
- package/dist/types/services/task/constants.d.ts +3 -0
- package/dist/types/services/task/contact.d.ts +4 -0
- package/dist/types/services/task/digital/Digital.d.ts +2 -2
- package/dist/types/services/task/state-machine/TaskStateMachine.d.ts +260 -56
- package/dist/types/services/task/state-machine/guards.d.ts +6 -5
- package/dist/types/services/task/state-machine/types.d.ts +9 -1
- package/dist/types/services/task/types.d.ts +81 -4
- package/dist/types/services/task/voice/Voice.d.ts +48 -9
- package/dist/types/services/task/voice/WebRTC.d.ts +2 -2
- package/dist/types/services/task/voice/wxAppVoiceMethods.d.ts +52 -0
- package/dist/types/services/wxAppTelephonyUtils.d.ts +5 -0
- package/dist/types/types.d.ts +14 -8
- package/dist/types/utils/PageCache.d.ts +20 -3
- package/dist/types.js +7 -2
- package/dist/types.js.map +1 -1
- package/dist/utils/PageCache.js +19 -5
- package/dist/utils/PageCache.js.map +1 -1
- package/dist/webex.js +1 -1
- package/package.json +1 -1
- package/src/cc.ts +506 -9
- package/src/config.ts +7 -0
- package/src/constants.ts +8 -0
- package/src/index.ts +2 -0
- package/src/metrics/ai-docs/metrics-spec.md +9 -3
- package/src/metrics/behavioral-events.ts +14 -0
- package/src/metrics/constants.ts +2 -0
- package/src/services/AddressBook.ts +17 -6
- package/src/services/AnswerCallOnWebexService.ts +206 -0
- package/src/services/EntryPoint.ts +59 -60
- package/src/services/Queue.ts +29 -12
- package/src/services/WebexCrossClientService.ts +212 -0
- package/src/services/WxAppTelephonyMercurySync.ts +115 -0
- package/src/services/ai-docs/AGENTS.md +10 -10
- package/src/services/ai-docs/services-spec.md +6 -1
- package/src/services/config/Util.ts +3 -0
- package/src/services/config/ai-docs/AGENTS.md +1 -1
- package/src/services/config/ai-docs/ARCHITECTURE.md +2 -2
- package/src/services/config/ai-docs/config-spec.md +6 -0
- package/src/services/config/constants.ts +10 -6
- package/src/services/config/types.ts +16 -4
- package/src/services/core/Err.ts +1 -0
- package/src/services/core/WebexRequest.ts +3 -1
- package/src/services/core/ai-docs/core-spec.md +5 -1
- package/src/services/core/aqm-reqs.ts +30 -15
- package/src/services/core/types.ts +2 -0
- package/src/services/task/Task.ts +79 -8
- package/src/services/task/TaskFactory.ts +8 -3
- package/src/services/task/TaskManager.ts +254 -15
- package/src/services/task/WebexCallingUtils.ts +136 -0
- package/src/services/task/ai-docs/ARCHITECTURE.md +1 -0
- package/src/services/task/ai-docs/task-spec.md +117 -2
- package/src/services/task/constants.ts +3 -0
- package/src/services/task/contact.ts +30 -0
- package/src/services/task/digital/Digital.ts +4 -2
- package/src/services/task/state-machine/TaskStateMachine.ts +210 -63
- package/src/services/task/state-machine/actions.ts +5 -2
- package/src/services/task/state-machine/ai-docs/AGENTS.md +8 -4
- package/src/services/task/state-machine/ai-docs/ARCHITECTURE.md +17 -8
- package/src/services/task/state-machine/ai-docs/task-state-machine-spec.md +46 -22
- package/src/services/task/state-machine/guards.ts +64 -11
- package/src/services/task/state-machine/types.ts +16 -1
- package/src/services/task/state-machine/uiControlsComputer.ts +206 -32
- package/src/services/task/types.ts +114 -4
- package/src/services/task/voice/Voice.ts +462 -12
- package/src/services/task/voice/WebRTC.ts +5 -1
- package/src/services/task/voice/wxAppVoiceMethods.ts +307 -0
- package/src/services/wxAppTelephonyUtils.ts +14 -0
- package/src/types.ts +33 -9
- package/src/utils/AGENTS.md +21 -10
- package/src/utils/PageCache.ts +38 -5
- package/src/utils/ai-docs/utils-spec.md +21 -11
- package/test/unit/spec/cc.ts +1274 -0
- package/test/unit/spec/metrics/behavioral-events.ts +18 -0
- package/test/unit/spec/services/AddressBook.ts +37 -6
- package/test/unit/spec/services/AnswerCallOnWebexService.ts +223 -0
- package/test/unit/spec/services/EntryPoint.ts +87 -40
- package/test/unit/spec/services/Queue.ts +123 -12
- package/test/unit/spec/services/WebexCrossClientService.ts +261 -0
- package/test/unit/spec/services/WxAppTelephonyMercurySync.ts +113 -0
- package/test/unit/spec/services/config/Util.ts +85 -0
- package/test/unit/spec/services/core/WebexRequest.ts +3 -1
- package/test/unit/spec/services/core/aqm-reqs.ts +113 -1
- package/test/unit/spec/services/task/Task.ts +200 -0
- package/test/unit/spec/services/task/TaskFactory.ts +39 -2
- package/test/unit/spec/services/task/TaskManager.ts +653 -1
- package/test/unit/spec/services/task/WebexCallingUtils.ts +153 -0
- package/test/unit/spec/services/task/contact.ts +33 -0
- package/test/unit/spec/services/task/state-machine/TaskStateMachine.ts +854 -72
- package/test/unit/spec/services/task/state-machine/guards.ts +210 -8
- package/test/unit/spec/services/task/state-machine/uiControlsComputer.ts +445 -7
- package/test/unit/spec/services/task/voice/Voice.ts +874 -0
- package/test/unit/spec/services/task/voice/wxAppVoiceMethods.ts +459 -0
- package/umd/contact-center.min.js +2 -2
- package/umd/contact-center.min.js.map +1 -1
|
@@ -14,11 +14,13 @@ var _types3 = require("../../types");
|
|
|
14
14
|
var _loggerProxy = _interopRequireDefault(require("../../logger-proxy"));
|
|
15
15
|
var _TaskUtils = require("./TaskUtils");
|
|
16
16
|
var _TaskFactory = _interopRequireDefault(require("./TaskFactory"));
|
|
17
|
+
var _WebexCallingUtils = require("./WebexCallingUtils");
|
|
17
18
|
var _WebRTC = _interopRequireDefault(require("./voice/WebRTC"));
|
|
18
19
|
var _stateMachine = require("./state-machine");
|
|
19
20
|
var _taskDataNormalizer = require("./taskDataNormalizer");
|
|
20
21
|
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
|
|
21
22
|
const CC_EVENT_SET = new Set(Object.values(_types2.CC_EVENTS));
|
|
23
|
+
const MAIN_INTERACTION_CORRELATED_EVENTS = new Set([_types2.CC_EVENTS.AGENT_CONSULT_ENDED, _types2.CC_EVENTS.PARTICIPANT_LEFT_CONFERENCE]);
|
|
22
24
|
const isCcEvent = value => CC_EVENT_SET.has(value);
|
|
23
25
|
|
|
24
26
|
/** @internal */
|
|
@@ -109,6 +111,9 @@ class TaskManager extends _events.default {
|
|
|
109
111
|
setWebRtcEnabled(webRtcEnabled) {
|
|
110
112
|
this.webRtcEnabled = webRtcEnabled;
|
|
111
113
|
}
|
|
114
|
+
setAnswerCallOnWebexService(answerCallOnWebexService) {
|
|
115
|
+
this.answerCallOnWebexService = answerCallOnWebexService;
|
|
116
|
+
}
|
|
112
117
|
handleIncomingWebCall = call => {
|
|
113
118
|
const currentTask = Object.values(this.taskCollection).find(task => task.data.interaction.mediaType === 'telephony' && !(0, _TaskUtils.isCampaignPreviewReservation)(task));
|
|
114
119
|
if (currentTask) {
|
|
@@ -139,9 +144,10 @@ class TaskManager extends _events.default {
|
|
|
139
144
|
* @param ccEvent - The CC_EVENT type from WebSocket
|
|
140
145
|
* @param payload - The event payload
|
|
141
146
|
* @param agentId - Optional agent ID for state detection (needed for HYDRATE)
|
|
147
|
+
* @param task - Optional task instance for state-aware CONTACT_ENDED mapping
|
|
142
148
|
* @returns TaskEventPayload for state machine or null if no mapping
|
|
143
149
|
*/
|
|
144
|
-
static mapEventToTaskStateMachineEvent(ccEvent, payload, agentId) {
|
|
150
|
+
static mapEventToTaskStateMachineEvent(ccEvent, payload, agentId, task, enableWxBetterTogether) {
|
|
145
151
|
const mediaResourceId = payload.mediaResourceId || payload.interaction?.media?.[payload.interactionId]?.mediaResourceId;
|
|
146
152
|
switch (ccEvent) {
|
|
147
153
|
// CC -> TaskEvent mappings (see TaskStateMachine comment for quick reference)
|
|
@@ -284,13 +290,31 @@ class TaskManager extends _events.default {
|
|
|
284
290
|
taskData: payload
|
|
285
291
|
};
|
|
286
292
|
case _types2.CC_EVENTS.CONTACT_ENDED:
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
293
|
+
{
|
|
294
|
+
const wrapUpRequired = (0, _TaskUtils.isCampaignPreviewTask)(payload) ? false : payload.agentsPendingWrapUp?.includes(agentId || '') || false;
|
|
295
|
+
|
|
296
|
+
// Post-accept wxApp outdial agent-end delivers ContactEnded instead of
|
|
297
|
+
// AgentOutboundFailed. Normalize to OUTBOUND_FAILED so state machine
|
|
298
|
+
// enters WRAPPING_UP and emits TASK_OUTDIAL_FAILED (AGENT_ENDS).
|
|
299
|
+
// Pre-accept cancelTask decline stays CONTACT_ENDED → TERMINATED (no wrapup).
|
|
300
|
+
if (TaskManager.isAgentTerminatedOutdialWrapup(payload, wrapUpRequired, task, agentId, enableWxBetterTogether)) {
|
|
301
|
+
return {
|
|
302
|
+
type: _stateMachine.TaskEvent.OUTBOUND_FAILED,
|
|
303
|
+
reason: 'AGENT_ENDS',
|
|
304
|
+
taskData: {
|
|
305
|
+
...payload,
|
|
306
|
+
wrapUpRequired: true
|
|
307
|
+
}
|
|
308
|
+
};
|
|
292
309
|
}
|
|
293
|
-
|
|
310
|
+
return {
|
|
311
|
+
type: _stateMachine.TaskEvent.CONTACT_ENDED,
|
|
312
|
+
taskData: {
|
|
313
|
+
...payload,
|
|
314
|
+
wrapUpRequired
|
|
315
|
+
}
|
|
316
|
+
};
|
|
317
|
+
}
|
|
294
318
|
case _types2.CC_EVENTS.AGENT_INVITE_FAILED:
|
|
295
319
|
return {
|
|
296
320
|
type: _stateMachine.TaskEvent.INVITE_FAILED,
|
|
@@ -308,11 +332,18 @@ class TaskManager extends _events.default {
|
|
|
308
332
|
reason: payload.reason
|
|
309
333
|
};
|
|
310
334
|
case _types2.CC_EVENTS.AGENT_OUTBOUND_FAILED:
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
335
|
+
{
|
|
336
|
+
const isAgentTerminatedOutdial = payload.interaction?.outboundType === 'OUTDIAL' && (payload.terminatingParty === 'Agent' || payload.reason === 'AGENT_ENDS');
|
|
337
|
+
const suppressOutdialFailedPopup = isAgentTerminatedOutdial && !TaskManager.isWxAppManagedOutdialTask(agentId, payload, task, enableWxBetterTogether);
|
|
338
|
+
return {
|
|
339
|
+
type: _stateMachine.TaskEvent.OUTBOUND_FAILED,
|
|
340
|
+
taskData: suppressOutdialFailedPopup ? {
|
|
341
|
+
...payload,
|
|
342
|
+
suppressOutdialFailedPopup: true
|
|
343
|
+
} : payload,
|
|
344
|
+
reason: payload.reason
|
|
345
|
+
};
|
|
346
|
+
}
|
|
316
347
|
case _types2.CC_EVENTS.CAMPAIGN_PREVIEW_ACCEPT_FAILED:
|
|
317
348
|
return {
|
|
318
349
|
type: _stateMachine.TaskEvent.CAMPAIGN_PREVIEW_ACCEPT_FAILED,
|
|
@@ -385,6 +416,43 @@ class TaskManager extends _events.default {
|
|
|
385
416
|
}
|
|
386
417
|
}
|
|
387
418
|
|
|
419
|
+
/**
|
|
420
|
+
* True when the current agent's task is a wxApp-managed outdial (thick-client telephony).
|
|
421
|
+
*/
|
|
422
|
+
static isWxAppManagedOutdialTask(agentId, payload, task, enableWxBetterTogether) {
|
|
423
|
+
const wxAppEnabled = task?.uiControlConfig?.enableWxBetterTogether ?? enableWxBetterTogether ?? false;
|
|
424
|
+
if (!wxAppEnabled) {
|
|
425
|
+
return false;
|
|
426
|
+
}
|
|
427
|
+
const effectiveAgentId = agentId ?? task?.data?.agentId;
|
|
428
|
+
const participants = payload.interaction?.participants ?? task?.data?.interaction?.participants;
|
|
429
|
+
const details = (0, _WebexCallingUtils.getWebexCallingDeviceDetailsForAgent)(effectiveAgentId, participants);
|
|
430
|
+
return details?.deviceType === 'wxApp';
|
|
431
|
+
}
|
|
432
|
+
|
|
433
|
+
/**
|
|
434
|
+
* True when ContactEnded represents an agent-terminated wxApp outdial that should
|
|
435
|
+
* enter wrapup with an outdial-failed popup (legacy AgentOutboundFailed parity).
|
|
436
|
+
*/
|
|
437
|
+
static isAgentTerminatedOutdialWrapup(payload, wrapUpRequired, task, agentId, enableWxBetterTogether) {
|
|
438
|
+
const isOutdial = payload.interaction?.outboundType === 'OUTDIAL';
|
|
439
|
+
const agentTerminated = payload.terminatingParty === 'Agent';
|
|
440
|
+
if (!isOutdial || !agentTerminated) {
|
|
441
|
+
return false;
|
|
442
|
+
}
|
|
443
|
+
if (!TaskManager.isWxAppManagedOutdialTask(agentId, payload, task, enableWxBetterTogether)) {
|
|
444
|
+
return false;
|
|
445
|
+
}
|
|
446
|
+
const wxAppAnswerPending = task?.uiControlConfig?.wxAppAnswerPending ?? false;
|
|
447
|
+
|
|
448
|
+
// Pre-accept decline: decline() clears wxAppAnswerPending; backend may still send state wrapUp.
|
|
449
|
+
if (!wxAppAnswerPending && !wrapUpRequired) {
|
|
450
|
+
return false;
|
|
451
|
+
}
|
|
452
|
+
const interactionWrapUp = payload.interaction?.state === 'wrapUp';
|
|
453
|
+
return wrapUpRequired || interactionWrapUp || wxAppAnswerPending;
|
|
454
|
+
}
|
|
455
|
+
|
|
388
456
|
/**
|
|
389
457
|
* Register WebSocket message listeners for task events
|
|
390
458
|
*
|
|
@@ -493,6 +561,9 @@ class TaskManager extends _events.default {
|
|
|
493
561
|
this.taskCollection[interactionId] = task;
|
|
494
562
|
}
|
|
495
563
|
}
|
|
564
|
+
if (!task && MAIN_INTERACTION_CORRELATED_EVENTS.has(eventType)) {
|
|
565
|
+
task = this.findUniqueTaskByRelatedInteraction(message.data);
|
|
566
|
+
}
|
|
496
567
|
const wasConsultedTask = Boolean(task?.data?.isConsulted);
|
|
497
568
|
const computeWrapUpRequired = () => {
|
|
498
569
|
if (message.data.wrapUpRequired !== undefined) {
|
|
@@ -507,7 +578,7 @@ class TaskManager extends _events.default {
|
|
|
507
578
|
...message.data,
|
|
508
579
|
wrapUpRequired: computeWrapUpRequired()
|
|
509
580
|
} : message.data;
|
|
510
|
-
const stateMachineEvent = TaskManager.mapEventToTaskStateMachineEvent(eventType, adjustedPayload, this.agentId);
|
|
581
|
+
const stateMachineEvent = TaskManager.mapEventToTaskStateMachineEvent(eventType, adjustedPayload, this.agentId, task, this.configFlags?.enableWxBetterTogether);
|
|
511
582
|
_loggerProxy.default.info(`Handling task event ${eventType}`, {
|
|
512
583
|
module: _constants.TASK_MANAGER_FILE,
|
|
513
584
|
method: 'prepareEventContext',
|
|
@@ -521,6 +592,33 @@ class TaskManager extends _events.default {
|
|
|
521
592
|
};
|
|
522
593
|
}
|
|
523
594
|
|
|
595
|
+
/**
|
|
596
|
+
* Resolve lifecycle events that are emitted for the main interaction while the
|
|
597
|
+
* local task can still be indexed by a child consult interaction. Exact task
|
|
598
|
+
* keys are handled before this fallback. Multiple aliases of the same task are
|
|
599
|
+
* treated as one candidate; genuinely ambiguous matches are intentionally ignored.
|
|
600
|
+
*/
|
|
601
|
+
findUniqueTaskByRelatedInteraction(payload) {
|
|
602
|
+
const payloadInteractionIds = new Set([payload.interactionId, payload.interaction?.interactionId, payload.interaction?.mainInteractionId, payload.interaction?.parentInteractionId, payload.interaction?.callProcessingDetails?.parentInteractionId].filter(interactionId => Boolean(interactionId)));
|
|
603
|
+
if (payloadInteractionIds.size === 0) return undefined;
|
|
604
|
+
const candidates = [...new Set(Object.values(this.taskCollection).filter(candidate => {
|
|
605
|
+
const taskInteraction = candidate?.data?.interaction;
|
|
606
|
+
const candidateInteractionIds = [candidate?.data?.interactionId, taskInteraction?.interactionId, taskInteraction?.mainInteractionId, taskInteraction?.parentInteractionId, taskInteraction?.callProcessingDetails?.parentInteractionId];
|
|
607
|
+
return candidateInteractionIds.some(interactionId => Boolean(interactionId) && payloadInteractionIds.has(interactionId));
|
|
608
|
+
}))];
|
|
609
|
+
if (candidates.length === 1) {
|
|
610
|
+
return candidates[0];
|
|
611
|
+
}
|
|
612
|
+
if (candidates.length > 1) {
|
|
613
|
+
_loggerProxy.default.warn('Unable to correlate task event to a unique main interaction task', {
|
|
614
|
+
module: _constants.TASK_MANAGER_FILE,
|
|
615
|
+
method: 'findUniqueTaskByRelatedInteraction',
|
|
616
|
+
interactionId: payload.interaction?.mainInteractionId || payload.interaction?.parentInteractionId || payload.interaction?.callProcessingDetails?.parentInteractionId || payload.interactionId
|
|
617
|
+
});
|
|
618
|
+
}
|
|
619
|
+
return undefined;
|
|
620
|
+
}
|
|
621
|
+
|
|
524
622
|
/**
|
|
525
623
|
* Handle task lifecycle events and determine required actions
|
|
526
624
|
*
|
|
@@ -638,7 +736,7 @@ class TaskManager extends _events.default {
|
|
|
638
736
|
wrapUpRequired: false,
|
|
639
737
|
isConferenceInProgress: false,
|
|
640
738
|
isAutoAnswering: false
|
|
641
|
-
}, this.configFlags, this.wrapupData, this.agentId);
|
|
739
|
+
}, this.configFlags, this.wrapupData, this.agentId, this.answerCallOnWebexService);
|
|
642
740
|
this.setupTaskListeners(task);
|
|
643
741
|
this.taskCollection[payload.interactionId] = task;
|
|
644
742
|
} else {
|
|
@@ -664,7 +762,7 @@ class TaskManager extends _events.default {
|
|
|
664
762
|
isConsulted: isConsultedTask,
|
|
665
763
|
isAutoAnswering: shouldAutoAnswer
|
|
666
764
|
};
|
|
667
|
-
const task = _TaskFactory.default.createTask(this.contact, this.webCallingService, taskData, this.configFlags, this.wrapupData, this.agentId);
|
|
765
|
+
const task = _TaskFactory.default.createTask(this.contact, this.webCallingService, taskData, this.configFlags, this.wrapupData, this.agentId, this.answerCallOnWebexService);
|
|
668
766
|
this.setupTaskListeners(task);
|
|
669
767
|
this.taskCollection[payload.interactionId] = task;
|
|
670
768
|
return {
|
|
@@ -693,7 +791,7 @@ class TaskManager extends _events.default {
|
|
|
693
791
|
isConferenceInProgress: (0, _TaskUtils.getIsConferenceInProgress)(payload),
|
|
694
792
|
isAutoAnswering: shouldAutoAnswer
|
|
695
793
|
};
|
|
696
|
-
task = _TaskFactory.default.createTask(this.contact, this.webCallingService, taskData, this.configFlags, this.wrapupData, this.agentId);
|
|
794
|
+
task = _TaskFactory.default.createTask(this.contact, this.webCallingService, taskData, this.configFlags, this.wrapupData, this.agentId, this.answerCallOnWebexService);
|
|
697
795
|
this.setupTaskListeners(task);
|
|
698
796
|
this.taskCollection[payload.interactionId] = task;
|
|
699
797
|
}
|
|
@@ -713,6 +811,14 @@ class TaskManager extends _events.default {
|
|
|
713
811
|
destinationType: taskData.destinationType ?? snapshot?.context?.consultDestinationType ?? null
|
|
714
812
|
} : taskData;
|
|
715
813
|
task.updateTaskData(updateTaskData);
|
|
814
|
+
|
|
815
|
+
// A main-interaction lifecycle event can re-key a child consult task. Remove
|
|
816
|
+
// any aliases first so consumers never observe duplicate task entries.
|
|
817
|
+
Object.entries(this.taskCollection).forEach(([taskId, candidate]) => {
|
|
818
|
+
if (candidate === task && taskId !== taskData.interactionId) {
|
|
819
|
+
delete this.taskCollection[taskId];
|
|
820
|
+
}
|
|
821
|
+
});
|
|
716
822
|
this.taskCollection[taskData.interactionId] = task;
|
|
717
823
|
return task;
|
|
718
824
|
}
|
|
@@ -753,8 +859,8 @@ class TaskManager extends _events.default {
|
|
|
753
859
|
task.on(_types.TASK_EVENTS.TASK_CLEANUP, (t, options) => {
|
|
754
860
|
this.handleTaskCleanup(t);
|
|
755
861
|
if (options?.removeFromCollection) {
|
|
756
|
-
const
|
|
757
|
-
if (
|
|
862
|
+
const taskIsStillCollected = Object.values(this.taskCollection).some(candidate => candidate === t);
|
|
863
|
+
if (taskIsStillCollected) {
|
|
758
864
|
this.removeTaskFromCollection(t);
|
|
759
865
|
}
|
|
760
866
|
}
|
|
@@ -765,7 +871,11 @@ class TaskManager extends _events.default {
|
|
|
765
871
|
task.cancelAutoWrapupTimer();
|
|
766
872
|
}
|
|
767
873
|
if (task?.data?.interactionId) {
|
|
768
|
-
|
|
874
|
+
Object.entries(this.taskCollection).forEach(([taskId, candidate]) => {
|
|
875
|
+
if (candidate === task) {
|
|
876
|
+
delete this.taskCollection[taskId];
|
|
877
|
+
}
|
|
878
|
+
});
|
|
769
879
|
_loggerProxy.default.info(`Task removed from collection`, {
|
|
770
880
|
module: _constants.TASK_MANAGER_FILE,
|
|
771
881
|
method: _constants2.METHODS.REMOVE_TASK_FROM_COLLECTION,
|
|
@@ -810,7 +920,7 @@ class TaskManager extends _events.default {
|
|
|
810
920
|
isConferenceInProgress: (0, _TaskUtils.getIsConferenceInProgress)(payload),
|
|
811
921
|
isConsulted: false
|
|
812
922
|
};
|
|
813
|
-
task = _TaskFactory.default.createTask(this.contact, this.webCallingService, taskData, this.configFlags, this.wrapupData, this.agentId);
|
|
923
|
+
task = _TaskFactory.default.createTask(this.contact, this.webCallingService, taskData, this.configFlags, this.wrapupData, this.agentId, this.answerCallOnWebexService);
|
|
814
924
|
this.taskCollection[payload.interactionId] = task;
|
|
815
925
|
|
|
816
926
|
// Transition the new task out of IDLE immediately so UI controls are
|
|
@@ -884,6 +994,52 @@ class TaskManager extends _events.default {
|
|
|
884
994
|
...this.taskCollection
|
|
885
995
|
};
|
|
886
996
|
}
|
|
997
|
+
|
|
998
|
+
/**
|
|
999
|
+
* Propagate runtime enableWxBetterTogether changes to config flags and active tasks.
|
|
1000
|
+
*/
|
|
1001
|
+
applyEnableWxBetterTogether(enabled) {
|
|
1002
|
+
if (this.configFlags) {
|
|
1003
|
+
this.configFlags = {
|
|
1004
|
+
...this.configFlags,
|
|
1005
|
+
enableWxBetterTogether: enabled
|
|
1006
|
+
};
|
|
1007
|
+
}
|
|
1008
|
+
Object.values(this.taskCollection).forEach(task => {
|
|
1009
|
+
task.setEnableWxBetterTogether(enabled);
|
|
1010
|
+
if (enabled) {
|
|
1011
|
+
TaskManager.syncWxAppMuteFromCallDetailsForTask(task);
|
|
1012
|
+
}
|
|
1013
|
+
});
|
|
1014
|
+
}
|
|
1015
|
+
|
|
1016
|
+
/**
|
|
1017
|
+
* Propagate wxApp mute state from Mercury sync to active voice tasks.
|
|
1018
|
+
*/
|
|
1019
|
+
applyWxAppMuteStateFromSync(callId, muted) {
|
|
1020
|
+
Object.values(this.taskCollection).forEach(task => {
|
|
1021
|
+
task.applyWxAppMuteStateFromSync(callId, muted);
|
|
1022
|
+
});
|
|
1023
|
+
}
|
|
1024
|
+
|
|
1025
|
+
/**
|
|
1026
|
+
* Re-seeds wxApp mute state from GET telephony/calls/{callId} for one task.
|
|
1027
|
+
*/
|
|
1028
|
+
static syncWxAppMuteFromCallDetailsForTask(task) {
|
|
1029
|
+
const sync = task.syncWxAppMuteFromCallDetails?.bind(task);
|
|
1030
|
+
if (typeof sync === 'function') {
|
|
1031
|
+
sync().catch(() => undefined);
|
|
1032
|
+
}
|
|
1033
|
+
}
|
|
1034
|
+
|
|
1035
|
+
/**
|
|
1036
|
+
* Re-seeds wxApp mute for all engaged voice tasks (reload / runtime enable backfill).
|
|
1037
|
+
*/
|
|
1038
|
+
syncWxAppMuteFromCallDetailsForAllTasks() {
|
|
1039
|
+
Object.values(this.taskCollection).forEach(task => {
|
|
1040
|
+
TaskManager.syncWxAppMuteFromCallDetailsForTask(task);
|
|
1041
|
+
});
|
|
1042
|
+
}
|
|
887
1043
|
static getTaskManager(apiAIAssistant, contact, webCallingService, webSocketManager, rtdWebSocketManager) {
|
|
888
1044
|
if (!TaskManager.taskManager) {
|
|
889
1045
|
TaskManager.taskManager = new TaskManager(apiAIAssistant, contact, webCallingService, webSocketManager, rtdWebSocketManager);
|