@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
@@ -291,6 +291,7 @@ class TaskManager extends _events.default {
291
291
  case _types2.CC_EVENTS.AGENT_OUTBOUND_FAILED:
292
292
  return {
293
293
  type: _stateMachine.TaskEvent.OUTBOUND_FAILED,
294
+ taskData: payload,
294
295
  reason: payload.reason
295
296
  };
296
297
  case _types2.CC_EVENTS.CONTACT_RECORDING_STARTED:
@@ -1 +1 @@
1
- {"version":3,"names":["_events","_interopRequireDefault","require","_calling","_types","_constants","_constants2","_types2","_types3","_loggerProxy","_TaskUtils","_TaskFactory","_WebRTC","_stateMachine","_taskDataNormalizer","e","__esModule","default","CC_EVENT_SET","Set","Object","values","CC_EVENTS","isCcEvent","value","has","TaskManager","EventEmitter","constructor","apiAIAssistant","contact","webCallingService","webSocketManager","rtdWebSocketManager","taskCollection","webRtcEnabled","registerTaskListeners","registerIncomingCallEvent","handleRealtimeWebsocketEvent","event","payload","JSON","parse","interactionId","data","conversationId","task","LoggerProxy","info","module","TASK_MANAGER_FILE","method","METHODS","HANDLE_REAL_TIME_WEBSOCKET_EVENT","emit","type","error","setConfigFlags","configFlags","setWrapupData","wrapupData","setAgentId","agentId","getAgentId","setWebRtcEnabled","handleIncomingWebCall","call","currentTask","find","t","interaction","mediaType","MEDIA_CHANNEL","TELEPHONY","mapCallToTask","getCallId","log","HANDLE_INCOMING_WEB_CALL","eventPayload","mapEventToTaskStateMachineEvent","AGENT_CONTACT_RESERVED","sendStateMachineEvent","on","LINE_EVENTS","INCOMING_CALL","unregisterIncomingCallEvent","off","ccEvent","mediaResourceId","media","TaskEvent","TASK_INCOMING","taskData","AGENT_OFFER_CONTACT","TASK_OFFERED","AGENT_CONTACT","HYDRATE","CONTACT_UPDATED","CONTACT_OWNER_CHANGED","AGENT_OFFER_CONSULT","OFFER_CONSULT","isConsulted","AGENT_CONTACT_ASSIGNED","ASSIGN","AGENT_CONTACT_HELD","HOLD_SUCCESS","AGENT_CONTACT_UNHELD","UNHOLD_SUCCESS","AGENT_CONSULT_CREATED","CONSULT_CREATED","AGENT_CONSULTING","CONSULTING_ACTIVE","consultDestinationAgentJoined","AGENT_CONSULT_ENDED","CONSULT_END","AGENT_CONSULT_FAILED","AGENT_CTQ_FAILED","CONSULT_FAILED","reason","AGENT_CTQ_CANCELLED","CTQ_CANCEL","AGENT_CTQ_CANCEL_FAILED","CTQ_CANCEL_FAILED","AGENT_BLIND_TRANSFERRED","AGENT_CONSULT_TRANSFERRED","AGENT_VTEAM_TRANSFERRED","TRANSFER_SUCCESS","AGENT_WRAPUP","TASK_WRAPUP","wrapUpRequired","AGENT_CONTACT_UNASSIGNED","AGENT_BLIND_TRANSFER_FAILED","AGENT_VTEAM_TRANSFER_FAILED","AGENT_CONSULT_TRANSFER_FAILED","AGENT_CONFERENCE_TRANSFER_FAILED","TRANSFER_FAILED","CONTACT_ENDED","state","AGENT_INVITE_FAILED","INVITE_FAILED","AGENT_CONTACT_ASSIGN_FAILED","ASSIGN_FAILED","AGENT_CONTACT_OFFER_RONA","RONA","AGENT_OUTBOUND_FAILED","OUTBOUND_FAILED","CONTACT_RECORDING_STARTED","RECORDING_STARTED","CONTACT_RECORDING_PAUSED","PAUSE_RECORDING","CONTACT_RECORDING_RESUMED","RESUME_RECORDING","AGENT_WRAPPEDUP","WRAPUP_COMPLETE","AGENT_CONSULT_CONFERENCED","AGENT_CONSULT_CONFERENCING","PARTICIPANT_JOINED_CONFERENCE","CONFERENCE_START","AGENT_CONSULT_CONFERENCE_FAILED","CONFERENCE_FAILED","AGENT_CONSULT_CONFERENCE_ENDED","CONFERENCE_END","PARTICIPANT_LEFT_CONFERENCE","PARTICIPANT_LEAVE","participantId","AGENT_CONFERENCE_TRANSFERRED","TRANSFER_CONFERENCE_SUCCESS","message","parseWebSocketMessage","eventContext","prepareEventContext","actions","handleTaskLifecycleEvent","stateMachineEvent","updateTaskData","eventType","PARTICIPANT_POST_CALL_ACTIVITY","TASK_EVENTS","TASK_POST_CALL_ACTIVITY","requestRealTimeTranscripts","keepalive","normalizeTaskData","wasConsultedTask","Boolean","computeWrapUpRequired","undefined","adjustedPayload","context","handleContactReserved","handleAgentContact","CONTACT_MERGED","handleContactMergedEvent","isConsultedTask","isSecondaryEpDnAgent","shouldAutoAnswer","shouldAutoAnswerTask","loginOption","isAutoAnswering","TaskFactory","createTask","setupTaskListeners","participants","isWrapUp","isConferenceInProgress","getIsConferenceInProgress","Error","snapshot","stateMachineService","getSnapshot","isConsultingFlow","destAgentId","consultDestinationAgentId","destinationType","consultDestinationType","REGISTER_TASK_LISTENERS","TASK_HYDRATE","TASK_CLEANUP","options","handleTaskCleanup","removeFromCollection","removeTaskFromCollection","cancelAutoWrapupTimer","REMOVE_TASK_FROM_COLLECTION","childInteractionId","TASK_MERGED","LoginOption","BROWSER","WebRTC","unregisterWebCallListeners","cleanUpCall","isOutdial","outboundType","isNew","needsWrapUp","agentsPendingWrapUp","length","action","TRANSCRIPT_EVENT_MAP","aiFeature","realtimeTranscripts","enable","sendEvent","AIAssistantEventType","CUSTOM_EVENT","AIAssistantEventName","GET_TRANSCRIPTS","catch","REQUEST_REAL_TIME_TRANSCRIPTS","getTask","taskId","getAllTasks","getTaskManager","taskManager","exports"],"sources":["TaskManager.ts"],"sourcesContent":["import EventEmitter from 'events';\nimport {ICall, LINE_EVENTS} from '@webex/calling';\nimport {WebSocketManager} from '../core/websocket/WebSocketManager';\nimport routingContact from './contact';\nimport WebCallingService from '../WebCallingService';\nimport {\n MEDIA_CHANNEL,\n TASK_EVENTS,\n TaskData,\n TaskId,\n ITask,\n WebSocketPayload,\n WebSocketMessage,\n TaskEventActions,\n EventContext,\n} from './types';\nimport {TASK_MANAGER_FILE} from '../../constants';\nimport {METHODS, TRANSCRIPT_EVENT_MAP} from './constants';\nimport {CC_EVENTS, WrapupData} from '../config/types';\nimport {ConfigFlags, LoginOption, AIAssistantEventType, AIAssistantEventName} from '../../types';\nimport LoggerProxy from '../../logger-proxy';\nimport {getIsConferenceInProgress, isSecondaryEpDnAgent, shouldAutoAnswerTask} from './TaskUtils';\nimport TaskFactory from './TaskFactory';\nimport WebRTC from './voice/WebRTC';\nimport {TaskEvent, type TaskEventPayload} from './state-machine';\nimport {normalizeTaskData} from './taskDataNormalizer';\nimport {ApiAIAssistant} from '../ApiAiAssistant';\n\nconst CC_EVENT_SET = new Set<CC_EVENTS>(Object.values(CC_EVENTS) as CC_EVENTS[]);\n\nconst isCcEvent = (value: string): value is CC_EVENTS => CC_EVENT_SET.has(value as CC_EVENTS);\n\n/** @internal */\nexport default class TaskManager extends EventEmitter {\n private call: ICall;\n private contact: ReturnType<typeof routingContact>;\n /**\n * Collection of tasks indexed by TaskId\n * @type {Record<TaskId, ITask>}\n * @private\n */\n private taskCollection: Record<TaskId, ITask>;\n private webCallingService: WebCallingService;\n private webSocketManager: WebSocketManager;\n private rtdWebSocketManager: WebSocketManager;\n // eslint-disable-next-line no-use-before-define\n private static taskManager: TaskManager;\n private configFlags?: ConfigFlags;\n private wrapupData: WrapupData;\n private agentId: string;\n private webRtcEnabled: boolean;\n private apiAIAssistant?: ApiAIAssistant;\n /**\n * @param contact - Routing Contact layer. Talks to AQMReq layer to convert events to promises\n * @param webCallingService - Webrtc Service Layer\n * @param webSocketManager - Websocket Manager to maintain websocket connection and keepalives\n */\n constructor(\n apiAIAssistant: ApiAIAssistant,\n contact: ReturnType<typeof routingContact>,\n webCallingService: WebCallingService,\n webSocketManager: WebSocketManager,\n rtdWebSocketManager: WebSocketManager\n ) {\n super();\n this.apiAIAssistant = apiAIAssistant;\n this.contact = contact;\n this.webCallingService = webCallingService;\n this.webSocketManager = webSocketManager;\n this.rtdWebSocketManager = rtdWebSocketManager;\n this.taskCollection = {};\n this.webRtcEnabled = false;\n\n this.registerTaskListeners();\n this.registerIncomingCallEvent();\n }\n\n public handleRealtimeWebsocketEvent(event: string) {\n try {\n const payload = JSON.parse(event);\n\n const interactionId = payload?.data?.data?.conversationId;\n if (!interactionId) return;\n\n const task = this.taskCollection[interactionId];\n if (!task) {\n LoggerProxy.info(`Realtime transcription task not found`, {\n module: TASK_MANAGER_FILE,\n method: METHODS.HANDLE_REAL_TIME_WEBSOCKET_EVENT,\n interactionId,\n });\n\n return;\n }\n\n task.emit(payload.type, payload.data);\n } catch (error) {\n LoggerProxy.error('Failed to parse RTD WebSocket message', {\n module: TASK_MANAGER_FILE,\n method: METHODS.HANDLE_REAL_TIME_WEBSOCKET_EVENT,\n error,\n });\n }\n }\n\n /**\n * Set config flags for task creation\n */\n public setConfigFlags(configFlags: ConfigFlags) {\n this.configFlags = configFlags;\n }\n\n /**\n * Set wrapup configuration data\n */\n public setWrapupData(wrapupData: WrapupData) {\n this.wrapupData = wrapupData;\n }\n\n /**\n * Set agent ID for task operations\n */\n public setAgentId(agentId: string) {\n this.agentId = agentId;\n }\n\n /**\n * Gets the current agent ID\n * @returns {string} The agent ID set for this task manager instance\n * @public\n */\n public getAgentId(): string {\n return this.agentId;\n }\n\n public setWebRtcEnabled(webRtcEnabled: boolean) {\n this.webRtcEnabled = webRtcEnabled;\n }\n\n private handleIncomingWebCall = (call: ICall) => {\n const currentTask = Object.values(this.taskCollection).find(\n (t) => t.data.interaction.mediaType === MEDIA_CHANNEL.TELEPHONY\n );\n\n if (currentTask) {\n this.webCallingService.mapCallToTask(call.getCallId(), currentTask.data.interactionId);\n LoggerProxy.log(`Call mapped to task`, {\n module: TASK_MANAGER_FILE,\n method: METHODS.HANDLE_INCOMING_WEB_CALL,\n interactionId: currentTask.data.interactionId,\n });\n\n // Send TASK_INCOMING to state machine - it will emit on the task object\n const eventPayload = TaskManager.mapEventToTaskStateMachineEvent(\n CC_EVENTS.AGENT_CONTACT_RESERVED,\n currentTask.data\n );\n if (eventPayload && currentTask) {\n currentTask.sendStateMachineEvent(eventPayload);\n }\n }\n this.call = call;\n };\n\n public registerIncomingCallEvent() {\n this.webCallingService.on(LINE_EVENTS.INCOMING_CALL, this.handleIncomingWebCall);\n }\n\n public unregisterIncomingCallEvent() {\n this.webCallingService.off(LINE_EVENTS.INCOMING_CALL, this.handleIncomingWebCall);\n }\n\n /**\n * Map WebSocket CC_EVENTS to state machine TaskEvent\n * @param ccEvent - The CC_EVENT type from WebSocket\n * @param payload - The event payload\n * @param agentId - Optional agent ID for state detection (needed for HYDRATE)\n * @returns TaskEventPayload for state machine or null if no mapping\n */\n private static mapEventToTaskStateMachineEvent(\n ccEvent: CC_EVENTS,\n payload: WebSocketPayload,\n agentId?: string\n ): TaskEventPayload | null {\n const mediaResourceId =\n payload.mediaResourceId ||\n payload.interaction?.media?.[payload.interactionId]?.mediaResourceId;\n\n switch (ccEvent) {\n // CC -> TaskEvent mappings (see TaskStateMachine comment for quick reference)\n case CC_EVENTS.AGENT_CONTACT_RESERVED: // AgentContactReserved -> TASK_INCOMING\n return {type: TaskEvent.TASK_INCOMING, taskData: payload};\n\n case CC_EVENTS.AGENT_OFFER_CONTACT: // AgentOfferContact -> TASK_OFFERED\n return {type: TaskEvent.TASK_OFFERED, taskData: payload};\n\n case CC_EVENTS.AGENT_CONTACT: // AgentContact -> HYDRATE\n // Include agentId for state detection (e.g., checking isWrapUp in participant data)\n return {type: TaskEvent.HYDRATE, taskData: payload, agentId};\n\n case CC_EVENTS.CONTACT_UPDATED:\n return {type: TaskEvent.CONTACT_UPDATED, taskData: payload};\n case CC_EVENTS.CONTACT_OWNER_CHANGED:\n return {type: TaskEvent.CONTACT_OWNER_CHANGED, taskData: payload};\n\n case CC_EVENTS.AGENT_OFFER_CONSULT: // AgentOfferConsult -> OFFER_CONSULT\n return {\n type: TaskEvent.OFFER_CONSULT,\n taskData: {...payload, isConsulted: true},\n };\n\n case CC_EVENTS.AGENT_CONTACT_ASSIGNED: // AgentContactAssigned -> ASSIGN\n return {type: TaskEvent.ASSIGN, taskData: payload};\n\n case CC_EVENTS.AGENT_CONTACT_HELD:\n return {\n type: TaskEvent.HOLD_SUCCESS,\n mediaResourceId: mediaResourceId || '',\n taskData: payload,\n };\n\n case CC_EVENTS.AGENT_CONTACT_UNHELD:\n return {\n type: TaskEvent.UNHOLD_SUCCESS,\n mediaResourceId: mediaResourceId || '',\n taskData: payload,\n };\n\n case CC_EVENTS.AGENT_CONSULT_CREATED:\n return {\n type: TaskEvent.CONSULT_CREATED,\n taskData: {...payload, isConsulted: false},\n };\n\n case CC_EVENTS.AGENT_CONSULTING: // AgentConsulting -> CONSULTING_ACTIVE\n // use context to figure out if it's the initiator or receiver using consultInitiator from context\n return {\n type: TaskEvent.CONSULTING_ACTIVE,\n consultDestinationAgentJoined: true,\n taskData: payload,\n };\n\n case CC_EVENTS.AGENT_CONSULT_ENDED: // AgentConsultEnded -> CONSULT_END\n return {type: TaskEvent.CONSULT_END, taskData: payload};\n\n case CC_EVENTS.AGENT_CONSULT_FAILED:\n case CC_EVENTS.AGENT_CTQ_FAILED:\n return {type: TaskEvent.CONSULT_FAILED, reason: payload.reason, taskData: payload};\n\n case CC_EVENTS.AGENT_CTQ_CANCELLED:\n return {type: TaskEvent.CTQ_CANCEL, taskData: payload};\n\n case CC_EVENTS.AGENT_CTQ_CANCEL_FAILED:\n return {type: TaskEvent.CTQ_CANCEL_FAILED, taskData: payload};\n\n case CC_EVENTS.AGENT_BLIND_TRANSFERRED: // AgentBlindTransferred -> TRANSFER_SUCCESS\n case CC_EVENTS.AGENT_CONSULT_TRANSFERRED: // AgentConsultTransferred -> TRANSFER_SUCCESS\n case CC_EVENTS.AGENT_VTEAM_TRANSFERRED: // AgentVTeamTransferred -> TRANSFER_SUCCESS\n return {\n type: TaskEvent.TRANSFER_SUCCESS,\n taskData: payload,\n };\n\n case CC_EVENTS.AGENT_WRAPUP:\n return {type: TaskEvent.TASK_WRAPUP, taskData: {...payload, wrapUpRequired: true}};\n case CC_EVENTS.AGENT_CONTACT_UNASSIGNED:\n return null; // Add WRAPUP if needed\n\n case CC_EVENTS.AGENT_BLIND_TRANSFER_FAILED:\n case CC_EVENTS.AGENT_VTEAM_TRANSFER_FAILED:\n case CC_EVENTS.AGENT_CONSULT_TRANSFER_FAILED:\n case CC_EVENTS.AGENT_CONFERENCE_TRANSFER_FAILED:\n return {type: TaskEvent.TRANSFER_FAILED, taskData: payload};\n\n case CC_EVENTS.CONTACT_ENDED:\n return {\n type: TaskEvent.CONTACT_ENDED,\n taskData: {\n ...payload,\n wrapUpRequired: payload.interaction?.state !== 'new',\n },\n };\n\n case CC_EVENTS.AGENT_INVITE_FAILED:\n return {type: TaskEvent.INVITE_FAILED, reason: payload.reason};\n\n case CC_EVENTS.AGENT_CONTACT_ASSIGN_FAILED:\n return {type: TaskEvent.ASSIGN_FAILED, reason: payload.reason};\n\n case CC_EVENTS.AGENT_CONTACT_OFFER_RONA:\n return {type: TaskEvent.RONA, taskData: payload, reason: payload.reason};\n\n case CC_EVENTS.AGENT_OUTBOUND_FAILED:\n return {type: TaskEvent.OUTBOUND_FAILED, reason: payload.reason};\n\n case CC_EVENTS.CONTACT_RECORDING_STARTED:\n return {type: TaskEvent.RECORDING_STARTED, taskData: payload};\n\n case CC_EVENTS.CONTACT_RECORDING_PAUSED:\n return {type: TaskEvent.PAUSE_RECORDING, taskData: payload};\n\n case CC_EVENTS.CONTACT_RECORDING_RESUMED:\n return {type: TaskEvent.RESUME_RECORDING, taskData: payload};\n\n case CC_EVENTS.AGENT_WRAPPEDUP:\n return {type: TaskEvent.WRAPUP_COMPLETE, taskData: payload};\n\n // Conference events - these trigger state machine transition to CONFERENCING\n case CC_EVENTS.AGENT_CONSULT_CONFERENCED:\n case CC_EVENTS.AGENT_CONSULT_CONFERENCING:\n case CC_EVENTS.PARTICIPANT_JOINED_CONFERENCE:\n return {type: TaskEvent.CONFERENCE_START, taskData: payload};\n\n case CC_EVENTS.AGENT_CONSULT_CONFERENCE_FAILED:\n return {type: TaskEvent.CONFERENCE_FAILED, reason: payload.reason, taskData: payload};\n\n case CC_EVENTS.AGENT_CONSULT_CONFERENCE_ENDED:\n return {type: TaskEvent.CONFERENCE_END, taskData: payload};\n\n case CC_EVENTS.PARTICIPANT_LEFT_CONFERENCE:\n return {\n type: TaskEvent.PARTICIPANT_LEAVE,\n taskData: payload,\n participantId: payload?.participantId,\n };\n\n case CC_EVENTS.AGENT_CONFERENCE_TRANSFERRED:\n return {type: TaskEvent.TRANSFER_CONFERENCE_SUCCESS, taskData: payload};\n\n default:\n // Not all events need state machine mapping\n return null;\n }\n }\n\n /**\n * Register WebSocket message listeners for task events\n *\n * Main entry point that orchestrates event processing through a clear pipeline:\n * 1. Parse and validate incoming WebSocket messages\n * 2. Prepare event context with task and state machine mappings\n * 3. Handle task lifecycle (creation, updates, collection management)\n * 4. Send events to state machine (task-level transitions/emissions)\n * 5. Cleanup is triggered via task events emitted by the state machine\n *\n * This architecture separates concerns:\n * - TaskManager: Manages task collection lifecycle and operational concerns\n * - State Machine: Manages individual task state and event emissions\n */\n private registerTaskListeners() {\n this.webSocketManager.on('message', (event) => {\n // Step 1: Parse and validate the message\n const message = TaskManager.parseWebSocketMessage(event);\n if (!message) return;\n\n // Step 2: Prepare event context\n const eventContext = this.prepareEventContext(message);\n if (!eventContext) return;\n\n const actions = this.handleTaskLifecycleEvent(eventContext);\n\n const {task} = actions;\n if (!task) return;\n\n const {payload, stateMachineEvent} = eventContext;\n\n // Always keep task.data updated (even for mapped events) so consumers relying\n // on TaskManager-managed task instances see the latest payload.\n if (payload) {\n this.updateTaskData(task, payload);\n }\n\n // Send event to state machine - this will trigger all TASK_EVENTS emissions\n // including TASK_INCOMING which is now handled via the state machine callbacks\n if (stateMachineEvent) {\n task.sendStateMachineEvent(stateMachineEvent);\n }\n\n // Emit TASK_POST_CALL_ACTIVITY for ParticipantPostCallActivity events so\n // consumers (Widgets) can detect the interaction state change to post_call.\n if (eventContext.eventType === CC_EVENTS.PARTICIPANT_POST_CALL_ACTIVITY) {\n task.emit(TASK_EVENTS.TASK_POST_CALL_ACTIVITY, task);\n }\n\n // Send transcript start/stop events for relevant CC events\n this.requestRealTimeTranscripts(eventContext.eventType, payload.interactionId);\n });\n }\n\n /**\n * Parse and validate WebSocket message\n * @returns Parsed message or null if invalid/keepalive\n */\n private static parseWebSocketMessage(event: string): WebSocketMessage | null {\n try {\n const payload = JSON.parse(event) as WebSocketMessage;\n\n // Filter out keepalive messages\n if (payload?.keepalive === 'true' || payload?.keepalive === true) {\n return null;\n }\n\n // Normalize task data if present\n if (payload?.data?.interaction) {\n payload.data = normalizeTaskData(payload.data);\n }\n\n return payload;\n } catch (error) {\n LoggerProxy.error('Failed to parse WebSocket message', {\n module: TASK_MANAGER_FILE,\n method: 'parseWebSocketMessage',\n error,\n });\n\n return null;\n }\n }\n\n /**\n * Prepare context for event processing\n * @returns Event context or null if event type is invalid\n */\n private prepareEventContext(message: WebSocketMessage): EventContext | null {\n const eventType = message.data?.type || message.type;\n\n if (!eventType || !isCcEvent(eventType)) {\n return null;\n }\n\n const interactionId = message.data.interactionId;\n const task = this.taskCollection[interactionId];\n\n const wasConsultedTask = Boolean(task?.data?.isConsulted);\n const computeWrapUpRequired = () => {\n if (message.data.wrapUpRequired !== undefined) {\n return message.data.wrapUpRequired;\n }\n if (message.data.isConsulted !== undefined) {\n return !message.data.isConsulted;\n }\n\n return !wasConsultedTask;\n };\n\n const adjustedPayload =\n eventType === CC_EVENTS.AGENT_CONSULT_TRANSFERRED ||\n eventType === CC_EVENTS.AGENT_BLIND_TRANSFERRED ||\n eventType === CC_EVENTS.AGENT_VTEAM_TRANSFERRED\n ? {\n ...message.data,\n wrapUpRequired: computeWrapUpRequired(),\n }\n : message.data;\n\n const stateMachineEvent = TaskManager.mapEventToTaskStateMachineEvent(\n eventType,\n adjustedPayload,\n this.agentId\n );\n\n LoggerProxy.info(`Handling task event ${eventType}`, {\n module: TASK_MANAGER_FILE,\n method: 'prepareEventContext',\n interactionId,\n });\n\n return {\n eventType,\n payload: adjustedPayload,\n task,\n stateMachineEvent,\n };\n }\n\n /**\n * Handle task lifecycle events and determine required actions\n *\n * Delegates to specific event handlers based on event type. Each handler\n * is responsible for TaskManager-level concerns:\n * - Task creation and collection management\n * - Metrics tracking\n * - Resource cleanup decisions\n *\n * Note: Task-level state transitions and event emissions are handled by\n * the task state machine via sendStateMachineEvent()\n */\n private handleTaskLifecycleEvent(context: EventContext): TaskEventActions {\n const {eventType} = context;\n\n switch (eventType) {\n case CC_EVENTS.AGENT_CONTACT_RESERVED:\n return this.handleContactReserved(context);\n\n case CC_EVENTS.AGENT_CONTACT:\n return this.handleAgentContact(context);\n\n case CC_EVENTS.CONTACT_MERGED:\n return this.handleContactMergedEvent(context);\n\n default:\n return {task: context.task};\n }\n }\n\n /**\n * Handle AGENT_CONTACT_RESERVED event\n * Creates a new task; state machine event is sent during processing\n */\n private handleContactReserved(context: EventContext): TaskEventActions {\n const {payload} = context;\n const isConsultedTask =\n payload.isConsulted === true || isSecondaryEpDnAgent(payload.interaction);\n const shouldAutoAnswer = shouldAutoAnswerTask(\n payload,\n this.agentId,\n this.webCallingService.loginOption,\n this.webRtcEnabled\n );\n\n const taskData: TaskData = {\n ...payload,\n isConsulted: isConsultedTask,\n isAutoAnswering: shouldAutoAnswer,\n };\n\n const task = TaskFactory.createTask(\n this.contact,\n this.webCallingService,\n taskData,\n this.configFlags,\n this.wrapupData,\n this.agentId\n );\n\n this.setupTaskListeners(task);\n this.taskCollection[payload.interactionId] = task;\n\n return {task};\n }\n\n /**\n * Handle AGENT_CONTACT event\n * Re-creates task if missing (multi-session scenario)\n */\n private handleAgentContact(context: EventContext): TaskEventActions {\n let {task} = context;\n const {payload} = context;\n\n if (!task) {\n const isConsultedTask =\n payload.isConsulted === true || isSecondaryEpDnAgent(payload.interaction);\n const shouldAutoAnswer = shouldAutoAnswerTask(\n payload,\n this.agentId,\n this.webCallingService.loginOption,\n this.webRtcEnabled\n );\n const taskData: TaskData = {\n ...payload,\n isConsulted: isConsultedTask,\n wrapUpRequired: payload.interaction?.participants?.[this.agentId]?.isWrapUp || false,\n isConferenceInProgress: getIsConferenceInProgress(payload),\n isAutoAnswering: shouldAutoAnswer,\n };\n\n task = TaskFactory.createTask(\n this.contact,\n this.webCallingService,\n taskData,\n this.configFlags,\n this.wrapupData,\n this.agentId\n );\n this.setupTaskListeners(task);\n this.taskCollection[payload.interactionId] = task;\n }\n\n return {task};\n }\n\n private updateTaskData(task: ITask, taskData: TaskData): ITask {\n if (!task) {\n throw new Error('Task not found for update');\n }\n\n const snapshot = task.stateMachineService?.getSnapshot?.();\n const isConsultingFlow =\n snapshot?.value === 'CONSULTING' || taskData.interaction?.state === 'consulting';\n\n const updateTaskData = isConsultingFlow\n ? {\n ...taskData,\n destAgentId: taskData.destAgentId ?? snapshot?.context?.consultDestinationAgentId ?? null,\n destinationType:\n taskData.destinationType ?? snapshot?.context?.consultDestinationType ?? null,\n }\n : taskData;\n\n task.updateTaskData(updateTaskData);\n this.taskCollection[taskData.interactionId] = task;\n\n return task;\n }\n\n /**\n * Setup listeners for task events that need to be bubbled up to TaskManager\n * This replaces the previous callback injection pattern\n */\n private setupTaskListeners(task: ITask): void {\n // Listen for TASK_INCOMING and re-emit so webex.cc can notify consumers\n task.on(TASK_EVENTS.TASK_INCOMING, (t: ITask) => {\n LoggerProxy.log(`Task incoming event received`, {\n module: TASK_MANAGER_FILE,\n method: METHODS.REGISTER_TASK_LISTENERS,\n interactionId: t.data?.interactionId,\n });\n\n this.emit(TASK_EVENTS.TASK_INCOMING, t);\n });\n\n // Listen for TASK_HYDRATE on the task and re-emit on TaskManager\n task.on(TASK_EVENTS.TASK_HYDRATE, (t: ITask) => {\n // Task data is already updated by the task itself before emitting\n this.emit(TASK_EVENTS.TASK_HYDRATE, t);\n });\n\n // Listen for internal cleanup signal emitted by the state machine\n task.on(TASK_EVENTS.TASK_CLEANUP, (t: ITask, options?: {removeFromCollection?: boolean}) => {\n this.handleTaskCleanup(t);\n if (options?.removeFromCollection) {\n const interactionId = t?.data?.interactionId;\n if (interactionId && this.taskCollection[interactionId]) {\n this.removeTaskFromCollection(t);\n }\n }\n });\n }\n\n private removeTaskFromCollection(task: ITask) {\n if (typeof task.cancelAutoWrapupTimer === 'function') {\n task.cancelAutoWrapupTimer();\n }\n if (task?.data?.interactionId) {\n delete this.taskCollection[task.data.interactionId];\n LoggerProxy.info(`Task removed from collection`, {\n module: TASK_MANAGER_FILE,\n method: METHODS.REMOVE_TASK_FROM_COLLECTION,\n interactionId: task.data.interactionId,\n });\n }\n }\n\n /**\n * Handles CONTACT_MERGED event logic\n * @param task - The task to process\n * @param taskData - The task data from the event payload\n * @returns Updated or newly created task\n * @private\n */\n private handleContactMergedEvent(context: EventContext): TaskEventActions {\n const {payload} = context;\n let task = context.task;\n\n if (payload.childInteractionId && this.taskCollection[payload.childInteractionId]) {\n this.removeTaskFromCollection(this.taskCollection[payload.childInteractionId]);\n }\n\n if (task) {\n LoggerProxy.log(`Got CONTACT_MERGED: Task already exists in collection`, {\n module: TASK_MANAGER_FILE,\n method: METHODS.REGISTER_TASK_LISTENERS,\n interactionId: payload.interactionId,\n });\n // update the task data\n this.updateTaskData(task, payload);\n } else {\n // Case2 : Task is not present in taskCollection\n LoggerProxy.log(`Got CONTACT_MERGED : Creating new task in taskManager`, {\n module: TASK_MANAGER_FILE,\n method: METHODS.REGISTER_TASK_LISTENERS,\n interactionId: payload.interactionId,\n });\n\n const taskData: TaskData = {\n ...payload,\n wrapUpRequired: payload.interaction?.participants?.[this.agentId]?.isWrapUp || false,\n isConferenceInProgress: getIsConferenceInProgress(payload),\n isConsulted: false,\n };\n\n task = TaskFactory.createTask(\n this.contact,\n this.webCallingService,\n taskData,\n this.configFlags,\n this.wrapupData,\n this.agentId\n );\n this.taskCollection[payload.interactionId] = task;\n\n // Transition the new task out of IDLE immediately so UI controls are\n // computed before TASK_MERGED is emitted. This handles the race where\n // AgentContactAssigned arrives before ContactMerged and gets dropped.\n // Send HYDRATE before setupTaskListeners so the emitTaskHydrate action\n // doesn't bubble up to the Widget (avoids duplicate listener registration).\n task.sendStateMachineEvent({\n type: TaskEvent.HYDRATE,\n taskData,\n agentId: this.agentId,\n } as TaskEventPayload);\n\n this.setupTaskListeners(task);\n }\n\n if (task) {\n this.emit(TASK_EVENTS.TASK_MERGED, task);\n }\n\n return {task};\n }\n\n /**\n * Handles cleanup of task resources including Desktop/WebRTC call cleanup and task removal\n * @param task - The task to clean up\n * @private\n */\n private handleTaskCleanup(task: ITask) {\n if (\n this.webCallingService.loginOption === LoginOption.BROWSER &&\n task.data.interaction.mediaType === MEDIA_CHANNEL.TELEPHONY &&\n task instanceof WebRTC\n ) {\n task.unregisterWebCallListeners();\n this.webCallingService.cleanUpCall();\n }\n\n const isOutdial = task.data.interaction.outboundType === 'OUTDIAL';\n const isNew = task.data.interaction.state === 'new';\n const needsWrapUp = task.data.agentsPendingWrapUp?.length > 0;\n\n // For OUTDIAL: only remove if NOT terminated (user-declined, no wrap-up follows)\n // If terminated, keep task for wrap-up flow (CONTACT_ENDED → AGENT_WRAPUP)\n // For non-OUTDIAL: remove if state is 'new'\n // Always remove if secondary EpDn agent\n if ((isNew && !(isOutdial && needsWrapUp)) || isSecondaryEpDnAgent(task.data.interaction)) {\n this.removeTaskFromCollection(task);\n }\n }\n\n /**\n * Sends transcript start/stop event based on the CC event type.\n * Fire-and-forget; errors are logged but do not interrupt event processing.\n */\n private requestRealTimeTranscripts(eventType: string, interactionId: string): void {\n const action = TRANSCRIPT_EVENT_MAP[eventType];\n if (!action || !this.apiAIAssistant) return;\n if (this.configFlags?.aiFeature?.realtimeTranscripts?.enable === false) return;\n\n this.apiAIAssistant\n .sendEvent(\n this.agentId,\n interactionId,\n AIAssistantEventType.CUSTOM_EVENT,\n AIAssistantEventName.GET_TRANSCRIPTS,\n action\n )\n .catch((error) => {\n LoggerProxy.error(`Failed to send transcript ${action} event`, {\n module: TASK_MANAGER_FILE,\n method: METHODS.REQUEST_REAL_TIME_TRANSCRIPTS,\n interactionId,\n error,\n });\n });\n }\n\n public getTask(taskId: TaskId): ITask {\n return this.taskCollection[taskId];\n }\n\n public getAllTasks(): Record<TaskId, ITask> {\n return {...this.taskCollection};\n }\n\n public static getTaskManager(\n apiAIAssistant: ApiAIAssistant,\n contact: ReturnType<typeof routingContact>,\n webCallingService: WebCallingService,\n webSocketManager: WebSocketManager,\n rtdWebSocketManager?: WebSocketManager\n ): TaskManager {\n if (!TaskManager.taskManager) {\n TaskManager.taskManager = new TaskManager(\n apiAIAssistant,\n contact,\n webCallingService,\n webSocketManager,\n rtdWebSocketManager\n );\n }\n\n return TaskManager.taskManager;\n }\n}\n"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"names":["_events","_interopRequireDefault","require","_calling","_types","_constants","_constants2","_types2","_types3","_loggerProxy","_TaskUtils","_TaskFactory","_WebRTC","_stateMachine","_taskDataNormalizer","e","__esModule","default","CC_EVENT_SET","Set","Object","values","CC_EVENTS","isCcEvent","value","has","TaskManager","EventEmitter","constructor","apiAIAssistant","contact","webCallingService","webSocketManager","rtdWebSocketManager","taskCollection","webRtcEnabled","registerTaskListeners","registerIncomingCallEvent","handleRealtimeWebsocketEvent","event","payload","JSON","parse","interactionId","data","conversationId","task","LoggerProxy","info","module","TASK_MANAGER_FILE","method","METHODS","HANDLE_REAL_TIME_WEBSOCKET_EVENT","emit","type","error","setConfigFlags","configFlags","setWrapupData","wrapupData","setAgentId","agentId","getAgentId","setWebRtcEnabled","handleIncomingWebCall","call","currentTask","find","t","interaction","mediaType","MEDIA_CHANNEL","TELEPHONY","mapCallToTask","getCallId","log","HANDLE_INCOMING_WEB_CALL","eventPayload","mapEventToTaskStateMachineEvent","AGENT_CONTACT_RESERVED","sendStateMachineEvent","on","LINE_EVENTS","INCOMING_CALL","unregisterIncomingCallEvent","off","ccEvent","mediaResourceId","media","TaskEvent","TASK_INCOMING","taskData","AGENT_OFFER_CONTACT","TASK_OFFERED","AGENT_CONTACT","HYDRATE","CONTACT_UPDATED","CONTACT_OWNER_CHANGED","AGENT_OFFER_CONSULT","OFFER_CONSULT","isConsulted","AGENT_CONTACT_ASSIGNED","ASSIGN","AGENT_CONTACT_HELD","HOLD_SUCCESS","AGENT_CONTACT_UNHELD","UNHOLD_SUCCESS","AGENT_CONSULT_CREATED","CONSULT_CREATED","AGENT_CONSULTING","CONSULTING_ACTIVE","consultDestinationAgentJoined","AGENT_CONSULT_ENDED","CONSULT_END","AGENT_CONSULT_FAILED","AGENT_CTQ_FAILED","CONSULT_FAILED","reason","AGENT_CTQ_CANCELLED","CTQ_CANCEL","AGENT_CTQ_CANCEL_FAILED","CTQ_CANCEL_FAILED","AGENT_BLIND_TRANSFERRED","AGENT_CONSULT_TRANSFERRED","AGENT_VTEAM_TRANSFERRED","TRANSFER_SUCCESS","AGENT_WRAPUP","TASK_WRAPUP","wrapUpRequired","AGENT_CONTACT_UNASSIGNED","AGENT_BLIND_TRANSFER_FAILED","AGENT_VTEAM_TRANSFER_FAILED","AGENT_CONSULT_TRANSFER_FAILED","AGENT_CONFERENCE_TRANSFER_FAILED","TRANSFER_FAILED","CONTACT_ENDED","state","AGENT_INVITE_FAILED","INVITE_FAILED","AGENT_CONTACT_ASSIGN_FAILED","ASSIGN_FAILED","AGENT_CONTACT_OFFER_RONA","RONA","AGENT_OUTBOUND_FAILED","OUTBOUND_FAILED","CONTACT_RECORDING_STARTED","RECORDING_STARTED","CONTACT_RECORDING_PAUSED","PAUSE_RECORDING","CONTACT_RECORDING_RESUMED","RESUME_RECORDING","AGENT_WRAPPEDUP","WRAPUP_COMPLETE","AGENT_CONSULT_CONFERENCED","AGENT_CONSULT_CONFERENCING","PARTICIPANT_JOINED_CONFERENCE","CONFERENCE_START","AGENT_CONSULT_CONFERENCE_FAILED","CONFERENCE_FAILED","AGENT_CONSULT_CONFERENCE_ENDED","CONFERENCE_END","PARTICIPANT_LEFT_CONFERENCE","PARTICIPANT_LEAVE","participantId","AGENT_CONFERENCE_TRANSFERRED","TRANSFER_CONFERENCE_SUCCESS","message","parseWebSocketMessage","eventContext","prepareEventContext","actions","handleTaskLifecycleEvent","stateMachineEvent","updateTaskData","eventType","PARTICIPANT_POST_CALL_ACTIVITY","TASK_EVENTS","TASK_POST_CALL_ACTIVITY","requestRealTimeTranscripts","keepalive","normalizeTaskData","wasConsultedTask","Boolean","computeWrapUpRequired","undefined","adjustedPayload","context","handleContactReserved","handleAgentContact","CONTACT_MERGED","handleContactMergedEvent","isConsultedTask","isSecondaryEpDnAgent","shouldAutoAnswer","shouldAutoAnswerTask","loginOption","isAutoAnswering","TaskFactory","createTask","setupTaskListeners","participants","isWrapUp","isConferenceInProgress","getIsConferenceInProgress","Error","snapshot","stateMachineService","getSnapshot","isConsultingFlow","destAgentId","consultDestinationAgentId","destinationType","consultDestinationType","REGISTER_TASK_LISTENERS","TASK_HYDRATE","TASK_CLEANUP","options","handleTaskCleanup","removeFromCollection","removeTaskFromCollection","cancelAutoWrapupTimer","REMOVE_TASK_FROM_COLLECTION","childInteractionId","TASK_MERGED","LoginOption","BROWSER","WebRTC","unregisterWebCallListeners","cleanUpCall","isOutdial","outboundType","isNew","needsWrapUp","agentsPendingWrapUp","length","action","TRANSCRIPT_EVENT_MAP","aiFeature","realtimeTranscripts","enable","sendEvent","AIAssistantEventType","CUSTOM_EVENT","AIAssistantEventName","GET_TRANSCRIPTS","catch","REQUEST_REAL_TIME_TRANSCRIPTS","getTask","taskId","getAllTasks","getTaskManager","taskManager","exports"],"sources":["TaskManager.ts"],"sourcesContent":["import EventEmitter from 'events';\nimport {ICall, LINE_EVENTS} from '@webex/calling';\nimport {WebSocketManager} from '../core/websocket/WebSocketManager';\nimport routingContact from './contact';\nimport WebCallingService from '../WebCallingService';\nimport {\n MEDIA_CHANNEL,\n TASK_EVENTS,\n TaskData,\n TaskId,\n ITask,\n WebSocketPayload,\n WebSocketMessage,\n TaskEventActions,\n EventContext,\n} from './types';\nimport {TASK_MANAGER_FILE} from '../../constants';\nimport {METHODS, TRANSCRIPT_EVENT_MAP} from './constants';\nimport {CC_EVENTS, WrapupData} from '../config/types';\nimport {ConfigFlags, LoginOption, AIAssistantEventType, AIAssistantEventName} from '../../types';\nimport LoggerProxy from '../../logger-proxy';\nimport {getIsConferenceInProgress, isSecondaryEpDnAgent, shouldAutoAnswerTask} from './TaskUtils';\nimport TaskFactory from './TaskFactory';\nimport WebRTC from './voice/WebRTC';\nimport {TaskEvent, type TaskEventPayload} from './state-machine';\nimport {normalizeTaskData} from './taskDataNormalizer';\nimport {ApiAIAssistant} from '../ApiAiAssistant';\n\nconst CC_EVENT_SET = new Set<CC_EVENTS>(Object.values(CC_EVENTS) as CC_EVENTS[]);\n\nconst isCcEvent = (value: string): value is CC_EVENTS => CC_EVENT_SET.has(value as CC_EVENTS);\n\n/** @internal */\nexport default class TaskManager extends EventEmitter {\n private call: ICall;\n private contact: ReturnType<typeof routingContact>;\n /**\n * Collection of tasks indexed by TaskId\n * @type {Record<TaskId, ITask>}\n * @private\n */\n private taskCollection: Record<TaskId, ITask>;\n private webCallingService: WebCallingService;\n private webSocketManager: WebSocketManager;\n private rtdWebSocketManager: WebSocketManager;\n // eslint-disable-next-line no-use-before-define\n private static taskManager: TaskManager;\n private configFlags?: ConfigFlags;\n private wrapupData: WrapupData;\n private agentId: string;\n private webRtcEnabled: boolean;\n private apiAIAssistant?: ApiAIAssistant;\n /**\n * @param contact - Routing Contact layer. Talks to AQMReq layer to convert events to promises\n * @param webCallingService - Webrtc Service Layer\n * @param webSocketManager - Websocket Manager to maintain websocket connection and keepalives\n */\n constructor(\n apiAIAssistant: ApiAIAssistant,\n contact: ReturnType<typeof routingContact>,\n webCallingService: WebCallingService,\n webSocketManager: WebSocketManager,\n rtdWebSocketManager: WebSocketManager\n ) {\n super();\n this.apiAIAssistant = apiAIAssistant;\n this.contact = contact;\n this.webCallingService = webCallingService;\n this.webSocketManager = webSocketManager;\n this.rtdWebSocketManager = rtdWebSocketManager;\n this.taskCollection = {};\n this.webRtcEnabled = false;\n\n this.registerTaskListeners();\n this.registerIncomingCallEvent();\n }\n\n public handleRealtimeWebsocketEvent(event: string) {\n try {\n const payload = JSON.parse(event);\n\n const interactionId = payload?.data?.data?.conversationId;\n if (!interactionId) return;\n\n const task = this.taskCollection[interactionId];\n if (!task) {\n LoggerProxy.info(`Realtime transcription task not found`, {\n module: TASK_MANAGER_FILE,\n method: METHODS.HANDLE_REAL_TIME_WEBSOCKET_EVENT,\n interactionId,\n });\n\n return;\n }\n\n task.emit(payload.type, payload.data);\n } catch (error) {\n LoggerProxy.error('Failed to parse RTD WebSocket message', {\n module: TASK_MANAGER_FILE,\n method: METHODS.HANDLE_REAL_TIME_WEBSOCKET_EVENT,\n error,\n });\n }\n }\n\n /**\n * Set config flags for task creation\n */\n public setConfigFlags(configFlags: ConfigFlags) {\n this.configFlags = configFlags;\n }\n\n /**\n * Set wrapup configuration data\n */\n public setWrapupData(wrapupData: WrapupData) {\n this.wrapupData = wrapupData;\n }\n\n /**\n * Set agent ID for task operations\n */\n public setAgentId(agentId: string) {\n this.agentId = agentId;\n }\n\n /**\n * Gets the current agent ID\n * @returns {string} The agent ID set for this task manager instance\n * @public\n */\n public getAgentId(): string {\n return this.agentId;\n }\n\n public setWebRtcEnabled(webRtcEnabled: boolean) {\n this.webRtcEnabled = webRtcEnabled;\n }\n\n private handleIncomingWebCall = (call: ICall) => {\n const currentTask = Object.values(this.taskCollection).find(\n (t) => t.data.interaction.mediaType === MEDIA_CHANNEL.TELEPHONY\n );\n\n if (currentTask) {\n this.webCallingService.mapCallToTask(call.getCallId(), currentTask.data.interactionId);\n LoggerProxy.log(`Call mapped to task`, {\n module: TASK_MANAGER_FILE,\n method: METHODS.HANDLE_INCOMING_WEB_CALL,\n interactionId: currentTask.data.interactionId,\n });\n\n // Send TASK_INCOMING to state machine - it will emit on the task object\n const eventPayload = TaskManager.mapEventToTaskStateMachineEvent(\n CC_EVENTS.AGENT_CONTACT_RESERVED,\n currentTask.data\n );\n if (eventPayload && currentTask) {\n currentTask.sendStateMachineEvent(eventPayload);\n }\n }\n this.call = call;\n };\n\n public registerIncomingCallEvent() {\n this.webCallingService.on(LINE_EVENTS.INCOMING_CALL, this.handleIncomingWebCall);\n }\n\n public unregisterIncomingCallEvent() {\n this.webCallingService.off(LINE_EVENTS.INCOMING_CALL, this.handleIncomingWebCall);\n }\n\n /**\n * Map WebSocket CC_EVENTS to state machine TaskEvent\n * @param ccEvent - The CC_EVENT type from WebSocket\n * @param payload - The event payload\n * @param agentId - Optional agent ID for state detection (needed for HYDRATE)\n * @returns TaskEventPayload for state machine or null if no mapping\n */\n private static mapEventToTaskStateMachineEvent(\n ccEvent: CC_EVENTS,\n payload: WebSocketPayload,\n agentId?: string\n ): TaskEventPayload | null {\n const mediaResourceId =\n payload.mediaResourceId ||\n payload.interaction?.media?.[payload.interactionId]?.mediaResourceId;\n\n switch (ccEvent) {\n // CC -> TaskEvent mappings (see TaskStateMachine comment for quick reference)\n case CC_EVENTS.AGENT_CONTACT_RESERVED: // AgentContactReserved -> TASK_INCOMING\n return {type: TaskEvent.TASK_INCOMING, taskData: payload};\n\n case CC_EVENTS.AGENT_OFFER_CONTACT: // AgentOfferContact -> TASK_OFFERED\n return {type: TaskEvent.TASK_OFFERED, taskData: payload};\n\n case CC_EVENTS.AGENT_CONTACT: // AgentContact -> HYDRATE\n // Include agentId for state detection (e.g., checking isWrapUp in participant data)\n return {type: TaskEvent.HYDRATE, taskData: payload, agentId};\n\n case CC_EVENTS.CONTACT_UPDATED:\n return {type: TaskEvent.CONTACT_UPDATED, taskData: payload};\n case CC_EVENTS.CONTACT_OWNER_CHANGED:\n return {type: TaskEvent.CONTACT_OWNER_CHANGED, taskData: payload};\n\n case CC_EVENTS.AGENT_OFFER_CONSULT: // AgentOfferConsult -> OFFER_CONSULT\n return {\n type: TaskEvent.OFFER_CONSULT,\n taskData: {...payload, isConsulted: true},\n };\n\n case CC_EVENTS.AGENT_CONTACT_ASSIGNED: // AgentContactAssigned -> ASSIGN\n return {type: TaskEvent.ASSIGN, taskData: payload};\n\n case CC_EVENTS.AGENT_CONTACT_HELD:\n return {\n type: TaskEvent.HOLD_SUCCESS,\n mediaResourceId: mediaResourceId || '',\n taskData: payload,\n };\n\n case CC_EVENTS.AGENT_CONTACT_UNHELD:\n return {\n type: TaskEvent.UNHOLD_SUCCESS,\n mediaResourceId: mediaResourceId || '',\n taskData: payload,\n };\n\n case CC_EVENTS.AGENT_CONSULT_CREATED:\n return {\n type: TaskEvent.CONSULT_CREATED,\n taskData: {...payload, isConsulted: false},\n };\n\n case CC_EVENTS.AGENT_CONSULTING: // AgentConsulting -> CONSULTING_ACTIVE\n // use context to figure out if it's the initiator or receiver using consultInitiator from context\n return {\n type: TaskEvent.CONSULTING_ACTIVE,\n consultDestinationAgentJoined: true,\n taskData: payload,\n };\n\n case CC_EVENTS.AGENT_CONSULT_ENDED: // AgentConsultEnded -> CONSULT_END\n return {type: TaskEvent.CONSULT_END, taskData: payload};\n\n case CC_EVENTS.AGENT_CONSULT_FAILED:\n case CC_EVENTS.AGENT_CTQ_FAILED:\n return {type: TaskEvent.CONSULT_FAILED, reason: payload.reason, taskData: payload};\n\n case CC_EVENTS.AGENT_CTQ_CANCELLED:\n return {type: TaskEvent.CTQ_CANCEL, taskData: payload};\n\n case CC_EVENTS.AGENT_CTQ_CANCEL_FAILED:\n return {type: TaskEvent.CTQ_CANCEL_FAILED, taskData: payload};\n\n case CC_EVENTS.AGENT_BLIND_TRANSFERRED: // AgentBlindTransferred -> TRANSFER_SUCCESS\n case CC_EVENTS.AGENT_CONSULT_TRANSFERRED: // AgentConsultTransferred -> TRANSFER_SUCCESS\n case CC_EVENTS.AGENT_VTEAM_TRANSFERRED: // AgentVTeamTransferred -> TRANSFER_SUCCESS\n return {\n type: TaskEvent.TRANSFER_SUCCESS,\n taskData: payload,\n };\n\n case CC_EVENTS.AGENT_WRAPUP:\n return {type: TaskEvent.TASK_WRAPUP, taskData: {...payload, wrapUpRequired: true}};\n case CC_EVENTS.AGENT_CONTACT_UNASSIGNED:\n return null; // Add WRAPUP if needed\n\n case CC_EVENTS.AGENT_BLIND_TRANSFER_FAILED:\n case CC_EVENTS.AGENT_VTEAM_TRANSFER_FAILED:\n case CC_EVENTS.AGENT_CONSULT_TRANSFER_FAILED:\n case CC_EVENTS.AGENT_CONFERENCE_TRANSFER_FAILED:\n return {type: TaskEvent.TRANSFER_FAILED, taskData: payload};\n\n case CC_EVENTS.CONTACT_ENDED:\n return {\n type: TaskEvent.CONTACT_ENDED,\n taskData: {\n ...payload,\n wrapUpRequired: payload.interaction?.state !== 'new',\n },\n };\n\n case CC_EVENTS.AGENT_INVITE_FAILED:\n return {type: TaskEvent.INVITE_FAILED, reason: payload.reason};\n\n case CC_EVENTS.AGENT_CONTACT_ASSIGN_FAILED:\n return {type: TaskEvent.ASSIGN_FAILED, reason: payload.reason};\n\n case CC_EVENTS.AGENT_CONTACT_OFFER_RONA:\n return {type: TaskEvent.RONA, taskData: payload, reason: payload.reason};\n\n case CC_EVENTS.AGENT_OUTBOUND_FAILED:\n return {type: TaskEvent.OUTBOUND_FAILED, taskData: payload, reason: payload.reason};\n\n case CC_EVENTS.CONTACT_RECORDING_STARTED:\n return {type: TaskEvent.RECORDING_STARTED, taskData: payload};\n\n case CC_EVENTS.CONTACT_RECORDING_PAUSED:\n return {type: TaskEvent.PAUSE_RECORDING, taskData: payload};\n\n case CC_EVENTS.CONTACT_RECORDING_RESUMED:\n return {type: TaskEvent.RESUME_RECORDING, taskData: payload};\n\n case CC_EVENTS.AGENT_WRAPPEDUP:\n return {type: TaskEvent.WRAPUP_COMPLETE, taskData: payload};\n\n // Conference events - these trigger state machine transition to CONFERENCING\n case CC_EVENTS.AGENT_CONSULT_CONFERENCED:\n case CC_EVENTS.AGENT_CONSULT_CONFERENCING:\n case CC_EVENTS.PARTICIPANT_JOINED_CONFERENCE:\n return {type: TaskEvent.CONFERENCE_START, taskData: payload};\n\n case CC_EVENTS.AGENT_CONSULT_CONFERENCE_FAILED:\n return {type: TaskEvent.CONFERENCE_FAILED, reason: payload.reason, taskData: payload};\n\n case CC_EVENTS.AGENT_CONSULT_CONFERENCE_ENDED:\n return {type: TaskEvent.CONFERENCE_END, taskData: payload};\n\n case CC_EVENTS.PARTICIPANT_LEFT_CONFERENCE:\n return {\n type: TaskEvent.PARTICIPANT_LEAVE,\n taskData: payload,\n participantId: payload?.participantId,\n };\n\n case CC_EVENTS.AGENT_CONFERENCE_TRANSFERRED:\n return {type: TaskEvent.TRANSFER_CONFERENCE_SUCCESS, taskData: payload};\n\n default:\n // Not all events need state machine mapping\n return null;\n }\n }\n\n /**\n * Register WebSocket message listeners for task events\n *\n * Main entry point that orchestrates event processing through a clear pipeline:\n * 1. Parse and validate incoming WebSocket messages\n * 2. Prepare event context with task and state machine mappings\n * 3. Handle task lifecycle (creation, updates, collection management)\n * 4. Send events to state machine (task-level transitions/emissions)\n * 5. Cleanup is triggered via task events emitted by the state machine\n *\n * This architecture separates concerns:\n * - TaskManager: Manages task collection lifecycle and operational concerns\n * - State Machine: Manages individual task state and event emissions\n */\n private registerTaskListeners() {\n this.webSocketManager.on('message', (event) => {\n // Step 1: Parse and validate the message\n const message = TaskManager.parseWebSocketMessage(event);\n if (!message) return;\n\n // Step 2: Prepare event context\n const eventContext = this.prepareEventContext(message);\n if (!eventContext) return;\n\n const actions = this.handleTaskLifecycleEvent(eventContext);\n\n const {task} = actions;\n if (!task) return;\n\n const {payload, stateMachineEvent} = eventContext;\n\n // Always keep task.data updated (even for mapped events) so consumers relying\n // on TaskManager-managed task instances see the latest payload.\n if (payload) {\n this.updateTaskData(task, payload);\n }\n\n // Send event to state machine - this will trigger all TASK_EVENTS emissions\n // including TASK_INCOMING which is now handled via the state machine callbacks\n if (stateMachineEvent) {\n task.sendStateMachineEvent(stateMachineEvent);\n }\n\n // Emit TASK_POST_CALL_ACTIVITY for ParticipantPostCallActivity events so\n // consumers (Widgets) can detect the interaction state change to post_call.\n if (eventContext.eventType === CC_EVENTS.PARTICIPANT_POST_CALL_ACTIVITY) {\n task.emit(TASK_EVENTS.TASK_POST_CALL_ACTIVITY, task);\n }\n\n // Send transcript start/stop events for relevant CC events\n this.requestRealTimeTranscripts(eventContext.eventType, payload.interactionId);\n });\n }\n\n /**\n * Parse and validate WebSocket message\n * @returns Parsed message or null if invalid/keepalive\n */\n private static parseWebSocketMessage(event: string): WebSocketMessage | null {\n try {\n const payload = JSON.parse(event) as WebSocketMessage;\n\n // Filter out keepalive messages\n if (payload?.keepalive === 'true' || payload?.keepalive === true) {\n return null;\n }\n\n // Normalize task data if present\n if (payload?.data?.interaction) {\n payload.data = normalizeTaskData(payload.data);\n }\n\n return payload;\n } catch (error) {\n LoggerProxy.error('Failed to parse WebSocket message', {\n module: TASK_MANAGER_FILE,\n method: 'parseWebSocketMessage',\n error,\n });\n\n return null;\n }\n }\n\n /**\n * Prepare context for event processing\n * @returns Event context or null if event type is invalid\n */\n private prepareEventContext(message: WebSocketMessage): EventContext | null {\n const eventType = message.data?.type || message.type;\n\n if (!eventType || !isCcEvent(eventType)) {\n return null;\n }\n\n const interactionId = message.data.interactionId;\n const task = this.taskCollection[interactionId];\n\n const wasConsultedTask = Boolean(task?.data?.isConsulted);\n const computeWrapUpRequired = () => {\n if (message.data.wrapUpRequired !== undefined) {\n return message.data.wrapUpRequired;\n }\n if (message.data.isConsulted !== undefined) {\n return !message.data.isConsulted;\n }\n\n return !wasConsultedTask;\n };\n\n const adjustedPayload =\n eventType === CC_EVENTS.AGENT_CONSULT_TRANSFERRED ||\n eventType === CC_EVENTS.AGENT_BLIND_TRANSFERRED ||\n eventType === CC_EVENTS.AGENT_VTEAM_TRANSFERRED\n ? {\n ...message.data,\n wrapUpRequired: computeWrapUpRequired(),\n }\n : message.data;\n\n const stateMachineEvent = TaskManager.mapEventToTaskStateMachineEvent(\n eventType,\n adjustedPayload,\n this.agentId\n );\n\n LoggerProxy.info(`Handling task event ${eventType}`, {\n module: TASK_MANAGER_FILE,\n method: 'prepareEventContext',\n interactionId,\n });\n\n return {\n eventType,\n payload: adjustedPayload,\n task,\n stateMachineEvent,\n };\n }\n\n /**\n * Handle task lifecycle events and determine required actions\n *\n * Delegates to specific event handlers based on event type. Each handler\n * is responsible for TaskManager-level concerns:\n * - Task creation and collection management\n * - Metrics tracking\n * - Resource cleanup decisions\n *\n * Note: Task-level state transitions and event emissions are handled by\n * the task state machine via sendStateMachineEvent()\n */\n private handleTaskLifecycleEvent(context: EventContext): TaskEventActions {\n const {eventType} = context;\n\n switch (eventType) {\n case CC_EVENTS.AGENT_CONTACT_RESERVED:\n return this.handleContactReserved(context);\n\n case CC_EVENTS.AGENT_CONTACT:\n return this.handleAgentContact(context);\n\n case CC_EVENTS.CONTACT_MERGED:\n return this.handleContactMergedEvent(context);\n\n default:\n return {task: context.task};\n }\n }\n\n /**\n * Handle AGENT_CONTACT_RESERVED event\n * Creates a new task; state machine event is sent during processing\n */\n private handleContactReserved(context: EventContext): TaskEventActions {\n const {payload} = context;\n const isConsultedTask =\n payload.isConsulted === true || isSecondaryEpDnAgent(payload.interaction);\n const shouldAutoAnswer = shouldAutoAnswerTask(\n payload,\n this.agentId,\n this.webCallingService.loginOption,\n this.webRtcEnabled\n );\n\n const taskData: TaskData = {\n ...payload,\n isConsulted: isConsultedTask,\n isAutoAnswering: shouldAutoAnswer,\n };\n\n const task = TaskFactory.createTask(\n this.contact,\n this.webCallingService,\n taskData,\n this.configFlags,\n this.wrapupData,\n this.agentId\n );\n\n this.setupTaskListeners(task);\n this.taskCollection[payload.interactionId] = task;\n\n return {task};\n }\n\n /**\n * Handle AGENT_CONTACT event\n * Re-creates task if missing (multi-session scenario)\n */\n private handleAgentContact(context: EventContext): TaskEventActions {\n let {task} = context;\n const {payload} = context;\n\n if (!task) {\n const isConsultedTask =\n payload.isConsulted === true || isSecondaryEpDnAgent(payload.interaction);\n const shouldAutoAnswer = shouldAutoAnswerTask(\n payload,\n this.agentId,\n this.webCallingService.loginOption,\n this.webRtcEnabled\n );\n const taskData: TaskData = {\n ...payload,\n isConsulted: isConsultedTask,\n wrapUpRequired: payload.interaction?.participants?.[this.agentId]?.isWrapUp || false,\n isConferenceInProgress: getIsConferenceInProgress(payload),\n isAutoAnswering: shouldAutoAnswer,\n };\n\n task = TaskFactory.createTask(\n this.contact,\n this.webCallingService,\n taskData,\n this.configFlags,\n this.wrapupData,\n this.agentId\n );\n this.setupTaskListeners(task);\n this.taskCollection[payload.interactionId] = task;\n }\n\n return {task};\n }\n\n private updateTaskData(task: ITask, taskData: TaskData): ITask {\n if (!task) {\n throw new Error('Task not found for update');\n }\n\n const snapshot = task.stateMachineService?.getSnapshot?.();\n const isConsultingFlow =\n snapshot?.value === 'CONSULTING' || taskData.interaction?.state === 'consulting';\n\n const updateTaskData = isConsultingFlow\n ? {\n ...taskData,\n destAgentId: taskData.destAgentId ?? snapshot?.context?.consultDestinationAgentId ?? null,\n destinationType:\n taskData.destinationType ?? snapshot?.context?.consultDestinationType ?? null,\n }\n : taskData;\n\n task.updateTaskData(updateTaskData);\n this.taskCollection[taskData.interactionId] = task;\n\n return task;\n }\n\n /**\n * Setup listeners for task events that need to be bubbled up to TaskManager\n * This replaces the previous callback injection pattern\n */\n private setupTaskListeners(task: ITask): void {\n // Listen for TASK_INCOMING and re-emit so webex.cc can notify consumers\n task.on(TASK_EVENTS.TASK_INCOMING, (t: ITask) => {\n LoggerProxy.log(`Task incoming event received`, {\n module: TASK_MANAGER_FILE,\n method: METHODS.REGISTER_TASK_LISTENERS,\n interactionId: t.data?.interactionId,\n });\n\n this.emit(TASK_EVENTS.TASK_INCOMING, t);\n });\n\n // Listen for TASK_HYDRATE on the task and re-emit on TaskManager\n task.on(TASK_EVENTS.TASK_HYDRATE, (t: ITask) => {\n // Task data is already updated by the task itself before emitting\n this.emit(TASK_EVENTS.TASK_HYDRATE, t);\n });\n\n // Listen for internal cleanup signal emitted by the state machine\n task.on(TASK_EVENTS.TASK_CLEANUP, (t: ITask, options?: {removeFromCollection?: boolean}) => {\n this.handleTaskCleanup(t);\n if (options?.removeFromCollection) {\n const interactionId = t?.data?.interactionId;\n if (interactionId && this.taskCollection[interactionId]) {\n this.removeTaskFromCollection(t);\n }\n }\n });\n }\n\n private removeTaskFromCollection(task: ITask) {\n if (typeof task.cancelAutoWrapupTimer === 'function') {\n task.cancelAutoWrapupTimer();\n }\n if (task?.data?.interactionId) {\n delete this.taskCollection[task.data.interactionId];\n LoggerProxy.info(`Task removed from collection`, {\n module: TASK_MANAGER_FILE,\n method: METHODS.REMOVE_TASK_FROM_COLLECTION,\n interactionId: task.data.interactionId,\n });\n }\n }\n\n /**\n * Handles CONTACT_MERGED event logic\n * @param task - The task to process\n * @param taskData - The task data from the event payload\n * @returns Updated or newly created task\n * @private\n */\n private handleContactMergedEvent(context: EventContext): TaskEventActions {\n const {payload} = context;\n let task = context.task;\n\n if (payload.childInteractionId && this.taskCollection[payload.childInteractionId]) {\n this.removeTaskFromCollection(this.taskCollection[payload.childInteractionId]);\n }\n\n if (task) {\n LoggerProxy.log(`Got CONTACT_MERGED: Task already exists in collection`, {\n module: TASK_MANAGER_FILE,\n method: METHODS.REGISTER_TASK_LISTENERS,\n interactionId: payload.interactionId,\n });\n // update the task data\n this.updateTaskData(task, payload);\n } else {\n // Case2 : Task is not present in taskCollection\n LoggerProxy.log(`Got CONTACT_MERGED : Creating new task in taskManager`, {\n module: TASK_MANAGER_FILE,\n method: METHODS.REGISTER_TASK_LISTENERS,\n interactionId: payload.interactionId,\n });\n\n const taskData: TaskData = {\n ...payload,\n wrapUpRequired: payload.interaction?.participants?.[this.agentId]?.isWrapUp || false,\n isConferenceInProgress: getIsConferenceInProgress(payload),\n isConsulted: false,\n };\n\n task = TaskFactory.createTask(\n this.contact,\n this.webCallingService,\n taskData,\n this.configFlags,\n this.wrapupData,\n this.agentId\n );\n this.taskCollection[payload.interactionId] = task;\n\n // Transition the new task out of IDLE immediately so UI controls are\n // computed before TASK_MERGED is emitted. This handles the race where\n // AgentContactAssigned arrives before ContactMerged and gets dropped.\n // Send HYDRATE before setupTaskListeners so the emitTaskHydrate action\n // doesn't bubble up to the Widget (avoids duplicate listener registration).\n task.sendStateMachineEvent({\n type: TaskEvent.HYDRATE,\n taskData,\n agentId: this.agentId,\n } as TaskEventPayload);\n\n this.setupTaskListeners(task);\n }\n\n if (task) {\n this.emit(TASK_EVENTS.TASK_MERGED, task);\n }\n\n return {task};\n }\n\n /**\n * Handles cleanup of task resources including Desktop/WebRTC call cleanup and task removal\n * @param task - The task to clean up\n * @private\n */\n private handleTaskCleanup(task: ITask) {\n if (\n this.webCallingService.loginOption === LoginOption.BROWSER &&\n task.data.interaction.mediaType === MEDIA_CHANNEL.TELEPHONY &&\n task instanceof WebRTC\n ) {\n task.unregisterWebCallListeners();\n this.webCallingService.cleanUpCall();\n }\n\n const isOutdial = task.data.interaction.outboundType === 'OUTDIAL';\n const isNew = task.data.interaction.state === 'new';\n const needsWrapUp = task.data.agentsPendingWrapUp?.length > 0;\n\n // For OUTDIAL: only remove if NOT terminated (user-declined, no wrap-up follows)\n // If terminated, keep task for wrap-up flow (CONTACT_ENDED → AGENT_WRAPUP)\n // For non-OUTDIAL: remove if state is 'new'\n // Always remove if secondary EpDn agent\n if ((isNew && !(isOutdial && needsWrapUp)) || isSecondaryEpDnAgent(task.data.interaction)) {\n this.removeTaskFromCollection(task);\n }\n }\n\n /**\n * Sends transcript start/stop event based on the CC event type.\n * Fire-and-forget; errors are logged but do not interrupt event processing.\n */\n private requestRealTimeTranscripts(eventType: string, interactionId: string): void {\n const action = TRANSCRIPT_EVENT_MAP[eventType];\n if (!action || !this.apiAIAssistant) return;\n if (this.configFlags?.aiFeature?.realtimeTranscripts?.enable === false) return;\n\n this.apiAIAssistant\n .sendEvent(\n this.agentId,\n interactionId,\n AIAssistantEventType.CUSTOM_EVENT,\n AIAssistantEventName.GET_TRANSCRIPTS,\n action\n )\n .catch((error) => {\n LoggerProxy.error(`Failed to send transcript ${action} event`, {\n module: TASK_MANAGER_FILE,\n method: METHODS.REQUEST_REAL_TIME_TRANSCRIPTS,\n interactionId,\n error,\n });\n });\n }\n\n public getTask(taskId: TaskId): ITask {\n return this.taskCollection[taskId];\n }\n\n public getAllTasks(): Record<TaskId, ITask> {\n return {...this.taskCollection};\n }\n\n public static getTaskManager(\n apiAIAssistant: ApiAIAssistant,\n contact: ReturnType<typeof routingContact>,\n webCallingService: WebCallingService,\n webSocketManager: WebSocketManager,\n rtdWebSocketManager?: WebSocketManager\n ): TaskManager {\n if (!TaskManager.taskManager) {\n TaskManager.taskManager = new TaskManager(\n apiAIAssistant,\n contact,\n webCallingService,\n webSocketManager,\n rtdWebSocketManager\n );\n }\n\n return TaskManager.taskManager;\n }\n}\n"],"mappings":"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","ignoreList":[]}
@@ -18,12 +18,13 @@ var _constants2 = require("./state-machine/constants");
18
18
  * @returns true if customer is in the call
19
19
  */
20
20
  const getIsCustomerInCall = (interaction, interactionId) => {
21
- const mainCallMedia = interaction.media[interactionId];
22
- if (!mainCallMedia?.participants) {
21
+ const mainCallMedia = interaction.media?.[interactionId];
22
+ const participants = interaction.participants;
23
+ if (!mainCallMedia?.participants || !participants) {
23
24
  return false;
24
25
  }
25
26
  return mainCallMedia.participants.some(participantId => {
26
- const participant = interaction.participants[participantId];
27
+ const participant = participants[participantId];
27
28
  return participant?.pType === _constants2.PARTICIPANT_TYPE.CUSTOMER && !participant.hasLeft;
28
29
  });
29
30
  };
@@ -38,13 +39,14 @@ const getIsCustomerInCall = (interaction, interactionId) => {
38
39
  */
39
40
  exports.getIsCustomerInCall = getIsCustomerInCall;
40
41
  const getConferenceParticipantsCount = (interaction, interactionId) => {
41
- const mainCallMedia = interaction.media[interactionId];
42
- if (!mainCallMedia?.participants) {
42
+ const mainCallMedia = interaction.media?.[interactionId];
43
+ const participants = interaction.participants;
44
+ if (!mainCallMedia?.participants || !participants) {
43
45
  return 0;
44
46
  }
45
47
  let count = 0;
46
48
  for (const participantId of mainCallMedia.participants) {
47
- const participant = interaction.participants[participantId];
49
+ const participant = participants[participantId];
48
50
  if (participant && participant.pType !== _constants2.PARTICIPANT_TYPE.CUSTOMER && participant.pType !== _constants2.PARTICIPANT_TYPE.SUPERVISOR && participant.pType !== _constants2.PARTICIPANT_TYPE.VVA && !participant.hasLeft) {
49
51
  count += 1;
50
52
  }
@@ -1 +1 @@
1
- {"version":3,"names":["_types","require","_constants","_types2","_constants2","getIsCustomerInCall","interaction","interactionId","mainCallMedia","media","participants","some","participantId","participant","pType","PARTICIPANT_TYPE","CUSTOMER","hasLeft","exports","getConferenceParticipantsCount","count","SUPERVISOR","VVA","getIsConsultInProgressForConferenceControls","mainCallId","selfAgentId","mainParticipants","Array","isArray","length","mainSet","Set","Object","values","m","mType","p","consultLegActive","consultState","isConsulted","currentState","has","getIsConsultedAgentForControls","taskData","context","isConsultingState","Boolean","consultInitiator","getServerHoldStateForControls","fallbackTaskData","undefined","isHold","mediaId","mediaResourceId","isPrimary","task","agentId","data","owner","isParticipantInMainInteraction","mediaObj","MEDIA_TYPE_MAIN_CALL","includes","checkParticipantNotInInteraction","getIsConferenceInProgress","mainInteractionId","mediaMainCall","participantsInMainCall","agentParticipants","forEach","add","size","isSecondaryAgent","callProcessingDetails","relationshipType","parentInteractionId","isSecondaryEpDnAgent","mediaType","isAutoAnswerEnabled","autoAnswerEnabled","isWebRTCCall","loginOption","webRtcEnabled","LoginOption","BROWSER","OUTDIAL_MEDIA_TYPE","isDigitalOutbound","contactDirection","type","OUTDIAL_DIRECTION","outboundType","OUTBOUND_TYPE","mediaChannel","MEDIA_CHANNEL","EMAIL","SMS","hasAgentInitiatedOutdial","outdialAgentId","BLIND_TRANSFER_IN_PROGRESS","shouldAutoAnswerTask","agentInitiatedOutdial","hasPreviousVteams","previousVTeams","getConsultMediaResourceId","consultMediaResourceId","entries"],"sources":["TaskUtils.ts"],"sourcesContent":["/* eslint-disable import/prefer-default-export */\nimport {Interaction, ITask, TaskData, MEDIA_CHANNEL} from './types';\nimport {OUTDIAL_DIRECTION, OUTDIAL_MEDIA_TYPE, OUTBOUND_TYPE} from '../../constants';\nimport {LoginOption} from '../../types';\nimport {PARTICIPANT_TYPE, MEDIA_TYPE_MAIN_CALL} from './state-machine/constants';\nimport {TaskContext} from './state-machine/types';\n\n/**\n * Checks if the customer is still in the call (not left)\n *\n * @param interaction - The interaction object\n * @param interactionId - The main interaction ID\n * @returns true if customer is in the call\n */\nexport const getIsCustomerInCall = (interaction: Interaction, interactionId: string): boolean => {\n const mainCallMedia = interaction.media[interactionId];\n if (!mainCallMedia?.participants) {\n return false;\n }\n\n return mainCallMedia.participants.some((participantId: string) => {\n const participant = interaction.participants[participantId];\n\n return participant?.pType === PARTICIPANT_TYPE.CUSTOMER && !participant.hasLeft;\n });\n};\n\n/**\n * Gets the count of active agent participants in the conference\n * Excludes Customer, Supervisor, and VVA participant types\n *\n * @param interaction - The interaction object\n * @param interactionId - The main interaction ID\n * @returns Number of active agent participants\n */\nexport const getConferenceParticipantsCount = (\n interaction: Interaction,\n interactionId: string\n): number => {\n const mainCallMedia = interaction.media[interactionId];\n if (!mainCallMedia?.participants) {\n return 0;\n }\n\n let count = 0;\n for (const participantId of mainCallMedia.participants) {\n const participant = interaction.participants[participantId];\n if (\n participant &&\n participant.pType !== PARTICIPANT_TYPE.CUSTOMER &&\n participant.pType !== PARTICIPANT_TYPE.SUPERVISOR &&\n participant.pType !== PARTICIPANT_TYPE.VVA &&\n !participant.hasLeft\n ) {\n count += 1;\n }\n }\n\n return count;\n};\n\n/**\n * Determines if a consult is actively in-progress for conference control gating.\n * This is used to disable conference controls (End/Consult) only when a consult leg\n * still exists outside the main call participants.\n */\nexport const getIsConsultInProgressForConferenceControls = (\n interaction: Interaction | undefined,\n mainCallId: string | undefined,\n selfAgentId: string | undefined\n): boolean => {\n if (!interaction || !mainCallId) return false;\n\n const mainParticipants = interaction.media?.[mainCallId]?.participants;\n if (!Array.isArray(mainParticipants) || mainParticipants.length === 0) return false;\n\n const mainSet = new Set(mainParticipants);\n const media = interaction.media;\n if (!media) return false;\n\n return Object.values(media).some((m: any) => {\n if (!m || m.mType !== 'consult') return false;\n if (!Array.isArray(m.participants) || m.participants.length === 0) return false;\n\n return m.participants.some((participantId: string) => {\n const p: any = interaction.participants?.[participantId];\n if (!p || p.hasLeft) return false;\n if (selfAgentId && participantId === selfAgentId) return false;\n\n const consultLegActive =\n p.consultState === 'consulting' ||\n p.isConsulted === true ||\n p.currentState === 'consulting';\n\n return consultLegActive && !mainSet.has(participantId);\n });\n });\n};\n\nexport const getIsConsultedAgentForControls = (\n taskData: TaskData | null,\n context: TaskContext,\n isConsultingState: boolean\n): boolean => {\n return Boolean(taskData?.isConsulted) || (isConsultingState && !context.consultInitiator);\n};\n\nexport const getServerHoldStateForControls = (\n context: TaskContext,\n mainCallId?: string,\n fallbackTaskData?: TaskData | null\n): boolean | undefined => {\n const media = context.taskData?.interaction?.media ?? fallbackTaskData?.interaction?.media;\n if (!media) return undefined;\n\n if (mainCallId && media[mainCallId]) {\n return media[mainCallId].isHold ?? false;\n }\n\n const mediaId = context.taskData?.mediaResourceId ?? fallbackTaskData?.mediaResourceId;\n if (!mediaId) return undefined;\n\n return media[mediaId]?.isHold;\n};\n\n/**\n * Determines if the given agent is the primary agent (owner) of the task\n * @param task - The task to check\n * @param agentId - The agent ID to check for primary status\n * @returns true if the agent is the primary agent, false otherwise\n */\nexport const isPrimary = (task: ITask, agentId: string): boolean => {\n if (!task.data?.interaction?.owner) {\n // Fall back to checking data.agentId when owner is not set\n return task.data.agentId === agentId;\n }\n\n return task.data.interaction.owner === agentId;\n};\n\n/**\n * Checks if the given agent is a participant in the main interaction (mainCall)\n * @param task - The task to check\n * @param agentId - The agent ID to check for participation\n * @returns true if the agent is a participant in the main interaction, false otherwise\n */\nexport const isParticipantInMainInteraction = (task: ITask, agentId: string): boolean => {\n if (!task?.data?.interaction?.media) {\n return false;\n }\n\n return Object.values(task.data.interaction.media).some(\n (mediaObj) =>\n mediaObj &&\n mediaObj.mType === MEDIA_TYPE_MAIN_CALL &&\n mediaObj.participants?.includes(agentId)\n );\n};\n\n/**\n * Checks if the given agent is not in the interaction or has left the interaction\n * @param task - The task to check\n * @param agentId - The agent ID to check\n * @returns true if the agent is not in the interaction or has left, false otherwise\n */\nexport const checkParticipantNotInInteraction = (task: ITask, agentId: string): boolean => {\n if (!task?.data?.interaction?.participants) {\n return true;\n }\n const {data} = task;\n\n return (\n !(agentId in data.interaction.participants) ||\n (agentId in data.interaction.participants && data.interaction.participants[agentId].hasLeft)\n );\n};\n\n/**\n * Determines if a conference is currently in progress based on the number of active agent participants\n * @param data - The task data to check for conference status\n * @returns true if there are 2 or more active agent participants in the main call, false otherwise\n *\n * For Agent B (consulted agent), their task's interactionId may be different from the main call.\n * We use mainInteractionId from the interaction if available, otherwise fallback to interactionId.\n */\nexport const getIsConferenceInProgress = (data: TaskData): boolean => {\n if (!data.interaction) return false;\n\n const mainCallId = data.interaction.mainInteractionId || data.interactionId;\n const mediaMainCall = data.interaction.media?.[mainCallId];\n const participantsInMainCall = new Set(mediaMainCall?.participants);\n const {participants} = data.interaction;\n\n const agentParticipants = new Set();\n participantsInMainCall.forEach((participantId: string) => {\n const participant = participants[participantId];\n if (\n participant &&\n participant.pType !== PARTICIPANT_TYPE.CUSTOMER &&\n participant.pType !== PARTICIPANT_TYPE.SUPERVISOR &&\n participant.pType !== PARTICIPANT_TYPE.VVA &&\n !participant.hasLeft\n ) {\n agentParticipants.add(participantId);\n }\n });\n\n return agentParticipants.size >= 2;\n};\n\n/**\n * Checks if the current agent is a secondary agent in a consultation scenario.\n * Secondary agents are those who were consulted (not the original call owner).\n * @param task - The task object containing interaction details\n * @returns true if this is a secondary agent (consulted party), false otherwise\n */\nexport const isSecondaryAgent = (interaction: Interaction): boolean => {\n if (!interaction.callProcessingDetails) {\n return false;\n }\n\n return (\n interaction.callProcessingDetails.relationshipType === 'consult' &&\n !!interaction.callProcessingDetails.parentInteractionId &&\n interaction.callProcessingDetails.parentInteractionId !== interaction.interactionId\n );\n};\n\n/**\n * Checks if the current agent is a secondary EP-DN (Entry Point Dial Number) agent.\n * This is specifically for telephony consultations to external numbers/entry points.\n * @param interaction - The interaction object\n * @returns true if this is a secondary EP-DN agent in telephony consultation, false otherwise\n */\nexport const isSecondaryEpDnAgent = (interaction: Interaction): boolean => {\n return interaction.mediaType === 'telephony' && isSecondaryAgent(interaction);\n};\n\n/**\n * Checks if auto-answer is enabled for the agent participant\n * @param interaction - The interaction object\n * @param agentId - Current agent ID\n * @returns true if auto-answer is enabled, false otherwise\n */\nexport const isAutoAnswerEnabled = (interaction: Interaction, agentId: string): boolean => {\n return interaction.participants?.[agentId]?.autoAnswerEnabled === true;\n};\n\n/**\n * Checks if the interaction is a WebRTC call eligible for auto-answer\n * @param interaction - The interaction object\n * @param loginOption - The agent's login option (BROWSER, AGENT_DN, etc.)\n * @param webRtcEnabled - Whether WebRTC is enabled for the agent\n * @returns true if this is a WebRTC call, false otherwise\n */\nexport const isWebRTCCall = (\n interaction: Interaction,\n loginOption: string,\n webRtcEnabled: boolean\n): boolean => {\n return (\n webRtcEnabled &&\n loginOption === LoginOption.BROWSER &&\n interaction.mediaType === OUTDIAL_MEDIA_TYPE\n );\n};\n\n/**\n * Checks if the interaction is a digital outbound (Email/SMS)\n * @param interaction - The interaction object\n * @returns true if this is a digital outbound, false otherwise\n */\nexport const isDigitalOutbound = (interaction: Interaction): boolean => {\n return (\n interaction.contactDirection?.type === OUTDIAL_DIRECTION &&\n interaction.outboundType === OUTBOUND_TYPE &&\n (interaction.mediaChannel === MEDIA_CHANNEL.EMAIL ||\n interaction.mediaChannel === MEDIA_CHANNEL.SMS)\n );\n};\n\n/**\n * Checks if the outdial was initiated by the current agent\n * @param interaction - The interaction object\n * @param agentId - Current agent ID\n * @returns true if agent initiated the outdial, false otherwise\n */\nexport const hasAgentInitiatedOutdial = (interaction: Interaction, agentId: string): boolean => {\n return (\n interaction.contactDirection?.type === OUTDIAL_DIRECTION &&\n interaction.outboundType === OUTBOUND_TYPE &&\n interaction.callProcessingDetails?.outdialAgentId === agentId &&\n interaction.owner === agentId &&\n !interaction.callProcessingDetails?.BLIND_TRANSFER_IN_PROGRESS\n );\n};\n\n/**\n * Determines if a task should be auto-answered based on interaction data\n * Auto-answer logic handles:\n * 1. WebRTC calls with auto-answer enabled in agent profile\n * 2. Agent-initiated WebRTC outdial calls\n * 3. Agent-initiated digital outbound (Email/SMS) without previous transfers\n *\n * @param taskData - The task data\n * @param agentId - Current agent ID\n * @param loginOption - Agent's login option\n * @param webRtcEnabled - Whether WebRTC is enabled for the agent\n * @returns true if task should be auto-answered, false otherwise\n */\nexport const shouldAutoAnswerTask = (\n taskData: TaskData,\n agentId: string,\n loginOption: string,\n webRtcEnabled: boolean\n): boolean => {\n const {interaction} = taskData;\n\n if (!interaction || !agentId) {\n return false;\n }\n\n // Check if auto-answer is enabled for this agent\n const autoAnswerEnabled = isAutoAnswerEnabled(interaction, agentId);\n\n // Check if this is an agent-initiated outdial\n const agentInitiatedOutdial = hasAgentInitiatedOutdial(interaction, agentId);\n\n // WebRTC telephony calls\n if (isWebRTCCall(interaction, loginOption, webRtcEnabled)) {\n return autoAnswerEnabled || agentInitiatedOutdial;\n }\n\n // Digital outbound (Email/SMS)\n if (isDigitalOutbound(interaction) && agentInitiatedOutdial) {\n // Don't auto-answer if task has been transferred (has previous vteams)\n const hasPreviousVteams = interaction.previousVTeams && interaction.previousVTeams.length > 0;\n\n return !hasPreviousVteams;\n }\n\n return false;\n};\n\n/**\n * Gets the consult media resource ID for switch-call operations.\n * Searches for the consult media leg in the interaction.\n *\n * @param interaction - The interaction object\n * @param consultMediaResourceId - The consult media resource ID from task data\n * @param agentId - Current agent ID\n * @returns The consult media resource ID or undefined\n */\nexport const getConsultMediaResourceId = (\n interaction: Interaction | undefined,\n consultMediaResourceId: string | undefined,\n agentId: string | undefined\n): string | undefined => {\n // First priority: use consultMediaResourceId from task data if available\n if (consultMediaResourceId) {\n return consultMediaResourceId;\n }\n\n // Second priority: search for consult media leg in interaction.media\n if (!interaction?.media || !agentId) {\n return undefined;\n }\n\n // Find the consult media leg where this agent is a participant\n for (const [mediaId, media] of Object.entries(interaction.media)) {\n if (media.mType === 'consult' && media.participants?.includes(agentId)) {\n return mediaId;\n }\n }\n\n return undefined;\n};\n"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"names":["_types","require","_constants","_types2","_constants2","getIsCustomerInCall","interaction","interactionId","mainCallMedia","media","participants","some","participantId","participant","pType","PARTICIPANT_TYPE","CUSTOMER","hasLeft","exports","getConferenceParticipantsCount","count","SUPERVISOR","VVA","getIsConsultInProgressForConferenceControls","mainCallId","selfAgentId","mainParticipants","Array","isArray","length","mainSet","Set","Object","values","m","mType","p","consultLegActive","consultState","isConsulted","currentState","has","getIsConsultedAgentForControls","taskData","context","isConsultingState","Boolean","consultInitiator","getServerHoldStateForControls","fallbackTaskData","undefined","isHold","mediaId","mediaResourceId","isPrimary","task","agentId","data","owner","isParticipantInMainInteraction","mediaObj","MEDIA_TYPE_MAIN_CALL","includes","checkParticipantNotInInteraction","getIsConferenceInProgress","mainInteractionId","mediaMainCall","participantsInMainCall","agentParticipants","forEach","add","size","isSecondaryAgent","callProcessingDetails","relationshipType","parentInteractionId","isSecondaryEpDnAgent","mediaType","isAutoAnswerEnabled","autoAnswerEnabled","isWebRTCCall","loginOption","webRtcEnabled","LoginOption","BROWSER","OUTDIAL_MEDIA_TYPE","isDigitalOutbound","contactDirection","type","OUTDIAL_DIRECTION","outboundType","OUTBOUND_TYPE","mediaChannel","MEDIA_CHANNEL","EMAIL","SMS","hasAgentInitiatedOutdial","outdialAgentId","BLIND_TRANSFER_IN_PROGRESS","shouldAutoAnswerTask","agentInitiatedOutdial","hasPreviousVteams","previousVTeams","getConsultMediaResourceId","consultMediaResourceId","entries"],"sources":["TaskUtils.ts"],"sourcesContent":["/* eslint-disable import/prefer-default-export */\nimport {Interaction, ITask, TaskData, MEDIA_CHANNEL} from './types';\nimport {OUTDIAL_DIRECTION, OUTDIAL_MEDIA_TYPE, OUTBOUND_TYPE} from '../../constants';\nimport {LoginOption} from '../../types';\nimport {PARTICIPANT_TYPE, MEDIA_TYPE_MAIN_CALL} from './state-machine/constants';\nimport {TaskContext} from './state-machine/types';\n\n/**\n * Checks if the customer is still in the call (not left)\n *\n * @param interaction - The interaction object\n * @param interactionId - The main interaction ID\n * @returns true if customer is in the call\n */\nexport const getIsCustomerInCall = (interaction: Interaction, interactionId: string): boolean => {\n const mainCallMedia = interaction.media?.[interactionId];\n const participants = interaction.participants;\n if (!mainCallMedia?.participants || !participants) {\n return false;\n }\n\n return mainCallMedia.participants.some((participantId: string) => {\n const participant = participants[participantId];\n\n return participant?.pType === PARTICIPANT_TYPE.CUSTOMER && !participant.hasLeft;\n });\n};\n\n/**\n * Gets the count of active agent participants in the conference\n * Excludes Customer, Supervisor, and VVA participant types\n *\n * @param interaction - The interaction object\n * @param interactionId - The main interaction ID\n * @returns Number of active agent participants\n */\nexport const getConferenceParticipantsCount = (\n interaction: Interaction,\n interactionId: string\n): number => {\n const mainCallMedia = interaction.media?.[interactionId];\n const participants = interaction.participants;\n if (!mainCallMedia?.participants || !participants) {\n return 0;\n }\n\n let count = 0;\n for (const participantId of mainCallMedia.participants) {\n const participant = participants[participantId];\n if (\n participant &&\n participant.pType !== PARTICIPANT_TYPE.CUSTOMER &&\n participant.pType !== PARTICIPANT_TYPE.SUPERVISOR &&\n participant.pType !== PARTICIPANT_TYPE.VVA &&\n !participant.hasLeft\n ) {\n count += 1;\n }\n }\n\n return count;\n};\n\n/**\n * Determines if a consult is actively in-progress for conference control gating.\n * This is used to disable conference controls (End/Consult) only when a consult leg\n * still exists outside the main call participants.\n */\nexport const getIsConsultInProgressForConferenceControls = (\n interaction: Interaction | undefined,\n mainCallId: string | undefined,\n selfAgentId: string | undefined\n): boolean => {\n if (!interaction || !mainCallId) return false;\n\n const mainParticipants = interaction.media?.[mainCallId]?.participants;\n if (!Array.isArray(mainParticipants) || mainParticipants.length === 0) return false;\n\n const mainSet = new Set(mainParticipants);\n const media = interaction.media;\n if (!media) return false;\n\n return Object.values(media).some((m: any) => {\n if (!m || m.mType !== 'consult') return false;\n if (!Array.isArray(m.participants) || m.participants.length === 0) return false;\n\n return m.participants.some((participantId: string) => {\n const p: any = interaction.participants?.[participantId];\n if (!p || p.hasLeft) return false;\n if (selfAgentId && participantId === selfAgentId) return false;\n\n const consultLegActive =\n p.consultState === 'consulting' ||\n p.isConsulted === true ||\n p.currentState === 'consulting';\n\n return consultLegActive && !mainSet.has(participantId);\n });\n });\n};\n\nexport const getIsConsultedAgentForControls = (\n taskData: TaskData | null,\n context: TaskContext,\n isConsultingState: boolean\n): boolean => {\n return Boolean(taskData?.isConsulted) || (isConsultingState && !context.consultInitiator);\n};\n\nexport const getServerHoldStateForControls = (\n context: TaskContext,\n mainCallId?: string,\n fallbackTaskData?: TaskData | null\n): boolean | undefined => {\n const media = context.taskData?.interaction?.media ?? fallbackTaskData?.interaction?.media;\n if (!media) return undefined;\n\n if (mainCallId && media[mainCallId]) {\n return media[mainCallId].isHold ?? false;\n }\n\n const mediaId = context.taskData?.mediaResourceId ?? fallbackTaskData?.mediaResourceId;\n if (!mediaId) return undefined;\n\n return media[mediaId]?.isHold;\n};\n\n/**\n * Determines if the given agent is the primary agent (owner) of the task\n * @param task - The task to check\n * @param agentId - The agent ID to check for primary status\n * @returns true if the agent is the primary agent, false otherwise\n */\nexport const isPrimary = (task: ITask, agentId: string): boolean => {\n if (!task.data?.interaction?.owner) {\n // Fall back to checking data.agentId when owner is not set\n return task.data.agentId === agentId;\n }\n\n return task.data.interaction.owner === agentId;\n};\n\n/**\n * Checks if the given agent is a participant in the main interaction (mainCall)\n * @param task - The task to check\n * @param agentId - The agent ID to check for participation\n * @returns true if the agent is a participant in the main interaction, false otherwise\n */\nexport const isParticipantInMainInteraction = (task: ITask, agentId: string): boolean => {\n if (!task?.data?.interaction?.media) {\n return false;\n }\n\n return Object.values(task.data.interaction.media).some(\n (mediaObj) =>\n mediaObj &&\n mediaObj.mType === MEDIA_TYPE_MAIN_CALL &&\n mediaObj.participants?.includes(agentId)\n );\n};\n\n/**\n * Checks if the given agent is not in the interaction or has left the interaction\n * @param task - The task to check\n * @param agentId - The agent ID to check\n * @returns true if the agent is not in the interaction or has left, false otherwise\n */\nexport const checkParticipantNotInInteraction = (task: ITask, agentId: string): boolean => {\n if (!task?.data?.interaction?.participants) {\n return true;\n }\n const {data} = task;\n\n return (\n !(agentId in data.interaction.participants) ||\n (agentId in data.interaction.participants && data.interaction.participants[agentId].hasLeft)\n );\n};\n\n/**\n * Determines if a conference is currently in progress based on the number of active agent participants\n * @param data - The task data to check for conference status\n * @returns true if there are 2 or more active agent participants in the main call, false otherwise\n *\n * For Agent B (consulted agent), their task's interactionId may be different from the main call.\n * We use mainInteractionId from the interaction if available, otherwise fallback to interactionId.\n */\nexport const getIsConferenceInProgress = (data: TaskData): boolean => {\n if (!data.interaction) return false;\n\n const mainCallId = data.interaction.mainInteractionId || data.interactionId;\n const mediaMainCall = data.interaction.media?.[mainCallId];\n const participantsInMainCall = new Set(mediaMainCall?.participants);\n const {participants} = data.interaction;\n\n const agentParticipants = new Set();\n participantsInMainCall.forEach((participantId: string) => {\n const participant = participants[participantId];\n if (\n participant &&\n participant.pType !== PARTICIPANT_TYPE.CUSTOMER &&\n participant.pType !== PARTICIPANT_TYPE.SUPERVISOR &&\n participant.pType !== PARTICIPANT_TYPE.VVA &&\n !participant.hasLeft\n ) {\n agentParticipants.add(participantId);\n }\n });\n\n return agentParticipants.size >= 2;\n};\n\n/**\n * Checks if the current agent is a secondary agent in a consultation scenario.\n * Secondary agents are those who were consulted (not the original call owner).\n * @param task - The task object containing interaction details\n * @returns true if this is a secondary agent (consulted party), false otherwise\n */\nexport const isSecondaryAgent = (interaction: Interaction): boolean => {\n if (!interaction.callProcessingDetails) {\n return false;\n }\n\n return (\n interaction.callProcessingDetails.relationshipType === 'consult' &&\n !!interaction.callProcessingDetails.parentInteractionId &&\n interaction.callProcessingDetails.parentInteractionId !== interaction.interactionId\n );\n};\n\n/**\n * Checks if the current agent is a secondary EP-DN (Entry Point Dial Number) agent.\n * This is specifically for telephony consultations to external numbers/entry points.\n * @param interaction - The interaction object\n * @returns true if this is a secondary EP-DN agent in telephony consultation, false otherwise\n */\nexport const isSecondaryEpDnAgent = (interaction: Interaction): boolean => {\n return interaction.mediaType === 'telephony' && isSecondaryAgent(interaction);\n};\n\n/**\n * Checks if auto-answer is enabled for the agent participant\n * @param interaction - The interaction object\n * @param agentId - Current agent ID\n * @returns true if auto-answer is enabled, false otherwise\n */\nexport const isAutoAnswerEnabled = (interaction: Interaction, agentId: string): boolean => {\n return interaction.participants?.[agentId]?.autoAnswerEnabled === true;\n};\n\n/**\n * Checks if the interaction is a WebRTC call eligible for auto-answer\n * @param interaction - The interaction object\n * @param loginOption - The agent's login option (BROWSER, AGENT_DN, etc.)\n * @param webRtcEnabled - Whether WebRTC is enabled for the agent\n * @returns true if this is a WebRTC call, false otherwise\n */\nexport const isWebRTCCall = (\n interaction: Interaction,\n loginOption: string,\n webRtcEnabled: boolean\n): boolean => {\n return (\n webRtcEnabled &&\n loginOption === LoginOption.BROWSER &&\n interaction.mediaType === OUTDIAL_MEDIA_TYPE\n );\n};\n\n/**\n * Checks if the interaction is a digital outbound (Email/SMS)\n * @param interaction - The interaction object\n * @returns true if this is a digital outbound, false otherwise\n */\nexport const isDigitalOutbound = (interaction: Interaction): boolean => {\n return (\n interaction.contactDirection?.type === OUTDIAL_DIRECTION &&\n interaction.outboundType === OUTBOUND_TYPE &&\n (interaction.mediaChannel === MEDIA_CHANNEL.EMAIL ||\n interaction.mediaChannel === MEDIA_CHANNEL.SMS)\n );\n};\n\n/**\n * Checks if the outdial was initiated by the current agent\n * @param interaction - The interaction object\n * @param agentId - Current agent ID\n * @returns true if agent initiated the outdial, false otherwise\n */\nexport const hasAgentInitiatedOutdial = (interaction: Interaction, agentId: string): boolean => {\n return (\n interaction.contactDirection?.type === OUTDIAL_DIRECTION &&\n interaction.outboundType === OUTBOUND_TYPE &&\n interaction.callProcessingDetails?.outdialAgentId === agentId &&\n interaction.owner === agentId &&\n !interaction.callProcessingDetails?.BLIND_TRANSFER_IN_PROGRESS\n );\n};\n\n/**\n * Determines if a task should be auto-answered based on interaction data\n * Auto-answer logic handles:\n * 1. WebRTC calls with auto-answer enabled in agent profile\n * 2. Agent-initiated WebRTC outdial calls\n * 3. Agent-initiated digital outbound (Email/SMS) without previous transfers\n *\n * @param taskData - The task data\n * @param agentId - Current agent ID\n * @param loginOption - Agent's login option\n * @param webRtcEnabled - Whether WebRTC is enabled for the agent\n * @returns true if task should be auto-answered, false otherwise\n */\nexport const shouldAutoAnswerTask = (\n taskData: TaskData,\n agentId: string,\n loginOption: string,\n webRtcEnabled: boolean\n): boolean => {\n const {interaction} = taskData;\n\n if (!interaction || !agentId) {\n return false;\n }\n\n // Check if auto-answer is enabled for this agent\n const autoAnswerEnabled = isAutoAnswerEnabled(interaction, agentId);\n\n // Check if this is an agent-initiated outdial\n const agentInitiatedOutdial = hasAgentInitiatedOutdial(interaction, agentId);\n\n // WebRTC telephony calls\n if (isWebRTCCall(interaction, loginOption, webRtcEnabled)) {\n return autoAnswerEnabled || agentInitiatedOutdial;\n }\n\n // Digital outbound (Email/SMS)\n if (isDigitalOutbound(interaction) && agentInitiatedOutdial) {\n // Don't auto-answer if task has been transferred (has previous vteams)\n const hasPreviousVteams = interaction.previousVTeams && interaction.previousVTeams.length > 0;\n\n return !hasPreviousVteams;\n }\n\n return false;\n};\n\n/**\n * Gets the consult media resource ID for switch-call operations.\n * Searches for the consult media leg in the interaction.\n *\n * @param interaction - The interaction object\n * @param consultMediaResourceId - The consult media resource ID from task data\n * @param agentId - Current agent ID\n * @returns The consult media resource ID or undefined\n */\nexport const getConsultMediaResourceId = (\n interaction: Interaction | undefined,\n consultMediaResourceId: string | undefined,\n agentId: string | undefined\n): string | undefined => {\n // First priority: use consultMediaResourceId from task data if available\n if (consultMediaResourceId) {\n return consultMediaResourceId;\n }\n\n // Second priority: search for consult media leg in interaction.media\n if (!interaction?.media || !agentId) {\n return undefined;\n }\n\n // Find the consult media leg where this agent is a participant\n for (const [mediaId, media] of Object.entries(interaction.media)) {\n if (media.mType === 'consult' && media.participants?.includes(agentId)) {\n return mediaId;\n }\n }\n\n return undefined;\n};\n"],"mappings":"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","ignoreList":[]}
@@ -112,11 +112,16 @@ function getTaskStateMachineConfig(uiControlConfig) {
112
112
  target: _constants.TaskState.OFFERED,
113
113
  actions: ['initializeTask', 'emitTaskIncoming']
114
114
  },
115
+ // AgentOutboundFailed can arrive before TASK_INCOMING due to race conditions
116
+ [_constants.TaskEvent.OUTBOUND_FAILED]: {
117
+ target: _constants.TaskState.TERMINATED,
118
+ actions: ['updateTaskData', 'markEnded', 'emitTaskOutdialFailed', 'emitTaskEnd']
119
+ },
115
120
  // EP-DN split-leg ordering can deliver AgentConsulting before HYDRATE/TASK_INCOMING.
116
121
  // Do not drop it in IDLE; bootstrap to CONSULTING using event taskData.
117
122
  [_constants.TaskEvent.CONSULTING_ACTIVE]: {
118
123
  target: _constants.TaskState.CONSULTING,
119
- actions: ['updateTaskData', 'setConsultInitiator', 'setConsultDestination', 'setConsultFromConference', 'setConsultAgentJoined', 'emitTaskConsultAccepted', 'emitTaskConsulting']
124
+ actions: ['setConsultInitiator', 'setConsultDestination', 'setConsultFromConference', 'setConsultAgentJoined', 'updateTaskData', 'emitTaskConsultAccepted', 'emitTaskConsulting']
120
125
  }
121
126
  }
122
127
  },
@@ -165,12 +170,12 @@ function getTaskStateMachineConfig(uiControlConfig) {
165
170
  actions: ['updateTaskData', 'markEnded', 'emitTaskOutdialFailed', 'emitTaskWrapup']
166
171
  }, {
167
172
  target: _constants.TaskState.TERMINATED,
168
- actions: ['updateTaskData', 'markEnded', 'emitTaskOutdialFailed', 'emitTaskReject']
173
+ actions: ['updateTaskData', 'markEnded', 'emitTaskOutdialFailed', 'emitTaskEnd']
169
174
  }],
170
175
  // AgentConsulting comes for received after the initial consult is accepted
171
176
  [_constants.TaskEvent.CONSULTING_ACTIVE]: [{
172
177
  target: _constants.TaskState.CONSULTING,
173
- actions: ['updateTaskData', 'setConsultAgentJoined', 'emitTaskConsultAccepted', 'emitTaskConsulting']
178
+ actions: ['setConsultAgentJoined', 'setConsultDestination', 'updateTaskData', 'emitTaskConsultAccepted', 'emitTaskConsulting']
174
179
  }],
175
180
  // agentOfferConsult happens only on the receiver side of consult
176
181
  [_constants.TaskEvent.OFFER_CONSULT]: {
@@ -192,11 +197,16 @@ function getTaskStateMachineConfig(uiControlConfig) {
192
197
  },
193
198
  [_constants.TaskState.CONNECTED]: {
194
199
  on: {
200
+ // AgentConsultConferenced / ParticipantJoinedConference can arrive while connected.
201
+ [_constants.TaskEvent.CONFERENCE_START]: {
202
+ target: _constants.TaskState.CONFERENCING,
203
+ actions: ['updateTaskData', 'syncTaskDataFromEvent', 'clearConsultState', 'emitTaskConferenceStarted']
204
+ },
195
205
  // AgentConsulting may arrive while machine is CONNECTED (EP-DN/event ordering).
196
206
  // Derive consultInitiator from payload so controls are set correctly.
197
207
  [_constants.TaskEvent.CONSULTING_ACTIVE]: {
198
208
  target: _constants.TaskState.CONSULTING,
199
- actions: ['updateTaskData', 'setConsultInitiator', 'setConsultDestination', 'setConsultAgentJoined', 'emitTaskConsultAccepted', 'emitTaskConsulting']
209
+ actions: ['setConsultInitiator', 'setConsultDestination', 'setConsultAgentJoined', 'updateTaskData', 'emitTaskConsultAccepted', 'emitTaskConsulting']
200
210
  },
201
211
  // AgentContactAssigned can be resent after consult transfers; keep context in sync
202
212
  [_constants.TaskEvent.ASSIGN]: {
@@ -273,6 +283,17 @@ function getTaskStateMachineConfig(uiControlConfig) {
273
283
  },
274
284
  [_constants.TaskState.HELD]: {
275
285
  on: {
286
+ // Conference can be merged while this agent is in held state after refresh/recovery.
287
+ [_constants.TaskEvent.CONFERENCE_START]: {
288
+ target: _constants.TaskState.CONFERENCING,
289
+ actions: ['updateTaskData', 'syncTaskDataFromEvent', 'clearConsultState', 'emitTaskConferenceStarted']
290
+ },
291
+ [_constants.TaskEvent.PAUSE_RECORDING]: {
292
+ actions: ['updateTaskData', 'setRecordingState', 'emitTaskRecordingPaused']
293
+ },
294
+ [_constants.TaskEvent.RESUME_RECORDING]: {
295
+ actions: ['updateTaskData', 'setRecordingState', 'emitTaskRecordingResumed']
296
+ },
276
297
  // Click of the unhold button
277
298
  [_constants.TaskEvent.UNHOLD_INITIATED]: {
278
299
  target: _constants.TaskState.RESUME_INITIATING
@@ -376,20 +397,48 @@ function getTaskStateMachineConfig(uiControlConfig) {
376
397
  on: {
377
398
  // AgentConsulting updates consulted agent arrival
378
399
  [_constants.TaskEvent.CONSULTING_ACTIVE]: {
379
- actions: ['updateTaskData', 'setConsultAgentJoined', 'setConsultDestination', 'emitTaskConsulting']
400
+ actions: ['setConsultAgentJoined', 'setConsultDestination', 'updateTaskData', 'emitTaskConsulting']
380
401
  },
381
402
  // AgentConsultEnded
382
403
  [_constants.TaskEvent.CONSULT_END]: [{
383
- // Initiator returning to conference (flag set OR backend still shows conference)
404
+ // Initiator returning to conference only while conference is still active.
384
405
  guard: ({
385
406
  context,
386
407
  event
387
- }) => context.consultInitiator === true && (context.consultFromConference === true || _guards.guards.conferenceInProgressFromEvent({
408
+ }) => context.consultInitiator === true && _guards.guards.conferenceInProgressFromEvent({
388
409
  context,
389
410
  event
390
- })),
411
+ }),
391
412
  target: _constants.TaskState.CONFERENCING,
392
413
  actions: ['updateTaskData', 'clearConsultState', 'emitTaskConsultEnd']
414
+ }, {
415
+ // Conference consult ended after conference downgrade while main leg is held.
416
+ guard: ({
417
+ context,
418
+ event
419
+ }) => context.consultInitiator === true && context.consultFromConference === true && !_guards.guards.conferenceInProgressFromEvent({
420
+ context,
421
+ event
422
+ }) && _guards.guards.isConferenceHoldParticipantFromEvent({
423
+ context,
424
+ event
425
+ }),
426
+ target: _constants.TaskState.HELD,
427
+ actions: ['updateTaskData', 'clearConsultState', 'emitTaskConsultEnd']
428
+ }, {
429
+ // Conference consult ended after conference downgrade while main leg is connected.
430
+ guard: ({
431
+ context,
432
+ event
433
+ }) => context.consultInitiator === true && context.consultFromConference === true && !_guards.guards.conferenceInProgressFromEvent({
434
+ context,
435
+ event
436
+ }) && !_guards.guards.isConferenceHoldParticipantFromEvent({
437
+ context,
438
+ event
439
+ }),
440
+ target: _constants.TaskState.CONNECTED,
441
+ actions: ['updateTaskData', 'clearConsultState', 'emitTaskConsultEnd']
393
442
  }, {
394
443
  // Initiator already switched back to the main/customer leg
395
444
  guard: ({
@@ -398,15 +447,17 @@ function getTaskStateMachineConfig(uiControlConfig) {
398
447
  target: _constants.TaskState.CONNECTED,
399
448
  actions: ['updateTaskData', 'clearConsultState', 'emitTaskConsultEnd']
400
449
  }, {
401
- // Customer left during consult → WRAPPING_UP
450
+ // Interaction terminated during consult (customer left) → WRAPPING_UP
402
451
  guard: ({
403
452
  context,
404
453
  event
405
454
  }) => {
455
+ // if (context.consultInitiator !== true) return false;
456
+ // const taskData = getTaskDataFromEvent(event);
406
457
  const taskData = (0, _guards.getTaskDataFromEvent)(event);
407
458
  const cpd = taskData?.interaction?.callProcessingDetails;
408
459
  if (cpd?.hasCustomerLeft !== 'true') return false;
409
- return (0, _guards.shouldWrapUpForThisAgent)(context, taskData);
460
+ return taskData?.interaction?.isTerminated === true && (0, _guards.shouldWrapUpForThisAgent)(context, taskData);
410
461
  },
411
462
  target: _constants.TaskState.WRAPPING_UP,
412
463
  actions: ['updateTaskData', 'markEnded', 'clearConsultState', 'emitTaskWrapup', 'requestCleanup']
@@ -553,12 +604,24 @@ function getTaskStateMachineConfig(uiControlConfig) {
553
604
  }, {
554
605
  actions: ['updateTaskData', 'clearConsultState']
555
606
  }],
556
- [_constants.TaskEvent.HOLD_SUCCESS]: {
607
+ [_constants.TaskEvent.HOLD_SUCCESS]: [{
608
+ // Conference already downgraded (no other agents) and backend hold arrives.
609
+ // Move to HELD so the UI renders resume action.
610
+ guard: _guards.guards.shouldDowngradeConferenceToConnected,
611
+ target: _constants.TaskState.HELD,
557
612
  actions: ['updateTaskData', 'setHoldState', 'emitTaskHold']
558
- },
559
- [_constants.TaskEvent.UNHOLD_SUCCESS]: {
613
+ }, {
614
+ actions: ['updateTaskData', 'setHoldState', 'emitTaskHold']
615
+ }],
616
+ [_constants.TaskEvent.UNHOLD_SUCCESS]: [{
617
+ // Conference already downgraded (no other agents) and backend unhold arrives.
618
+ // Move to CONNECTED so hold action is available again.
619
+ guard: _guards.guards.shouldDowngradeConferenceToConnected,
620
+ target: _constants.TaskState.CONNECTED,
560
621
  actions: ['updateTaskData', 'syncTaskDataFromEvent', 'setHoldState', 'emitTaskResume']
561
- },
622
+ }, {
623
+ actions: ['updateTaskData', 'syncTaskDataFromEvent', 'setHoldState', 'emitTaskResume']
624
+ }],
562
625
  // Start a new consult from within an active conference
563
626
  [_constants.TaskEvent.CONSULT]: {
564
627
  target: _constants.TaskState.CONSULT_INITIATING,