@webex/contact-center 3.12.0-next.95 → 3.12.0-next.97

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 (34) hide show
  1. package/dist/services/task/TaskUtils.js +51 -3
  2. package/dist/services/task/TaskUtils.js.map +1 -1
  3. package/dist/services/task/state-machine/TaskStateMachine.js +50 -14
  4. package/dist/services/task/state-machine/TaskStateMachine.js.map +1 -1
  5. package/dist/services/task/state-machine/actions.js +57 -33
  6. package/dist/services/task/state-machine/actions.js.map +1 -1
  7. package/dist/services/task/state-machine/guards.js +42 -0
  8. package/dist/services/task/state-machine/guards.js.map +1 -1
  9. package/dist/services/task/state-machine/types.js.map +1 -1
  10. package/dist/services/task/state-machine/uiControlsComputer.js +78 -28
  11. package/dist/services/task/state-machine/uiControlsComputer.js.map +1 -1
  12. package/dist/services/task/voice/Voice.js +5 -3
  13. package/dist/services/task/voice/Voice.js.map +1 -1
  14. package/dist/types/services/task/TaskUtils.d.ts +2 -0
  15. package/dist/types/services/task/state-machine/TaskStateMachine.d.ts +72 -22
  16. package/dist/types/services/task/state-machine/guards.d.ts +12 -0
  17. package/dist/types/services/task/state-machine/types.d.ts +2 -0
  18. package/dist/webex.js +1 -1
  19. package/package.json +2 -2
  20. package/src/services/task/TaskUtils.ts +100 -2
  21. package/src/services/task/state-machine/TaskStateMachine.ts +101 -12
  22. package/src/services/task/state-machine/actions.ts +88 -35
  23. package/src/services/task/state-machine/ai-docs/task-state-machine-spec.md +73 -11
  24. package/src/services/task/state-machine/guards.ts +39 -0
  25. package/src/services/task/state-machine/types.ts +2 -0
  26. package/src/services/task/state-machine/uiControlsComputer.ts +135 -41
  27. package/src/services/task/voice/Voice.ts +6 -3
  28. package/test/unit/spec/services/task/TaskUtils.ts +29 -0
  29. package/test/unit/spec/services/task/state-machine/TaskStateMachine.ts +826 -0
  30. package/test/unit/spec/services/task/state-machine/guards.ts +158 -0
  31. package/test/unit/spec/services/task/state-machine/uiControlsComputer.ts +648 -5
  32. package/test/unit/spec/services/task/voice/Voice.ts +18 -0
  33. package/umd/contact-center.min.js +2 -2
  34. package/umd/contact-center.min.js.map +1 -1
@@ -64,6 +64,11 @@ function hasConsultMediaInInteraction(interaction, consultMediaResourceId) {
64
64
  if (!consultMediaResourceId) return false;
65
65
  return Boolean(media[consultMediaResourceId]);
66
66
  }
