@webex/contact-center 3.12.0-task-refactor.4 → 3.12.0-task-refactor.6

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 (35) hide show
  1. package/dist/services/task/TaskManager.js +1 -0
  2. package/dist/services/task/TaskManager.js.map +1 -1
  3. package/dist/services/task/TaskUtils.js +8 -6
  4. package/dist/services/task/TaskUtils.js.map +1 -1
  5. package/dist/services/task/state-machine/TaskStateMachine.js +77 -14
  6. package/dist/services/task/state-machine/TaskStateMachine.js.map +1 -1
  7. package/dist/services/task/state-machine/actions.js +85 -13
  8. package/dist/services/task/state-machine/actions.js.map +1 -1
  9. package/dist/services/task/state-machine/guards.js +35 -0
  10. package/dist/services/task/state-machine/guards.js.map +1 -1
  11. package/dist/services/task/state-machine/uiControlsComputer.js +76 -10
  12. package/dist/services/task/state-machine/uiControlsComputer.js.map +1 -1
  13. package/dist/services/task/voice/Voice.js +10 -4
  14. package/dist/services/task/voice/Voice.js.map +1 -1
  15. package/dist/types/services/task/state-machine/TaskStateMachine.d.ts +68 -8
  16. package/dist/types/services/task/state-machine/guards.d.ts +5 -0
  17. package/dist/types/services/task/voice/Voice.d.ts +18 -17
  18. package/dist/webex.js +1 -1
  19. package/package.json +1 -1
  20. package/src/services/task/TaskManager.ts +1 -1
  21. package/src/services/task/TaskUtils.ts +8 -6
  22. package/src/services/task/state-machine/TaskStateMachine.ts +101 -16
  23. package/src/services/task/state-machine/actions.ts +148 -24
  24. package/src/services/task/state-machine/guards.ts +46 -0
  25. package/src/services/task/state-machine/uiControlsComputer.ts +158 -15
  26. package/src/services/task/voice/Voice.ts +12 -5
  27. package/test/unit/spec/services/WebCallingService.ts +7 -1
  28. package/test/unit/spec/services/task/TaskManager.ts +26 -0
  29. package/test/unit/spec/services/task/TaskUtils.ts +16 -0
  30. package/test/unit/spec/services/task/state-machine/TaskStateMachine.ts +573 -0
  31. package/test/unit/spec/services/task/state-machine/guards.ts +88 -0
  32. package/test/unit/spec/services/task/state-machine/uiControlsComputer.ts +1023 -46
  33. package/test/unit/spec/services/task/voice/Voice.ts +44 -0
  34. package/umd/contact-center.min.js +2 -2
  35. package/umd/contact-center.min.js.map +1 -1