67
+
68
+ /** True when this agent is actively initiating a consult, not a stale context flag alone (CAI-8329). */
69
+ function isSelfActiveConsultInitiator(consultInitiator, selfAgentId, selfParticipant, selfInConsultCall, consultingAgentId) {
70
+ return consultInitiator && (selfParticipant?.consultState === 'consultInitiated' || selfParticipant?.consultState === 'consulting' || selfInConsultCall || Boolean(consultingAgentId) && consultingAgentId === selfAgentId);
71
+ }
67
72
  function computeVoiceInteractionUIControls(state, context, config, fallbackTaskData, currentLeg = 'main') {
68
73
  // Early exit for idle
69
74
  if (state === _constants.TaskState.IDLE) {
@@ -95,7 +100,8 @@ function computeVoiceInteractionUIControls(state, context, config, fallbackTaskD
95
100
  consultDestinationAgentJoined,
96
101
  consultDestinationType,
97
102
  consultCallHeld,
98
- consultFromConference
103
+ consultFromConference,
104
+ hideBlindTransferForEpDnPendingMerge
99
105
  } = context;
100
106
  const {
101
107
  recordingControlsAvailable
@@ -118,7 +124,14 @@ function computeVoiceInteractionUIControls(state, context, config, fallbackTaskD
118
124
  const selfParticipant = selfAgentId ? interaction?.participants?.[selfAgentId] : null;
119
125
  const selfInConsultCall = Boolean(selfAgentId) && Boolean(consultMedia?.participants?.includes(selfAgentId));
120
126
  const hasConsultMedia = hasConsultMediaInInteraction(interaction, taskData?.consultMediaResourceId);
121
- const isConsultEndedForSelf = taskData?.type === 'AgentConsultEnded' || taskData?.type === 'AgentConsultFailed' || selfParticipant?.consultState === 'consultCompleted' && !hasConsultMedia && taskData?.isConsulted === false;
127
+ const isSecondaryConsultRejectedWhileEpDnActive = taskData?.type === 'AgentConsultFailed' && hideBlindTransferForEpDnPendingMerge;
128
+ const isSelfConsultCompleted = selfParticipant?.consultState === 'consultCompleted' && taskData?.isConsulted === false;
129
+ const isConsultEndedForSelf = taskData?.type === 'AgentConsultEnded' || taskData?.type === 'AgentConsultFailed' && !isSecondaryConsultRejectedWhileEpDnActive || isSelfConsultCompleted;
130
+ // EP-DN consult merged to conference before destination joins main (CAI-8329).
131
+ // Context flag is set in actions.ts; treat as main-leg conference UI only here.
132
+ const isEpDnPendingConferenceMergeUi = hideBlindTransferForEpDnPendingMerge && participantCount <= 1 && (isConferencing || conferenceFromBackend || interaction?.state === _constants.INTERACTION_STATE.POST_CALL) && !isConsultEndedForSelf;
133
+ const isEpDnPostCallCustomerLeft = isEpDnPendingConferenceMergeUi && !customerPresent;
134
+ const effectiveConsultInProgress = isEpDnPendingConferenceMergeUi ? false : consultInProgress;
122
135
  const effectiveConsultInitiator = isConsultEndedForSelf ? false : consultInitiator;
123
136
  const effectiveConsultCallHeld = isConsultEndedForSelf ? false : consultCallHeld;
124
137
  const effectiveConsultFromConference = isConsultEndedForSelf ? false : consultFromConference;
@@ -142,20 +155,21 @@ function computeVoiceInteractionUIControls(state, context, config, fallbackTaskD
142
155
  // Consulted agents have limited controls until they're in conference or wrapup
143
156
  // Use inConference (not isConferencing) so controls remain enabled after state downgrade
144
157
  const hasFullControls = !isConsulted || effectiveConsultInitiator || inConference || isWrappingUp;
145
- const consultOwnedBySelf = effectiveConsultInitiator || Boolean(selfAgentId) && taskData?.consultingAgentId === selfAgentId;
158
+ const selfActiveConsultInitiator = isSelfActiveConsultInitiator(effectiveConsultInitiator, selfAgentId, selfParticipant, selfInConsultCall, taskData?.consultingAgentId);
159
+ const consultOwnedBySelf = !isEpDnPendingConferenceMergeUi && selfActiveConsultInitiator;
146
160
  const selfConsultPendingOnConsultMedia = selfParticipant?.consultState === 'consultInitiated' && !taskData?.isConsulted && hasConsultMedia;
147
161
  const ownerParticipant = interaction?.owner ? interaction.participants?.[interaction.owner] : undefined;
148
162
  const otherAgentConsultInProgress = Boolean(interaction?.participants && Object.values(interaction.participants).some(participant => {
149
163
  if (!participant || participant.hasLeft) return false;
150
164
  if (participant.id === selfAgentId) return false;
151
- if (participant.pType !== 'AGENT') return false;
165
+ if (String(participant.pType ?? '').toUpperCase() !== 'AGENT') return false;
152
166
  return participant.consultState === 'consultInitiated' || participant.consultState === 'consultReserved' || participant.consultState === 'consulting' || participant.currentState === 'consulting';
153
167
  }));
154
168
  const isHydratedConferenceConsultPending = inConference && selfConsultPendingOnConsultMedia && !effectiveConsultDestinationAgentJoined;
155
- const hasParallelConsultLeg = !isConsultEndedForSelf && consultOwnedBySelf && !isConsulting && !isConsulted && (consultInProgress || effectiveConsultCallHeld || hasConsultMedia);
169
+ const hasParallelConsultLeg = !isConsultEndedForSelf && consultOwnedBySelf && !isConsulting && !isConsulted && (effectiveConsultInProgress || effectiveConsultCallHeld || hasConsultMedia);
156
170
  const activeLegForConferenceConsult = effectiveConsultCallHeld ? 'main' : 'consult';
157
171
  const isCurrentLegActive = currentLeg === activeLegForConferenceConsult;
158
- const isConferenceConsultTransferContext = inConference && effectiveConsultInitiator && hasConsultMedia && isConsultDestinationReady;
172
+ const isConferenceConsultTransferContext = inConference && selfActiveConsultInitiator && hasConsultMedia && isConsultDestinationReady;
159
173
  const consultLegOnHold = isConsulting && effectiveConsultCallHeld;
160
174
  const callProcessingDetails = interaction?.callProcessingDetails;
161
175
  const conferenceHoldParticipant = callProcessingDetails?.conferenceHoldParticipant === true || callProcessingDetails?.conferenceHoldParticipant === 'true';
@@ -163,15 +177,17 @@ function computeVoiceInteractionUIControls(state, context, config, fallbackTaskD
163
177
  const postConsultCompletedHeldMainLeg = selfParticipant?.consultState === 'consultCompleted' && isHeld && inConference && !isConsulting;
164
178
  const nonOwnerPostConsultCompletedHeldMainLeg = isHeld && inConference && !isConsulting && !consultInitiator && Boolean(selfAgentId) && Boolean(interaction?.owner) && selfAgentId !== interaction?.owner && ownerParticipant?.consultState === 'consultCompleted';
165
179
  const isConsultPendingBeforeJoin = selfParticipant?.consultState === 'consultInitiated' && !consultDestinationAgentJoined;
166
- const hideExitConferenceWhileConsultPending = currentLeg === 'main' && inConference && isConsultPendingBeforeJoin && (consultFromConference || consultInitiator || taskData?.type === 'AgentConsultCreated' || consultInProgress || isConsulting);
167
- const hideExitConferenceDuringActiveConsultFromConference = inConference && consultInitiator && consultDestinationAgentJoined && (isConsulting || taskData?.type === 'AgentConsulting' || selfParticipant?.consultState === 'consulting');
168
- const hideExitConferenceOnMainLegForEpDnConsultFromConference = currentLeg === 'main' && inConference && consultFromConference && consultInitiator && (isConsulting || consultInProgress || taskData?.type === 'AgentConsultCreated' || taskData?.type === 'AgentConsulting' || selfParticipant?.consultState === 'consultInitiated' || selfParticipant?.consultState === 'consulting');
180
+ const hideExitConferenceWhileConsultPending = currentLeg === 'main' && inConference && isConsultPendingBeforeJoin && (consultFromConference || consultInitiator || taskData?.type === 'AgentConsultCreated' || effectiveConsultInProgress || isConsulting);
181
+ const hideExitConferenceDuringActiveConsultFromConference = inConference && selfActiveConsultInitiator && consultDestinationAgentJoined && (isConsulting || taskData?.type === 'AgentConsulting' || selfParticipant?.consultState === 'consulting');
182
+ const hideExitConferenceOnMainLegForEpDnConsultFromConference = currentLeg === 'main' && inConference && consultFromConference && selfActiveConsultInitiator && (isConsulting || effectiveConsultInProgress || taskData?.type === 'AgentConsultCreated' || taskData?.type === 'AgentConsulting' || selfParticipant?.consultState === 'consultInitiated' || selfParticipant?.consultState === 'consulting');
169
183
  const forceHeldPostConsultControls = !hideExitConferenceWhileConsultPending && (postDeclineHeldMainLeg || postConsultCompletedHeldMainLeg);
170
184
  const selfOnConsultLeg = selfParticipant?.consultState === 'consulting' || selfParticipant?.currentState === 'consulting';
171
- const showMainLegConferenceControlsDuringConsult = currentLeg === 'main' && inConference && consultInProgress && !selfOnConsultLeg;
185
+ const showMainLegConferenceControlsDuringConsult = currentLeg === 'main' && inConference && effectiveConsultInProgress && !selfOnConsultLeg;
172
186
  const allowHeldMainLegControlsForNonInitiator = showMainLegConferenceControlsDuringConsult && !isHydratedConferenceConsultPending;
173
187
  const isConsultRequestedPhase = isConsultPendingBeforeJoin && !isConsulted && (consultInitiator || Boolean(selfAgentId) && selfParticipant?.consultState === 'consultInitiated' && taskData?.agentId === selfAgentId);
174
188
  const isConsultUnansweredFailure = currentLeg === 'main' && !inConference && !taskData?.isConsulted && !effectiveHasConsultMedia && isHeld && selfParticipant?.consultState === 'consultCompleted' && (taskData?.type === 'AgentConsultFailed' || taskData?.type === 'AgentConsultEnded' || isConsultEndedForSelf);
189
+ // EP-DN consult merged to conference before a second agent joins main: hide blind transfer (CAI-8329).
190
+ const shouldHideBlindTransferForEpDnPendingConferenceMerge = isEpDnPendingConferenceMergeUi;
175
191
  if (isConsultUnansweredFailure) {
176
192
  const recordingControl = recordingControlsAvailable && config.isRecordingEnabled && !inConference ? VISIBLE_ENABLED : DISABLED;
177
193
  return {
@@ -183,11 +199,11 @@ function computeVoiceInteractionUIControls(state, context, config, fallbackTaskD
183
199
  end: VISIBLE_DISABLED
184
200
  };
185
201
  }
186
- if (isConsultRequestedPhase) {
202
+ if (isConsultRequestedPhase && !isEpDnPendingConferenceMergeUi) {
187
203
  if (currentLeg === 'main') {
188
204
  return {
189
205
  ...getDefaultInteractionUIControls(),
190
- transfer: VISIBLE_DISABLED,
206
+ transfer: shouldHideBlindTransferForEpDnPendingConferenceMerge ? DISABLED : VISIBLE_DISABLED,
191
207
  conference: VISIBLE_DISABLED,
192
208
  end: VISIBLE_DISABLED
193
209
  };
@@ -219,6 +235,7 @@ function computeVoiceInteractionUIControls(state, context, config, fallbackTaskD
219
235
  // Hold: visible in connected/held/conference, disabled in conference/consulting
220
236
  hold: (() => {
221
237
  if (!hasFullControls) return DISABLED;
238
+ if (isEpDnPostCallCustomerLeft) return VISIBLE_DISABLED;
222
239
  if (forceHeldPostConsultControls) return VISIBLE_ENABLED;
223
240
  if (consultOwnedBySelf && (isConsulting || hasParallelConsultLeg || effectiveConsultCallHeld)) {
224
241
  return DISABLED;
@@ -236,6 +253,7 @@ function computeVoiceInteractionUIControls(state, context, config, fallbackTaskD
236
253
  mute: (() => {
237
254
  if (!isWebrtc) return DISABLED;
238
255
  if (isWrappingUp) return DISABLED;
256
+ if (isEpDnPostCallCustomerLeft && inConference) return VISIBLE_DISABLED;
239
257
  if (currentLeg === 'consult' && !selfInConsultCall) return DISABLED;
240
258
  // The consulted agent has no separate consult leg; their main leg is the active call, so
241
259
  // mute stays available while they consult (the heuristic below targets the initiator's
@@ -267,7 +285,7 @@ function computeVoiceInteractionUIControls(state, context, config, fallbackTaskD
267
285
  if (inConference) {
268
286
  if (isConsulted) return DISABLED;
269
287
  if (forceHeldPostConsultControls) return VISIBLE_DISABLED;
270
- if (consultInProgress) return VISIBLE_DISABLED;
288
+ if (effectiveConsultInProgress) return VISIBLE_DISABLED;
271
289
  return isWrappingUp ? VISIBLE_DISABLED : VISIBLE_ENABLED;
272
290
  }
273
291
  if (!hasFullControls) return DISABLED;
@@ -283,6 +301,7 @@ function computeVoiceInteractionUIControls(state, context, config, fallbackTaskD
283
301
  if (inConference && isConsulting && consultInitiator) return DISABLED;
284
302
  if (hasParallelConsultLeg) {
285
303
  if (!customerPresent) return DISABLED;
304
+ if (shouldHideBlindTransferForEpDnPendingConferenceMerge) return DISABLED;
286
305
  if (state === _constants.TaskState.CONNECTED) return VISIBLE_ENABLED;
287
306
  if (state === _constants.TaskState.HELD) return VISIBLE_DISABLED;
288
307
  }
@@ -296,7 +315,15 @@ function computeVoiceInteractionUIControls(state, context, config, fallbackTaskD
296
315
  if (inConference) {
297
316
  // Real conference (multiple agents): transfer is hidden
298
317
  // Pending conference (only self agent): transfer remains available
299
- return participantCount > 1 ? DISABLED : VISIBLE_ENABLED;
318
+ // EP-DN consult merged before destination joins: hide blind transfer on main
319
+ // (Agent 2 may still be ringing on the consult leg — blind transfer causes stuck ringing)
320
+ if (shouldHideBlindTransferForEpDnPendingConferenceMerge) {
321
+ return DISABLED;
322
+ }
323
+ if (participantCount > 1) {
324
+ return DISABLED;
325
+ }
326
+ return customerPresent ? VISIBLE_ENABLED : DISABLED;
300
327
  }
301
328
  if (state === _constants.TaskState.CONNECTED || state === _constants.TaskState.HELD) return VISIBLE_ENABLED;
302
329
  return DISABLED;
@@ -322,7 +349,7 @@ function computeVoiceInteractionUIControls(state, context, config, fallbackTaskD
322
349
  // Pending conference (only self agent): consult disabled
323
350
  if (participantCount <= 1) return VISIBLE_DISABLED;
324
351
  // Real conference: consult enabled if conditions met
325
- const canFromConference = !maxParticipants && customerPresent && !consultInProgress && !otherAgentConsultInProgress && !isConsulting;
352
+ const canFromConference = !maxParticipants && customerPresent && !effectiveConsultInProgress && !otherAgentConsultInProgress && !isConsulting;
326
353
  return {
327
354
  isVisible: true,
328
355
  isEnabled: canFromConference
@@ -330,7 +357,7 @@ function computeVoiceInteractionUIControls(state, context, config, fallbackTaskD
330
357
  }
331
358
 
332
359
  // Enabled conditions for connected/held
333
- const canFromConnected = !maxParticipants && customerPresent && !consultInProgress && !isConsulted;
360
+ const canFromConnected = !maxParticipants && customerPresent && !effectiveConsultInProgress && !isConsulted;
334
361
  return {
335
362
  isVisible: true,
336
363
  isEnabled: canFromConnected
@@ -350,14 +377,15 @@ function computeVoiceInteractionUIControls(state, context, config, fallbackTaskD
350
377
  isEnabled: consultInitiator || config.isEndConsultEnabled
351
378
  };
352
379
  })(),
353
- // Recording: connected/held, hidden in real conference, visible in pending conference
380
+ // Recording: connected/held/conference when backend exposes recording controls
354
381
  recording: (() => {
355
382
  if (!recordingControlsAvailable || !config.isRecordingEnabled) return DISABLED;
356
383
  if (!hasFullControls || isConsulting) return DISABLED;
357
384
  if (inConference) {
358
- // Real conference (multiple agents): recording hidden
359
- // Pending conference (only self agent): recording available
360
- return participantCount > 1 ? DISABLED : VISIBLE_ENABLED;
385
+ // Recording stays available in conference when backend exposes controls
386
+ // (including after EP-DN pending merge transitions to real conference — CAI-8329)
387
+ if (isEpDnPostCallCustomerLeft) return VISIBLE_DISABLED;
388
+ return VISIBLE_ENABLED;
361
389
  }
362
390
  if (hasParallelConsultLeg && !customerPresent) return DISABLED;
363
391
  if (state === _constants.TaskState.CONNECTED || state === _constants.TaskState.HELD) {
@@ -395,21 +423,22 @@ function computeVoiceInteractionUIControls(state, context, config, fallbackTaskD
395
423
  if (forceHeldPostConsultControls) return VISIBLE_DISABLED;
396
424
  if (isConsulted && !isConferencing) return DISABLED;
397
425
  if (!inConference) return DISABLED;
426
+ if (isEpDnPendingConferenceMergeUi) return VISIBLE_ENABLED;
398
427
  if (participantCount <= 1) return DISABLED;
399
- if (consultInProgress) return VISIBLE_DISABLED;
428
+ if (effectiveConsultInProgress) return VISIBLE_DISABLED;
400
429
  const consultingFromConference = consultInitiator && isConsulting && conferenceFromBackend;
401
430
  return consultingFromConference ? VISIBLE_DISABLED : VISIBLE_ENABLED;
402
431
  })(),
403
432
  // TransferConference: in conference with active consult, owner consulting from conference
404
433
  transferConference: (() => {
405
434
  if (isConferenceConsultTransferContext && !isCurrentLegActive) return VISIBLE_DISABLED;
406
- const consultLegTransferAvailable = currentLeg === 'consult' && inConference && consultInitiator && hasConsultMedia;
435
+ const consultLegTransferAvailable = currentLeg === 'consult' && inConference && selfActiveConsultInitiator && hasConsultMedia;
407
436
  const selfConsultingOnParticipantState = selfParticipant?.consultState === 'consulting';
408
- const conferenceTransferAvailable = consultLegTransferAvailable || inConference && consultInitiator && hasConsultMedia && (isConsulting || consultInProgress || selfConsultingOnParticipantState);
437
+ const conferenceTransferAvailable = consultLegTransferAvailable || inConference && selfActiveConsultInitiator && hasConsultMedia && (isConsulting || effectiveConsultInProgress || selfConsultingOnParticipantState);
409
438
  if (consultLegOnHold) return DISABLED;
410
439
  if (hasParallelConsultLeg && !conferenceTransferAvailable) return DISABLED;
411
440
  if (!conferenceTransferAvailable && (!inConference || !isConsulting)) return DISABLED;
412
- if (!consultInitiator || isConsulted) return DISABLED;
441
+ if (!selfActiveConsultInitiator || isConsulted) return DISABLED;
413
442
  return isConsultDestinationReady ? VISIBLE_ENABLED : VISIBLE_DISABLED;
414
443
  })(),
415
444
  // MergeToConference: mirrors conference control, enabled on both legs
@@ -473,15 +502,32 @@ function getVoiceLegState(currentState, context, config, fallbackTaskData) {
473
502
  const interaction = taskData?.interaction;
474
503
  const mainCallId = interaction?.mainInteractionId || taskData?.interactionId;
475
504
  const selfAgentId = config.agentId ?? taskData?.agentId;
505
+ if (context.hideBlindTransferForEpDnPendingMerge && taskData) {
506
+ const conferenceFromBackend = (0, _TaskUtils.getIsConferenceInProgress)(taskData);
507
+ const participantCount = interaction && mainCallId ? (0, _TaskUtils.getConferenceParticipantsCount)(interaction, mainCallId) : 0;
508
+ if (participantCount <= 1 && (currentState === _constants.TaskState.CONFERENCING || conferenceFromBackend)) {
509
+ return {
510
+ hasConsultLeg: false,
511
+ activeLeg: 'main',
512
+ mainState: _constants.TaskState.CONFERENCING,
513
+ consultState: _constants.TaskState.CONSULTING
514
+ };
515
+ }
516
+ }
476
517
  const selfParticipant = selfAgentId ? interaction?.participants?.[selfAgentId] : null;
477
518
  const hasConsultMedia = hasConsultMediaInInteraction(interaction, taskData?.consultMediaResourceId);
478
- const isConsultEndedForSelf = taskData?.type === 'AgentConsultEnded' || taskData?.type === 'AgentConsultFailed' || selfParticipant?.consultState === 'consultCompleted' && !hasConsultMedia && taskData?.isConsulted === false;
519
+ const isSecondaryConsultRejectedWhileEpDnActive = taskData?.type === 'AgentConsultFailed' && context.hideBlindTransferForEpDnPendingMerge;
520
+ const isSelfConsultCompleted = selfParticipant?.consultState === 'consultCompleted' && taskData?.isConsulted === false;
521
+ const isConsultEndedForSelf = taskData?.type === 'AgentConsultEnded' || taskData?.type === 'AgentConsultFailed' && !isSecondaryConsultRejectedWhileEpDnActive || isSelfConsultCompleted;
479
522
  const consultInProgress = (0, _TaskUtils.getIsConsultInProgressForConferenceControls)(interaction, mainCallId, selfAgentId);
480
523
  const isConsultingState = currentState === _constants.TaskState.CONSULTING || currentState === _constants.TaskState.CONSULT_INITIATING || currentState === _constants.TaskState.CONF_INITIATING;
481
- const consultOwnedBySelf = context.consultInitiator || Boolean(selfAgentId) && taskData?.consultingAgentId === selfAgentId;
524
+ const consultMedia = Object.values(interaction?.media ?? {}).find(media => media?.mediaResourceId === taskData?.consultMediaResourceId || media?.mType === 'consult');
525
+ const selfInConsultCall = Boolean(selfAgentId) && Boolean(consultMedia?.participants?.includes(selfAgentId));
526
+ const selfActiveConsultInitiator = isSelfActiveConsultInitiator(context.consultInitiator, selfAgentId, selfParticipant, selfInConsultCall, taskData?.consultingAgentId);
527
+ const consultOwnedBySelf = !context.hideBlindTransferForEpDnPendingMerge && selfActiveConsultInitiator;
482
528
  const selfConsultPendingOnConsultMedia = selfParticipant?.consultState === 'consultInitiated' && !taskData?.isConsulted && hasConsultMedia;
483
529
  const selfConsultingOnConsultMedia = selfParticipant?.consultState === 'consulting' && hasConsultMedia;
484
- const isConsultUnansweredFailure = !taskData?.isConsulted && !hasConsultMedia && selfParticipant?.consultState === 'consultCompleted' && Boolean(mainCallId && taskData?.interaction?.media?.[mainCallId]?.isHold === true) && taskData?.interaction?.state !== 'conference' && !(0, _TaskUtils.getIsConferenceInProgress)(taskData);
530
+ const isConsultUnansweredFailure = isSelfConsultCompleted && Boolean(mainCallId && taskData?.interaction?.media?.[mainCallId]?.isHold === true) && taskData?.interaction?.state !== 'conference' && !(0, _TaskUtils.getIsConferenceInProgress)(taskData);
485
531
  const hasConsultLeg = Boolean(!isConsultEndedForSelf && !interaction?.isTerminated && !isConsultUnansweredFailure && (consultOwnedBySelf || selfConsultingOnConsultMedia || selfConsultPendingOnConsultMedia) && (consultInProgress || isConsultingState || context.consultCallHeld || hasConsultMedia));
486
532
  if (!hasConsultLeg) {
487
533
  let mainState = currentState;
@@ -507,7 +553,11 @@ function getVoiceLegState(currentState, context, config, fallbackTaskData) {
507
553
  if (currentState === _constants.TaskState.CONFERENCING) {
508
554
  mainState = _constants.TaskState.CONFERENCING;
509
555
  } else if (context.consultCallHeld) {
510
- mainState = _constants.TaskState.CONNECTED;
556
+ const mainMediaId = taskData?.interaction?.mainInteractionId || taskData?.interactionId;
557
+ const isMainHeld = Boolean(mainMediaId && taskData?.interaction?.media?.[mainMediaId]?.isHold === true);
558
+ mainState = isMainHeld || taskData?.interaction?.state === 'hold' ? _constants.TaskState.HELD : _constants.TaskState.CONNECTED;
559
+ } else if (currentState === _constants.TaskState.CONNECTED || currentState === _constants.TaskState.HELD) {
560
+ mainState = currentState;
511
561
  }
512
562
  return {
513
563
  hasConsultLeg: true,
@@ -1 +1 @@
1
- {"version":3,"names":["_types","require","_constants","_TaskUtils","DISABLED","isVisible","isEnabled","VISIBLE_ENABLED","VISIBLE_DISABLED","getDefaultInteractionUIControls","accept","decline","hold","mute","end","transfer","consult","consultTransfer","endConsult","recording","conference","wrapup","exitConference","transferConference","mergeToConference","switch","createTaskUIControls","main","activeLeg","getDefaultUIControls","hasConsultMediaInInteraction","interaction","consultMediaResourceId","media","hasConsultLeg","Object","values","some","entry","mType","Boolean","computeVoiceInteractionUIControls","state","context","config","fallbackTaskData","currentLeg","TaskState","IDLE","taskData","mainCallId","mainInteractionId","interactionId","isWebrtc","voiceVariant","VOICE_VARIANT","WEBRTC","isOutdial","outboundType","serverHold","getServerHoldStateForControls","customerInCall","getIsCustomerInCall","customerPresent","participants","p","pType","hasLeft","participantCount","getConferenceParticipantsCount","maxParticipants","MAX_PARTICIPANTS_IN_MULTIPARTY_CONFERENCE","selfAgentId","agentId","consultInProgress","getIsConsultInProgressForConferenceControls","conferenceFromBackend","getIsConferenceInProgress","consultInitiator","consultDestinationAgentJoined","consultDestinationType","consultCallHeld","consultFromConference","recordingControlsAvailable","isEpDnConsult","stateImpliesHeld","HELD","RESUME_INITIATING","stateImpliesConnected","CONNECTED","HOLD_INITIATING","isHeld","isConnected","isConsulting","CONSULTING","CONSULT_INITIATING","CONF_INITIATING","isConferencing","CONFERENCING","isWrappingUp","WRAPPING_UP","selfInMainCall","includes","consultMedia","find","mediaResourceId","selfParticipant","selfInConsultCall","hasConsultMedia","isConsultEndedForSelf","type","consultState","isConsulted","effectiveConsultInitiator","effectiveConsultCallHeld","effectiveConsultFromConference","effectiveConsultDestinationAgentJoined","effectiveHasConsultMedia","isConsultDestinationReady","conferenceActive","inConference","isSoleAgentOnCall","getIsConsultedAgentForControls","isActive","hasFullControls","consultOwnedBySelf","consultingAgentId","selfConsultPendingOnConsultMedia","ownerParticipant","owner","undefined","otherAgentConsultInProgress","participant","id","currentState","isHydratedConferenceConsultPending","hasParallelConsultLeg","activeLegForConferenceConsult","isCurrentLegActive","isConferenceConsultTransferContext","consultLegOnHold","callProcessingDetails","conferenceHoldParticipant","postDeclineHeldMainLeg","postConsultCompletedHeldMainLeg","nonOwnerPostConsultCompletedHeldMainLeg","isConsultPendingBeforeJoin","hideExitConferenceWhileConsultPending","hideExitConferenceDuringActiveConsultFromConference","hideExitConferenceOnMainLegForEpDnConsultFromConference","forceHeldPostConsultControls","selfOnConsultLeg","showMainLegConferenceControlsDuringConsult","allowHeldMainLegControlsForNonInitiator","isConsultRequestedPhase","isConsultUnansweredFailure","recordingControl","isRecordingEnabled","OFFERED","isTerminated","canHold","isConsultedActiveMainLeg","isEndTaskEnabled","isConnectedOrHeld","canRetryConsult","canFromConference","canFromConnected","isEndConsultEnabled","consultingFromConference","consultLegTransferAvailable","selfConsultingOnParticipantState","conferenceTransferAvailable","computeDigitalInteractionUIControls","getVoiceLegState","mainState","isConsultingState","selfConsultingOnConsultMedia","isHold","resolvedMainId","isMainHeld","computeUIControls","TERMINATED","COMPLETED","uiControlConfig","channelType","TASK_CHANNEL_TYPE","VOICE","mainControls","consultControls","DIGITAL","haveInteractionUIControlsChanged","previous","next","keys","key","prev","curr","haveUIControlsChanged"],"sources":["uiControlsComputer.ts"],"sourcesContent":["/**\n * UI Controls Computer - Centralized logic for computing UI control states\n */\n\nimport {\n InteractionUIControls,\n TASK_CHANNEL_TYPE,\n TaskData,\n TaskUILeg,\n TaskUIControls,\n VOICE_VARIANT,\n} from '../types';\nimport {TaskContext, UIControlConfig} from './types';\nimport {TaskState, MAX_PARTICIPANTS_IN_MULTIPARTY_CONFERENCE} from './constants';\nimport {\n getIsCustomerInCall,\n getConferenceParticipantsCount,\n getIsConferenceInProgress,\n getIsConsultInProgressForConferenceControls,\n getIsConsultedAgentForControls,\n getServerHoldStateForControls,\n} from '../TaskUtils';\n\nconst DISABLED = {isVisible: false, isEnabled: false} as const;\nconst VISIBLE_ENABLED = {isVisible: true, isEnabled: true} as const;\nconst VISIBLE_DISABLED = {isVisible: true, isEnabled: false} as const;\n\nfunction getDefaultInteractionUIControls(): InteractionUIControls {\n return {\n accept: DISABLED,\n decline: DISABLED,\n hold: DISABLED,\n mute: DISABLED,\n end: DISABLED,\n transfer: DISABLED,\n consult: DISABLED,\n consultTransfer: DISABLED,\n endConsult: DISABLED,\n recording: DISABLED,\n conference: DISABLED,\n wrapup: DISABLED,\n exitConference: DISABLED,\n transferConference: DISABLED,\n mergeToConference: DISABLED,\n switch: DISABLED,\n };\n}\n\nfunction createTaskUIControls(\n main: InteractionUIControls,\n consult: InteractionUIControls,\n activeLeg: TaskUILeg\n): TaskUIControls {\n return {\n main,\n consult,\n activeLeg,\n };\n}\n\nexport function getDefaultUIControls(): TaskUIControls {\n return createTaskUIControls(\n getDefaultInteractionUIControls(),\n getDefaultInteractionUIControls(),\n 'main'\n );\n}\n\n/** Consult media must exist on the interaction payload, not only as a stale resource id. */\nfunction hasConsultMediaInInteraction(\n interaction: TaskData['interaction'] | undefined,\n consultMediaResourceId?: string\n): boolean {\n const media = interaction?.media ?? {};\n const hasConsultLeg = Object.values(media).some((entry: any) => entry?.mType === 'consult');\n\n if (hasConsultLeg) return true;\n if (!consultMediaResourceId) return false;\n\n return Boolean(media[consultMediaResourceId]);\n}\n\nfunction computeVoiceInteractionUIControls(\n state: TaskState,\n context: TaskContext,\n config: UIControlConfig,\n fallbackTaskData?: TaskData,\n currentLeg: TaskUILeg = 'main'\n): InteractionUIControls {\n // Early exit for idle\n if (state === TaskState.IDLE) {\n return getDefaultInteractionUIControls();\n }\n\n // Prefer live task.data (fallback) over stale state-machine snapshot during multi-login sync.\n const taskData = fallbackTaskData ?? context.taskData ?? null;\n const interaction = taskData?.interaction;\n const mainCallId = interaction?.mainInteractionId || taskData?.interactionId;\n const isWebrtc = config.voiceVariant === VOICE_VARIANT.WEBRTC;\n const isOutdial = interaction?.outboundType === 'OUTDIAL';\n const serverHold = getServerHoldStateForControls(context, mainCallId, fallbackTaskData);\n\n // Backend-derived checks\n const customerInCall =\n interaction && mainCallId ? getIsCustomerInCall(interaction, mainCallId) : false;\n // EP-DN/secondary legs can have incomplete media participant lists; fall back to participants map.\n const customerPresent =\n customerInCall ||\n Boolean(\n interaction &&\n interaction.participants &&\n Object.values(interaction.participants).some(\n (p: any) => p?.pType === 'Customer' && !p?.hasLeft\n )\n );\n const participantCount =\n interaction && mainCallId ? getConferenceParticipantsCount(interaction, mainCallId) : 0;\n const maxParticipants = participantCount >= MAX_PARTICIPANTS_IN_MULTIPARTY_CONFERENCE;\n const selfAgentId = config.agentId ?? taskData?.agentId;\n const consultInProgress = getIsConsultInProgressForConferenceControls(\n interaction,\n mainCallId,\n selfAgentId\n );\n const conferenceFromBackend = taskData ? getIsConferenceInProgress(taskData) : false;\n // Note: ownership is used by some controls; keep computations local to those controls\n\n // Context flags (set by state machine actions)\n const {\n consultInitiator,\n consultDestinationAgentJoined,\n consultDestinationType,\n consultCallHeld,\n consultFromConference,\n } = context;\n const {recordingControlsAvailable} = context;\n\n // EP_DN consults are \"ready\" as soon as the consult is created (EP accepts routing immediately).\n // Backend sends destinationType as 'EP-DN'; SDK method uses 'entryPoint' — check both.\n const isEpDnConsult =\n consultDestinationType === 'entryPoint' || consultDestinationType === ('EP-DN' as any);\n\n const stateImpliesHeld = state === TaskState.HELD || state === TaskState.RESUME_INITIATING;\n const stateImpliesConnected =\n state === TaskState.CONNECTED || state === TaskState.HOLD_INITIATING;\n const isHeld = stateImpliesHeld || serverHold === true;\n const isConnected = stateImpliesConnected || (!stateImpliesHeld && serverHold === false);\n\n // State categories for cleaner logic\n const isConsulting =\n state === TaskState.CONSULTING ||\n state === TaskState.CONSULT_INITIATING ||\n state === TaskState.CONF_INITIATING;\n const isConferencing = state === TaskState.CONFERENCING;\n const isWrappingUp = state === TaskState.WRAPPING_UP;\n const selfInMainCall =\n Boolean(selfAgentId) &&\n Boolean(mainCallId) &&\n Boolean(interaction?.media?.[mainCallId]?.participants?.includes(selfAgentId as string));\n const consultMedia = Object.values(interaction?.media ?? {}).find(\n (media: any) =>\n media?.mediaResourceId === taskData?.consultMediaResourceId || media?.mType === 'consult'\n ) as {participants?: string[]} | undefined;\n const selfParticipant = selfAgentId ? interaction?.participants?.[selfAgentId] : null;\n const selfInConsultCall =\n Boolean(selfAgentId) && Boolean(consultMedia?.participants?.includes(selfAgentId as string));\n const hasConsultMedia = hasConsultMediaInInteraction(\n interaction,\n taskData?.consultMediaResourceId\n );\n const isConsultEndedForSelf =\n taskData?.type === 'AgentConsultEnded' ||\n taskData?.type === 'AgentConsultFailed' ||\n (selfParticipant?.consultState === 'consultCompleted' &&\n !hasConsultMedia &&\n taskData?.isConsulted === false);\n const effectiveConsultInitiator = isConsultEndedForSelf ? false : consultInitiator;\n const effectiveConsultCallHeld = isConsultEndedForSelf ? false : consultCallHeld;\n const effectiveConsultFromConference = isConsultEndedForSelf ? false : consultFromConference;\n const effectiveConsultDestinationAgentJoined = isConsultEndedForSelf\n ? false\n : consultDestinationAgentJoined;\n // After a consult ends for self, the backend stops sending consult media but the merged\n // task.data can still carry the stale consult-media entry (reconcileData never deletes keys).\n // Treat it as gone so post-consult main-leg controls (consult retry) are not blocked.\n const effectiveHasConsultMedia = isConsultEndedForSelf ? false : hasConsultMedia;\n const isConsultDestinationReady = effectiveConsultDestinationAgentJoined || isEpDnConsult;\n const conferenceActive =\n isConferencing || conferenceFromBackend || effectiveConsultFromConference;\n // Treat consult initiator as \"in conference\" even if mainCall participant list lags while consulting.\n const inConference =\n conferenceActive && (isConferencing || selfInMainCall || effectiveConsultInitiator);\n\n // Check if this is a consulted agent (must be after isConsulting is computed).\n const isSoleAgentOnCall =\n participantCount <= 1 && selfInMainCall && !isConsulting && !inConference;\n const isConsulted =\n inConference || isSoleAgentOnCall\n ? false\n : getIsConsultedAgentForControls(taskData, context, isConsulting) ||\n (!effectiveConsultInitiator &&\n (selfParticipant?.isConsulted === true ||\n selfParticipant?.consultState === 'consulting'));\n\n // Active call = can perform call operations\n const isActive =\n state === TaskState.CONNECTED ||\n state === TaskState.HELD ||\n state === TaskState.HOLD_INITIATING ||\n state === TaskState.RESUME_INITIATING ||\n isConsulting ||\n isConferencing;\n\n // Consulted agents have limited controls until they're in conference or wrapup\n // Use inConference (not isConferencing) so controls remain enabled after state downgrade\n const hasFullControls = !isConsulted || effectiveConsultInitiator || inConference || isWrappingUp;\n const consultOwnedBySelf =\n effectiveConsultInitiator ||\n (Boolean(selfAgentId) && taskData?.consultingAgentId === selfAgentId);\n const selfConsultPendingOnConsultMedia =\n selfParticipant?.consultState === 'consultInitiated' &&\n !taskData?.isConsulted &&\n hasConsultMedia;\n const ownerParticipant = interaction?.owner\n ? interaction.participants?.[interaction.owner]\n : undefined;\n const otherAgentConsultInProgress = Boolean(\n interaction?.participants &&\n Object.values(interaction.participants).some((participant: any) => {\n if (!participant || participant.hasLeft) return false;\n if (participant.id === selfAgentId) return false;\n if (participant.pType !== 'AGENT') return false;\n\n return (\n participant.consultState === 'consultInitiated' ||\n participant.consultState === 'consultReserved' ||\n participant.consultState === 'consulting' ||\n participant.currentState === 'consulting'\n );\n })\n );\n const isHydratedConferenceConsultPending =\n inConference && selfConsultPendingOnConsultMedia && !effectiveConsultDestinationAgentJoined;\n const hasParallelConsultLeg =\n !isConsultEndedForSelf &&\n consultOwnedBySelf &&\n !isConsulting &&\n !isConsulted &&\n (consultInProgress || effectiveConsultCallHeld || hasConsultMedia);\n const activeLegForConferenceConsult = effectiveConsultCallHeld ? 'main' : 'consult';\n const isCurrentLegActive = currentLeg === activeLegForConferenceConsult;\n const isConferenceConsultTransferContext =\n inConference && effectiveConsultInitiator && hasConsultMedia && isConsultDestinationReady;\n const consultLegOnHold = isConsulting && effectiveConsultCallHeld;\n const callProcessingDetails = interaction?.callProcessingDetails as\n | {conferenceHoldParticipant?: boolean | string}\n | undefined;\n const conferenceHoldParticipant =\n callProcessingDetails?.conferenceHoldParticipant === true ||\n callProcessingDetails?.conferenceHoldParticipant === 'true';\n const postDeclineHeldMainLeg =\n consultInitiator &&\n !consultDestinationAgentJoined &&\n isHeld &&\n inConference &&\n conferenceHoldParticipant;\n const postConsultCompletedHeldMainLeg =\n selfParticipant?.consultState === 'consultCompleted' && isHeld && inConference && !isConsulting;\n const nonOwnerPostConsultCompletedHeldMainLeg =\n isHeld &&\n inConference &&\n !isConsulting &&\n !consultInitiator &&\n Boolean(selfAgentId) &&\n Boolean(interaction?.owner) &&\n selfAgentId !== interaction?.owner &&\n ownerParticipant?.consultState === 'consultCompleted';\n const isConsultPendingBeforeJoin =\n selfParticipant?.consultState === 'consultInitiated' && !consultDestinationAgentJoined;\n const hideExitConferenceWhileConsultPending =\n currentLeg === 'main' &&\n inConference &&\n isConsultPendingBeforeJoin &&\n (consultFromConference ||\n consultInitiator ||\n taskData?.type === 'AgentConsultCreated' ||\n consultInProgress ||\n isConsulting);\n const hideExitConferenceDuringActiveConsultFromConference =\n inConference &&\n consultInitiator &&\n consultDestinationAgentJoined &&\n (isConsulting ||\n taskData?.type === 'AgentConsulting' ||\n selfParticipant?.consultState === 'consulting');\n const hideExitConferenceOnMainLegForEpDnConsultFromConference =\n currentLeg === 'main' &&\n inConference &&\n consultFromConference &&\n consultInitiator &&\n (isConsulting ||\n consultInProgress ||\n taskData?.type === 'AgentConsultCreated' ||\n taskData?.type === 'AgentConsulting' ||\n selfParticipant?.consultState === 'consultInitiated' ||\n selfParticipant?.consultState === 'consulting');\n const forceHeldPostConsultControls =\n !hideExitConferenceWhileConsultPending &&\n (postDeclineHeldMainLeg || postConsultCompletedHeldMainLeg);\n const selfOnConsultLeg =\n selfParticipant?.consultState === 'consulting' ||\n selfParticipant?.currentState === 'consulting';\n const showMainLegConferenceControlsDuringConsult =\n currentLeg === 'main' && inConference && consultInProgress && !selfOnConsultLeg;\n const allowHeldMainLegControlsForNonInitiator =\n showMainLegConferenceControlsDuringConsult && !isHydratedConferenceConsultPending;\n const isConsultRequestedPhase =\n isConsultPendingBeforeJoin &&\n !isConsulted &&\n (consultInitiator ||\n (Boolean(selfAgentId) &&\n selfParticipant?.consultState === 'consultInitiated' &&\n taskData?.agentId === selfAgentId));\n const isConsultUnansweredFailure =\n currentLeg === 'main' &&\n !inConference &&\n !taskData?.isConsulted &&\n !effectiveHasConsultMedia &&\n isHeld &&\n selfParticipant?.consultState === 'consultCompleted' &&\n (taskData?.type === 'AgentConsultFailed' ||\n taskData?.type === 'AgentConsultEnded' ||\n isConsultEndedForSelf);\n\n if (isConsultUnansweredFailure) {\n const recordingControl =\n recordingControlsAvailable && config.isRecordingEnabled && !inConference\n ? VISIBLE_ENABLED\n : DISABLED;\n\n return {\n ...getDefaultInteractionUIControls(),\n hold: VISIBLE_ENABLED,\n transfer: VISIBLE_ENABLED,\n consult: VISIBLE_ENABLED,\n recording: recordingControl,\n end: VISIBLE_DISABLED,\n };\n }\n\n if (isConsultRequestedPhase) {\n if (currentLeg === 'main') {\n return {\n ...getDefaultInteractionUIControls(),\n transfer: VISIBLE_DISABLED,\n conference: VISIBLE_DISABLED,\n end: VISIBLE_DISABLED,\n };\n }\n\n if (currentLeg === 'consult') {\n return {\n ...getDefaultInteractionUIControls(),\n endConsult: VISIBLE_ENABLED,\n switch: VISIBLE_DISABLED,\n transfer: VISIBLE_DISABLED,\n transferConference: inConference ? VISIBLE_DISABLED : DISABLED,\n mergeToConference: VISIBLE_DISABLED,\n };\n }\n }\n\n return {\n // Accept/Decline: Voice tasks in offered state\n // Desktop/WebRTC + inbound: accept enabled (agent manually accepts)\n // Desktop/WebRTC + outdial: accept disabled (auto-answer handles it; Widgets show \"Accept\" disabled)\n // Extension mode (non-WebRTC): accept disabled (Widgets show \"Ringing...\")\n accept:\n state === TaskState.OFFERED && !interaction?.isTerminated\n ? {isVisible: true, isEnabled: isWebrtc && !isOutdial}\n : DISABLED,\n decline: (() => {\n if (!isWebrtc || state !== TaskState.OFFERED || interaction?.isTerminated) return DISABLED;\n\n return isOutdial ? VISIBLE_DISABLED : VISIBLE_ENABLED;\n })(),\n\n // Hold: visible in connected/held/conference, disabled in conference/consulting\n hold: (() => {\n if (!hasFullControls) return DISABLED;\n if (forceHeldPostConsultControls) return VISIBLE_ENABLED;\n if (\n consultOwnedBySelf &&\n (isConsulting || hasParallelConsultLeg || effectiveConsultCallHeld)\n ) {\n return DISABLED;\n }\n if (hasParallelConsultLeg) return DISABLED;\n if (state === TaskState.OFFERED) return DISABLED;\n if (isWrappingUp) return DISABLED;\n // Visibility: connected || held || inConference\n if (!(isConnected || isHeld || inConference)) return DISABLED;\n // Enabled: (connected || held) && !inConference && !isConsulting\n const canHold = (isConnected || isHeld) && !inConference && !isConsulting;\n\n return canHold ? VISIBLE_ENABLED : VISIBLE_DISABLED;\n })(),\n\n // Mute: WebRTC only, active calls; hidden entirely during wrapup\n mute: (() => {\n if (!isWebrtc) return DISABLED;\n if (isWrappingUp) return DISABLED;\n if (currentLeg === 'consult' && !selfInConsultCall) return DISABLED;\n // The consulted agent has no separate consult leg; their main leg is the active call, so\n // mute stays available while they consult (the heuristic below targets the initiator's\n // inactive leg, not the consultee's only leg).\n const isConsultedActiveMainLeg = isConsulted && currentLeg === 'main';\n if (\n (isConsulting || hasParallelConsultLeg) &&\n !isCurrentLegActive &&\n !isConsultedActiveMainLeg\n ) {\n return VISIBLE_DISABLED;\n }\n if (isConsulting) return VISIBLE_ENABLED;\n\n if (isConnected || isHeld || isConferencing) {\n if (inConference) return VISIBLE_ENABLED;\n\n return isHeld ? VISIBLE_DISABLED : VISIBLE_ENABLED;\n }\n\n return DISABLED;\n })(),\n\n // End: varies by state; during consulting only on main leg (consult held)\n end: (() => {\n if (allowHeldMainLegControlsForNonInitiator) return VISIBLE_ENABLED;\n if (showMainLegConferenceControlsDuringConsult) return VISIBLE_DISABLED;\n if (isHydratedConferenceConsultPending && currentLeg === 'main') return VISIBLE_DISABLED;\n if (!config.isEndTaskEnabled && !isWebrtc) return DISABLED;\n if (hasParallelConsultLeg) {\n return isConnected && isEpDnConsult ? VISIBLE_ENABLED : VISIBLE_DISABLED;\n }\n\n if (isConsulting) {\n if (currentLeg === 'consult' && consultCallHeld) return DISABLED;\n\n return consultInitiator && consultCallHeld ? VISIBLE_ENABLED : DISABLED;\n }\n\n if (inConference) {\n if (isConsulted) return DISABLED;\n if (forceHeldPostConsultControls) return VISIBLE_DISABLED;\n\n if (consultInProgress) return VISIBLE_DISABLED;\n\n return isWrappingUp ? VISIBLE_DISABLED : VISIBLE_ENABLED;\n }\n if (!hasFullControls) return DISABLED;\n if (isActive) return isHeld || isWrappingUp ? VISIBLE_DISABLED : VISIBLE_ENABLED;\n\n return DISABLED;\n })(),\n\n // Transfer: connected/held/conference\n transfer: (() => {\n if (isHydratedConferenceConsultPending) return VISIBLE_DISABLED;\n if (isConferenceConsultTransferContext && currentLeg === 'main' && isCurrentLegActive) {\n return DISABLED;\n }\n if (inConference && isConsulting && consultInitiator) return DISABLED;\n if (hasParallelConsultLeg) {\n if (!customerPresent) return DISABLED;\n if (state === TaskState.CONNECTED) return VISIBLE_ENABLED;\n if (state === TaskState.HELD) return VISIBLE_DISABLED;\n }\n if (isConsulting) {\n if (!consultInitiator) return DISABLED;\n if (!customerPresent) return VISIBLE_DISABLED;\n if (consultLegOnHold) return VISIBLE_DISABLED;\n\n return isConsultDestinationReady ? VISIBLE_ENABLED : VISIBLE_DISABLED;\n }\n if (!hasFullControls) return DISABLED;\n if (inConference) {\n // Real conference (multiple agents): transfer is hidden\n // Pending conference (only self agent): transfer remains available\n return participantCount > 1 ? DISABLED : VISIBLE_ENABLED;\n }\n if (state === TaskState.CONNECTED || state === TaskState.HELD) return VISIBLE_ENABLED;\n\n return DISABLED;\n })(),\n\n // Consult: connected/held/conference when conditions met\n consult: (() => {\n const isConnectedOrHeld = state === TaskState.CONNECTED || state === TaskState.HELD;\n\n if (\n isHeld &&\n !inConference &&\n !effectiveHasConsultMedia &&\n selfParticipant?.consultState === 'consultCompleted' &&\n !taskData?.isConsulted\n ) {\n const canRetryConsult = !maxParticipants && customerPresent && !otherAgentConsultInProgress;\n\n return {isVisible: true, isEnabled: canRetryConsult};\n }\n\n if (inConference && nonOwnerPostConsultCompletedHeldMainLeg) return VISIBLE_DISABLED;\n if (hasParallelConsultLeg) return DISABLED;\n if (!hasFullControls || !(isConnectedOrHeld || inConference)) {\n return DISABLED;\n }\n\n // In conference: behavior depends on whether it's a real multi-agent conference\n if (inConference) {\n // Pending conference (only self agent): consult disabled\n if (participantCount <= 1) return VISIBLE_DISABLED;\n // Real conference: consult enabled if conditions met\n const canFromConference =\n !maxParticipants &&\n customerPresent &&\n !consultInProgress &&\n !otherAgentConsultInProgress &&\n !isConsulting;\n\n return {isVisible: true, isEnabled: canFromConference};\n }\n\n // Enabled conditions for connected/held\n const canFromConnected =\n !maxParticipants && customerPresent && !consultInProgress && !isConsulted;\n\n return {isVisible: true, isEnabled: canFromConnected};\n })(),\n\n // ConsultTransfer: always hidden (use transfer button)\n consultTransfer: DISABLED,\n\n // EndConsult: during consulting\n endConsult: (() => {\n if (!isConsulting) return DISABLED;\n if (isConsulted && isConferencing) return DISABLED;\n if (!isConsulted && isConferencing && !(consultInitiator && conferenceFromBackend)) {\n return DISABLED;\n }\n\n return {isVisible: true, isEnabled: consultInitiator || config.isEndConsultEnabled};\n })(),\n\n // Recording: connected/held, hidden in real conference, visible in pending conference\n recording: (() => {\n if (!recordingControlsAvailable || !config.isRecordingEnabled) return DISABLED;\n if (!hasFullControls || isConsulting) return DISABLED;\n if (inConference) {\n // Real conference (multiple agents): recording hidden\n // Pending conference (only self agent): recording available\n return participantCount > 1 ? DISABLED : VISIBLE_ENABLED;\n }\n if (hasParallelConsultLeg && !customerPresent) return DISABLED;\n if (state === TaskState.CONNECTED || state === TaskState.HELD) {\n return VISIBLE_ENABLED;\n }\n\n return DISABLED;\n })(),\n\n // Conference: during consulting, enabled on both legs when agent joined\n // Label changes based on leg: \"Conference\" on main leg, \"Merge\" on consult leg\n conference: (() => {\n if (isHydratedConferenceConsultPending && currentLeg === 'main') return VISIBLE_DISABLED;\n if (hasParallelConsultLeg) {\n if (!customerPresent) return DISABLED;\n if (state === TaskState.CONNECTED) {\n return maxParticipants ? VISIBLE_DISABLED : VISIBLE_ENABLED;\n }\n if (state === TaskState.HELD) return VISIBLE_DISABLED;\n\n return DISABLED;\n }\n if (!hasFullControls || !isConsulting) return DISABLED;\n if (!consultInitiator) return DISABLED;\n if (!customerPresent) return VISIBLE_DISABLED;\n if (consultLegOnHold) return VISIBLE_DISABLED;\n\n return isConsultDestinationReady && !maxParticipants ? VISIBLE_ENABLED : VISIBLE_DISABLED;\n })(),\n\n // Wrapup: wrapping up state\n wrapup: isWrappingUp ? VISIBLE_ENABLED : DISABLED,\n\n // ExitConference: in conference with multiple agents in main call\n exitConference: (() => {\n if (hideExitConferenceWhileConsultPending) return DISABLED;\n if (hideExitConferenceOnMainLegForEpDnConsultFromConference) return DISABLED;\n if (allowHeldMainLegControlsForNonInitiator) return VISIBLE_ENABLED;\n if (showMainLegConferenceControlsDuringConsult) return VISIBLE_DISABLED;\n if (hideExitConferenceDuringActiveConsultFromConference) return DISABLED;\n if (forceHeldPostConsultControls) return VISIBLE_DISABLED;\n if (isConsulted && !isConferencing) return DISABLED;\n if (!inConference) return DISABLED;\n if (participantCount <= 1) return DISABLED;\n if (consultInProgress) return VISIBLE_DISABLED;\n const consultingFromConference = consultInitiator && isConsulting && conferenceFromBackend;\n\n return consultingFromConference ? VISIBLE_DISABLED : VISIBLE_ENABLED;\n })(),\n\n // TransferConference: in conference with active consult, owner consulting from conference\n transferConference: (() => {\n if (isConferenceConsultTransferContext && !isCurrentLegActive) return VISIBLE_DISABLED;\n const consultLegTransferAvailable =\n currentLeg === 'consult' && inConference && consultInitiator && hasConsultMedia;\n const selfConsultingOnParticipantState = selfParticipant?.consultState === 'consulting';\n const conferenceTransferAvailable =\n consultLegTransferAvailable ||\n (inConference &&\n consultInitiator &&\n hasConsultMedia &&\n (isConsulting || consultInProgress || selfConsultingOnParticipantState));\n if (consultLegOnHold) return DISABLED;\n if (hasParallelConsultLeg && !conferenceTransferAvailable) return DISABLED;\n if (!conferenceTransferAvailable && (!inConference || !isConsulting)) return DISABLED;\n if (!consultInitiator || isConsulted) return DISABLED;\n\n return isConsultDestinationReady ? VISIBLE_ENABLED : VISIBLE_DISABLED;\n })(),\n\n // MergeToConference: mirrors conference control, enabled on both legs\n mergeToConference: (() => {\n if (isHydratedConferenceConsultPending && currentLeg === 'consult') return VISIBLE_DISABLED;\n if (!isConsulting || !consultInitiator) return DISABLED;\n if (!customerPresent) return VISIBLE_DISABLED;\n if (consultLegOnHold) return VISIBLE_DISABLED;\n\n return isConsultDestinationReady && !maxParticipants ? VISIBLE_ENABLED : VISIBLE_DISABLED;\n })(),\n\n // Switch: visible only on the currently active leg\n switch: (() => {\n if (isHydratedConferenceConsultPending && currentLeg === 'consult') return VISIBLE_DISABLED;\n if (!customerPresent && hasParallelConsultLeg) return DISABLED;\n if (currentLeg === 'consult') {\n if (!isConsulting || !consultInitiator || consultCallHeld) return DISABLED;\n if (!customerPresent) return VISIBLE_DISABLED;\n\n return isConsultDestinationReady ? VISIBLE_ENABLED : VISIBLE_DISABLED;\n }\n\n if (hasParallelConsultLeg && state === TaskState.CONNECTED) {\n return isConsultDestinationReady ? VISIBLE_ENABLED : VISIBLE_DISABLED;\n }\n\n return DISABLED;\n })(),\n };\n}\n\nfunction computeDigitalInteractionUIControls(\n state: TaskState,\n context: TaskContext,\n fallbackTaskData?: TaskData\n): InteractionUIControls {\n const taskData = context.taskData ?? fallbackTaskData ?? null;\n const isTerminated = taskData?.interaction?.isTerminated ?? false;\n\n const isConnected = state === TaskState.CONNECTED;\n const isWrappingUp = state === TaskState.WRAPPING_UP;\n\n return {\n accept: state === TaskState.OFFERED ? VISIBLE_ENABLED : DISABLED,\n decline: DISABLED,\n hold: DISABLED,\n mute: DISABLED,\n end: isConnected && !isWrappingUp ? VISIBLE_ENABLED : DISABLED,\n transfer: isConnected && !isWrappingUp ? VISIBLE_ENABLED : DISABLED,\n consult: DISABLED,\n consultTransfer: DISABLED,\n endConsult: DISABLED,\n recording: DISABLED,\n conference: DISABLED,\n wrapup: isTerminated || isWrappingUp ? VISIBLE_ENABLED : DISABLED,\n exitConference: DISABLED,\n transferConference: DISABLED,\n mergeToConference: DISABLED,\n switch: DISABLED,\n };\n}\n\nfunction getVoiceLegState(\n currentState: TaskState,\n context: TaskContext,\n config: UIControlConfig,\n fallbackTaskData?: TaskData\n): {hasConsultLeg: boolean; activeLeg: TaskUILeg; mainState: TaskState; consultState: TaskState} {\n if (currentState === TaskState.WRAPPING_UP) {\n return {\n hasConsultLeg: false,\n activeLeg: 'main',\n mainState: currentState,\n consultState: TaskState.CONSULTING,\n };\n }\n\n const taskData = fallbackTaskData ?? context.taskData ?? null;\n const interaction = taskData?.interaction;\n const mainCallId = interaction?.mainInteractionId || taskData?.interactionId;\n const selfAgentId = config.agentId ?? taskData?.agentId;\n const selfParticipant = selfAgentId ? interaction?.participants?.[selfAgentId] : null;\n const hasConsultMedia = hasConsultMediaInInteraction(\n interaction,\n taskData?.consultMediaResourceId\n );\n const isConsultEndedForSelf =\n taskData?.type === 'AgentConsultEnded' ||\n taskData?.type === 'AgentConsultFailed' ||\n (selfParticipant?.consultState === 'consultCompleted' &&\n !hasConsultMedia &&\n taskData?.isConsulted === false);\n const consultInProgress = getIsConsultInProgressForConferenceControls(\n interaction,\n mainCallId,\n selfAgentId\n );\n const isConsultingState =\n currentState === TaskState.CONSULTING ||\n currentState === TaskState.CONSULT_INITIATING ||\n currentState === TaskState.CONF_INITIATING;\n const consultOwnedBySelf =\n context.consultInitiator ||\n (Boolean(selfAgentId) && taskData?.consultingAgentId === selfAgentId);\n const selfConsultPendingOnConsultMedia =\n selfParticipant?.consultState === 'consultInitiated' &&\n !taskData?.isConsulted &&\n hasConsultMedia;\n const selfConsultingOnConsultMedia =\n selfParticipant?.consultState === 'consulting' && hasConsultMedia;\n const isConsultUnansweredFailure =\n !taskData?.isConsulted &&\n !hasConsultMedia &&\n selfParticipant?.consultState === 'consultCompleted' &&\n Boolean(mainCallId && taskData?.interaction?.media?.[mainCallId]?.isHold === true) &&\n taskData?.interaction?.state !== 'conference' &&\n !getIsConferenceInProgress(taskData);\n const hasConsultLeg = Boolean(\n !isConsultEndedForSelf &&\n !interaction?.isTerminated &&\n !isConsultUnansweredFailure &&\n (consultOwnedBySelf || selfConsultingOnConsultMedia || selfConsultPendingOnConsultMedia) &&\n (consultInProgress || isConsultingState || context.consultCallHeld || hasConsultMedia)\n );\n\n if (!hasConsultLeg) {\n let mainState = currentState;\n if (isConsultEndedForSelf && taskData?.interaction) {\n const resolvedMainId = taskData.interaction.mainInteractionId || taskData.interactionId;\n const isMainHeld = Boolean(\n resolvedMainId && taskData.interaction.media?.[resolvedMainId]?.isHold === true\n );\n\n if (taskData.interaction.state === 'conference' || getIsConferenceInProgress(taskData)) {\n mainState = TaskState.CONFERENCING;\n } else if (isMainHeld || taskData.interaction.state === 'hold') {\n mainState = TaskState.HELD;\n } else {\n mainState = TaskState.CONNECTED;\n }\n }\n\n return {\n hasConsultLeg: false,\n activeLeg: 'main',\n mainState,\n consultState: TaskState.CONSULTING,\n };\n }\n\n let mainState = TaskState.HELD;\n if (currentState === TaskState.CONFERENCING) {\n mainState = TaskState.CONFERENCING;\n } else if (context.consultCallHeld) {\n mainState = TaskState.CONNECTED;\n }\n\n return {\n hasConsultLeg: true,\n activeLeg: context.consultCallHeld ? 'main' : 'consult',\n mainState,\n consultState: isConsultingState ? currentState : TaskState.CONSULTING,\n };\n}\n\nexport function computeUIControls(\n currentState: TaskState,\n context: TaskContext,\n fallbackTaskData?: TaskData\n): TaskUIControls {\n if (currentState === TaskState.TERMINATED || currentState === TaskState.COMPLETED) {\n return getDefaultUIControls();\n }\n\n switch (context.uiControlConfig.channelType) {\n case TASK_CHANNEL_TYPE.VOICE: {\n const {hasConsultLeg, activeLeg, mainState, consultState} = getVoiceLegState(\n currentState,\n context,\n context.uiControlConfig,\n fallbackTaskData\n );\n\n const mainControls = computeVoiceInteractionUIControls(\n mainState,\n context,\n context.uiControlConfig,\n fallbackTaskData,\n 'main'\n );\n const consultControls = hasConsultLeg\n ? computeVoiceInteractionUIControls(\n consultState,\n context,\n context.uiControlConfig,\n fallbackTaskData,\n 'consult'\n )\n : getDefaultInteractionUIControls();\n\n return createTaskUIControls(mainControls, consultControls, activeLeg);\n }\n case TASK_CHANNEL_TYPE.DIGITAL:\n return createTaskUIControls(\n computeDigitalInteractionUIControls(currentState, context, fallbackTaskData),\n getDefaultInteractionUIControls(),\n 'main'\n );\n default:\n return getDefaultUIControls();\n }\n}\n\nfunction haveInteractionUIControlsChanged(\n previous: InteractionUIControls,\n next: InteractionUIControls\n): boolean {\n return (Object.keys(next) as (keyof InteractionUIControls)[]).some((key) => {\n const prev = previous[key];\n const curr = next[key];\n\n return prev.isVisible !== curr.isVisible || prev.isEnabled !== curr.isEnabled;\n });\n}\n\nexport function haveUIControlsChanged(\n previous: TaskUIControls | undefined,\n next: TaskUIControls\n): boolean {\n if (!previous) return true;\n\n return (\n previous.activeLeg !== next.activeLeg ||\n haveInteractionUIControlsChanged(previous.main, next.main) ||\n haveInteractionUIControlsChanged(previous.consult, next.consult)\n );\n}\n"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"names":["_types","require","_constants","_TaskUtils","DISABLED","isVisible","isEnabled","VISIBLE_ENABLED","VISIBLE_DISABLED","getDefaultInteractionUIControls","accept","decline","hold","mute","end","transfer","consult","consultTransfer","endConsult","recording","conference","wrapup","exitConference","transferConference","mergeToConference","switch","createTaskUIControls","main","activeLeg","getDefaultUIControls","hasConsultMediaInInteraction","interaction","consultMediaResourceId","media","hasConsultLeg","Object","values","some","entry","mType","Boolean","isSelfActiveConsultInitiator","consultInitiator","selfAgentId","selfParticipant","selfInConsultCall","consultingAgentId","consultState","computeVoiceInteractionUIControls","state","context","config","fallbackTaskData","currentLeg","TaskState","IDLE","taskData","mainCallId","mainInteractionId","interactionId","isWebrtc","voiceVariant","VOICE_VARIANT","WEBRTC","isOutdial","outboundType","serverHold","getServerHoldStateForControls","customerInCall","getIsCustomerInCall","customerPresent","participants","p","pType","hasLeft","participantCount","getConferenceParticipantsCount","maxParticipants","MAX_PARTICIPANTS_IN_MULTIPARTY_CONFERENCE","agentId","consultInProgress","getIsConsultInProgressForConferenceControls","conferenceFromBackend","getIsConferenceInProgress","consultDestinationAgentJoined","consultDestinationType","consultCallHeld","consultFromConference","hideBlindTransferForEpDnPendingMerge","recordingControlsAvailable","isEpDnConsult","stateImpliesHeld","HELD","RESUME_INITIATING","stateImpliesConnected","CONNECTED","HOLD_INITIATING","isHeld","isConnected","isConsulting","CONSULTING","CONSULT_INITIATING","CONF_INITIATING","isConferencing","CONFERENCING","isWrappingUp","WRAPPING_UP","selfInMainCall","includes","consultMedia","find","mediaResourceId","hasConsultMedia","isSecondaryConsultRejectedWhileEpDnActive","type","isSelfConsultCompleted","isConsulted","isConsultEndedForSelf","isEpDnPendingConferenceMergeUi","INTERACTION_STATE","POST_CALL","isEpDnPostCallCustomerLeft","effectiveConsultInProgress","effectiveConsultInitiator","effectiveConsultCallHeld","effectiveConsultFromConference","effectiveConsultDestinationAgentJoined","effectiveHasConsultMedia","isConsultDestinationReady","conferenceActive","inConference","isSoleAgentOnCall","getIsConsultedAgentForControls","isActive","hasFullControls","selfActiveConsultInitiator","consultOwnedBySelf","selfConsultPendingOnConsultMedia","ownerParticipant","owner","undefined","otherAgentConsultInProgress","participant","id","String","toUpperCase","currentState","isHydratedConferenceConsultPending","hasParallelConsultLeg","activeLegForConferenceConsult","isCurrentLegActive","isConferenceConsultTransferContext","consultLegOnHold","callProcessingDetails","conferenceHoldParticipant","postDeclineHeldMainLeg","postConsultCompletedHeldMainLeg","nonOwnerPostConsultCompletedHeldMainLeg","isConsultPendingBeforeJoin","hideExitConferenceWhileConsultPending","hideExitConferenceDuringActiveConsultFromConference","hideExitConferenceOnMainLegForEpDnConsultFromConference","forceHeldPostConsultControls","selfOnConsultLeg","showMainLegConferenceControlsDuringConsult","allowHeldMainLegControlsForNonInitiator","isConsultRequestedPhase","isConsultUnansweredFailure","shouldHideBlindTransferForEpDnPendingConferenceMerge","recordingControl","isRecordingEnabled","OFFERED","isTerminated","canHold","isConsultedActiveMainLeg","isEndTaskEnabled","isConnectedOrHeld","canRetryConsult","canFromConference","canFromConnected","isEndConsultEnabled","consultingFromConference","consultLegTransferAvailable","selfConsultingOnParticipantState","conferenceTransferAvailable","computeDigitalInteractionUIControls","getVoiceLegState","mainState","isConsultingState","selfConsultingOnConsultMedia","isHold","resolvedMainId","isMainHeld","mainMediaId","computeUIControls","TERMINATED","COMPLETED","uiControlConfig","channelType","TASK_CHANNEL_TYPE","VOICE","mainControls","consultControls","DIGITAL","haveInteractionUIControlsChanged","previous","next","keys","key","prev","curr","haveUIControlsChanged"],"sources":["uiControlsComputer.ts"],"sourcesContent":["/**\n * UI Controls Computer - Centralized logic for computing UI control states\n */\n\nimport {\n InteractionUIControls,\n TASK_CHANNEL_TYPE,\n TaskData,\n TaskUILeg,\n TaskUIControls,\n VOICE_VARIANT,\n} from '../types';\nimport {TaskContext, UIControlConfig} from './types';\nimport {TaskState, MAX_PARTICIPANTS_IN_MULTIPARTY_CONFERENCE, INTERACTION_STATE} from './constants';\nimport {\n getIsCustomerInCall,\n getConferenceParticipantsCount,\n getIsConferenceInProgress,\n getIsConsultInProgressForConferenceControls,\n getIsConsultedAgentForControls,\n getServerHoldStateForControls,\n} from '../TaskUtils';\n\nconst DISABLED = {isVisible: false, isEnabled: false} as const;\nconst VISIBLE_ENABLED = {isVisible: true, isEnabled: true} as const;\nconst VISIBLE_DISABLED = {isVisible: true, isEnabled: false} as const;\n\nfunction getDefaultInteractionUIControls(): InteractionUIControls {\n return {\n accept: DISABLED,\n decline: DISABLED,\n hold: DISABLED,\n mute: DISABLED,\n end: DISABLED,\n transfer: DISABLED,\n consult: DISABLED,\n consultTransfer: DISABLED,\n endConsult: DISABLED,\n recording: DISABLED,\n conference: DISABLED,\n wrapup: DISABLED,\n exitConference: DISABLED,\n transferConference: DISABLED,\n mergeToConference: DISABLED,\n switch: DISABLED,\n };\n}\n\nfunction createTaskUIControls(\n main: InteractionUIControls,\n consult: InteractionUIControls,\n activeLeg: TaskUILeg\n): TaskUIControls {\n return {\n main,\n consult,\n activeLeg,\n };\n}\n\nexport function getDefaultUIControls(): TaskUIControls {\n return createTaskUIControls(\n getDefaultInteractionUIControls(),\n getDefaultInteractionUIControls(),\n 'main'\n );\n}\n\n/** Consult media must exist on the interaction payload, not only as a stale resource id. */\nfunction hasConsultMediaInInteraction(\n interaction: TaskData['interaction'] | undefined,\n consultMediaResourceId?: string\n): boolean {\n const media = interaction?.media ?? {};\n const hasConsultLeg = Object.values(media).some((entry: any) => entry?.mType === 'consult');\n\n if (hasConsultLeg) return true;\n if (!consultMediaResourceId) return false;\n\n return Boolean(media[consultMediaResourceId]);\n}\n\n/** True when this agent is actively initiating a consult, not a stale context flag alone (CAI-8329). */\nfunction isSelfActiveConsultInitiator(\n consultInitiator: boolean,\n selfAgentId: string | undefined,\n selfParticipant: {consultState?: string} | null | undefined,\n selfInConsultCall: boolean,\n consultingAgentId?: string\n): boolean {\n return (\n consultInitiator &&\n (selfParticipant?.consultState === 'consultInitiated' ||\n selfParticipant?.consultState === 'consulting' ||\n selfInConsultCall ||\n (Boolean(consultingAgentId) && consultingAgentId === selfAgentId))\n );\n}\n\nfunction computeVoiceInteractionUIControls(\n state: TaskState,\n context: TaskContext,\n config: UIControlConfig,\n fallbackTaskData?: TaskData,\n currentLeg: TaskUILeg = 'main'\n): InteractionUIControls {\n // Early exit for idle\n if (state === TaskState.IDLE) {\n return getDefaultInteractionUIControls();\n }\n\n // Prefer live task.data (fallback) over stale state-machine snapshot during multi-login sync.\n const taskData = fallbackTaskData ?? context.taskData ?? null;\n const interaction = taskData?.interaction;\n const mainCallId = interaction?.mainInteractionId || taskData?.interactionId;\n const isWebrtc = config.voiceVariant === VOICE_VARIANT.WEBRTC;\n const isOutdial = interaction?.outboundType === 'OUTDIAL';\n const serverHold = getServerHoldStateForControls(context, mainCallId, fallbackTaskData);\n\n // Backend-derived checks\n const customerInCall =\n interaction && mainCallId ? getIsCustomerInCall(interaction, mainCallId) : false;\n // EP-DN/secondary legs can have incomplete media participant lists; fall back to participants map.\n const customerPresent =\n customerInCall ||\n Boolean(\n interaction &&\n interaction.participants &&\n Object.values(interaction.participants).some(\n (p: any) => p?.pType === 'Customer' && !p?.hasLeft\n )\n );\n const participantCount =\n interaction && mainCallId ? getConferenceParticipantsCount(interaction, mainCallId) : 0;\n const maxParticipants = participantCount >= MAX_PARTICIPANTS_IN_MULTIPARTY_CONFERENCE;\n const selfAgentId = config.agentId ?? taskData?.agentId;\n const consultInProgress = getIsConsultInProgressForConferenceControls(\n interaction,\n mainCallId,\n selfAgentId\n );\n const conferenceFromBackend = taskData ? getIsConferenceInProgress(taskData) : false;\n // Note: ownership is used by some controls; keep computations local to those controls\n\n // Context flags (set by state machine actions)\n const {\n consultInitiator,\n consultDestinationAgentJoined,\n consultDestinationType,\n consultCallHeld,\n consultFromConference,\n hideBlindTransferForEpDnPendingMerge,\n } = context;\n const {recordingControlsAvailable} = context;\n\n // EP_DN consults are \"ready\" as soon as the consult is created (EP accepts routing immediately).\n // Backend sends destinationType as 'EP-DN'; SDK method uses 'entryPoint' — check both.\n const isEpDnConsult =\n consultDestinationType === 'entryPoint' || consultDestinationType === ('EP-DN' as any);\n\n const stateImpliesHeld = state === TaskState.HELD || state === TaskState.RESUME_INITIATING;\n const stateImpliesConnected =\n state === TaskState.CONNECTED || state === TaskState.HOLD_INITIATING;\n const isHeld = stateImpliesHeld || serverHold === true;\n const isConnected = stateImpliesConnected || (!stateImpliesHeld && serverHold === false);\n\n // State categories for cleaner logic\n const isConsulting =\n state === TaskState.CONSULTING ||\n state === TaskState.CONSULT_INITIATING ||\n state === TaskState.CONF_INITIATING;\n const isConferencing = state === TaskState.CONFERENCING;\n const isWrappingUp = state === TaskState.WRAPPING_UP;\n const selfInMainCall =\n Boolean(selfAgentId) &&\n Boolean(mainCallId) &&\n Boolean(interaction?.media?.[mainCallId]?.participants?.includes(selfAgentId as string));\n const consultMedia = Object.values(interaction?.media ?? {}).find(\n (media: any) =>\n media?.mediaResourceId === taskData?.consultMediaResourceId || media?.mType === 'consult'\n ) as {participants?: string[]} | undefined;\n const selfParticipant = selfAgentId ? interaction?.participants?.[selfAgentId] : null;\n const selfInConsultCall =\n Boolean(selfAgentId) && Boolean(consultMedia?.participants?.includes(selfAgentId as string));\n const hasConsultMedia = hasConsultMediaInInteraction(\n interaction,\n taskData?.consultMediaResourceId\n );\n const isSecondaryConsultRejectedWhileEpDnActive =\n taskData?.type === 'AgentConsultFailed' && hideBlindTransferForEpDnPendingMerge;\n const isSelfConsultCompleted =\n selfParticipant?.consultState === 'consultCompleted' && taskData?.isConsulted === false;\n const isConsultEndedForSelf =\n taskData?.type === 'AgentConsultEnded' ||\n (taskData?.type === 'AgentConsultFailed' && !isSecondaryConsultRejectedWhileEpDnActive) ||\n isSelfConsultCompleted;\n // EP-DN consult merged to conference before destination joins main (CAI-8329).\n // Context flag is set in actions.ts; treat as main-leg conference UI only here.\n const isEpDnPendingConferenceMergeUi =\n hideBlindTransferForEpDnPendingMerge &&\n participantCount <= 1 &&\n (isConferencing ||\n conferenceFromBackend ||\n interaction?.state === INTERACTION_STATE.POST_CALL) &&\n !isConsultEndedForSelf;\n const isEpDnPostCallCustomerLeft = isEpDnPendingConferenceMergeUi && !customerPresent;\n const effectiveConsultInProgress = isEpDnPendingConferenceMergeUi ? false : consultInProgress;\n const effectiveConsultInitiator = isConsultEndedForSelf ? false : consultInitiator;\n const effectiveConsultCallHeld = isConsultEndedForSelf ? false : consultCallHeld;\n const effectiveConsultFromConference = isConsultEndedForSelf ? false : consultFromConference;\n const effectiveConsultDestinationAgentJoined = isConsultEndedForSelf\n ? false\n : consultDestinationAgentJoined;\n // After a consult ends for self, the backend stops sending consult media but the merged\n // task.data can still carry the stale consult-media entry (reconcileData never deletes keys).\n // Treat it as gone so post-consult main-leg controls (consult retry) are not blocked.\n const effectiveHasConsultMedia = isConsultEndedForSelf ? false : hasConsultMedia;\n const isConsultDestinationReady = effectiveConsultDestinationAgentJoined || isEpDnConsult;\n const conferenceActive =\n isConferencing || conferenceFromBackend || effectiveConsultFromConference;\n // Treat consult initiator as \"in conference\" even if mainCall participant list lags while consulting.\n const inConference =\n conferenceActive && (isConferencing || selfInMainCall || effectiveConsultInitiator);\n\n // Check if this is a consulted agent (must be after isConsulting is computed).\n const isSoleAgentOnCall =\n participantCount <= 1 && selfInMainCall && !isConsulting && !inConference;\n const isConsulted =\n inConference || isSoleAgentOnCall\n ? false\n : getIsConsultedAgentForControls(taskData, context, isConsulting) ||\n (!effectiveConsultInitiator &&\n (selfParticipant?.isConsulted === true ||\n selfParticipant?.consultState === 'consulting'));\n\n // Active call = can perform call operations\n const isActive =\n state === TaskState.CONNECTED ||\n state === TaskState.HELD ||\n state === TaskState.HOLD_INITIATING ||\n state === TaskState.RESUME_INITIATING ||\n isConsulting ||\n isConferencing;\n\n // Consulted agents have limited controls until they're in conference or wrapup\n // Use inConference (not isConferencing) so controls remain enabled after state downgrade\n const hasFullControls = !isConsulted || effectiveConsultInitiator || inConference || isWrappingUp;\n const selfActiveConsultInitiator = isSelfActiveConsultInitiator(\n effectiveConsultInitiator,\n selfAgentId,\n selfParticipant,\n selfInConsultCall,\n taskData?.consultingAgentId\n );\n const consultOwnedBySelf = !isEpDnPendingConferenceMergeUi && selfActiveConsultInitiator;\n const selfConsultPendingOnConsultMedia =\n selfParticipant?.consultState === 'consultInitiated' &&\n !taskData?.isConsulted &&\n hasConsultMedia;\n const ownerParticipant = interaction?.owner\n ? interaction.participants?.[interaction.owner]\n : undefined;\n const otherAgentConsultInProgress = Boolean(\n interaction?.participants &&\n Object.values(interaction.participants).some((participant: any) => {\n if (!participant || participant.hasLeft) return false;\n if (participant.id === selfAgentId) return false;\n if (String(participant.pType ?? '').toUpperCase() !== 'AGENT') return false;\n\n return (\n participant.consultState === 'consultInitiated' ||\n participant.consultState === 'consultReserved' ||\n participant.consultState === 'consulting' ||\n participant.currentState === 'consulting'\n );\n })\n );\n const isHydratedConferenceConsultPending =\n inConference && selfConsultPendingOnConsultMedia && !effectiveConsultDestinationAgentJoined;\n const hasParallelConsultLeg =\n !isConsultEndedForSelf &&\n consultOwnedBySelf &&\n !isConsulting &&\n !isConsulted &&\n (effectiveConsultInProgress || effectiveConsultCallHeld || hasConsultMedia);\n const activeLegForConferenceConsult = effectiveConsultCallHeld ? 'main' : 'consult';\n const isCurrentLegActive = currentLeg === activeLegForConferenceConsult;\n const isConferenceConsultTransferContext =\n inConference && selfActiveConsultInitiator && hasConsultMedia && isConsultDestinationReady;\n const consultLegOnHold = isConsulting && effectiveConsultCallHeld;\n const callProcessingDetails = interaction?.callProcessingDetails as\n | {conferenceHoldParticipant?: boolean | string}\n | undefined;\n const conferenceHoldParticipant =\n callProcessingDetails?.conferenceHoldParticipant === true ||\n callProcessingDetails?.conferenceHoldParticipant === 'true';\n const postDeclineHeldMainLeg =\n consultInitiator &&\n !consultDestinationAgentJoined &&\n isHeld &&\n inConference &&\n conferenceHoldParticipant;\n const postConsultCompletedHeldMainLeg =\n selfParticipant?.consultState === 'consultCompleted' && isHeld && inConference && !isConsulting;\n const nonOwnerPostConsultCompletedHeldMainLeg =\n isHeld &&\n inConference &&\n !isConsulting &&\n !consultInitiator &&\n Boolean(selfAgentId) &&\n Boolean(interaction?.owner) &&\n selfAgentId !== interaction?.owner &&\n ownerParticipant?.consultState === 'consultCompleted';\n const isConsultPendingBeforeJoin =\n selfParticipant?.consultState === 'consultInitiated' && !consultDestinationAgentJoined;\n const hideExitConferenceWhileConsultPending =\n currentLeg === 'main' &&\n inConference &&\n isConsultPendingBeforeJoin &&\n (consultFromConference ||\n consultInitiator ||\n taskData?.type === 'AgentConsultCreated' ||\n effectiveConsultInProgress ||\n isConsulting);\n const hideExitConferenceDuringActiveConsultFromConference =\n inConference &&\n selfActiveConsultInitiator &&\n consultDestinationAgentJoined &&\n (isConsulting ||\n taskData?.type === 'AgentConsulting' ||\n selfParticipant?.consultState === 'consulting');\n const hideExitConferenceOnMainLegForEpDnConsultFromConference =\n currentLeg === 'main' &&\n inConference &&\n consultFromConference &&\n selfActiveConsultInitiator &&\n (isConsulting ||\n effectiveConsultInProgress ||\n taskData?.type === 'AgentConsultCreated' ||\n taskData?.type === 'AgentConsulting' ||\n selfParticipant?.consultState === 'consultInitiated' ||\n selfParticipant?.consultState === 'consulting');\n const forceHeldPostConsultControls =\n !hideExitConferenceWhileConsultPending &&\n (postDeclineHeldMainLeg || postConsultCompletedHeldMainLeg);\n const selfOnConsultLeg =\n selfParticipant?.consultState === 'consulting' ||\n selfParticipant?.currentState === 'consulting';\n const showMainLegConferenceControlsDuringConsult =\n currentLeg === 'main' && inConference && effectiveConsultInProgress && !selfOnConsultLeg;\n const allowHeldMainLegControlsForNonInitiator =\n showMainLegConferenceControlsDuringConsult && !isHydratedConferenceConsultPending;\n const isConsultRequestedPhase =\n isConsultPendingBeforeJoin &&\n !isConsulted &&\n (consultInitiator ||\n (Boolean(selfAgentId) &&\n selfParticipant?.consultState === 'consultInitiated' &&\n taskData?.agentId === selfAgentId));\n const isConsultUnansweredFailure =\n currentLeg === 'main' &&\n !inConference &&\n !taskData?.isConsulted &&\n !effectiveHasConsultMedia &&\n isHeld &&\n selfParticipant?.consultState === 'consultCompleted' &&\n (taskData?.type === 'AgentConsultFailed' ||\n taskData?.type === 'AgentConsultEnded' ||\n isConsultEndedForSelf);\n // EP-DN consult merged to conference before a second agent joins main: hide blind transfer (CAI-8329).\n const shouldHideBlindTransferForEpDnPendingConferenceMerge = isEpDnPendingConferenceMergeUi;\n\n if (isConsultUnansweredFailure) {\n const recordingControl =\n recordingControlsAvailable && config.isRecordingEnabled && !inConference\n ? VISIBLE_ENABLED\n : DISABLED;\n\n return {\n ...getDefaultInteractionUIControls(),\n hold: VISIBLE_ENABLED,\n transfer: VISIBLE_ENABLED,\n consult: VISIBLE_ENABLED,\n recording: recordingControl,\n end: VISIBLE_DISABLED,\n };\n }\n\n if (isConsultRequestedPhase && !isEpDnPendingConferenceMergeUi) {\n if (currentLeg === 'main') {\n return {\n ...getDefaultInteractionUIControls(),\n transfer: shouldHideBlindTransferForEpDnPendingConferenceMerge\n ? DISABLED\n : VISIBLE_DISABLED,\n conference: VISIBLE_DISABLED,\n end: VISIBLE_DISABLED,\n };\n }\n\n if (currentLeg === 'consult') {\n return {\n ...getDefaultInteractionUIControls(),\n endConsult: VISIBLE_ENABLED,\n switch: VISIBLE_DISABLED,\n transfer: VISIBLE_DISABLED,\n transferConference: inConference ? VISIBLE_DISABLED : DISABLED,\n mergeToConference: VISIBLE_DISABLED,\n };\n }\n }\n\n return {\n // Accept/Decline: Voice tasks in offered state\n // Desktop/WebRTC + inbound: accept enabled (agent manually accepts)\n // Desktop/WebRTC + outdial: accept disabled (auto-answer handles it; Widgets show \"Accept\" disabled)\n // Extension mode (non-WebRTC): accept disabled (Widgets show \"Ringing...\")\n accept:\n state === TaskState.OFFERED && !interaction?.isTerminated\n ? {isVisible: true, isEnabled: isWebrtc && !isOutdial}\n : DISABLED,\n decline: (() => {\n if (!isWebrtc || state !== TaskState.OFFERED || interaction?.isTerminated) return DISABLED;\n\n return isOutdial ? VISIBLE_DISABLED : VISIBLE_ENABLED;\n })(),\n\n // Hold: visible in connected/held/conference, disabled in conference/consulting\n hold: (() => {\n if (!hasFullControls) return DISABLED;\n if (isEpDnPostCallCustomerLeft) return VISIBLE_DISABLED;\n if (forceHeldPostConsultControls) return VISIBLE_ENABLED;\n if (\n consultOwnedBySelf &&\n (isConsulting || hasParallelConsultLeg || effectiveConsultCallHeld)\n ) {\n return DISABLED;\n }\n if (hasParallelConsultLeg) return DISABLED;\n if (state === TaskState.OFFERED) return DISABLED;\n if (isWrappingUp) return DISABLED;\n // Visibility: connected || held || inConference\n if (!(isConnected || isHeld || inConference)) return DISABLED;\n // Enabled: (connected || held) && !inConference && !isConsulting\n const canHold = (isConnected || isHeld) && !inConference && !isConsulting;\n\n return canHold ? VISIBLE_ENABLED : VISIBLE_DISABLED;\n })(),\n\n // Mute: WebRTC only, active calls; hidden entirely during wrapup\n mute: (() => {\n if (!isWebrtc) return DISABLED;\n if (isWrappingUp) return DISABLED;\n if (isEpDnPostCallCustomerLeft && inConference) return VISIBLE_DISABLED;\n if (currentLeg === 'consult' && !selfInConsultCall) return DISABLED;\n // The consulted agent has no separate consult leg; their main leg is the active call, so\n // mute stays available while they consult (the heuristic below targets the initiator's\n // inactive leg, not the consultee's only leg).\n const isConsultedActiveMainLeg = isConsulted && currentLeg === 'main';\n if (\n (isConsulting || hasParallelConsultLeg) &&\n !isCurrentLegActive &&\n !isConsultedActiveMainLeg\n ) {\n return VISIBLE_DISABLED;\n }\n if (isConsulting) return VISIBLE_ENABLED;\n\n if (isConnected || isHeld || isConferencing) {\n if (inConference) return VISIBLE_ENABLED;\n\n return isHeld ? VISIBLE_DISABLED : VISIBLE_ENABLED;\n }\n\n return DISABLED;\n })(),\n\n // End: varies by state; during consulting only on main leg (consult held)\n end: (() => {\n if (allowHeldMainLegControlsForNonInitiator) return VISIBLE_ENABLED;\n if (showMainLegConferenceControlsDuringConsult) return VISIBLE_DISABLED;\n if (isHydratedConferenceConsultPending && currentLeg === 'main') return VISIBLE_DISABLED;\n if (!config.isEndTaskEnabled && !isWebrtc) return DISABLED;\n if (hasParallelConsultLeg) {\n return isConnected && isEpDnConsult ? VISIBLE_ENABLED : VISIBLE_DISABLED;\n }\n\n if (isConsulting) {\n if (currentLeg === 'consult' && consultCallHeld) return DISABLED;\n\n return consultInitiator && consultCallHeld ? VISIBLE_ENABLED : DISABLED;\n }\n\n if (inConference) {\n if (isConsulted) return DISABLED;\n if (forceHeldPostConsultControls) return VISIBLE_DISABLED;\n\n if (effectiveConsultInProgress) return VISIBLE_DISABLED;\n\n return isWrappingUp ? VISIBLE_DISABLED : VISIBLE_ENABLED;\n }\n if (!hasFullControls) return DISABLED;\n if (isActive) return isHeld || isWrappingUp ? VISIBLE_DISABLED : VISIBLE_ENABLED;\n\n return DISABLED;\n })(),\n\n // Transfer: connected/held/conference\n transfer: (() => {\n if (isHydratedConferenceConsultPending) return VISIBLE_DISABLED;\n if (isConferenceConsultTransferContext && currentLeg === 'main' && isCurrentLegActive) {\n return DISABLED;\n }\n if (inConference && isConsulting && consultInitiator) return DISABLED;\n if (hasParallelConsultLeg) {\n if (!customerPresent) return DISABLED;\n if (shouldHideBlindTransferForEpDnPendingConferenceMerge) return DISABLED;\n if (state === TaskState.CONNECTED) return VISIBLE_ENABLED;\n if (state === TaskState.HELD) return VISIBLE_DISABLED;\n }\n if (isConsulting) {\n if (!consultInitiator) return DISABLED;\n if (!customerPresent) return VISIBLE_DISABLED;\n if (consultLegOnHold) return VISIBLE_DISABLED;\n\n return isConsultDestinationReady ? VISIBLE_ENABLED : VISIBLE_DISABLED;\n }\n if (!hasFullControls) return DISABLED;\n if (inConference) {\n // Real conference (multiple agents): transfer is hidden\n // Pending conference (only self agent): transfer remains available\n // EP-DN consult merged before destination joins: hide blind transfer on main\n // (Agent 2 may still be ringing on the consult leg — blind transfer causes stuck ringing)\n if (shouldHideBlindTransferForEpDnPendingConferenceMerge) {\n return DISABLED;\n }\n\n if (participantCount > 1) {\n return DISABLED;\n }\n\n return customerPresent ? VISIBLE_ENABLED : DISABLED;\n }\n if (state === TaskState.CONNECTED || state === TaskState.HELD) return VISIBLE_ENABLED;\n\n return DISABLED;\n })(),\n\n // Consult: connected/held/conference when conditions met\n consult: (() => {\n const isConnectedOrHeld = state === TaskState.CONNECTED || state === TaskState.HELD;\n\n if (\n isHeld &&\n !inConference &&\n !effectiveHasConsultMedia &&\n selfParticipant?.consultState === 'consultCompleted' &&\n !taskData?.isConsulted\n ) {\n const canRetryConsult = !maxParticipants && customerPresent && !otherAgentConsultInProgress;\n\n return {isVisible: true, isEnabled: canRetryConsult};\n }\n\n if (inConference && nonOwnerPostConsultCompletedHeldMainLeg) return VISIBLE_DISABLED;\n if (hasParallelConsultLeg) return DISABLED;\n if (!hasFullControls || !(isConnectedOrHeld || inConference)) {\n return DISABLED;\n }\n\n // In conference: behavior depends on whether it's a real multi-agent conference\n if (inConference) {\n // Pending conference (only self agent): consult disabled\n if (participantCount <= 1) return VISIBLE_DISABLED;\n // Real conference: consult enabled if conditions met\n const canFromConference =\n !maxParticipants &&\n customerPresent &&\n !effectiveConsultInProgress &&\n !otherAgentConsultInProgress &&\n !isConsulting;\n\n return {isVisible: true, isEnabled: canFromConference};\n }\n\n // Enabled conditions for connected/held\n const canFromConnected =\n !maxParticipants && customerPresent && !effectiveConsultInProgress && !isConsulted;\n\n return {isVisible: true, isEnabled: canFromConnected};\n })(),\n\n // ConsultTransfer: always hidden (use transfer button)\n consultTransfer: DISABLED,\n\n // EndConsult: during consulting\n endConsult: (() => {\n if (!isConsulting) return DISABLED;\n if (isConsulted && isConferencing) return DISABLED;\n if (!isConsulted && isConferencing && !(consultInitiator && conferenceFromBackend)) {\n return DISABLED;\n }\n\n return {isVisible: true, isEnabled: consultInitiator || config.isEndConsultEnabled};\n })(),\n\n // Recording: connected/held/conference when backend exposes recording controls\n recording: (() => {\n if (!recordingControlsAvailable || !config.isRecordingEnabled) return DISABLED;\n if (!hasFullControls || isConsulting) return DISABLED;\n if (inConference) {\n // Recording stays available in conference when backend exposes controls\n // (including after EP-DN pending merge transitions to real conference — CAI-8329)\n if (isEpDnPostCallCustomerLeft) return VISIBLE_DISABLED;\n\n return VISIBLE_ENABLED;\n }\n if (hasParallelConsultLeg && !customerPresent) return DISABLED;\n if (state === TaskState.CONNECTED || state === TaskState.HELD) {\n return VISIBLE_ENABLED;\n }\n\n return DISABLED;\n })(),\n\n // Conference: during consulting, enabled on both legs when agent joined\n // Label changes based on leg: \"Conference\" on main leg, \"Merge\" on consult leg\n conference: (() => {\n if (isHydratedConferenceConsultPending && currentLeg === 'main') return VISIBLE_DISABLED;\n if (hasParallelConsultLeg) {\n if (!customerPresent) return DISABLED;\n if (state === TaskState.CONNECTED) {\n return maxParticipants ? VISIBLE_DISABLED : VISIBLE_ENABLED;\n }\n if (state === TaskState.HELD) return VISIBLE_DISABLED;\n\n return DISABLED;\n }\n if (!hasFullControls || !isConsulting) return DISABLED;\n if (!consultInitiator) return DISABLED;\n if (!customerPresent) return VISIBLE_DISABLED;\n if (consultLegOnHold) return VISIBLE_DISABLED;\n\n return isConsultDestinationReady && !maxParticipants ? VISIBLE_ENABLED : VISIBLE_DISABLED;\n })(),\n\n // Wrapup: wrapping up state\n wrapup: isWrappingUp ? VISIBLE_ENABLED : DISABLED,\n\n // ExitConference: in conference with multiple agents in main call\n exitConference: (() => {\n if (hideExitConferenceWhileConsultPending) return DISABLED;\n if (hideExitConferenceOnMainLegForEpDnConsultFromConference) return DISABLED;\n if (allowHeldMainLegControlsForNonInitiator) return VISIBLE_ENABLED;\n if (showMainLegConferenceControlsDuringConsult) return VISIBLE_DISABLED;\n if (hideExitConferenceDuringActiveConsultFromConference) return DISABLED;\n if (forceHeldPostConsultControls) return VISIBLE_DISABLED;\n if (isConsulted && !isConferencing) return DISABLED;\n if (!inConference) return DISABLED;\n if (isEpDnPendingConferenceMergeUi) return VISIBLE_ENABLED;\n if (participantCount <= 1) return DISABLED;\n if (effectiveConsultInProgress) return VISIBLE_DISABLED;\n const consultingFromConference = consultInitiator && isConsulting && conferenceFromBackend;\n\n return consultingFromConference ? VISIBLE_DISABLED : VISIBLE_ENABLED;\n })(),\n\n // TransferConference: in conference with active consult, owner consulting from conference\n transferConference: (() => {\n if (isConferenceConsultTransferContext && !isCurrentLegActive) return VISIBLE_DISABLED;\n const consultLegTransferAvailable =\n currentLeg === 'consult' && inConference && selfActiveConsultInitiator && hasConsultMedia;\n const selfConsultingOnParticipantState = selfParticipant?.consultState === 'consulting';\n const conferenceTransferAvailable =\n consultLegTransferAvailable ||\n (inConference &&\n selfActiveConsultInitiator &&\n hasConsultMedia &&\n (isConsulting || effectiveConsultInProgress || selfConsultingOnParticipantState));\n if (consultLegOnHold) return DISABLED;\n if (hasParallelConsultLeg && !conferenceTransferAvailable) return DISABLED;\n if (!conferenceTransferAvailable && (!inConference || !isConsulting)) return DISABLED;\n if (!selfActiveConsultInitiator || isConsulted) return DISABLED;\n\n return isConsultDestinationReady ? VISIBLE_ENABLED : VISIBLE_DISABLED;\n })(),\n\n // MergeToConference: mirrors conference control, enabled on both legs\n mergeToConference: (() => {\n if (isHydratedConferenceConsultPending && currentLeg === 'consult') return VISIBLE_DISABLED;\n if (!isConsulting || !consultInitiator) return DISABLED;\n if (!customerPresent) return VISIBLE_DISABLED;\n if (consultLegOnHold) return VISIBLE_DISABLED;\n\n return isConsultDestinationReady && !maxParticipants ? VISIBLE_ENABLED : VISIBLE_DISABLED;\n })(),\n\n // Switch: visible only on the currently active leg\n switch: (() => {\n if (isHydratedConferenceConsultPending && currentLeg === 'consult') return VISIBLE_DISABLED;\n if (!customerPresent && hasParallelConsultLeg) return DISABLED;\n if (currentLeg === 'consult') {\n if (!isConsulting || !consultInitiator || consultCallHeld) return DISABLED;\n if (!customerPresent) return VISIBLE_DISABLED;\n\n return isConsultDestinationReady ? VISIBLE_ENABLED : VISIBLE_DISABLED;\n }\n\n if (hasParallelConsultLeg && state === TaskState.CONNECTED) {\n return isConsultDestinationReady ? VISIBLE_ENABLED : VISIBLE_DISABLED;\n }\n\n return DISABLED;\n })(),\n };\n}\n\nfunction computeDigitalInteractionUIControls(\n state: TaskState,\n context: TaskContext,\n fallbackTaskData?: TaskData\n): InteractionUIControls {\n const taskData = context.taskData ?? fallbackTaskData ?? null;\n const isTerminated = taskData?.interaction?.isTerminated ?? false;\n\n const isConnected = state === TaskState.CONNECTED;\n const isWrappingUp = state === TaskState.WRAPPING_UP;\n\n return {\n accept: state === TaskState.OFFERED ? VISIBLE_ENABLED : DISABLED,\n decline: DISABLED,\n hold: DISABLED,\n mute: DISABLED,\n end: isConnected && !isWrappingUp ? VISIBLE_ENABLED : DISABLED,\n transfer: isConnected && !isWrappingUp ? VISIBLE_ENABLED : DISABLED,\n consult: DISABLED,\n consultTransfer: DISABLED,\n endConsult: DISABLED,\n recording: DISABLED,\n conference: DISABLED,\n wrapup: isTerminated || isWrappingUp ? VISIBLE_ENABLED : DISABLED,\n exitConference: DISABLED,\n transferConference: DISABLED,\n mergeToConference: DISABLED,\n switch: DISABLED,\n };\n}\n\nfunction getVoiceLegState(\n currentState: TaskState,\n context: TaskContext,\n config: UIControlConfig,\n fallbackTaskData?: TaskData\n): {hasConsultLeg: boolean; activeLeg: TaskUILeg; mainState: TaskState; consultState: TaskState} {\n if (currentState === TaskState.WRAPPING_UP) {\n return {\n hasConsultLeg: false,\n activeLeg: 'main',\n mainState: currentState,\n consultState: TaskState.CONSULTING,\n };\n }\n\n const taskData = fallbackTaskData ?? context.taskData ?? null;\n const interaction = taskData?.interaction;\n const mainCallId = interaction?.mainInteractionId || taskData?.interactionId;\n const selfAgentId = config.agentId ?? taskData?.agentId;\n\n if (context.hideBlindTransferForEpDnPendingMerge && taskData) {\n const conferenceFromBackend = getIsConferenceInProgress(taskData);\n const participantCount =\n interaction && mainCallId ? getConferenceParticipantsCount(interaction, mainCallId) : 0;\n\n if (\n participantCount <= 1 &&\n (currentState === TaskState.CONFERENCING || conferenceFromBackend)\n ) {\n return {\n hasConsultLeg: false,\n activeLeg: 'main',\n mainState: TaskState.CONFERENCING,\n consultState: TaskState.CONSULTING,\n };\n }\n }\n\n const selfParticipant = selfAgentId ? interaction?.participants?.[selfAgentId] : null;\n const hasConsultMedia = hasConsultMediaInInteraction(\n interaction,\n taskData?.consultMediaResourceId\n );\n const isSecondaryConsultRejectedWhileEpDnActive =\n taskData?.type === 'AgentConsultFailed' && context.hideBlindTransferForEpDnPendingMerge;\n const isSelfConsultCompleted =\n selfParticipant?.consultState === 'consultCompleted' && taskData?.isConsulted === false;\n const isConsultEndedForSelf =\n taskData?.type === 'AgentConsultEnded' ||\n (taskData?.type === 'AgentConsultFailed' && !isSecondaryConsultRejectedWhileEpDnActive) ||\n isSelfConsultCompleted;\n const consultInProgress = getIsConsultInProgressForConferenceControls(\n interaction,\n mainCallId,\n selfAgentId\n );\n const isConsultingState =\n currentState === TaskState.CONSULTING ||\n currentState === TaskState.CONSULT_INITIATING ||\n currentState === TaskState.CONF_INITIATING;\n const consultMedia = Object.values(interaction?.media ?? {}).find(\n (media: any) =>\n media?.mediaResourceId === taskData?.consultMediaResourceId || media?.mType === 'consult'\n ) as {participants?: string[]} | undefined;\n const selfInConsultCall =\n Boolean(selfAgentId) && Boolean(consultMedia?.participants?.includes(selfAgentId as string));\n const selfActiveConsultInitiator = isSelfActiveConsultInitiator(\n context.consultInitiator,\n selfAgentId,\n selfParticipant,\n selfInConsultCall,\n taskData?.consultingAgentId\n );\n const consultOwnedBySelf =\n !context.hideBlindTransferForEpDnPendingMerge && selfActiveConsultInitiator;\n const selfConsultPendingOnConsultMedia =\n selfParticipant?.consultState === 'consultInitiated' &&\n !taskData?.isConsulted &&\n hasConsultMedia;\n const selfConsultingOnConsultMedia =\n selfParticipant?.consultState === 'consulting' && hasConsultMedia;\n const isConsultUnansweredFailure =\n isSelfConsultCompleted &&\n Boolean(mainCallId && taskData?.interaction?.media?.[mainCallId]?.isHold === true) &&\n taskData?.interaction?.state !== 'conference' &&\n !getIsConferenceInProgress(taskData);\n const hasConsultLeg = Boolean(\n !isConsultEndedForSelf &&\n !interaction?.isTerminated &&\n !isConsultUnansweredFailure &&\n (consultOwnedBySelf || selfConsultingOnConsultMedia || selfConsultPendingOnConsultMedia) &&\n (consultInProgress || isConsultingState || context.consultCallHeld || hasConsultMedia)\n );\n\n if (!hasConsultLeg) {\n let mainState = currentState;\n if (isConsultEndedForSelf && taskData?.interaction) {\n const resolvedMainId = taskData.interaction.mainInteractionId || taskData.interactionId;\n const isMainHeld = Boolean(\n resolvedMainId && taskData.interaction.media?.[resolvedMainId]?.isHold === true\n );\n\n if (taskData.interaction.state === 'conference' || getIsConferenceInProgress(taskData)) {\n mainState = TaskState.CONFERENCING;\n } else if (isMainHeld || taskData.interaction.state === 'hold') {\n mainState = TaskState.HELD;\n } else {\n mainState = TaskState.CONNECTED;\n }\n }\n\n return {\n hasConsultLeg: false,\n activeLeg: 'main',\n mainState,\n consultState: TaskState.CONSULTING,\n };\n }\n\n let mainState = TaskState.HELD;\n if (currentState === TaskState.CONFERENCING) {\n mainState = TaskState.CONFERENCING;\n } else if (context.consultCallHeld) {\n const mainMediaId = taskData?.interaction?.mainInteractionId || taskData?.interactionId;\n const isMainHeld = Boolean(\n mainMediaId && taskData?.interaction?.media?.[mainMediaId]?.isHold === true\n );\n mainState =\n isMainHeld || taskData?.interaction?.state === 'hold' ? TaskState.HELD : TaskState.CONNECTED;\n } else if (currentState === TaskState.CONNECTED || currentState === TaskState.HELD) {\n mainState = currentState;\n }\n\n return {\n hasConsultLeg: true,\n activeLeg: context.consultCallHeld ? 'main' : 'consult',\n mainState,\n consultState: isConsultingState ? currentState : TaskState.CONSULTING,\n };\n}\n\nexport function computeUIControls(\n currentState: TaskState,\n context: TaskContext,\n fallbackTaskData?: TaskData\n): TaskUIControls {\n if (currentState === TaskState.TERMINATED || currentState === TaskState.COMPLETED) {\n return getDefaultUIControls();\n }\n\n switch (context.uiControlConfig.channelType) {\n case TASK_CHANNEL_TYPE.VOICE: {\n const {hasConsultLeg, activeLeg, mainState, consultState} = getVoiceLegState(\n currentState,\n context,\n context.uiControlConfig,\n fallbackTaskData\n );\n\n const mainControls = computeVoiceInteractionUIControls(\n mainState,\n context,\n context.uiControlConfig,\n fallbackTaskData,\n 'main'\n );\n const consultControls = hasConsultLeg\n ? computeVoiceInteractionUIControls(\n consultState,\n context,\n context.uiControlConfig,\n fallbackTaskData,\n 'consult'\n )\n : getDefaultInteractionUIControls();\n\n return createTaskUIControls(mainControls, consultControls, activeLeg);\n }\n case TASK_CHANNEL_TYPE.DIGITAL:\n return createTaskUIControls(\n computeDigitalInteractionUIControls(currentState, context, fallbackTaskData),\n getDefaultInteractionUIControls(),\n 'main'\n );\n default:\n return getDefaultUIControls();\n }\n}\n\nfunction haveInteractionUIControlsChanged(\n previous: InteractionUIControls,\n next: InteractionUIControls\n): boolean {\n return (Object.keys(next) as (keyof InteractionUIControls)[]).some((key) => {\n const prev = previous[key];\n const curr = next[key];\n\n return prev.isVisible !== curr.isVisible || prev.isEnabled !== curr.isEnabled;\n });\n}\n\nexport function haveUIControlsChanged(\n previous: TaskUIControls | undefined,\n next: TaskUIControls\n): boolean {\n if (!previous) return true;\n\n return (\n previous.activeLeg !== next.activeLeg ||\n haveInteractionUIControlsChanged(previous.main, next.main) ||\n haveInteractionUIControlsChanged(previous.consult, next.consult)\n );\n}\n"],"mappings":"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","ignoreList":[]}