@@ -98,6 +98,17 @@ const guards = exports.guards = {
98
98
  const taskData = getTaskDataFromEvent(event);
99
99
  if (taskData?.interaction?.state === _constants.INTERACTION_STATE.CONSULTING) return true;
100
100
 
101
+ // Hydrate can report interaction as conference/hold while this agent is actively consulting.
102
+ // Detect consult by participant consultState + consult media, independent of top-level state.
103
+ const selfAgentId = getSelfAgentId(context, taskData);
104
+ const selfParticipant = selfAgentId ? taskData?.interaction?.participants?.[selfAgentId] : null;
105
+ const hasConsultMedia = Object.values(taskData?.interaction?.media ?? {}).some(media => media?.mType === _constants.MEDIA_TYPE_CONSULT);
106
+ const selfActiveConsult = selfParticipant?.consultState === _constants.CONSULT_STATE.CONSULTING;
107
+ const selfPendingConsultInitiated = selfParticipant?.consultState === 'consultInitiated' && taskData?.isConsulted === false;
108
+ if ((selfActiveConsult || selfPendingConsultInitiated) && hasConsultMedia) {
109
+ return true;
110
+ }
111
+
101
112
  // EP_DN consulted agent: backend reports state as 'connected' but CPD indicates consult
102
113
  const cpd = taskData?.interaction?.callProcessingDetails;
103
114
  if (cpd?.relationshipType === 'consult' && taskData?.interaction?.state === _constants.INTERACTION_STATE.CONNECTED) {
@@ -109,6 +120,17 @@ const guards = exports.guards = {
109
120
  if (hasActiveConsultInPostCall(taskData, getSelfAgentId(context, taskData))) {
110
121
  return true;
111
122
  }
123
+
124
+ // Customer left during consult: interaction state is "post_call" but consult
125
+ // between agents is still active. Detect via agent's consultState + consult media.
126
+ if (taskData?.interaction?.state === _constants.INTERACTION_STATE.POST_CALL) {
127
+ const postCallSelfAgentId = getSelfAgentId(context, taskData);
128
+ const postCallSelfParticipant = postCallSelfAgentId ? taskData?.interaction?.participants?.[postCallSelfAgentId] : null;
129
+ const hasPostCallConsultMedia = Object.values(taskData?.interaction?.media ?? {}).some(media => media?.mType === _constants.MEDIA_TYPE_CONSULT);
130
+ if (postCallSelfParticipant?.consultState === _constants.CONSULT_STATE.CONSULTING && hasPostCallConsultMedia) {
131
+ return true;
132
+ }
133
+ }
112
134
  return false;
113
135
  },
114
136
  isInteractionHeld: ({
@@ -154,6 +176,19 @@ const guards = exports.guards = {
154
176
  if (!taskData?.interaction) return false;
155
177
  return (0, _TaskUtils.getIsConferenceInProgress)(taskData);
156
178
  },
179
+ /**
180
+ * Conference hold signal for conference-downgraded consult-end transitions.
181
+ * Backend can report this as boolean or string.
182
+ */
183
+ isConferenceHoldParticipantFromEvent: ({
184
+ context,
185
+ event
186
+ }) => {
187
+ const taskData = getTaskDataFromEvent(event) ?? context.taskData;
188
+ const callProcessingDetails = taskData?.interaction?.callProcessingDetails;
189
+ const conferenceHoldParticipant = callProcessingDetails?.conferenceHoldParticipant;
190
+ return conferenceHoldParticipant === true || conferenceHoldParticipant === 'true';
191
+ },
157
192
  /**
158
193
  * Conference downgrade check specifically for transitioning back to CONNECTED.
159
194
  *
@@ -1 +1 @@
1
- {"version":3,"names":["_TaskUtils","require","_constants","getTaskDataFromEvent","event","taskData","undefined","exports","getSelfAgentId","context","uiControlConfig","agentId","isSelfConsultingAgent","selfAgentId","consultingAgentId","hasActiveConsultInPostCall","interaction","state","INTERACTION_STATE","POST_CALL","selfParticipant","participants","hasConsultMedia","Object","values","media","some","mType","MEDIA_TYPE_CONSULT","consultState","CONSULT_STATE","CONSULTING","shouldWrapUpForThisAgent","pending","agentsPendingWrapUp","Array","isArray","length","includes","participantWrapUp","isWrapUp","wrapUpRequired","owner","isConsulted","guards","isInteractionTerminated","isTerminated","isInteractionConsulting","cpd","callProcessingDetails","relationshipType","CONNECTED","isInteractionHeld","mainMediaId","mainInteractionId","interactionId","isHold","isInteractionConnected","isConferencingByParticipants","mainCallId","agentCount","pId","p","pType","hasLeft","conferenceInProgressFromEvent","getIsConferenceInProgress","shouldDowngradeConferenceToConnected","eventTaskData","CONFERENCE","agentParticipantsCount","getConferenceParticipantsCount","customerInCall","getIsCustomerInCall","selfInMainCall","Boolean","didInitiateConsult","consultInitiator","isConsultingAssignment","shouldWrapUp","type","TaskEvent","CONFERENCE_END","shouldWrapUpOrIsInitiator","didCurrentAgentLeaveConference","participantIdFromEvent","participantId","isPrimaryMediaOnHold","mediaId","mediaResourceId"],"sources":["guards.ts"],"sourcesContent":["/**\n * Task State Machine Guards\n *\n * Guard functions that determine if a state transition is allowed.\n * These functions validate the current context before allowing transitions.\n *\n * All guards are consolidated here for:\n * - Single source of truth\n * - Easy testing\n * - Reusability across state machine transitions\n *\n * Guards are organized by category:\n * 1. Helper Functions - Extract data from events/context\n * 2. Hydrate Guards - For state restoration on page refresh\n * 3. Conference Guards - Conference state checks\n * 4. Customer Guards - Customer presence checks\n * 5. Consult Guards - Consult flow checks\n * 6. Wrapup Guards - End-of-call flow checks\n * 7. Server State Guards - Check backend-reported state\n * 8. Recording Guards - Recording state checks\n */\n\nimport {TaskContext, TaskEventPayload} from './types';\nimport {TaskData} from '../types';\nimport {\n getIsCustomerInCall,\n getConferenceParticipantsCount,\n getIsConferenceInProgress,\n} from '../TaskUtils';\nimport {TaskEvent, INTERACTION_STATE, CONSULT_STATE, MEDIA_TYPE_CONSULT} from './constants';\n\nexport const getTaskDataFromEvent = (event?: TaskEventPayload): TaskData | undefined =>\n event && typeof event === 'object' && 'taskData' in event\n ? (event as {taskData?: TaskData}).taskData\n : undefined;\n\nexport const getSelfAgentId = (context: TaskContext, taskData?: TaskData): string | undefined =>\n context.uiControlConfig?.agentId ?? context.taskData?.agentId ?? taskData?.agentId;\n\nexport const isSelfConsultingAgent = (context: TaskContext, taskData?: TaskData): boolean => {\n const selfAgentId = getSelfAgentId(context, taskData);\n if (!selfAgentId) return false;\n\n return taskData?.consultingAgentId === selfAgentId;\n};\n\n/**\n * Detects an active consult during post_call state (customer left but agents still consulting).\n * Shared by hydration guard (isInteractionConsulting) and action (deriveTaskDataUpdates).\n */\nexport const hasActiveConsultInPostCall = (\n taskData: TaskData | undefined,\n selfAgentId?: string\n): boolean => {\n if (taskData?.interaction?.state !== INTERACTION_STATE.POST_CALL || !selfAgentId) return false;\n\n const selfParticipant = taskData.interaction?.participants?.[selfAgentId];\n const hasConsultMedia = Object.values(taskData.interaction?.media ?? {}).some(\n (media) => (media as {mType?: string})?.mType === MEDIA_TYPE_CONSULT\n );\n\n return selfParticipant?.consultState === CONSULT_STATE.CONSULTING && hasConsultMedia;\n};\n\n/**\n * Determines if this agent should enter WRAPPING_UP state.\n * Priority: agentsPendingWrapUp > wrapUpRequired / participant.isWrapUp > ownership > !isConsulted\n */\nexport const shouldWrapUpForThisAgent = (context: TaskContext, taskData: TaskData): boolean => {\n const selfAgentId = getSelfAgentId(context, taskData);\n if (!selfAgentId) return false;\n\n const pending = taskData?.agentsPendingWrapUp;\n if (Array.isArray(pending) && pending.length > 0) {\n return pending.includes(selfAgentId);\n }\n\n const participantWrapUp = taskData?.interaction?.participants?.[selfAgentId]?.isWrapUp === true;\n const wrapUpRequired = taskData?.wrapUpRequired === true;\n if (wrapUpRequired || participantWrapUp) {\n return true;\n }\n\n const owner = taskData?.interaction?.owner;\n if (owner && owner === selfAgentId) {\n return true;\n }\n\n if (taskData?.isConsulted === false) {\n return true;\n }\n\n return false;\n};\n\nexport interface GuardParams {\n context: TaskContext;\n event?: TaskEventPayload;\n}\n\nexport type GuardFunction = (params: GuardParams) => boolean;\n\nexport const guards = {\n // Hydrate Guards\n isInteractionTerminated: ({context, event}: GuardParams): boolean => {\n const taskData = getTaskDataFromEvent(event);\n\n if (taskData?.interaction?.isTerminated === true) return true;\n\n const selfAgentId = getSelfAgentId(context, taskData);\n if (selfAgentId && taskData?.interaction?.participants?.[selfAgentId]?.isWrapUp === true) {\n return true;\n }\n\n return false;\n },\n\n isInteractionConsulting: ({event, context}: GuardParams): boolean => {\n const taskData = getTaskDataFromEvent(event);\n\n if (taskData?.interaction?.state === INTERACTION_STATE.CONSULTING) return true;\n\n // EP_DN consulted agent: backend reports state as 'connected' but CPD indicates consult\n const cpd = taskData?.interaction?.callProcessingDetails;\n if (\n cpd?.relationshipType === 'consult' &&\n taskData?.interaction?.state === INTERACTION_STATE.CONNECTED\n ) {\n return true;\n }\n\n // Customer left during consult: interaction state is \"post_call\" but consult\n // between agents is still active. Detect via agent's consultState + consult media.\n if (hasActiveConsultInPostCall(taskData, getSelfAgentId(context, taskData))) {\n return true;\n }\n\n return false;\n },\n\n isInteractionHeld: ({event}: GuardParams): boolean => {\n const taskData = getTaskDataFromEvent(event);\n\n if (taskData?.interaction?.state === 'hold') return true;\n\n const mainMediaId = taskData?.interaction?.mainInteractionId || taskData?.interactionId;\n if (mainMediaId && taskData?.interaction?.media?.[mainMediaId]?.isHold === true) {\n return true;\n }\n\n return false;\n },\n\n isInteractionConnected: ({event}: GuardParams): boolean => {\n const taskData = getTaskDataFromEvent(event);\n\n return taskData?.interaction?.state === INTERACTION_STATE.CONNECTED;\n },\n\n isConferencingByParticipants: ({event}: GuardParams): boolean => {\n const taskData = getTaskDataFromEvent(event);\n if (!taskData) return false;\n const mainCallId = taskData.interaction?.mainInteractionId || taskData.interactionId;\n const media = taskData.interaction?.media?.[mainCallId];\n const participants = taskData.interaction?.participants;\n if (!media?.participants || !participants) return false;\n let agentCount = 0;\n for (const pId of media.participants) {\n const p = participants[pId];\n if (p && p.pType !== 'Customer' && p.pType !== 'Supervisor' && !p.hasLeft) {\n agentCount += 1;\n }\n }\n\n return agentCount >= 2;\n },\n\n // Conference Guards\n conferenceInProgressFromEvent: ({event}: GuardParams): boolean => {\n const taskData = getTaskDataFromEvent(event);\n if (!taskData?.interaction) return false;\n\n return getIsConferenceInProgress(taskData);\n },\n\n /**\n * Conference downgrade check specifically for transitioning back to CONNECTED.\n *\n * Returns true only when:\n * - conference has downgraded (fewer than 2 active agent participants in main call)\n * - customer is still in the call\n * - current agent is still in the main call\n */\n shouldDowngradeConferenceToConnected: ({context, event}: GuardParams): boolean => {\n const eventTaskData = getTaskDataFromEvent(event);\n const taskData = eventTaskData ?? context.taskData;\n if (!taskData?.interaction) return false;\n\n const selfAgentId = getSelfAgentId(context, taskData);\n if (!selfAgentId) return false;\n\n const mainCallId = taskData.interaction.mainInteractionId || taskData.interactionId;\n if (!mainCallId) return false;\n\n // Don't downgrade while backend still reports conference.\n if (taskData.interaction.state === INTERACTION_STATE.CONFERENCE) return false;\n\n const agentParticipantsCount = getConferenceParticipantsCount(taskData.interaction, mainCallId);\n if (agentParticipantsCount >= 2) return false;\n\n const customerInCall = getIsCustomerInCall(taskData.interaction, mainCallId);\n if (!customerInCall) return false;\n\n const selfInMainCall = Boolean(\n taskData.interaction.media?.[mainCallId]?.participants?.includes(selfAgentId)\n );\n\n return selfInMainCall;\n },\n\n // Consult Guards\n /**\n * Check if this agent initiated the consult (using event data)\n * Handles both consultingAgentId and fallback to context flag\n */\n didInitiateConsult: ({context, event}: GuardParams): boolean => {\n const taskData = getTaskDataFromEvent(event);\n if (taskData?.isConsulted === true) return false;\n\n return taskData?.consultingAgentId\n ? isSelfConsultingAgent(context, taskData)\n : context.consultInitiator === true;\n },\n\n /**\n * EP-DN / consulted consult legs can arrive as AGENT_CONTACT_ASSIGNED without a preceding\n * AgentConsulting event. When that happens, we should enter CONSULTING (not CONNECTED).\n */\n isConsultingAssignment: ({event}: GuardParams): boolean => {\n const taskData = getTaskDataFromEvent(event);\n if (!taskData) return false;\n\n const relationshipType = taskData.interaction?.callProcessingDetails?.relationshipType;\n\n return (\n taskData.isConsulted === true ||\n relationshipType === 'consult' ||\n taskData.interaction?.state === INTERACTION_STATE.CONSULTING\n );\n },\n\n // Wrapup Guards\n shouldWrapUp: ({context, event}: GuardParams): boolean => {\n const taskData = getTaskDataFromEvent(event);\n if (!taskData) return false;\n\n if (event?.type === TaskEvent.CONFERENCE_END) {\n const selfAgentId = getSelfAgentId(context, taskData);\n if (!selfAgentId) return false;\n\n const pending = taskData?.agentsPendingWrapUp;\n if (Array.isArray(pending) && pending.length > 0) {\n return pending.includes(selfAgentId);\n }\n\n const participantWrapUp =\n taskData?.interaction?.participants?.[selfAgentId]?.isWrapUp === true;\n const wrapUpRequired = taskData?.wrapUpRequired === true;\n\n return wrapUpRequired || participantWrapUp;\n }\n\n return shouldWrapUpForThisAgent(context, taskData);\n },\n\n /**\n * Check if wrapUpRequired in payload OR is consult initiator\n */\n shouldWrapUpOrIsInitiator: ({context, event}: GuardParams): boolean => {\n const taskData = getTaskDataFromEvent(event);\n\n return Boolean(taskData?.wrapUpRequired || context.consultInitiator);\n },\n\n /**\n * True if PARTICIPANT_LEAVE indicates that *this* agent left the conference.\n *\n * Important: PARTICIPANT_LEAVE is broadcast to all agents in the conference.\n * Only the agent whose id matches the leaving participant should transition to\n * TERMINATED / WRAPPING_UP based on wrapup rules.\n */\n didCurrentAgentLeaveConference: ({context, event}: GuardParams): boolean => {\n const taskData = getTaskDataFromEvent(event);\n const selfAgentId = getSelfAgentId(context, taskData);\n if (!selfAgentId) return false;\n\n const participantIdFromEvent =\n event && typeof event === 'object' && 'participantId' in event\n ? (event as {participantId?: string}).participantId\n : undefined;\n const participantId = participantIdFromEvent ?? taskData?.participantId;\n\n if (Boolean(participantId) && participantId === selfAgentId) {\n return true;\n }\n\n // For EP-DN agents the backend removes the leaving participant entirely\n // from the participants map (rather than setting hasLeft). If this task\n // is in CONFERENCING (implied by the guard being evaluated here) but the\n // agent is absent from the updated participants, they have left.\n const participants = taskData?.interaction?.participants;\n if (participants && !(selfAgentId in participants)) {\n return true;\n }\n\n return false;\n },\n\n // Server State Guards\n isPrimaryMediaOnHold: ({event}: GuardParams): boolean => {\n const taskData = getTaskDataFromEvent(event);\n if (!taskData) return false;\n const mediaId = taskData.mediaResourceId;\n if (!mediaId) return false;\n\n return taskData.interaction?.media?.[mediaId]?.isHold === true;\n },\n};\n\nexport type GuardName = keyof typeof guards;\n"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"names":["_TaskUtils","require","_constants","getTaskDataFromEvent","event","taskData","undefined","exports","getSelfAgentId","context","uiControlConfig","agentId","isSelfConsultingAgent","selfAgentId","consultingAgentId","hasActiveConsultInPostCall","interaction","state","INTERACTION_STATE","POST_CALL","selfParticipant","participants","hasConsultMedia","Object","values","media","some","mType","MEDIA_TYPE_CONSULT","consultState","CONSULT_STATE","CONSULTING","shouldWrapUpForThisAgent","pending","agentsPendingWrapUp","Array","isArray","length","includes","participantWrapUp","isWrapUp","wrapUpRequired","owner","isConsulted","guards","isInteractionTerminated","isTerminated","isInteractionConsulting","selfActiveConsult","selfPendingConsultInitiated","cpd","callProcessingDetails","relationshipType","CONNECTED","postCallSelfAgentId","postCallSelfParticipant","hasPostCallConsultMedia","isInteractionHeld","mainMediaId","mainInteractionId","interactionId","isHold","isInteractionConnected","isConferencingByParticipants","mainCallId","agentCount","pId","p","pType","hasLeft","conferenceInProgressFromEvent","getIsConferenceInProgress","isConferenceHoldParticipantFromEvent","conferenceHoldParticipant","shouldDowngradeConferenceToConnected","eventTaskData","CONFERENCE","agentParticipantsCount","getConferenceParticipantsCount","customerInCall","getIsCustomerInCall","selfInMainCall","Boolean","didInitiateConsult","consultInitiator","isConsultingAssignment","shouldWrapUp","type","TaskEvent","CONFERENCE_END","shouldWrapUpOrIsInitiator","didCurrentAgentLeaveConference","participantIdFromEvent","participantId","isPrimaryMediaOnHold","mediaId","mediaResourceId"],"sources":["guards.ts"],"sourcesContent":["/**\n * Task State Machine Guards\n *\n * Guard functions that determine if a state transition is allowed.\n * These functions validate the current context before allowing transitions.\n *\n * All guards are consolidated here for:\n * - Single source of truth\n * - Easy testing\n * - Reusability across state machine transitions\n *\n * Guards are organized by category:\n * 1. Helper Functions - Extract data from events/context\n * 2. Hydrate Guards - For state restoration on page refresh\n * 3. Conference Guards - Conference state checks\n * 4. Customer Guards - Customer presence checks\n * 5. Consult Guards - Consult flow checks\n * 6. Wrapup Guards - End-of-call flow checks\n * 7. Server State Guards - Check backend-reported state\n * 8. Recording Guards - Recording state checks\n */\n\nimport {TaskContext, TaskEventPayload} from './types';\nimport {TaskData} from '../types';\nimport {\n getIsCustomerInCall,\n getConferenceParticipantsCount,\n getIsConferenceInProgress,\n} from '../TaskUtils';\nimport {TaskEvent, INTERACTION_STATE, CONSULT_STATE, MEDIA_TYPE_CONSULT} from './constants';\n\nexport const getTaskDataFromEvent = (event?: TaskEventPayload): TaskData | undefined =>\n event && typeof event === 'object' && 'taskData' in event\n ? (event as {taskData?: TaskData}).taskData\n : undefined;\n\nexport const getSelfAgentId = (context: TaskContext, taskData?: TaskData): string | undefined =>\n context.uiControlConfig?.agentId ?? context.taskData?.agentId ?? taskData?.agentId;\n\nexport const isSelfConsultingAgent = (context: TaskContext, taskData?: TaskData): boolean => {\n const selfAgentId = getSelfAgentId(context, taskData);\n if (!selfAgentId) return false;\n\n return taskData?.consultingAgentId === selfAgentId;\n};\n\n/**\n * Detects an active consult during post_call state (customer left but agents still consulting).\n * Shared by hydration guard (isInteractionConsulting) and action (deriveTaskDataUpdates).\n */\nexport const hasActiveConsultInPostCall = (\n taskData: TaskData | undefined,\n selfAgentId?: string\n): boolean => {\n if (taskData?.interaction?.state !== INTERACTION_STATE.POST_CALL || !selfAgentId) return false;\n\n const selfParticipant = taskData.interaction?.participants?.[selfAgentId];\n const hasConsultMedia = Object.values(taskData.interaction?.media ?? {}).some(\n (media) => (media as {mType?: string})?.mType === MEDIA_TYPE_CONSULT\n );\n\n return selfParticipant?.consultState === CONSULT_STATE.CONSULTING && hasConsultMedia;\n};\n\n/**\n * Determines if this agent should enter WRAPPING_UP state.\n * Priority: agentsPendingWrapUp > wrapUpRequired / participant.isWrapUp > ownership > !isConsulted\n */\nexport const shouldWrapUpForThisAgent = (context: TaskContext, taskData: TaskData): boolean => {\n const selfAgentId = getSelfAgentId(context, taskData);\n if (!selfAgentId) return false;\n\n const pending = taskData?.agentsPendingWrapUp;\n if (Array.isArray(pending) && pending.length > 0) {\n return pending.includes(selfAgentId);\n }\n\n const participantWrapUp = taskData?.interaction?.participants?.[selfAgentId]?.isWrapUp === true;\n const wrapUpRequired = taskData?.wrapUpRequired === true;\n if (wrapUpRequired || participantWrapUp) {\n return true;\n }\n\n const owner = taskData?.interaction?.owner;\n if (owner && owner === selfAgentId) {\n return true;\n }\n\n if (taskData?.isConsulted === false) {\n return true;\n }\n\n return false;\n};\n\nexport interface GuardParams {\n context: TaskContext;\n event?: TaskEventPayload;\n}\n\nexport type GuardFunction = (params: GuardParams) => boolean;\n\nexport const guards = {\n // Hydrate Guards\n isInteractionTerminated: ({context, event}: GuardParams): boolean => {\n const taskData = getTaskDataFromEvent(event);\n\n if (taskData?.interaction?.isTerminated === true) return true;\n\n const selfAgentId = getSelfAgentId(context, taskData);\n if (selfAgentId && taskData?.interaction?.participants?.[selfAgentId]?.isWrapUp === true) {\n return true;\n }\n\n return false;\n },\n\n isInteractionConsulting: ({event, context}: GuardParams): boolean => {\n const taskData = getTaskDataFromEvent(event);\n\n if (taskData?.interaction?.state === INTERACTION_STATE.CONSULTING) return true;\n\n // Hydrate can report interaction as conference/hold while this agent is actively consulting.\n // Detect consult by participant consultState + consult media, independent of top-level state.\n const selfAgentId = getSelfAgentId(context, taskData);\n const selfParticipant = selfAgentId ? taskData?.interaction?.participants?.[selfAgentId] : null;\n const hasConsultMedia = Object.values(taskData?.interaction?.media ?? {}).some(\n (media: any) => media?.mType === MEDIA_TYPE_CONSULT\n );\n const selfActiveConsult = selfParticipant?.consultState === CONSULT_STATE.CONSULTING;\n const selfPendingConsultInitiated =\n selfParticipant?.consultState === 'consultInitiated' && taskData?.isConsulted === false;\n if ((selfActiveConsult || selfPendingConsultInitiated) && hasConsultMedia) {\n return true;\n }\n\n // EP_DN consulted agent: backend reports state as 'connected' but CPD indicates consult\n const cpd = taskData?.interaction?.callProcessingDetails;\n if (\n cpd?.relationshipType === 'consult' &&\n taskData?.interaction?.state === INTERACTION_STATE.CONNECTED\n ) {\n return true;\n }\n\n // Customer left during consult: interaction state is \"post_call\" but consult\n // between agents is still active. Detect via agent's consultState + consult media.\n if (hasActiveConsultInPostCall(taskData, getSelfAgentId(context, taskData))) {\n return true;\n }\n\n // Customer left during consult: interaction state is \"post_call\" but consult\n // between agents is still active. Detect via agent's consultState + consult media.\n if (taskData?.interaction?.state === INTERACTION_STATE.POST_CALL) {\n const postCallSelfAgentId = getSelfAgentId(context, taskData);\n const postCallSelfParticipant = postCallSelfAgentId\n ? taskData?.interaction?.participants?.[postCallSelfAgentId]\n : null;\n const hasPostCallConsultMedia = Object.values(taskData?.interaction?.media ?? {}).some(\n (media: any) => media?.mType === MEDIA_TYPE_CONSULT\n );\n if (\n postCallSelfParticipant?.consultState === CONSULT_STATE.CONSULTING &&\n hasPostCallConsultMedia\n ) {\n return true;\n }\n }\n\n return false;\n },\n\n isInteractionHeld: ({event}: GuardParams): boolean => {\n const taskData = getTaskDataFromEvent(event);\n\n if (taskData?.interaction?.state === 'hold') return true;\n\n const mainMediaId = taskData?.interaction?.mainInteractionId || taskData?.interactionId;\n if (mainMediaId && taskData?.interaction?.media?.[mainMediaId]?.isHold === true) {\n return true;\n }\n\n return false;\n },\n\n isInteractionConnected: ({event}: GuardParams): boolean => {\n const taskData = getTaskDataFromEvent(event);\n\n return taskData?.interaction?.state === INTERACTION_STATE.CONNECTED;\n },\n\n isConferencingByParticipants: ({event}: GuardParams): boolean => {\n const taskData = getTaskDataFromEvent(event);\n if (!taskData) return false;\n const mainCallId = taskData.interaction?.mainInteractionId || taskData.interactionId;\n const media = taskData.interaction?.media?.[mainCallId];\n const participants = taskData.interaction?.participants;\n if (!media?.participants || !participants) return false;\n let agentCount = 0;\n for (const pId of media.participants) {\n const p = participants[pId];\n if (p && p.pType !== 'Customer' && p.pType !== 'Supervisor' && !p.hasLeft) {\n agentCount += 1;\n }\n }\n\n return agentCount >= 2;\n },\n\n // Conference Guards\n conferenceInProgressFromEvent: ({event}: GuardParams): boolean => {\n const taskData = getTaskDataFromEvent(event);\n if (!taskData?.interaction) return false;\n\n return getIsConferenceInProgress(taskData);\n },\n\n /**\n * Conference hold signal for conference-downgraded consult-end transitions.\n * Backend can report this as boolean or string.\n */\n isConferenceHoldParticipantFromEvent: ({context, event}: GuardParams): boolean => {\n const taskData = getTaskDataFromEvent(event) ?? context.taskData;\n const callProcessingDetails = taskData?.interaction?.callProcessingDetails as\n | {conferenceHoldParticipant?: boolean | string}\n | undefined;\n const conferenceHoldParticipant = callProcessingDetails?.conferenceHoldParticipant;\n\n return conferenceHoldParticipant === true || conferenceHoldParticipant === 'true';\n },\n\n /**\n * Conference downgrade check specifically for transitioning back to CONNECTED.\n *\n * Returns true only when:\n * - conference has downgraded (fewer than 2 active agent participants in main call)\n * - customer is still in the call\n * - current agent is still in the main call\n */\n shouldDowngradeConferenceToConnected: ({context, event}: GuardParams): boolean => {\n const eventTaskData = getTaskDataFromEvent(event);\n const taskData = eventTaskData ?? context.taskData;\n if (!taskData?.interaction) return false;\n\n const selfAgentId = getSelfAgentId(context, taskData);\n if (!selfAgentId) return false;\n\n const mainCallId = taskData.interaction.mainInteractionId || taskData.interactionId;\n if (!mainCallId) return false;\n\n // Don't downgrade while backend still reports conference.\n if (taskData.interaction.state === INTERACTION_STATE.CONFERENCE) return false;\n\n const agentParticipantsCount = getConferenceParticipantsCount(taskData.interaction, mainCallId);\n if (agentParticipantsCount >= 2) return false;\n\n const customerInCall = getIsCustomerInCall(taskData.interaction, mainCallId);\n if (!customerInCall) return false;\n\n const selfInMainCall = Boolean(\n taskData.interaction.media?.[mainCallId]?.participants?.includes(selfAgentId)\n );\n\n return selfInMainCall;\n },\n\n // Consult Guards\n /**\n * Check if this agent initiated the consult (using event data)\n * Handles both consultingAgentId and fallback to context flag\n */\n didInitiateConsult: ({context, event}: GuardParams): boolean => {\n const taskData = getTaskDataFromEvent(event);\n if (taskData?.isConsulted === true) return false;\n\n return taskData?.consultingAgentId\n ? isSelfConsultingAgent(context, taskData)\n : context.consultInitiator === true;\n },\n\n /**\n * EP-DN / consulted consult legs can arrive as AGENT_CONTACT_ASSIGNED without a preceding\n * AgentConsulting event. When that happens, we should enter CONSULTING (not CONNECTED).\n */\n isConsultingAssignment: ({event}: GuardParams): boolean => {\n const taskData = getTaskDataFromEvent(event);\n if (!taskData) return false;\n\n const relationshipType = taskData.interaction?.callProcessingDetails?.relationshipType;\n\n return (\n taskData.isConsulted === true ||\n relationshipType === 'consult' ||\n taskData.interaction?.state === INTERACTION_STATE.CONSULTING\n );\n },\n\n // Wrapup Guards\n shouldWrapUp: ({context, event}: GuardParams): boolean => {\n const taskData = getTaskDataFromEvent(event);\n if (!taskData) return false;\n\n if (event?.type === TaskEvent.CONFERENCE_END) {\n const selfAgentId = getSelfAgentId(context, taskData);\n if (!selfAgentId) return false;\n\n const pending = taskData?.agentsPendingWrapUp;\n if (Array.isArray(pending) && pending.length > 0) {\n return pending.includes(selfAgentId);\n }\n\n const participantWrapUp =\n taskData?.interaction?.participants?.[selfAgentId]?.isWrapUp === true;\n const wrapUpRequired = taskData?.wrapUpRequired === true;\n\n return wrapUpRequired || participantWrapUp;\n }\n\n return shouldWrapUpForThisAgent(context, taskData);\n },\n\n /**\n * Check if wrapUpRequired in payload OR is consult initiator\n */\n shouldWrapUpOrIsInitiator: ({context, event}: GuardParams): boolean => {\n const taskData = getTaskDataFromEvent(event);\n\n return Boolean(taskData?.wrapUpRequired || context.consultInitiator);\n },\n\n /**\n * True if PARTICIPANT_LEAVE indicates that *this* agent left the conference.\n *\n * Important: PARTICIPANT_LEAVE is broadcast to all agents in the conference.\n * Only the agent whose id matches the leaving participant should transition to\n * TERMINATED / WRAPPING_UP based on wrapup rules.\n */\n didCurrentAgentLeaveConference: ({context, event}: GuardParams): boolean => {\n const taskData = getTaskDataFromEvent(event);\n const selfAgentId = getSelfAgentId(context, taskData);\n if (!selfAgentId) return false;\n\n const participantIdFromEvent =\n event && typeof event === 'object' && 'participantId' in event\n ? (event as {participantId?: string}).participantId\n : undefined;\n const participantId = participantIdFromEvent ?? taskData?.participantId;\n\n if (Boolean(participantId) && participantId === selfAgentId) {\n return true;\n }\n\n // For EP-DN agents the backend removes the leaving participant entirely\n // from the participants map (rather than setting hasLeft). If this task\n // is in CONFERENCING (implied by the guard being evaluated here) but the\n // agent is absent from the updated participants, they have left.\n const participants = taskData?.interaction?.participants;\n if (participants && !(selfAgentId in participants)) {\n return true;\n }\n\n return false;\n },\n\n // Server State Guards\n isPrimaryMediaOnHold: ({event}: GuardParams): boolean => {\n const taskData = getTaskDataFromEvent(event);\n if (!taskData) return false;\n const mediaId = taskData.mediaResourceId;\n if (!mediaId) return false;\n\n return taskData.interaction?.media?.[mediaId]?.isHold === true;\n },\n};\n\nexport type GuardName = keyof typeof guards;\n"],"mappings":"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","ignoreList":[]}
@@ -106,13 +106,16 @@ function computeVoiceInteractionUIControls(state, context, config, fallbackTaskD
106
106
  const isConferencing = state === _constants.TaskState.CONFERENCING;
107
107
  const isWrappingUp = state === _constants.TaskState.WRAPPING_UP;
108
108
  const selfInMainCall = Boolean(selfAgentId) && Boolean(mainCallId) && Boolean(interaction?.media?.[mainCallId]?.participants?.includes(selfAgentId));
109
+ const consultMedia = Object.values(interaction?.media ?? {}).find(media => media?.mediaResourceId === taskData?.consultMediaResourceId || media?.mType === 'consult');
110
+ const selfParticipant = selfAgentId ? interaction?.participants?.[selfAgentId] : null;
111
+ const selfInConsultCall = Boolean(selfAgentId) && Boolean(consultMedia?.participants?.includes(selfAgentId));
109
112
  const conferenceActive = isConferencing || conferenceFromBackend || consultFromConference;
110
113
  // Treat consult initiator as "in conference" even if mainCall participant list lags while consulting.
111
114
  const inConference = conferenceActive && (isConferencing || selfInMainCall || consultInitiator);
112
115
 
113
116
  // Check if this is a consulted agent (must be after isConsulting is computed).
114
- const isSoleAgentOnCall = participantCount <= 1 && !isConsulting && !inConference;
115
- const isConsulted = inConference || isSoleAgentOnCall ? false : (0, _TaskUtils.getIsConsultedAgentForControls)(taskData, context, isConsulting);
117
+ const isSoleAgentOnCall = participantCount <= 1 && selfInMainCall && !isConsulting && !inConference;
118
+ const isConsulted = inConference || isSoleAgentOnCall ? false : (0, _TaskUtils.getIsConsultedAgentForControls)(taskData, context, isConsulting) || !consultInitiator && (selfParticipant?.isConsulted === true || selfParticipant?.consultState === 'consulting');
116
119
 
117
120
  // Active call = can perform call operations
118
121
  const isActive = state === _constants.TaskState.CONNECTED || state === _constants.TaskState.HELD || state === _constants.TaskState.HOLD_INITIATING || state === _constants.TaskState.RESUME_INITIATING || isConsulting || isConferencing;
@@ -122,20 +125,49 @@ function computeVoiceInteractionUIControls(state, context, config, fallbackTaskD
122
125
  const hasFullControls = !isConsulted || consultInitiator || inConference || isWrappingUp;
123
126
  const consultOwnedBySelf = consultInitiator || Boolean(selfAgentId) && taskData?.consultingAgentId === selfAgentId;
124
127
  const hasConsultMedia = Boolean(taskData?.consultMediaResourceId || Object.values(interaction?.media ?? {}).some(media => media?.mType === 'consult'));
128
+ const selfConsultPendingOnConsultMedia = selfParticipant?.consultState === 'consultInitiated' && !taskData?.isConsulted && hasConsultMedia;
129
+ const ownerParticipant = interaction?.owner ? interaction.participants?.[interaction.owner] : undefined;
130
+ const otherAgentConsultInProgress = Boolean(interaction?.participants && Object.values(interaction.participants).some(participant => {
131
+ if (!participant || participant.hasLeft) return false;
132
+ if (participant.id === selfAgentId) return false;
133
+ if (participant.pType !== 'AGENT') return false;
134
+ return participant.consultState === 'consultInitiated' || participant.consultState === 'consultReserved' || participant.consultState === 'consulting' || participant.currentState === 'consulting';
135
+ }));
136
+ const isHydratedConferenceConsultPending = inConference && selfConsultPendingOnConsultMedia && !consultDestinationAgentJoined;
125
137
  const hasParallelConsultLeg = consultOwnedBySelf && !isConsulting && !isConsulted && (consultInProgress || consultCallHeld || hasConsultMedia);
138
+ const activeLegForConferenceConsult = consultCallHeld ? 'main' : 'consult';
139
+ const isCurrentLegActive = currentLeg === activeLegForConferenceConsult;
140
+ const isConferenceConsultTransferContext = inConference && consultInitiator && hasConsultMedia && isConsultDestinationReady;
126
141
  const consultLegOnHold = isConsulting && consultCallHeld;
142
+ const callProcessingDetails = interaction?.callProcessingDetails;
143
+ const conferenceHoldParticipant = callProcessingDetails?.conferenceHoldParticipant === true || callProcessingDetails?.conferenceHoldParticipant === 'true';
144
+ const postDeclineHeldMainLeg = consultInitiator && !consultDestinationAgentJoined && isHeld && inConference && conferenceHoldParticipant;
145
+ const postConsultCompletedHeldMainLeg = selfParticipant?.consultState === 'consultCompleted' && isHeld && inConference && !isConsulting;
146
+ const nonOwnerPostConsultCompletedHeldMainLeg = isHeld && inConference && !isConsulting && !consultInitiator && Boolean(selfAgentId) && Boolean(interaction?.owner) && selfAgentId !== interaction?.owner && ownerParticipant?.consultState === 'consultCompleted';
147
+ const isConsultPendingBeforeJoin = selfParticipant?.consultState === 'consultInitiated' && !consultDestinationAgentJoined;
148
+ const hideExitConferenceWhileConsultPending = currentLeg === 'main' && inConference && isConsultPendingBeforeJoin && (consultFromConference || consultInitiator || taskData?.type === 'AgentConsultCreated' || consultInProgress || isConsulting);
149
+ const hideExitConferenceDuringActiveConsultFromConference = inConference && consultInitiator && consultDestinationAgentJoined && (isConsulting || taskData?.type === 'AgentConsulting' || selfParticipant?.consultState === 'consulting');
150
+ const forceHeldPostConsultControls = !hideExitConferenceWhileConsultPending && (postDeclineHeldMainLeg || postConsultCompletedHeldMainLeg);
151
+ const selfOnConsultLeg = selfParticipant?.consultState === 'consulting' || selfParticipant?.currentState === 'consulting';
152
+ const showMainLegConferenceControlsDuringConsult = currentLeg === 'main' && inConference && consultInProgress && !selfOnConsultLeg;
153
+ const allowHeldMainLegControlsForNonInitiator = showMainLegConferenceControlsDuringConsult && !isHydratedConferenceConsultPending;
127
154
  return {
128
155
  // Accept/Decline: Voice tasks in offered state
129
- // For outdial, accept is disabled (auto-answer handles it), decline remains enabled
130
- // For Extension mode (non-WebRTC), accept shows as disabled "Ringing" button
156
+ // Desktop/WebRTC + inbound: accept enabled (agent manually accepts)
157
+ // Desktop/WebRTC + outdial: accept disabled (auto-answer handles it; Widgets show "Accept" disabled)
158
+ // Extension mode (non-WebRTC): accept disabled (Widgets show "Ringing...")
131
159
  accept: state === _constants.TaskState.OFFERED && !interaction?.isTerminated ? {
132
160
  isVisible: true,
133
161
  isEnabled: isWebrtc && !isOutdial
134
162
  } : DISABLED,
135
- decline: isWebrtc && state === _constants.TaskState.OFFERED && !interaction?.isTerminated ? VISIBLE_ENABLED : DISABLED,
163
+ decline: (() => {
164
+ if (!isWebrtc || state !== _constants.TaskState.OFFERED || interaction?.isTerminated) return DISABLED;
165
+ return isOutdial ? VISIBLE_DISABLED : VISIBLE_ENABLED;
166
+ })(),
136
167
  // Hold: visible in connected/held/conference, disabled in conference/consulting
137
168
  hold: (() => {
138
169
  if (!hasFullControls) return DISABLED;
170
+ if (forceHeldPostConsultControls) return VISIBLE_ENABLED;
139
171
  if (consultOwnedBySelf && (isConsulting || hasParallelConsultLeg || consultCallHeld)) {
140
172
  return DISABLED;
141
173
  }
@@ -152,6 +184,7 @@ function computeVoiceInteractionUIControls(state, context, config, fallbackTaskD
152
184
  mute: (() => {
153
185
  if (!isWebrtc) return DISABLED;
154
186
  if (isWrappingUp) return DISABLED;
187
+ if (currentLeg === 'consult' && !selfInConsultCall) return DISABLED;
155
188
  if (isConsulting) return VISIBLE_ENABLED;
156
189
  if (isConnected || isHeld || isConferencing) {
157
190
  if (inConference) return VISIBLE_ENABLED;
@@ -161,6 +194,9 @@ function computeVoiceInteractionUIControls(state, context, config, fallbackTaskD
161
194
  })(),
162
195
  // End: varies by state; during consulting only on main leg (consult held)
163
196
  end: (() => {
197
+ if (allowHeldMainLegControlsForNonInitiator) return VISIBLE_ENABLED;
198
+ if (showMainLegConferenceControlsDuringConsult) return VISIBLE_DISABLED;
199
+ if (isHydratedConferenceConsultPending && currentLeg === 'main') return VISIBLE_DISABLED;
164
200
  if (!config.isEndTaskEnabled) return DISABLED;
165
201
  if (hasParallelConsultLeg) {
166
202
  return isConnected && isEpDnConsult ? VISIBLE_ENABLED : VISIBLE_DISABLED;
@@ -171,6 +207,7 @@ function computeVoiceInteractionUIControls(state, context, config, fallbackTaskD
171
207
  }
172
208
  if (inConference) {
173
209
  if (isConsulted) return DISABLED;
210
+ if (forceHeldPostConsultControls) return VISIBLE_DISABLED;
174
211
  if (consultInProgress) return VISIBLE_DISABLED;
175
212
  return isWrappingUp ? VISIBLE_DISABLED : VISIBLE_ENABLED;
176
213
  }
@@ -180,6 +217,11 @@ function computeVoiceInteractionUIControls(state, context, config, fallbackTaskD
180
217
  })(),
181
218
  // Transfer: connected/held/conference
182
219
  transfer: (() => {
220
+ if (isHydratedConferenceConsultPending) return VISIBLE_DISABLED;
221
+ if (isConferenceConsultTransferContext && currentLeg === 'main' && isCurrentLegActive) {
222
+ return DISABLED;
223
+ }
224
+ if (inConference && isConsulting && consultInitiator) return DISABLED;
183
225
  if (hasParallelConsultLeg) {
184
226
  if (!customerPresent) return DISABLED;
185
227
  if (state === _constants.TaskState.CONNECTED) return VISIBLE_ENABLED;
@@ -203,6 +245,7 @@ function computeVoiceInteractionUIControls(state, context, config, fallbackTaskD
203
245
  // Consult: connected/held/conference when conditions met
204
246
  consult: (() => {
205
247
  const isConnectedOrHeld = state === _constants.TaskState.CONNECTED || state === _constants.TaskState.HELD;
248
+ if (inConference && nonOwnerPostConsultCompletedHeldMainLeg) return VISIBLE_DISABLED;
206
249
  if (hasParallelConsultLeg) return DISABLED;
207
250
  if (!hasFullControls || !(isConnectedOrHeld || inConference)) {
208
251
  return DISABLED;
@@ -213,7 +256,7 @@ function computeVoiceInteractionUIControls(state, context, config, fallbackTaskD
213
256
  // Pending conference (only self agent): consult disabled
214
257
  if (participantCount <= 1) return VISIBLE_DISABLED;
215
258
  // Real conference: consult enabled if conditions met
216
- const canFromConference = !maxParticipants && customerPresent && !consultInProgress && !isConsulting;
259
+ const canFromConference = !maxParticipants && customerPresent && !consultInProgress && !otherAgentConsultInProgress && !isConsulting;
217
260
  return {
218
261
  isVisible: true,
219
262
  isEnabled: canFromConference
@@ -259,6 +302,7 @@ function computeVoiceInteractionUIControls(state, context, config, fallbackTaskD
259
302
  // Conference: during consulting, enabled on both legs when agent joined
260
303
  // Label changes based on leg: "Conference" on main leg, "Merge" on consult leg
261
304
  conference: (() => {
305
+ if (isHydratedConferenceConsultPending && currentLeg === 'main') return VISIBLE_DISABLED;
262
306
  if (hasParallelConsultLeg) {
263
307
  if (!customerPresent) return DISABLED;
264
308
  if (state === _constants.TaskState.CONNECTED) {
@@ -277,21 +321,33 @@ function computeVoiceInteractionUIControls(state, context, config, fallbackTaskD
277
321
  wrapup: isWrappingUp ? VISIBLE_ENABLED : DISABLED,
278
322
  // ExitConference: in conference with multiple agents in main call
279
323
  exitConference: (() => {
324
+ if (hideExitConferenceWhileConsultPending) return DISABLED;
325
+ if (allowHeldMainLegControlsForNonInitiator) return VISIBLE_ENABLED;
326
+ if (showMainLegConferenceControlsDuringConsult) return VISIBLE_DISABLED;
327
+ if (hideExitConferenceDuringActiveConsultFromConference) return DISABLED;
328
+ if (forceHeldPostConsultControls) return VISIBLE_DISABLED;
280
329
  if (isConsulted && !isConferencing) return DISABLED;
281
330
  if (!inConference) return DISABLED;
282
331
  if (participantCount <= 1) return DISABLED;
332
+ if (consultInProgress) return VISIBLE_DISABLED;
283
333
  const consultingFromConference = consultInitiator && isConsulting && conferenceFromBackend;
284
334
  return consultingFromConference ? VISIBLE_DISABLED : VISIBLE_ENABLED;
285
335
  })(),
286
336
  // TransferConference: in conference with active consult, owner consulting from conference
287
337
  transferConference: (() => {
288
- if (hasParallelConsultLeg || consultLegOnHold) return DISABLED;
289
- if (!inConference || !isConsulting) return DISABLED;
338
+ if (isConferenceConsultTransferContext && !isCurrentLegActive) return VISIBLE_DISABLED;
339
+ const consultLegTransferAvailable = currentLeg === 'consult' && inConference && consultInitiator && hasConsultMedia;
340
+ const selfConsultingOnParticipantState = selfParticipant?.consultState === 'consulting';
341
+ const conferenceTransferAvailable = consultLegTransferAvailable || inConference && consultInitiator && hasConsultMedia && (isConsulting || consultInProgress || selfConsultingOnParticipantState);
342
+ if (consultLegOnHold) return DISABLED;
343
+ if (hasParallelConsultLeg && !conferenceTransferAvailable) return DISABLED;
344
+ if (!conferenceTransferAvailable && (!inConference || !isConsulting)) return DISABLED;
290
345
  if (!consultInitiator || isConsulted) return DISABLED;
291
346
  return isConsultDestinationReady ? VISIBLE_ENABLED : VISIBLE_DISABLED;
292
347
  })(),
293
348
  // MergeToConference: mirrors conference control, enabled on both legs
294
349
  mergeToConference: (() => {
350
+ if (isHydratedConferenceConsultPending && currentLeg === 'consult') return VISIBLE_DISABLED;
295
351
  if (!isConsulting || !consultInitiator) return DISABLED;
296
352
  if (!customerPresent) return VISIBLE_DISABLED;
297
353
  if (consultLegOnHold) return VISIBLE_DISABLED;
@@ -299,6 +355,7 @@ function computeVoiceInteractionUIControls(state, context, config, fallbackTaskD
299
355
  })(),
300
356
  // Switch: visible only on the currently active leg
301
357
  switch: (() => {
358
+ if (isHydratedConferenceConsultPending && currentLeg === 'consult') return VISIBLE_DISABLED;
302
359
  if (!customerPresent && hasParallelConsultLeg) return DISABLED;
303
360
  if (currentLeg === 'consult') {
304
361
  if (!isConsulting || !consultInitiator || consultCallHeld) return DISABLED;
@@ -353,7 +410,10 @@ function getVoiceLegState(currentState, context, config, fallbackTaskData) {
353
410
  const isConsultingState = currentState === _constants.TaskState.CONSULTING || currentState === _constants.TaskState.CONSULT_INITIATING || currentState === _constants.TaskState.CONF_INITIATING;
354
411
  const consultOwnedBySelf = context.consultInitiator || Boolean(selfAgentId) && taskData?.consultingAgentId === selfAgentId;
355
412
  const hasConsultMedia = Boolean(taskData?.consultMediaResourceId || Object.values(interaction?.media ?? {}).some(media => media?.mType === 'consult'));
356
- const hasConsultLeg = Boolean(consultOwnedBySelf && !taskData?.isConsulted && !interaction?.isTerminated && (consultInProgress || isConsultingState || context.consultCallHeld || hasConsultMedia));
413
+ const selfParticipant = selfAgentId ? interaction?.participants?.[selfAgentId] : null;
414
+ const selfConsultPendingOnConsultMedia = selfParticipant?.consultState === 'consultInitiated' && !taskData?.isConsulted && hasConsultMedia;
415
+ const selfConsultingOnConsultMedia = selfParticipant?.consultState === 'consulting' && hasConsultMedia;
416
+ const hasConsultLeg = Boolean(!interaction?.isTerminated && (consultOwnedBySelf && !taskData?.isConsulted || selfConsultingOnConsultMedia || selfConsultPendingOnConsultMedia) && (consultInProgress || isConsultingState || context.consultCallHeld || hasConsultMedia));
357
417
  if (!hasConsultLeg) {
358
418
  return {
359
419
  hasConsultLeg: false,
@@ -362,10 +422,16 @@ function getVoiceLegState(currentState, context, config, fallbackTaskData) {
362
422
  consultState: _constants.TaskState.CONSULTING
363
423
  };
364
424
  }
425
+ let mainState = _constants.TaskState.HELD;
426
+ if (currentState === _constants.TaskState.CONFERENCING) {
427
+ mainState = _constants.TaskState.CONFERENCING;
428
+ } else if (context.consultCallHeld) {
429
+ mainState = _constants.TaskState.CONNECTED;
430
+ }
365
431
  return {
366
432
  hasConsultLeg: true,
367
433
  activeLeg: context.consultCallHeld ? 'main' : 'consult',
368
- mainState: context.consultCallHeld ? _constants.TaskState.CONNECTED : _constants.TaskState.HELD,
434
+ mainState,
369
435
  consultState: isConsultingState ? currentState : _constants.TaskState.CONSULTING
370
436
  };
371
437
  }
@@ -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","computeVoiceInteractionUIControls","state","context","config","fallbackTaskData","currentLeg","TaskState","IDLE","taskData","interaction","mainCallId","mainInteractionId","interactionId","isWebrtc","voiceVariant","VOICE_VARIANT","WEBRTC","isOutdial","outboundType","serverHold","getServerHoldStateForControls","customerInCall","getIsCustomerInCall","customerPresent","Boolean","participants","Object","values","some","p","pType","hasLeft","participantCount","getConferenceParticipantsCount","maxParticipants","MAX_PARTICIPANTS_IN_MULTIPARTY_CONFERENCE","selfAgentId","agentId","consultInProgress","getIsConsultInProgressForConferenceControls","conferenceFromBackend","getIsConferenceInProgress","consultInitiator","consultDestinationAgentJoined","consultDestinationType","consultCallHeld","consultFromConference","recordingControlsAvailable","isEpDnConsult","isConsultDestinationReady","stateImpliesHeld","HELD","RESUME_INITIATING","stateImpliesConnected","CONNECTED","HOLD_INITIATING","isHeld","isConnected","isConsulting","CONSULTING","CONSULT_INITIATING","CONF_INITIATING","isConferencing","CONFERENCING","isWrappingUp","WRAPPING_UP","selfInMainCall","media","includes","conferenceActive","inConference","isSoleAgentOnCall","isConsulted","getIsConsultedAgentForControls","isActive","hasFullControls","consultOwnedBySelf","consultingAgentId","hasConsultMedia","consultMediaResourceId","mType","hasParallelConsultLeg","consultLegOnHold","OFFERED","isTerminated","canHold","isEndTaskEnabled","isConnectedOrHeld","canFromConference","canFromConnected","isEndConsultEnabled","isRecordingEnabled","consultingFromConference","computeDigitalInteractionUIControls","getVoiceLegState","currentState","hasConsultLeg","mainState","consultState","isConsultingState","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\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 // Essential data\n const taskData = context.taskData ?? fallbackTaskData ?? 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 const isConsultDestinationReady = consultDestinationAgentJoined || isEpDnConsult;\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 conferenceActive = isConferencing || conferenceFromBackend || consultFromConference;\n // Treat consult initiator as \"in conference\" even if mainCall participant list lags while consulting.\n const inConference = conferenceActive && (isConferencing || selfInMainCall || consultInitiator);\n\n // Check if this is a consulted agent (must be after isConsulting is computed).\n const isSoleAgentOnCall = participantCount <= 1 && !isConsulting && !inConference;\n const isConsulted =\n inConference || isSoleAgentOnCall\n ? false\n : getIsConsultedAgentForControls(taskData, context, isConsulting);\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 || consultInitiator || inConference || isWrappingUp;\n const consultOwnedBySelf =\n consultInitiator || (Boolean(selfAgentId) && taskData?.consultingAgentId === selfAgentId);\n const hasConsultMedia = Boolean(\n taskData?.consultMediaResourceId ||\n Object.values(interaction?.media ?? {}).some((media: any) => media?.mType === 'consult')\n );\n const hasParallelConsultLeg =\n consultOwnedBySelf &&\n !isConsulting &&\n !isConsulted &&\n (consultInProgress || consultCallHeld || hasConsultMedia);\n const consultLegOnHold = isConsulting && consultCallHeld;\n\n return {\n // Accept/Decline: Voice tasks in offered state\n // For outdial, accept is disabled (auto-answer handles it), decline remains enabled\n // For Extension mode (non-WebRTC), accept shows as disabled \"Ringing\" button\n accept:\n state === TaskState.OFFERED && !interaction?.isTerminated\n ? {isVisible: true, isEnabled: isWebrtc && !isOutdial}\n : DISABLED,\n decline:\n isWebrtc && state === TaskState.OFFERED && !interaction?.isTerminated\n ? VISIBLE_ENABLED\n : DISABLED,\n\n // Hold: visible in connected/held/conference, disabled in conference/consulting\n hold: (() => {\n if (!hasFullControls) return DISABLED;\n if (consultOwnedBySelf && (isConsulting || hasParallelConsultLeg || consultCallHeld)) {\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 (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 (!config.isEndTaskEnabled) 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\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 (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 (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 && customerPresent && !consultInProgress && !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 (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 (isConsulted && !isConferencing) return DISABLED;\n if (!inConference) return DISABLED;\n if (participantCount <= 1) return 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 (hasParallelConsultLeg || consultLegOnHold) return DISABLED;\n if (!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 (!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 (!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 = context.taskData ?? fallbackTaskData ?? null;\n const interaction = taskData?.interaction;\n const mainCallId = interaction?.mainInteractionId || taskData?.interactionId;\n const selfAgentId = config.agentId ?? taskData?.agentId;\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 hasConsultMedia = Boolean(\n taskData?.consultMediaResourceId ||\n Object.values(interaction?.media ?? {}).some((media: any) => media?.mType === 'consult')\n );\n const hasConsultLeg = Boolean(\n consultOwnedBySelf &&\n !taskData?.isConsulted &&\n !interaction?.isTerminated &&\n (consultInProgress || isConsultingState || context.consultCallHeld || hasConsultMedia)\n );\n\n if (!hasConsultLeg) {\n return {\n hasConsultLeg: false,\n activeLeg: 'main',\n mainState: currentState,\n consultState: TaskState.CONSULTING,\n };\n }\n\n return {\n hasConsultLeg: true,\n activeLeg: context.consultCallHeld ? 'main' : 'consult',\n mainState: context.consultCallHeld ? TaskState.CONNECTED : TaskState.HELD,\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","computeVoiceInteractionUIControls","state","context","config","fallbackTaskData","currentLeg","TaskState","IDLE","taskData","interaction","mainCallId","mainInteractionId","interactionId","isWebrtc","voiceVariant","VOICE_VARIANT","WEBRTC","isOutdial","outboundType","serverHold","getServerHoldStateForControls","customerInCall","getIsCustomerInCall","customerPresent","Boolean","participants","Object","values","some","p","pType","hasLeft","participantCount","getConferenceParticipantsCount","maxParticipants","MAX_PARTICIPANTS_IN_MULTIPARTY_CONFERENCE","selfAgentId","agentId","consultInProgress","getIsConsultInProgressForConferenceControls","conferenceFromBackend","getIsConferenceInProgress","consultInitiator","consultDestinationAgentJoined","consultDestinationType","consultCallHeld","consultFromConference","recordingControlsAvailable","isEpDnConsult","isConsultDestinationReady","stateImpliesHeld","HELD","RESUME_INITIATING","stateImpliesConnected","CONNECTED","HOLD_INITIATING","isHeld","isConnected","isConsulting","CONSULTING","CONSULT_INITIATING","CONF_INITIATING","isConferencing","CONFERENCING","isWrappingUp","WRAPPING_UP","selfInMainCall","media","includes","consultMedia","find","mediaResourceId","consultMediaResourceId","mType","selfParticipant","selfInConsultCall","conferenceActive","inConference","isSoleAgentOnCall","isConsulted","getIsConsultedAgentForControls","consultState","isActive","hasFullControls","consultOwnedBySelf","consultingAgentId","hasConsultMedia","selfConsultPendingOnConsultMedia","ownerParticipant","owner","undefined","otherAgentConsultInProgress","participant","id","currentState","isHydratedConferenceConsultPending","hasParallelConsultLeg","activeLegForConferenceConsult","isCurrentLegActive","isConferenceConsultTransferContext","consultLegOnHold","callProcessingDetails","conferenceHoldParticipant","postDeclineHeldMainLeg","postConsultCompletedHeldMainLeg","nonOwnerPostConsultCompletedHeldMainLeg","isConsultPendingBeforeJoin","hideExitConferenceWhileConsultPending","type","hideExitConferenceDuringActiveConsultFromConference","forceHeldPostConsultControls","selfOnConsultLeg","showMainLegConferenceControlsDuringConsult","allowHeldMainLegControlsForNonInitiator","OFFERED","isTerminated","canHold","isEndTaskEnabled","isConnectedOrHeld","canFromConference","canFromConnected","isEndConsultEnabled","isRecordingEnabled","consultingFromConference","consultLegTransferAvailable","selfConsultingOnParticipantState","conferenceTransferAvailable","computeDigitalInteractionUIControls","getVoiceLegState","hasConsultLeg","mainState","isConsultingState","selfConsultingOnConsultMedia","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\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 // Essential data\n const taskData = context.taskData ?? fallbackTaskData ?? 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 const isConsultDestinationReady = consultDestinationAgentJoined || isEpDnConsult;\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 conferenceActive = isConferencing || conferenceFromBackend || consultFromConference;\n // Treat consult initiator as \"in conference\" even if mainCall participant list lags while consulting.\n const inConference = conferenceActive && (isConferencing || selfInMainCall || consultInitiator);\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 (!consultInitiator &&\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 || consultInitiator || inConference || isWrappingUp;\n const consultOwnedBySelf =\n consultInitiator || (Boolean(selfAgentId) && taskData?.consultingAgentId === selfAgentId);\n const hasConsultMedia = Boolean(\n taskData?.consultMediaResourceId ||\n Object.values(interaction?.media ?? {}).some((media: any) => media?.mType === 'consult')\n );\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 && !consultDestinationAgentJoined;\n const hasParallelConsultLeg =\n consultOwnedBySelf &&\n !isConsulting &&\n !isConsulted &&\n (consultInProgress || consultCallHeld || hasConsultMedia);\n const activeLegForConferenceConsult = consultCallHeld ? 'main' : 'consult';\n const isCurrentLegActive = currentLeg === activeLegForConferenceConsult;\n const isConferenceConsultTransferContext =\n inConference && consultInitiator && hasConsultMedia && isConsultDestinationReady;\n const consultLegOnHold = isConsulting && consultCallHeld;\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 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\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 (consultOwnedBySelf && (isConsulting || hasParallelConsultLeg || consultCallHeld)) {\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 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) 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 (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 (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 = context.taskData ?? fallbackTaskData ?? null;\n const interaction = taskData?.interaction;\n const mainCallId = interaction?.mainInteractionId || taskData?.interactionId;\n const selfAgentId = config.agentId ?? taskData?.agentId;\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 hasConsultMedia = Boolean(\n taskData?.consultMediaResourceId ||\n Object.values(interaction?.media ?? {}).some((media: any) => media?.mType === 'consult')\n );\n const selfParticipant = selfAgentId ? interaction?.participants?.[selfAgentId] : null;\n const selfConsultPendingOnConsultMedia =\n selfParticipant?.consultState === 'consultInitiated' &&\n !taskData?.isConsulted &&\n hasConsultMedia;\n const selfConsultingOnConsultMedia =\n selfParticipant?.consultState === 'consulting' && hasConsultMedia;\n const hasConsultLeg = Boolean(\n !interaction?.isTerminated &&\n ((consultOwnedBySelf && !taskData?.isConsulted) ||\n selfConsultingOnConsultMedia ||\n selfConsultPendingOnConsultMedia) &&\n (consultInProgress || isConsultingState || context.consultCallHeld || hasConsultMedia)\n );\n\n if (!hasConsultLeg) {\n return {\n hasConsultLeg: false,\n activeLeg: 'main',\n mainState: currentState,\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":[]}