@webex/contact-center 3.12.0-task-refactor.1 → 3.12.0-task-refactor.2

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.
@@ -648,8 +648,19 @@ class TaskManager extends _events.default {
648
648
  isConsulted: false
649
649
  };
650
650
  task = _TaskFactory.default.createTask(this.contact, this.webCallingService, taskData, this.configFlags, this.wrapupData, this.agentId);
651
- this.setupTaskListeners(task);
652
651
  this.taskCollection[payload.interactionId] = task;
652
+
653
+ // Transition the new task out of IDLE immediately so UI controls are
654
+ // computed before TASK_MERGED is emitted. This handles the race where
655
+ // AgentContactAssigned arrives before ContactMerged and gets dropped.
656
+ // Send HYDRATE before setupTaskListeners so the emitTaskHydrate action
657
+ // doesn't bubble up to the Widget (avoids duplicate listener registration).
658
+ task.sendStateMachineEvent({
659
+ type: _stateMachine.TaskEvent.HYDRATE,
660
+ taskData,
661
+ agentId: this.agentId
662
+ });
663
+ this.setupTaskListeners(task);
653
664
  }
654
665
  if (task) {
655
666
  this.emit(_types.TASK_EVENTS.TASK_MERGED, task);
@@ -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","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","requestRealTimeTranscripts","eventType","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","TASK_EVENTS","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.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 // 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) {\n // remove the child task from collection\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.setupTaskListeners(task);\n this.taskCollection[payload.interactionId] = 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","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","requestRealTimeTranscripts","eventType","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","TASK_EVENTS","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.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 // 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) {\n // remove the child task from collection\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":";;;;;;AAAA,IAAAA,OAAA,GAAAC,sBAAA,CAAAC,OAAA;AACA,IAAAC,QAAA,GAAAD,OAAA;AAIA,IAAAE,MAAA,GAAAF,OAAA;AAWA,IAAAG,UAAA,GAAAH,OAAA;AACA,IAAAI,WAAA,GAAAJ,OAAA;AACA,IAAAK,OAAA,GAAAL,OAAA;AACA,IAAAM,OAAA,GAAAN,OAAA;AACA,IAAAO,YAAA,GAAAR,sBAAA,CAAAC,OAAA;AACA,IAAAQ,UAAA,GAAAR,OAAA;AACA,IAAAS,YAAA,GAAAV,sBAAA,CAAAC,OAAA;AACA,IAAAU,OAAA,GAAAX,sBAAA,CAAAC,OAAA;AACA,IAAAW,aAAA,GAAAX,OAAA;AACA,IAAAY,mBAAA,GAAAZ,OAAA;AAAuD,SAAAD,uBAAAc,CAAA,WAAAA,CAAA,IAAAA,CAAA,CAAAC,UAAA,GAAAD,CAAA,KAAAE,OAAA,EAAAF,CAAA;AAGvD,MAAMG,YAAY,GAAG,IAAIC,GAAG,CAAYC,MAAM,CAACC,MAAM,CAACC,iBAAS,CAAgB,CAAC;AAEhF,MAAMC,SAAS,GAAIC,KAAa,IAAyBN,YAAY,CAACO,GAAG,CAACD,KAAkB,CAAC;;AAE7F;AACe,MAAME,WAAW,SAASC,eAAY,CAAC;EAGpD;AACF;AACA;AACA;AACA;;EAKE;;EAOA;AACF;AACA;AACA;AACA;EACEC,WAAWA,CACTC,cAA8B,EAC9BC,OAA0C,EAC1CC,iBAAoC,EACpCC,gBAAkC,EAClCC,mBAAqC,EACrC;IACA,KAAK,CAAC,CAAC;IACP,IAAI,CAACJ,cAAc,GAAGA,cAAc;IACpC,IAAI,CAACC,OAAO,GAAGA,OAAO;IACtB,IAAI,CAACC,iBAAiB,GAAGA,iBAAiB;IAC1C,IAAI,CAACC,gBAAgB,GAAGA,gBAAgB;IACxC,IAAI,CAACC,mBAAmB,GAAGA,mBAAmB;IAC9C,IAAI,CAACC,cAAc,GAAG,CAAC,CAAC;IACxB,IAAI,CAACC,aAAa,GAAG,KAAK;IAE1B,IAAI,CAACC,qBAAqB,CAAC,CAAC;IAC5B,IAAI,CAACC,yBAAyB,CAAC,CAAC;EAClC;EAEOC,4BAA4BA,CAACC,KAAa,EAAE;IACjD,IAAI;MACF,MAAMC,OAAO,GAAGC,IAAI,CAACC,KAAK,CAACH,KAAK,CAAC;MAEjC,MAAMI,aAAa,GAAGH,OAAO,EAAEI,IAAI,EAAEA,IAAI,EAAEC,cAAc;MACzD,IAAI,CAACF,aAAa,EAAE;MAEpB,MAAMG,IAAI,GAAG,IAAI,CAACZ,cAAc,CAACS,aAAa,CAAC;MAC/C,IAAI,CAACG,IAAI,EAAE;QACTC,oBAAW,CAACC,IAAI,CAAC,uCAAuC,EAAE;UACxDC,MAAM,EAAEC,4BAAiB;UACzBC,MAAM,EAAEC,mBAAO,CAACC,gCAAgC;UAChDV;QACF,CAAC,CAAC;QAEF;MACF;MAEAG,IAAI,CAACQ,IAAI,CAACd,OAAO,CAACe,IAAI,EAAEf,OAAO,CAACI,IAAI,CAAC;IACvC,CAAC,CAAC,OAAOY,KAAK,EAAE;MACdT,oBAAW,CAACS,KAAK,CAAC,uCAAuC,EAAE;QACzDP,MAAM,EAAEC,4BAAiB;QACzBC,MAAM,EAAEC,mBAAO,CAACC,gCAAgC;QAChDG;MACF,CAAC,CAAC;IACJ;EACF;;EAEA;AACF;AACA;EACSC,cAAcA,CAACC,WAAwB,EAAE;IAC9C,IAAI,CAACA,WAAW,GAAGA,WAAW;EAChC;;EAEA;AACF;AACA;EACSC,aAAaA,CAACC,UAAsB,EAAE;IAC3C,IAAI,CAACA,UAAU,GAAGA,UAAU;EAC9B;;EAEA;AACF;AACA;EACSC,UAAUA,CAACC,OAAe,EAAE;IACjC,IAAI,CAACA,OAAO,GAAGA,OAAO;EACxB;;EAEA;AACF;AACA;AACA;AACA;EACSC,UAAUA,CAAA,EAAW;IAC1B,OAAO,IAAI,CAACD,OAAO;EACrB;EAEOE,gBAAgBA,CAAC7B,aAAsB,EAAE;IAC9C,IAAI,CAACA,aAAa,GAAGA,aAAa;EACpC;EAEQ8B,qBAAqB,GAAIC,IAAW,IAAK;IAC/C,MAAMC,WAAW,GAAG/C,MAAM,CAACC,MAAM,CAAC,IAAI,CAACa,cAAc,CAAC,CAACkC,IAAI,CACxDC,CAAC,IAAKA,CAAC,CAACzB,IAAI,CAAC0B,WAAW,CAACC,SAAS,KAAKC,oBAAa,CAACC,SACxD,CAAC;IAED,IAAIN,WAAW,EAAE;MACf,IAAI,CAACpC,iBAAiB,CAAC2C,aAAa,CAACR,IAAI,CAACS,SAAS,CAAC,CAAC,EAAER,WAAW,CAACvB,IAAI,CAACD,aAAa,CAAC;MACtFI,oBAAW,CAAC6B,GAAG,CAAC,qBAAqB,EAAE;QACrC3B,MAAM,EAAEC,4BAAiB;QACzBC,MAAM,EAAEC,mBAAO,CAACyB,wBAAwB;QACxClC,aAAa,EAAEwB,WAAW,CAACvB,IAAI,CAACD;MAClC,CAAC,CAAC;;MAEF;MACA,MAAMmC,YAAY,GAAGpD,WAAW,CAACqD,+BAA+B,CAC9DzD,iBAAS,CAAC0D,sBAAsB,EAChCb,WAAW,CAACvB,IACd,CAAC;MACD,IAAIkC,YAAY,IAAIX,WAAW,EAAE;QAC/BA,WAAW,CAACc,qBAAqB,CAACH,YAAY,CAAC;MACjD;IACF;IACA,IAAI,CAACZ,IAAI,GAAGA,IAAI;EAClB,CAAC;EAEM7B,yBAAyBA,CAAA,EAAG;IACjC,IAAI,CAACN,iBAAiB,CAACmD,EAAE,CAACC,oBAAW,CAACC,aAAa,EAAE,IAAI,CAACnB,qBAAqB,CAAC;EAClF;EAEOoB,2BAA2BA,CAAA,EAAG;IACnC,IAAI,CAACtD,iBAAiB,CAACuD,GAAG,CAACH,oBAAW,CAACC,aAAa,EAAE,IAAI,CAACnB,qBAAqB,CAAC;EACnF;;EAEA;AACF;AACA;AACA;AACA;AACA;AACA;EACE,OAAec,+BAA+BA,CAC5CQ,OAAkB,EAClB/C,OAAyB,EACzBsB,OAAgB,EACS;IACzB,MAAM0B,eAAe,GACnBhD,OAAO,CAACgD,eAAe,IACvBhD,OAAO,CAAC8B,WAAW,EAAEmB,KAAK,GAAGjD,OAAO,CAACG,aAAa,CAAC,EAAE6C,eAAe;IAEtE,QAAQD,OAAO;MACb;MACA,KAAKjE,iBAAS,CAAC0D,sBAAsB;QAAE;QACrC,OAAO;UAACzB,IAAI,EAAEmC,uBAAS,CAACC,aAAa;UAAEC,QAAQ,EAAEpD;QAAO,CAAC;MAE3D,KAAKlB,iBAAS,CAACuE,mBAAmB;QAAE;QAClC,OAAO;UAACtC,IAAI,EAAEmC,uBAAS,CAACI,YAAY;UAAEF,QAAQ,EAAEpD;QAAO,CAAC;MAE1D,KAAKlB,iBAAS,CAACyE,aAAa;QAAE;QAC5B;QACA,OAAO;UAACxC,IAAI,EAAEmC,uBAAS,CAACM,OAAO;UAAEJ,QAAQ,EAAEpD,OAAO;UAAEsB;QAAO,CAAC;MAE9D,KAAKxC,iBAAS,CAAC2E,eAAe;QAC5B,OAAO;UAAC1C,IAAI,EAAEmC,uBAAS,CAACO,eAAe;UAAEL,QAAQ,EAAEpD;QAAO,CAAC;MAC7D,KAAKlB,iBAAS,CAAC4E,qBAAqB;QAClC,OAAO;UAAC3C,IAAI,EAAEmC,uBAAS,CAACQ,qBAAqB;UAAEN,QAAQ,EAAEpD;QAAO,CAAC;MAEnE,KAAKlB,iBAAS,CAAC6E,mBAAmB;QAAE;QAClC,OAAO;UACL5C,IAAI,EAAEmC,uBAAS,CAACU,aAAa;UAC7BR,QAAQ,EAAE;YAAC,GAAGpD,OAAO;YAAE6D,WAAW,EAAE;UAAI;QAC1C,CAAC;MAEH,KAAK/E,iBAAS,CAACgF,sBAAsB;QAAE;QACrC,OAAO;UAAC/C,IAAI,EAAEmC,uBAAS,CAACa,MAAM;UAAEX,QAAQ,EAAEpD;QAAO,CAAC;MAEpD,KAAKlB,iBAAS,CAACkF,kBAAkB;QAC/B,OAAO;UACLjD,IAAI,EAAEmC,uBAAS,CAACe,YAAY;UAC5BjB,eAAe,EAAEA,eAAe,IAAI,EAAE;UACtCI,QAAQ,EAAEpD;QACZ,CAAC;MAEH,KAAKlB,iBAAS,CAACoF,oBAAoB;QACjC,OAAO;UACLnD,IAAI,EAAEmC,uBAAS,CAACiB,cAAc;UAC9BnB,eAAe,EAAEA,eAAe,IAAI,EAAE;UACtCI,QAAQ,EAAEpD;QACZ,CAAC;MAEH,KAAKlB,iBAAS,CAACsF,qBAAqB;QAClC,OAAO;UACLrD,IAAI,EAAEmC,uBAAS,CAACmB,eAAe;UAC/BjB,QAAQ,EAAE;YAAC,GAAGpD,OAAO;YAAE6D,WAAW,EAAE;UAAK;QAC3C,CAAC;MAEH,KAAK/E,iBAAS,CAACwF,gBAAgB;QAAE;QAC/B;QACA,OAAO;UACLvD,IAAI,EAAEmC,uBAAS,CAACqB,iBAAiB;UACjCC,6BAA6B,EAAE,IAAI;UACnCpB,QAAQ,EAAEpD;QACZ,CAAC;MAEH,KAAKlB,iBAAS,CAAC2F,mBAAmB;QAAE;QAClC,OAAO;UAAC1D,IAAI,EAAEmC,uBAAS,CAACwB,WAAW;UAAEtB,QAAQ,EAAEpD;QAAO,CAAC;MAEzD,KAAKlB,iBAAS,CAAC6F,oBAAoB;MACnC,KAAK7F,iBAAS,CAAC8F,gBAAgB;QAC7B,OAAO;UAAC7D,IAAI,EAAEmC,uBAAS,CAAC2B,cAAc;UAAEC,MAAM,EAAE9E,OAAO,CAAC8E,MAAM;UAAE1B,QAAQ,EAAEpD;QAAO,CAAC;MAEpF,KAAKlB,iBAAS,CAACiG,mBAAmB;QAChC,OAAO;UAAChE,IAAI,EAAEmC,uBAAS,CAAC8B,UAAU;UAAE5B,QAAQ,EAAEpD;QAAO,CAAC;MAExD,KAAKlB,iBAAS,CAACmG,uBAAuB;QACpC,OAAO;UAAClE,IAAI,EAAEmC,uBAAS,CAACgC,iBAAiB;UAAE9B,QAAQ,EAAEpD;QAAO,CAAC;MAE/D,KAAKlB,iBAAS,CAACqG,uBAAuB,CAAC,CAAC;MACxC,KAAKrG,iBAAS,CAACsG,yBAAyB,CAAC,CAAC;MAC1C,KAAKtG,iBAAS,CAACuG,uBAAuB;QAAE;QACtC,OAAO;UACLtE,IAAI,EAAEmC,uBAAS,CAACoC,gBAAgB;UAChClC,QAAQ,EAAEpD;QACZ,CAAC;MAEH,KAAKlB,iBAAS,CAACyG,YAAY;QACzB,OAAO;UAACxE,IAAI,EAAEmC,uBAAS,CAACsC,WAAW;UAAEpC,QAAQ,EAAE;YAAC,GAAGpD,OAAO;YAAEyF,cAAc,EAAE;UAAI;QAAC,CAAC;MACpF,KAAK3G,iBAAS,CAAC4G,wBAAwB;QACrC,OAAO,IAAI;MAAE;;MAEf,KAAK5G,iBAAS,CAAC6G,2BAA2B;MAC1C,KAAK7G,iBAAS,CAAC8G,2BAA2B;MAC1C,KAAK9G,iBAAS,CAAC+G,6BAA6B;MAC5C,KAAK/G,iBAAS,CAACgH,gCAAgC;QAC7C,OAAO;UAAC/E,IAAI,EAAEmC,uBAAS,CAAC6C,eAAe;UAAE3C,QAAQ,EAAEpD;QAAO,CAAC;MAE7D,KAAKlB,iBAAS,CAACkH,aAAa;QAC1B,OAAO;UACLjF,IAAI,EAAEmC,uBAAS,CAAC8C,aAAa;UAC7B5C,QAAQ,EAAE;YACR,GAAGpD,OAAO;YACVyF,cAAc,EAAEzF,OAAO,CAAC8B,WAAW,EAAEmE,KAAK,KAAK;UACjD;QACF,CAAC;MAEH,KAAKnH,iBAAS,CAACoH,mBAAmB;QAChC,OAAO;UAACnF,IAAI,EAAEmC,uBAAS,CAACiD,aAAa;UAAErB,MAAM,EAAE9E,OAAO,CAAC8E;QAAM,CAAC;MAEhE,KAAKhG,iBAAS,CAACsH,2BAA2B;QACxC,OAAO;UAACrF,IAAI,EAAEmC,uBAAS,CAACmD,aAAa;UAAEvB,MAAM,EAAE9E,OAAO,CAAC8E;QAAM,CAAC;MAEhE,KAAKhG,iBAAS,CAACwH,wBAAwB;QACrC,OAAO;UAACvF,IAAI,EAAEmC,uBAAS,CAACqD,IAAI;UAAEnD,QAAQ,EAAEpD,OAAO;UAAE8E,MAAM,EAAE9E,OAAO,CAAC8E;QAAM,CAAC;MAE1E,KAAKhG,iBAAS,CAAC0H,qBAAqB;QAClC,OAAO;UAACzF,IAAI,EAAEmC,uBAAS,CAACuD,eAAe;UAAE3B,MAAM,EAAE9E,OAAO,CAAC8E;QAAM,CAAC;MAElE,KAAKhG,iBAAS,CAAC4H,yBAAyB;QACtC,OAAO;UAAC3F,IAAI,EAAEmC,uBAAS,CAACyD,iBAAiB;UAAEvD,QAAQ,EAAEpD;QAAO,CAAC;MAE/D,KAAKlB,iBAAS,CAAC8H,wBAAwB;QACrC,OAAO;UAAC7F,IAAI,EAAEmC,uBAAS,CAAC2D,eAAe;UAAEzD,QAAQ,EAAEpD;QAAO,CAAC;MAE7D,KAAKlB,iBAAS,CAACgI,yBAAyB;QACtC,OAAO;UAAC/F,IAAI,EAAEmC,uBAAS,CAAC6D,gBAAgB;UAAE3D,QAAQ,EAAEpD;QAAO,CAAC;MAE9D,KAAKlB,iBAAS,CAACkI,eAAe;QAC5B,OAAO;UAACjG,IAAI,EAAEmC,uBAAS,CAAC+D,eAAe;UAAE7D,QAAQ,EAAEpD;QAAO,CAAC;;MAE7D;MACA,KAAKlB,iBAAS,CAACoI,yBAAyB;MACxC,KAAKpI,iBAAS,CAACqI,6BAA6B;QAC1C,OAAO;UAACpG,IAAI,EAAEmC,uBAAS,CAACkE,gBAAgB;UAAEhE,QAAQ,EAAEpD;QAAO,CAAC;MAE9D,KAAKlB,iBAAS,CAACuI,+BAA+B;QAC5C,OAAO;UAACtG,IAAI,EAAEmC,uBAAS,CAACoE,iBAAiB;UAAExC,MAAM,EAAE9E,OAAO,CAAC8E,MAAM;UAAE1B,QAAQ,EAAEpD;QAAO,CAAC;MAEvF,KAAKlB,iBAAS,CAACyI,8BAA8B;QAC3C,OAAO;UAACxG,IAAI,EAAEmC,uBAAS,CAACsE,cAAc;UAAEpE,QAAQ,EAAEpD;QAAO,CAAC;MAE5D,KAAKlB,iBAAS,CAAC2I,2BAA2B;QACxC,OAAO;UACL1G,IAAI,EAAEmC,uBAAS,CAACwE,iBAAiB;UACjCtE,QAAQ,EAAEpD,OAAO;UACjB2H,aAAa,EAAE3H,OAAO,EAAE2H;QAC1B,CAAC;MAEH,KAAK7I,iBAAS,CAAC8I,4BAA4B;QACzC,OAAO;UAAC7G,IAAI,EAAEmC,uBAAS,CAAC2E,2BAA2B;UAAEzE,QAAQ,EAAEpD;QAAO,CAAC;MAEzE;QACE;QACA,OAAO,IAAI;IACf;EACF;;EAEA;AACF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;EACUJ,qBAAqBA,CAAA,EAAG;IAC9B,IAAI,CAACJ,gBAAgB,CAACkD,EAAE,CAAC,SAAS,EAAG3C,KAAK,IAAK;MAC7C;MACA,MAAM+H,OAAO,GAAG5I,WAAW,CAAC6I,qBAAqB,CAAChI,KAAK,CAAC;MACxD,IAAI,CAAC+H,OAAO,EAAE;;MAEd;MACA,MAAME,YAAY,GAAG,IAAI,CAACC,mBAAmB,CAACH,OAAO,CAAC;MACtD,IAAI,CAACE,YAAY,EAAE;MAEnB,MAAME,OAAO,GAAG,IAAI,CAACC,wBAAwB,CAACH,YAAY,CAAC;MAE3D,MAAM;QAAC1H;MAAI,CAAC,GAAG4H,OAAO;MACtB,IAAI,CAAC5H,IAAI,EAAE;MAEX,MAAM;QAACN,OAAO;QAAEoI;MAAiB,CAAC,GAAGJ,YAAY;;MAEjD;MACA;MACA,IAAIhI,OAAO,EAAE;QACX,IAAI,CAACqI,cAAc,CAAC/H,IAAI,EAAEN,OAAO,CAAC;MACpC;;MAEA;MACA;MACA,IAAIoI,iBAAiB,EAAE;QACrB9H,IAAI,CAACmC,qBAAqB,CAAC2F,iBAAiB,CAAC;MAC/C;;MAEA;MACA,IAAI,CAACE,0BAA0B,CAACN,YAAY,CAACO,SAAS,EAAEvI,OAAO,CAACG,aAAa,CAAC;IAChF,CAAC,CAAC;EACJ;;EAEA;AACF;AACA;AACA;EACE,OAAe4H,qBAAqBA,CAAChI,KAAa,EAA2B;IAC3E,IAAI;MACF,MAAMC,OAAO,GAAGC,IAAI,CAACC,KAAK,CAACH,KAAK,CAAqB;;MAErD;MACA,IAAIC,OAAO,EAAEwI,SAAS,KAAK,MAAM,IAAIxI,OAAO,EAAEwI,SAAS,KAAK,IAAI,EAAE;QAChE,OAAO,IAAI;MACb;;MAEA;MACA,IAAIxI,OAAO,EAAEI,IAAI,EAAE0B,WAAW,EAAE;QAC9B9B,OAAO,CAACI,IAAI,GAAG,IAAAqI,qCAAiB,EAACzI,OAAO,CAACI,IAAI,CAAC;MAChD;MAEA,OAAOJ,OAAO;IAChB,CAAC,CAAC,OAAOgB,KAAK,EAAE;MACdT,oBAAW,CAACS,KAAK,CAAC,mCAAmC,EAAE;QACrDP,MAAM,EAAEC,4BAAiB;QACzBC,MAAM,EAAE,uBAAuB;QAC/BK;MACF,CAAC,CAAC;MAEF,OAAO,IAAI;IACb;EACF;;EAEA;AACF;AACA;AACA;EACUiH,mBAAmBA,CAACH,OAAyB,EAAuB;IAC1E,MAAMS,SAAS,GAAGT,OAAO,CAAC1H,IAAI,EAAEW,IAAI,IAAI+G,OAAO,CAAC/G,IAAI;IAEpD,IAAI,CAACwH,SAAS,IAAI,CAACxJ,SAAS,CAACwJ,SAAS,CAAC,EAAE;MACvC,OAAO,IAAI;IACb;IAEA,MAAMpI,aAAa,GAAG2H,OAAO,CAAC1H,IAAI,CAACD,aAAa;IAChD,MAAMG,IAAI,GAAG,IAAI,CAACZ,cAAc,CAACS,aAAa,CAAC;IAE/C,MAAMuI,gBAAgB,GAAGC,OAAO,CAACrI,IAAI,EAAEF,IAAI,EAAEyD,WAAW,CAAC;IACzD,MAAM+E,qBAAqB,GAAGA,CAAA,KAAM;MAClC,IAAId,OAAO,CAAC1H,IAAI,CAACqF,cAAc,KAAKoD,SAAS,EAAE;QAC7C,OAAOf,OAAO,CAAC1H,IAAI,CAACqF,cAAc;MACpC;MACA,IAAIqC,OAAO,CAAC1H,IAAI,CAACyD,WAAW,KAAKgF,SAAS,EAAE;QAC1C,OAAO,CAACf,OAAO,CAAC1H,IAAI,CAACyD,WAAW;MAClC;MAEA,OAAO,CAAC6E,gBAAgB;IAC1B,CAAC;IAED,MAAMI,eAAe,GACnBP,SAAS,KAAKzJ,iBAAS,CAACsG,yBAAyB,IACjDmD,SAAS,KAAKzJ,iBAAS,CAACqG,uBAAuB,IAC/CoD,SAAS,KAAKzJ,iBAAS,CAACuG,uBAAuB,GAC3C;MACE,GAAGyC,OAAO,CAAC1H,IAAI;MACfqF,cAAc,EAAEmD,qBAAqB,CAAC;IACxC,CAAC,GACDd,OAAO,CAAC1H,IAAI;IAElB,MAAMgI,iBAAiB,GAAGlJ,WAAW,CAACqD,+BAA+B,CACnEgG,SAAS,EACTO,eAAe,EACf,IAAI,CAACxH,OACP,CAAC;IAEDf,oBAAW,CAACC,IAAI,CAAC,uBAAuB+H,SAAS,EAAE,EAAE;MACnD9H,MAAM,EAAEC,4BAAiB;MACzBC,MAAM,EAAE,qBAAqB;MAC7BR;IACF,CAAC,CAAC;IAEF,OAAO;MACLoI,SAAS;MACTvI,OAAO,EAAE8I,eAAe;MACxBxI,IAAI;MACJ8H;IACF,CAAC;EACH;;EAEA;AACF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;EACUD,wBAAwBA,CAACY,OAAqB,EAAoB;IACxE,MAAM;MAACR;IAAS,CAAC,GAAGQ,OAAO;IAE3B,QAAQR,SAAS;MACf,KAAKzJ,iBAAS,CAAC0D,sBAAsB;QACnC,OAAO,IAAI,CAACwG,qBAAqB,CAACD,OAAO,CAAC;MAE5C,KAAKjK,iBAAS,CAACyE,aAAa;QAC1B,OAAO,IAAI,CAAC0F,kBAAkB,CAACF,OAAO,CAAC;MAEzC,KAAKjK,iBAAS,CAACoK,cAAc;QAC3B,OAAO,IAAI,CAACC,wBAAwB,CAACJ,OAAO,CAAC;MAE/C;QACE,OAAO;UAACzI,IAAI,EAAEyI,OAAO,CAACzI;QAAI,CAAC;IAC/B;EACF;;EAEA;AACF;AACA;AACA;EACU0I,qBAAqBA,CAACD,OAAqB,EAAoB;IACrE,MAAM;MAAC/I;IAAO,CAAC,GAAG+I,OAAO;IACzB,MAAMK,eAAe,GACnBpJ,OAAO,CAAC6D,WAAW,KAAK,IAAI,IAAI,IAAAwF,+BAAoB,EAACrJ,OAAO,CAAC8B,WAAW,CAAC;IAC3E,MAAMwH,gBAAgB,GAAG,IAAAC,+BAAoB,EAC3CvJ,OAAO,EACP,IAAI,CAACsB,OAAO,EACZ,IAAI,CAAC/B,iBAAiB,CAACiK,WAAW,EAClC,IAAI,CAAC7J,aACP,CAAC;IAED,MAAMyD,QAAkB,GAAG;MACzB,GAAGpD,OAAO;MACV6D,WAAW,EAAEuF,eAAe;MAC5BK,eAAe,EAAEH;IACnB,CAAC;IAED,MAAMhJ,IAAI,GAAGoJ,oBAAW,CAACC,UAAU,CACjC,IAAI,CAACrK,OAAO,EACZ,IAAI,CAACC,iBAAiB,EACtB6D,QAAQ,EACR,IAAI,CAAClC,WAAW,EAChB,IAAI,CAACE,UAAU,EACf,IAAI,CAACE,OACP,CAAC;IAED,IAAI,CAACsI,kBAAkB,CAACtJ,IAAI,CAAC;IAC7B,IAAI,CAACZ,cAAc,CAACM,OAAO,CAACG,aAAa,CAAC,GAAGG,IAAI;IAEjD,OAAO;MAACA;IAAI,CAAC;EACf;;EAEA;AACF;AACA;AACA;EACU2I,kBAAkBA,CAACF,OAAqB,EAAoB;IAClE,IAAI;MAACzI;IAAI,CAAC,GAAGyI,OAAO;IACpB,MAAM;MAAC/I;IAAO,CAAC,GAAG+I,OAAO;IAEzB,IAAI,CAACzI,IAAI,EAAE;MACT,MAAM8I,eAAe,GACnBpJ,OAAO,CAAC6D,WAAW,KAAK,IAAI,IAAI,IAAAwF,+BAAoB,EAACrJ,OAAO,CAAC8B,WAAW,CAAC;MAC3E,MAAMwH,gBAAgB,GAAG,IAAAC,+BAAoB,EAC3CvJ,OAAO,EACP,IAAI,CAACsB,OAAO,EACZ,IAAI,CAAC/B,iBAAiB,CAACiK,WAAW,EAClC,IAAI,CAAC7J,aACP,CAAC;MACD,MAAMyD,QAAkB,GAAG;QACzB,GAAGpD,OAAO;QACV6D,WAAW,EAAEuF,eAAe;QAC5B3D,cAAc,EAAEzF,OAAO,CAAC8B,WAAW,EAAE+H,YAAY,GAAG,IAAI,CAACvI,OAAO,CAAC,EAAEwI,QAAQ,IAAI,KAAK;QACpFC,sBAAsB,EAAE,IAAAC,oCAAyB,EAAChK,OAAO,CAAC;QAC1DyJ,eAAe,EAAEH;MACnB,CAAC;MAEDhJ,IAAI,GAAGoJ,oBAAW,CAACC,UAAU,CAC3B,IAAI,CAACrK,OAAO,EACZ,IAAI,CAACC,iBAAiB,EACtB6D,QAAQ,EACR,IAAI,CAAClC,WAAW,EAChB,IAAI,CAACE,UAAU,EACf,IAAI,CAACE,OACP,CAAC;MACD,IAAI,CAACsI,kBAAkB,CAACtJ,IAAI,CAAC;MAC7B,IAAI,CAACZ,cAAc,CAACM,OAAO,CAACG,aAAa,CAAC,GAAGG,IAAI;IACnD;IAEA,OAAO;MAACA;IAAI,CAAC;EACf;EAEQ+H,cAAcA,CAAC/H,IAAW,EAAE8C,QAAkB,EAAS;IAC7D,IAAI,CAAC9C,IAAI,EAAE;MACT,MAAM,IAAI2J,KAAK,CAAC,2BAA2B,CAAC;IAC9C;IAEA,MAAMC,QAAQ,GAAG5J,IAAI,CAAC6J,mBAAmB,EAAEC,WAAW,GAAG,CAAC;IAC1D,MAAMC,gBAAgB,GACpBH,QAAQ,EAAElL,KAAK,KAAK,YAAY,IAAIoE,QAAQ,CAACtB,WAAW,EAAEmE,KAAK,KAAK,YAAY;IAElF,MAAMoC,cAAc,GAAGgC,gBAAgB,GACnC;MACE,GAAGjH,QAAQ;MACXkH,WAAW,EAAElH,QAAQ,CAACkH,WAAW,IAAIJ,QAAQ,EAAEnB,OAAO,EAAEwB,yBAAyB,IAAI,IAAI;MACzFC,eAAe,EACbpH,QAAQ,CAACoH,eAAe,IAAIN,QAAQ,EAAEnB,OAAO,EAAE0B,sBAAsB,IAAI;IAC7E,CAAC,GACDrH,QAAQ;IAEZ9C,IAAI,CAAC+H,cAAc,CAACA,cAAc,CAAC;IACnC,IAAI,CAAC3I,cAAc,CAAC0D,QAAQ,CAACjD,aAAa,CAAC,GAAGG,IAAI;IAElD,OAAOA,IAAI;EACb;;EAEA;AACF;AACA;AACA;EACUsJ,kBAAkBA,CAACtJ,IAAW,EAAQ;IAC5C;IACAA,IAAI,CAACoC,EAAE,CAACgI,kBAAW,CAACvH,aAAa,EAAGtB,CAAQ,IAAK;MAC/CtB,oBAAW,CAAC6B,GAAG,CAAC,8BAA8B,EAAE;QAC9C3B,MAAM,EAAEC,4BAAiB;QACzBC,MAAM,EAAEC,mBAAO,CAAC+J,uBAAuB;QACvCxK,aAAa,EAAE0B,CAAC,CAACzB,IAAI,EAAED;MACzB,CAAC,CAAC;MAEF,IAAI,CAACW,IAAI,CAAC4J,kBAAW,CAACvH,aAAa,EAAEtB,CAAC,CAAC;IACzC,CAAC,CAAC;;IAEF;IACAvB,IAAI,CAACoC,EAAE,CAACgI,kBAAW,CAACE,YAAY,EAAG/I,CAAQ,IAAK;MAC9C;MACA,IAAI,CAACf,IAAI,CAAC4J,kBAAW,CAACE,YAAY,EAAE/I,CAAC,CAAC;IACxC,CAAC,CAAC;;IAEF;IACAvB,IAAI,CAACoC,EAAE,CAACgI,kBAAW,CAACG,YAAY,EAAE,CAAChJ,CAAQ,EAAEiJ,OAA0C,KAAK;MAC1F,IAAI,CAACC,iBAAiB,CAAClJ,CAAC,CAAC;MACzB,IAAIiJ,OAAO,EAAEE,oBAAoB,EAAE;QACjC,MAAM7K,aAAa,GAAG0B,CAAC,EAAEzB,IAAI,EAAED,aAAa;QAC5C,IAAIA,aAAa,IAAI,IAAI,CAACT,cAAc,CAACS,aAAa,CAAC,EAAE;UACvD,IAAI,CAAC8K,wBAAwB,CAACpJ,CAAC,CAAC;QAClC;MACF;IACF,CAAC,CAAC;EACJ;EAEQoJ,wBAAwBA,CAAC3K,IAAW,EAAE;IAC5C,IAAI,OAAOA,IAAI,CAAC4K,qBAAqB,KAAK,UAAU,EAAE;MACpD5K,IAAI,CAAC4K,qBAAqB,CAAC,CAAC;IAC9B;IACA,IAAI5K,IAAI,EAAEF,IAAI,EAAED,aAAa,EAAE;MAC7B,OAAO,IAAI,CAACT,cAAc,CAACY,IAAI,CAACF,IAAI,CAACD,aAAa,CAAC;MACnDI,oBAAW,CAACC,IAAI,CAAC,8BAA8B,EAAE;QAC/CC,MAAM,EAAEC,4BAAiB;QACzBC,MAAM,EAAEC,mBAAO,CAACuK,2BAA2B;QAC3ChL,aAAa,EAAEG,IAAI,CAACF,IAAI,CAACD;MAC3B,CAAC,CAAC;IACJ;EACF;;EAEA;AACF;AACA;AACA;AACA;AACA;AACA;EACUgJ,wBAAwBA,CAACJ,OAAqB,EAAoB;IACxE,MAAM;MAAC/I;IAAO,CAAC,GAAG+I,OAAO;IACzB,IAAIzI,IAAI,GAAGyI,OAAO,CAACzI,IAAI;IAEvB,IAAIN,OAAO,CAACoL,kBAAkB,EAAE;MAC9B;MACA,IAAI,CAACH,wBAAwB,CAAC,IAAI,CAACvL,cAAc,CAACM,OAAO,CAACoL,kBAAkB,CAAC,CAAC;IAChF;IAEA,IAAI9K,IAAI,EAAE;MACRC,oBAAW,CAAC6B,GAAG,CAAC,uDAAuD,EAAE;QACvE3B,MAAM,EAAEC,4BAAiB;QACzBC,MAAM,EAAEC,mBAAO,CAAC+J,uBAAuB;QACvCxK,aAAa,EAAEH,OAAO,CAACG;MACzB,CAAC,CAAC;MACF;MACA,IAAI,CAACkI,cAAc,CAAC/H,IAAI,EAAEN,OAAO,CAAC;IACpC,CAAC,MAAM;MACL;MACAO,oBAAW,CAAC6B,GAAG,CAAC,uDAAuD,EAAE;QACvE3B,MAAM,EAAEC,4BAAiB;QACzBC,MAAM,EAAEC,mBAAO,CAAC+J,uBAAuB;QACvCxK,aAAa,EAAEH,OAAO,CAACG;MACzB,CAAC,CAAC;MAEF,MAAMiD,QAAkB,GAAG;QACzB,GAAGpD,OAAO;QACVyF,cAAc,EAAEzF,OAAO,CAAC8B,WAAW,EAAE+H,YAAY,GAAG,IAAI,CAACvI,OAAO,CAAC,EAAEwI,QAAQ,IAAI,KAAK;QACpFC,sBAAsB,EAAE,IAAAC,oCAAyB,EAAChK,OAAO,CAAC;QAC1D6D,WAAW,EAAE;MACf,CAAC;MAEDvD,IAAI,GAAGoJ,oBAAW,CAACC,UAAU,CAC3B,IAAI,CAACrK,OAAO,EACZ,IAAI,CAACC,iBAAiB,EACtB6D,QAAQ,EACR,IAAI,CAAClC,WAAW,EAChB,IAAI,CAACE,UAAU,EACf,IAAI,CAACE,OACP,CAAC;MACD,IAAI,CAAC5B,cAAc,CAACM,OAAO,CAACG,aAAa,CAAC,GAAGG,IAAI;;MAEjD;MACA;MACA;MACA;MACA;MACAA,IAAI,CAACmC,qBAAqB,CAAC;QACzB1B,IAAI,EAAEmC,uBAAS,CAACM,OAAO;QACvBJ,QAAQ;QACR9B,OAAO,EAAE,IAAI,CAACA;MAChB,CAAqB,CAAC;MAEtB,IAAI,CAACsI,kBAAkB,CAACtJ,IAAI,CAAC;IAC/B;IAEA,IAAIA,IAAI,EAAE;MACR,IAAI,CAACQ,IAAI,CAAC4J,kBAAW,CAACW,WAAW,EAAE/K,IAAI,CAAC;IAC1C;IAEA,OAAO;MAACA;IAAI,CAAC;EACf;;EAEA;AACF;AACA;AACA;AACA;EACUyK,iBAAiBA,CAACzK,IAAW,EAAE;IACrC,IACE,IAAI,CAACf,iBAAiB,CAACiK,WAAW,KAAK8B,mBAAW,CAACC,OAAO,IAC1DjL,IAAI,CAACF,IAAI,CAAC0B,WAAW,CAACC,SAAS,KAAKC,oBAAa,CAACC,SAAS,IAC3D3B,IAAI,YAAYkL,eAAM,EACtB;MACAlL,IAAI,CAACmL,0BAA0B,CAAC,CAAC;MACjC,IAAI,CAAClM,iBAAiB,CAACmM,WAAW,CAAC,CAAC;IACtC;IAEA,MAAMC,SAAS,GAAGrL,IAAI,CAACF,IAAI,CAAC0B,WAAW,CAAC8J,YAAY,KAAK,SAAS;IAClE,MAAMC,KAAK,GAAGvL,IAAI,CAACF,IAAI,CAAC0B,WAAW,CAACmE,KAAK,KAAK,KAAK;IACnD,MAAM6F,WAAW,GAAGxL,IAAI,CAACF,IAAI,CAAC2L,mBAAmB,EAAEC,MAAM,GAAG,CAAC;;IAE7D;IACA;IACA;IACA;IACA,IAAKH,KAAK,IAAI,EAAEF,SAAS,IAAIG,WAAW,CAAC,IAAK,IAAAzC,+BAAoB,EAAC/I,IAAI,CAACF,IAAI,CAAC0B,WAAW,CAAC,EAAE;MACzF,IAAI,CAACmJ,wBAAwB,CAAC3K,IAAI,CAAC;IACrC;EACF;;EAEA;AACF;AACA;AACA;EACUgI,0BAA0BA,CAACC,SAAiB,EAAEpI,aAAqB,EAAQ;IACjF,MAAM8L,MAAM,GAAGC,gCAAoB,CAAC3D,SAAS,CAAC;IAC9C,IAAI,CAAC0D,MAAM,IAAI,CAAC,IAAI,CAAC5M,cAAc,EAAE;IACrC,IAAI,IAAI,CAAC6B,WAAW,EAAEiL,SAAS,EAAEC,mBAAmB,EAAEC,MAAM,KAAK,KAAK,EAAE;IAExE,IAAI,CAAChN,cAAc,CAChBiN,SAAS,CACR,IAAI,CAAChL,OAAO,EACZnB,aAAa,EACboM,4BAAoB,CAACC,YAAY,EACjCC,4BAAoB,CAACC,eAAe,EACpCT,MACF,CAAC,CACAU,KAAK,CAAE3L,KAAK,IAAK;MAChBT,oBAAW,CAACS,KAAK,CAAC,6BAA6BiL,MAAM,QAAQ,EAAE;QAC7DxL,MAAM,EAAEC,4BAAiB;QACzBC,MAAM,EAAEC,mBAAO,CAACgM,6BAA6B;QAC7CzM,aAAa;QACba;MACF,CAAC,CAAC;IACJ,CAAC,CAAC;EACN;EAEO6L,OAAOA,CAACC,MAAc,EAAS;IACpC,OAAO,IAAI,CAACpN,cAAc,CAACoN,MAAM,CAAC;EACpC;EAEOC,WAAWA,CAAA,EAA0B;IAC1C,OAAO;MAAC,GAAG,IAAI,CAACrN;IAAc,CAAC;EACjC;EAEA,OAAcsN,cAAcA,CAC1B3N,cAA8B,EAC9BC,OAA0C,EAC1CC,iBAAoC,EACpCC,gBAAkC,EAClCC,mBAAsC,EACzB;IACb,IAAI,CAACP,WAAW,CAAC+N,WAAW,EAAE;MAC5B/N,WAAW,CAAC+N,WAAW,GAAG,IAAI/N,WAAW,CACvCG,cAAc,EACdC,OAAO,EACPC,iBAAiB,EACjBC,gBAAgB,EAChBC,mBACF,CAAC;IACH;IAEA,OAAOP,WAAW,CAAC+N,WAAW;EAChC;AACF;AAACC,OAAA,CAAAzO,OAAA,GAAAS,WAAA","ignoreList":[]}
@@ -75,7 +75,13 @@ const deriveTaskDataUpdates = (context, taskData) => taskData ? (() => {
75
75
  if (taskData.interaction?.state === 'consulting') {
76
76
  if (!context.consultDestinationAgentJoined) {
77
77
  const hasJoinedConsultee = Boolean(taskData.interaction.participants && Object.values(taskData.interaction.participants).some(p => p?.isConsulted === true && !p?.hasLeft));
78
- if (hasJoinedConsultee) updates.consultDestinationAgentJoined = true;
78
+ const cpd = taskData.interaction?.callProcessingDetails;
79
+ const backendSaysJoined = cpd?.consultDestinationAgentJoined === 'true';
80
+ if (hasJoinedConsultee || backendSaysJoined) updates.consultDestinationAgentJoined = true;
81
+ }
82
+ if (!context.consultDestinationType && !updates.consultDestinationType) {
83
+ const hasEpDnParticipant = Boolean(taskData.interaction.participants && Object.values(taskData.interaction.participants).some(p => p?.pType === 'EP-DN' && !p?.hasLeft));
84
+ if (hasEpDnParticipant) updates.consultDestinationType = 'entryPoint';
79
85
  }
80
86
  const effectiveConsultInitiator = updates.consultInitiator ?? context.consultInitiator;
81
87
  if (effectiveConsultInitiator) {
@@ -1 +1 @@
1
- {"version":3,"names":["_xstate","require","_constants","_uiControlsComputer","determineConsultInitiator","taskData","selfAgentId","undefined","consultingAgentId","isConsulted","deriveRecordingState","callProcessingDetails","interaction","update","recordingStarted","recordInProgress","isPaused","recordingControlsAvailable","recordingInProgress","deriveTaskDataUpdates","context","updates","destAgentId","consultDestinationAgentId","state","destinationType","consultDestinationType","consultInitiator","uiControlConfig","agentId","consultDestinationAgentJoined","hasJoinedConsultee","Boolean","participants","Object","values","some","p","hasLeft","effectiveConsultInitiator","consultMediaId","consultMediaResourceId","consultMedia","media","find","m","mType","consultCallHeld","isHold","getTaskDataFromEvent","event","createInitialContext","initialState","TaskState","IDLE","baseContext","exitingConference","consultFromConference","transferConferenceRequested","uiControls","getDefaultUIControls","computeUIControls","updateUIControls","currentState","assign","actions","exports","initializeTask","updateTaskData","setConsultInitiator","type","TaskEvent","CONSULT","handleConsultFailed","handleConferenceStarted","setConsultDestination","setConsultFromConference","forceConsultInitiator","setConsultAgentJoined","CONSULTING_ACTIVE","eventValue","setRecordingState","PAUSE_RECORDING","RESUME_RECORDING","clearConsultState","setTransferConferenceRequested","clearTransferConferenceRequested","setConsultCallHeld","clearConsultCallHeld","handleSwitchToMainCall","handleSwitchToConsult","handleConferenceFailed","handleParticipantLeft","setExitingConference","handleTransferConferenceSuccess","setHoldState","HOLD_SUCCESS","UNHOLD_SUCCESS","mediaResourceId","mediaEntry","updatedMedia","isConsultMedia","markEnded","requestAutoAnswer","requestCleanup","cleanupResources","emitTaskIncoming","emitTaskHydrate","emitTaskOfferContact","emitTaskAssigned","emitTaskHold","emitTaskResume","emitTaskEnd","emitTaskOfferConsult","emitTaskConsultCreated","emitTaskConsulting","emitTaskConsultAccepted","emitTaskConsultEnd","emitTaskReject","emitTaskWrapup","emitTaskRecordingStarted","emitTaskRecordingPaused","emitTaskRecordingResumed","emitTaskWrappedup","emitTaskParticipantLeft","emitTaskConferenceStarted","emitTaskConferenceEnded","emitTaskExitConference","emitTaskTransferConference","emitTaskSwitchCall","emitTaskConferenceFailed","emitTaskTransferConferenceFailed","emitTaskOutdialFailed"],"sources":["actions.ts"],"sourcesContent":["/**\n * Task State Machine Actions - Action implementations executed during state transitions\n */\n\nimport {assign} from 'xstate';\nimport {\n TaskContext,\n TaskEventPayload,\n UIControlConfig,\n TaskActionsMap,\n TaskActionArgs,\n RecordingStateUpdate,\n} from './types';\nimport {TaskEvent, TaskState} from './constants';\nimport {DestinationType, TaskData} from '../types';\nimport {computeUIControls, getDefaultUIControls} from './uiControlsComputer';\n\nconst determineConsultInitiator = (\n taskData: TaskData | undefined,\n selfAgentId: string | undefined\n): boolean | undefined => {\n if (!selfAgentId) return undefined;\n\n if (taskData?.consultingAgentId) {\n return taskData.consultingAgentId === selfAgentId;\n }\n\n if (taskData?.isConsulted === true) return false;\n\n return undefined;\n};\n\nconst deriveRecordingState = (taskData?: TaskData | null): RecordingStateUpdate => {\n const callProcessingDetails = taskData?.interaction?.callProcessingDetails;\n\n if (!callProcessingDetails) {\n return {};\n }\n\n const update: RecordingStateUpdate = {};\n const {recordingStarted, recordInProgress, isPaused} = callProcessingDetails as {\n recordingStarted?: boolean;\n recordInProgress?: boolean;\n isPaused?: boolean;\n };\n\n if (recordingStarted !== undefined) {\n update.recordingControlsAvailable = recordingStarted;\n if (!recordingStarted) {\n update.recordingInProgress = false;\n }\n }\n\n if (recordInProgress !== undefined) {\n update.recordingControlsAvailable = recordInProgress || recordingStarted || false;\n update.recordingInProgress = recordInProgress;\n }\n\n if (\n update.recordingControlsAvailable === undefined &&\n update.recordingInProgress === undefined &&\n recordingStarted\n ) {\n update.recordingControlsAvailable = true;\n update.recordingInProgress = true;\n }\n\n if (isPaused !== undefined) {\n update.recordingControlsAvailable = true;\n update.recordingInProgress = !isPaused;\n }\n\n return update;\n};\n\nconst deriveTaskDataUpdates = (context: TaskContext, taskData: TaskData | undefined) =>\n taskData\n ? (() => {\n const updates: Partial<TaskContext> = {\n taskData,\n ...deriveRecordingState(taskData),\n };\n\n if (taskData.destAgentId) {\n updates.consultDestinationAgentId = taskData.destAgentId;\n }\n if (taskData.interaction?.state === 'consulting' && taskData.destinationType) {\n updates.consultDestinationType = taskData.destinationType as DestinationType;\n }\n\n if (!context.consultInitiator) {\n const selfAgentId = context.uiControlConfig.agentId ?? taskData?.agentId;\n const consultInitiator = determineConsultInitiator(taskData, selfAgentId);\n if (consultInitiator !== undefined) {\n updates.consultInitiator = consultInitiator;\n } else if (\n taskData.interaction?.state === 'consulting' &&\n taskData.isConsulted === false\n ) {\n updates.consultInitiator = true;\n }\n }\n\n if (taskData.interaction?.state === 'consulting') {\n if (!context.consultDestinationAgentJoined) {\n const hasJoinedConsultee = Boolean(\n taskData.interaction.participants &&\n Object.values(taskData.interaction.participants).some(\n (p: any) => p?.isConsulted === true && !p?.hasLeft\n )\n );\n if (hasJoinedConsultee) updates.consultDestinationAgentJoined = true;\n }\n\n const effectiveConsultInitiator = updates.consultInitiator ?? context.consultInitiator;\n if (effectiveConsultInitiator) {\n const consultMediaId = taskData.consultMediaResourceId;\n const consultMedia: any = consultMediaId\n ? taskData.interaction.media?.[consultMediaId]\n : Object.values(taskData.interaction.media ?? {}).find(\n (m: any) => m?.mType === 'consult'\n );\n if (consultMedia) {\n updates.consultCallHeld = Boolean(consultMedia.isHold);\n }\n }\n }\n\n return updates;\n })()\n : {};\n\nconst getTaskDataFromEvent = (event?: TaskEventPayload): TaskData | undefined =>\n event && typeof event === 'object' ? (event as any).taskData : undefined;\n\nexport function createInitialContext(\n uiControlConfig: UIControlConfig,\n initialState: TaskState = TaskState.IDLE\n): TaskContext {\n const baseContext: TaskContext = {\n taskData: null,\n consultInitiator: false,\n exitingConference: false,\n consultFromConference: false,\n transferConferenceRequested: false,\n consultDestinationType: null,\n consultDestinationAgentId: null,\n consultDestinationAgentJoined: false,\n consultCallHeld: false,\n recordingControlsAvailable: false,\n recordingInProgress: false,\n uiControlConfig,\n uiControls: getDefaultUIControls(),\n };\n\n baseContext.uiControls = computeUIControls(initialState, baseContext);\n\n return baseContext;\n}\n\nexport function updateUIControls(currentState: TaskState) {\n return assign(({context}: TaskActionArgs) => ({\n uiControls: computeUIControls(currentState, context),\n }));\n}\n\nexport const actions: TaskActionsMap = {\n initializeTask: assign(({context, event}: {context: TaskContext; event: TaskEventPayload}) => {\n return {\n consultInitiator: false,\n exitingConference: false,\n consultDestinationType: null,\n consultDestinationAgentJoined: false,\n ...deriveTaskDataUpdates(context, getTaskDataFromEvent(event)),\n };\n }),\n\n /**\n * Update task data from ASSIGN event\n */\n updateTaskData: assign(({context, event}: TaskActionArgs) => {\n return deriveTaskDataUpdates(context, getTaskDataFromEvent(event));\n }),\n\n /**\n * Set consult initiator flag\n *\n * IMPORTANT: This action is called for CONSULT (user action) and CONSULT_CREATED (backend event).\n * For CONSULT (user action): The user explicitly clicked Consult, so they ARE the initiator.\n * For CONSULT_CREATED (backend event): Check taskData.isConsulted to determine if this agent\n * is the initiator. If isConsulted === true, this is Agent B (the consulted party), NOT the initiator.\n *\n * This prevents all agents in a conference from becoming consultInitiator when one agent\n * starts a new consult.\n */\n setConsultInitiator: assign(({event}: TaskActionArgs) => {\n const taskData = getTaskDataFromEvent(event);\n\n if (event.type === TaskEvent.CONSULT) return {consultInitiator: true};\n\n const selfAgentId = taskData?.agentId;\n const consultInitiator = determineConsultInitiator(taskData, selfAgentId);\n if (consultInitiator === true) return {consultInitiator: true};\n if (consultInitiator === false) return {consultInitiator: false};\n\n return {};\n }),\n\n handleConsultFailed: assign({consultDestinationAgentJoined: false, consultInitiator: false}),\n handleConferenceStarted: assign({consultInitiator: false}),\n\n setConsultDestination: assign(({event}: TaskActionArgs) => {\n if (!event || event.type !== TaskEvent.CONSULT) {\n return {};\n }\n\n const taskData = getTaskDataFromEvent(event);\n const consultDestinationType =\n 'destinationType' in event ? event.destinationType ?? null : null;\n const consultDestinationAgentId = 'destAgentId' in event ? event.destAgentId ?? null : null;\n\n return {\n consultDestinationType,\n consultDestinationAgentId,\n consultDestinationAgentJoined: false,\n consultFromConference: false,\n taskData: {\n ...taskData,\n destAgentId: consultDestinationAgentId,\n },\n };\n }),\n\n setConsultFromConference: assign({consultFromConference: true}),\n\n forceConsultInitiator: assign({consultInitiator: true}),\n\n setConsultAgentJoined: assign(\n ({context, event}: {context: TaskContext; event: TaskEventPayload}) => {\n if (context.consultDestinationAgentJoined) {\n return {};\n }\n\n if (\n !event ||\n event.type !== TaskEvent.CONSULTING_ACTIVE ||\n !('consultDestinationAgentJoined' in event)\n ) {\n return {};\n }\n\n const eventValue = (event as {consultDestinationAgentJoined: boolean})\n .consultDestinationAgentJoined;\n\n return eventValue ? {consultDestinationAgentJoined: true} : {};\n }\n ),\n\n setRecordingState: assign(({event}: TaskActionArgs) => {\n if (!event || !('type' in event)) {\n return {};\n }\n\n if (event.type === TaskEvent.PAUSE_RECORDING) {\n return {\n recordingControlsAvailable: true,\n recordingInProgress: false,\n };\n }\n if (event.type === TaskEvent.RESUME_RECORDING) {\n return {\n recordingControlsAvailable: true,\n recordingInProgress: true,\n };\n }\n\n return {};\n }),\n\n clearConsultState: assign({\n consultDestinationType: null,\n consultDestinationAgentId: null,\n consultDestinationAgentJoined: false,\n consultInitiator: false,\n exitingConference: false,\n consultCallHeld: false,\n consultFromConference: false,\n transferConferenceRequested: false,\n }),\n\n setTransferConferenceRequested: assign({transferConferenceRequested: true}),\n clearTransferConferenceRequested: assign({transferConferenceRequested: false}),\n\n setConsultCallHeld: assign({consultCallHeld: true}),\n clearConsultCallHeld: assign({consultCallHeld: false}),\n handleSwitchToMainCall: assign({consultCallHeld: true}),\n handleSwitchToConsult: assign({consultCallHeld: false}),\n\n handleConferenceFailed: assign(({event}: TaskActionArgs) => {\n const taskData = getTaskDataFromEvent(event);\n\n return taskData ? {taskData} : {};\n }),\n handleParticipantLeft: assign(({event}: TaskActionArgs) => {\n const taskData = getTaskDataFromEvent(event);\n\n return taskData ? {taskData} : {};\n }),\n\n setExitingConference: assign({exitingConference: true}),\n\n handleTransferConferenceSuccess: assign(({event}: TaskActionArgs) => {\n const taskData = getTaskDataFromEvent(event);\n\n return taskData ? {taskData} : {};\n }),\n\n setHoldState: assign(({context, event}: TaskActionArgs) => {\n if (\n !event ||\n (event.type !== TaskEvent.HOLD_SUCCESS && event.type !== TaskEvent.UNHOLD_SUCCESS)\n ) {\n return {};\n }\n\n const mediaResourceId =\n 'mediaResourceId' in event\n ? (event as {mediaResourceId?: string}).mediaResourceId\n : undefined;\n\n if (!mediaResourceId) {\n return {};\n }\n\n const interaction = context.taskData?.interaction;\n const mediaEntry = interaction?.media?.[mediaResourceId];\n\n if (!interaction || !mediaEntry) {\n return {};\n }\n\n const updatedMedia = {\n ...interaction.media,\n [mediaResourceId]: {\n ...mediaEntry,\n isHold: event.type === TaskEvent.HOLD_SUCCESS,\n },\n };\n\n const updates: Partial<TaskContext> = {\n taskData: {\n ...(context.taskData as TaskData),\n interaction: {\n ...interaction,\n media: updatedMedia,\n },\n },\n };\n\n const consultMediaId = context.taskData?.consultMediaResourceId;\n const isConsultMedia = consultMediaId\n ? mediaResourceId === consultMediaId\n : mediaEntry?.mType === 'consult';\n\n if (isConsultMedia && context.consultInitiator) {\n updates.consultCallHeld = event.type === TaskEvent.HOLD_SUCCESS;\n }\n\n return updates;\n }),\n\n markEnded: assign(() => ({\n recordingControlsAvailable: false,\n recordingInProgress: false,\n })),\n\n requestAutoAnswer: () => undefined,\n requestCleanup: () => undefined,\n cleanupResources: () => undefined,\n\n // Event emitters - placeholders overridden by consumers\n emitTaskIncoming: () => undefined,\n emitTaskHydrate: () => undefined,\n emitTaskOfferContact: () => undefined,\n emitTaskAssigned: () => undefined,\n emitTaskHold: () => undefined,\n emitTaskResume: () => undefined,\n emitTaskEnd: () => undefined,\n emitTaskOfferConsult: () => undefined,\n emitTaskConsultCreated: () => undefined,\n emitTaskConsulting: () => undefined,\n emitTaskConsultAccepted: () => undefined,\n emitTaskConsultEnd: () => undefined,\n emitTaskReject: () => undefined,\n emitTaskWrapup: () => undefined,\n emitTaskRecordingStarted: () => undefined,\n emitTaskRecordingPaused: () => undefined,\n emitTaskRecordingResumed: () => undefined,\n emitTaskWrappedup: () => undefined,\n emitTaskParticipantLeft: () => undefined,\n emitTaskConferenceStarted: () => undefined,\n emitTaskConferenceEnded: () => undefined,\n emitTaskExitConference: () => undefined,\n emitTaskTransferConference: () => undefined,\n emitTaskSwitchCall: () => undefined,\n emitTaskConferenceFailed: () => undefined,\n emitTaskTransferConferenceFailed: () => undefined,\n emitTaskOutdialFailed: () => undefined,\n};\n"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"names":["_xstate","require","_constants","_uiControlsComputer","determineConsultInitiator","taskData","selfAgentId","undefined","consultingAgentId","isConsulted","deriveRecordingState","callProcessingDetails","interaction","update","recordingStarted","recordInProgress","isPaused","recordingControlsAvailable","recordingInProgress","deriveTaskDataUpdates","context","updates","destAgentId","consultDestinationAgentId","state","destinationType","consultDestinationType","consultInitiator","uiControlConfig","agentId","consultDestinationAgentJoined","hasJoinedConsultee","Boolean","participants","Object","values","some","p","hasLeft","cpd","backendSaysJoined","hasEpDnParticipant","pType","effectiveConsultInitiator","consultMediaId","consultMediaResourceId","consultMedia","media","find","m","mType","consultCallHeld","isHold","getTaskDataFromEvent","event","createInitialContext","initialState","TaskState","IDLE","baseContext","exitingConference","consultFromConference","transferConferenceRequested","uiControls","getDefaultUIControls","computeUIControls","updateUIControls","currentState","assign","actions","exports","initializeTask","updateTaskData","setConsultInitiator","type","TaskEvent","CONSULT","handleConsultFailed","handleConferenceStarted","setConsultDestination","setConsultFromConference","forceConsultInitiator","setConsultAgentJoined","CONSULTING_ACTIVE","eventValue","setRecordingState","PAUSE_RECORDING","RESUME_RECORDING","clearConsultState","setTransferConferenceRequested","clearTransferConferenceRequested","setConsultCallHeld","clearConsultCallHeld","handleSwitchToMainCall","handleSwitchToConsult","handleConferenceFailed","handleParticipantLeft","setExitingConference","handleTransferConferenceSuccess","setHoldState","HOLD_SUCCESS","UNHOLD_SUCCESS","mediaResourceId","mediaEntry","updatedMedia","isConsultMedia","markEnded","requestAutoAnswer","requestCleanup","cleanupResources","emitTaskIncoming","emitTaskHydrate","emitTaskOfferContact","emitTaskAssigned","emitTaskHold","emitTaskResume","emitTaskEnd","emitTaskOfferConsult","emitTaskConsultCreated","emitTaskConsulting","emitTaskConsultAccepted","emitTaskConsultEnd","emitTaskReject","emitTaskWrapup","emitTaskRecordingStarted","emitTaskRecordingPaused","emitTaskRecordingResumed","emitTaskWrappedup","emitTaskParticipantLeft","emitTaskConferenceStarted","emitTaskConferenceEnded","emitTaskExitConference","emitTaskTransferConference","emitTaskSwitchCall","emitTaskConferenceFailed","emitTaskTransferConferenceFailed","emitTaskOutdialFailed"],"sources":["actions.ts"],"sourcesContent":["/**\n * Task State Machine Actions - Action implementations executed during state transitions\n */\n\nimport {assign} from 'xstate';\nimport {\n TaskContext,\n TaskEventPayload,\n UIControlConfig,\n TaskActionsMap,\n TaskActionArgs,\n RecordingStateUpdate,\n} from './types';\nimport {TaskEvent, TaskState} from './constants';\nimport {DestinationType, TaskData} from '../types';\nimport {computeUIControls, getDefaultUIControls} from './uiControlsComputer';\n\nconst determineConsultInitiator = (\n taskData: TaskData | undefined,\n selfAgentId: string | undefined\n): boolean | undefined => {\n if (!selfAgentId) return undefined;\n\n if (taskData?.consultingAgentId) {\n return taskData.consultingAgentId === selfAgentId;\n }\n\n if (taskData?.isConsulted === true) return false;\n\n return undefined;\n};\n\nconst deriveRecordingState = (taskData?: TaskData | null): RecordingStateUpdate => {\n const callProcessingDetails = taskData?.interaction?.callProcessingDetails;\n\n if (!callProcessingDetails) {\n return {};\n }\n\n const update: RecordingStateUpdate = {};\n const {recordingStarted, recordInProgress, isPaused} = callProcessingDetails as {\n recordingStarted?: boolean;\n recordInProgress?: boolean;\n isPaused?: boolean;\n };\n\n if (recordingStarted !== undefined) {\n update.recordingControlsAvailable = recordingStarted;\n if (!recordingStarted) {\n update.recordingInProgress = false;\n }\n }\n\n if (recordInProgress !== undefined) {\n update.recordingControlsAvailable = recordInProgress || recordingStarted || false;\n update.recordingInProgress = recordInProgress;\n }\n\n if (\n update.recordingControlsAvailable === undefined &&\n update.recordingInProgress === undefined &&\n recordingStarted\n ) {\n update.recordingControlsAvailable = true;\n update.recordingInProgress = true;\n }\n\n if (isPaused !== undefined) {\n update.recordingControlsAvailable = true;\n update.recordingInProgress = !isPaused;\n }\n\n return update;\n};\n\nconst deriveTaskDataUpdates = (context: TaskContext, taskData: TaskData | undefined) =>\n taskData\n ? (() => {\n const updates: Partial<TaskContext> = {\n taskData,\n ...deriveRecordingState(taskData),\n };\n\n if (taskData.destAgentId) {\n updates.consultDestinationAgentId = taskData.destAgentId;\n }\n if (taskData.interaction?.state === 'consulting' && taskData.destinationType) {\n updates.consultDestinationType = taskData.destinationType as DestinationType;\n }\n\n if (!context.consultInitiator) {\n const selfAgentId = context.uiControlConfig.agentId ?? taskData?.agentId;\n const consultInitiator = determineConsultInitiator(taskData, selfAgentId);\n if (consultInitiator !== undefined) {\n updates.consultInitiator = consultInitiator;\n } else if (\n taskData.interaction?.state === 'consulting' &&\n taskData.isConsulted === false\n ) {\n updates.consultInitiator = true;\n }\n }\n\n if (taskData.interaction?.state === 'consulting') {\n if (!context.consultDestinationAgentJoined) {\n const hasJoinedConsultee = Boolean(\n taskData.interaction.participants &&\n Object.values(taskData.interaction.participants).some(\n (p: any) => p?.isConsulted === true && !p?.hasLeft\n )\n );\n const cpd = taskData.interaction?.callProcessingDetails;\n const backendSaysJoined = cpd?.consultDestinationAgentJoined === 'true';\n if (hasJoinedConsultee || backendSaysJoined)\n updates.consultDestinationAgentJoined = true;\n }\n\n if (!context.consultDestinationType && !updates.consultDestinationType) {\n const hasEpDnParticipant = Boolean(\n taskData.interaction.participants &&\n Object.values(taskData.interaction.participants).some(\n (p: any) => p?.pType === 'EP-DN' && !p?.hasLeft\n )\n );\n if (hasEpDnParticipant) updates.consultDestinationType = 'entryPoint' as any;\n }\n\n const effectiveConsultInitiator = updates.consultInitiator ?? context.consultInitiator;\n if (effectiveConsultInitiator) {\n const consultMediaId = taskData.consultMediaResourceId;\n const consultMedia: any = consultMediaId\n ? taskData.interaction.media?.[consultMediaId]\n : Object.values(taskData.interaction.media ?? {}).find(\n (m: any) => m?.mType === 'consult'\n );\n if (consultMedia) {\n updates.consultCallHeld = Boolean(consultMedia.isHold);\n }\n }\n }\n\n return updates;\n })()\n : {};\n\nconst getTaskDataFromEvent = (event?: TaskEventPayload): TaskData | undefined =>\n event && typeof event === 'object' ? (event as any).taskData : undefined;\n\nexport function createInitialContext(\n uiControlConfig: UIControlConfig,\n initialState: TaskState = TaskState.IDLE\n): TaskContext {\n const baseContext: TaskContext = {\n taskData: null,\n consultInitiator: false,\n exitingConference: false,\n consultFromConference: false,\n transferConferenceRequested: false,\n consultDestinationType: null,\n consultDestinationAgentId: null,\n consultDestinationAgentJoined: false,\n consultCallHeld: false,\n recordingControlsAvailable: false,\n recordingInProgress: false,\n uiControlConfig,\n uiControls: getDefaultUIControls(),\n };\n\n baseContext.uiControls = computeUIControls(initialState, baseContext);\n\n return baseContext;\n}\n\nexport function updateUIControls(currentState: TaskState) {\n return assign(({context}: TaskActionArgs) => ({\n uiControls: computeUIControls(currentState, context),\n }));\n}\n\nexport const actions: TaskActionsMap = {\n initializeTask: assign(({context, event}: {context: TaskContext; event: TaskEventPayload}) => {\n return {\n consultInitiator: false,\n exitingConference: false,\n consultDestinationType: null,\n consultDestinationAgentJoined: false,\n ...deriveTaskDataUpdates(context, getTaskDataFromEvent(event)),\n };\n }),\n\n /**\n * Update task data from ASSIGN event\n */\n updateTaskData: assign(({context, event}: TaskActionArgs) => {\n return deriveTaskDataUpdates(context, getTaskDataFromEvent(event));\n }),\n\n /**\n * Set consult initiator flag\n *\n * IMPORTANT: This action is called for CONSULT (user action) and CONSULT_CREATED (backend event).\n * For CONSULT (user action): The user explicitly clicked Consult, so they ARE the initiator.\n * For CONSULT_CREATED (backend event): Check taskData.isConsulted to determine if this agent\n * is the initiator. If isConsulted === true, this is Agent B (the consulted party), NOT the initiator.\n *\n * This prevents all agents in a conference from becoming consultInitiator when one agent\n * starts a new consult.\n */\n setConsultInitiator: assign(({event}: TaskActionArgs) => {\n const taskData = getTaskDataFromEvent(event);\n\n if (event.type === TaskEvent.CONSULT) return {consultInitiator: true};\n\n const selfAgentId = taskData?.agentId;\n const consultInitiator = determineConsultInitiator(taskData, selfAgentId);\n if (consultInitiator === true) return {consultInitiator: true};\n if (consultInitiator === false) return {consultInitiator: false};\n\n return {};\n }),\n\n handleConsultFailed: assign({consultDestinationAgentJoined: false, consultInitiator: false}),\n handleConferenceStarted: assign({consultInitiator: false}),\n\n setConsultDestination: assign(({event}: TaskActionArgs) => {\n if (!event || event.type !== TaskEvent.CONSULT) {\n return {};\n }\n\n const taskData = getTaskDataFromEvent(event);\n const consultDestinationType =\n 'destinationType' in event ? event.destinationType ?? null : null;\n const consultDestinationAgentId = 'destAgentId' in event ? event.destAgentId ?? null : null;\n\n return {\n consultDestinationType,\n consultDestinationAgentId,\n consultDestinationAgentJoined: false,\n consultFromConference: false,\n taskData: {\n ...taskData,\n destAgentId: consultDestinationAgentId,\n },\n };\n }),\n\n setConsultFromConference: assign({consultFromConference: true}),\n\n forceConsultInitiator: assign({consultInitiator: true}),\n\n setConsultAgentJoined: assign(\n ({context, event}: {context: TaskContext; event: TaskEventPayload}) => {\n if (context.consultDestinationAgentJoined) {\n return {};\n }\n\n if (\n !event ||\n event.type !== TaskEvent.CONSULTING_ACTIVE ||\n !('consultDestinationAgentJoined' in event)\n ) {\n return {};\n }\n\n const eventValue = (event as {consultDestinationAgentJoined: boolean})\n .consultDestinationAgentJoined;\n\n return eventValue ? {consultDestinationAgentJoined: true} : {};\n }\n ),\n\n setRecordingState: assign(({event}: TaskActionArgs) => {\n if (!event || !('type' in event)) {\n return {};\n }\n\n if (event.type === TaskEvent.PAUSE_RECORDING) {\n return {\n recordingControlsAvailable: true,\n recordingInProgress: false,\n };\n }\n if (event.type === TaskEvent.RESUME_RECORDING) {\n return {\n recordingControlsAvailable: true,\n recordingInProgress: true,\n };\n }\n\n return {};\n }),\n\n clearConsultState: assign({\n consultDestinationType: null,\n consultDestinationAgentId: null,\n consultDestinationAgentJoined: false,\n consultInitiator: false,\n exitingConference: false,\n consultCallHeld: false,\n consultFromConference: false,\n transferConferenceRequested: false,\n }),\n\n setTransferConferenceRequested: assign({transferConferenceRequested: true}),\n clearTransferConferenceRequested: assign({transferConferenceRequested: false}),\n\n setConsultCallHeld: assign({consultCallHeld: true}),\n clearConsultCallHeld: assign({consultCallHeld: false}),\n handleSwitchToMainCall: assign({consultCallHeld: true}),\n handleSwitchToConsult: assign({consultCallHeld: false}),\n\n handleConferenceFailed: assign(({event}: TaskActionArgs) => {\n const taskData = getTaskDataFromEvent(event);\n\n return taskData ? {taskData} : {};\n }),\n handleParticipantLeft: assign(({event}: TaskActionArgs) => {\n const taskData = getTaskDataFromEvent(event);\n\n return taskData ? {taskData} : {};\n }),\n\n setExitingConference: assign({exitingConference: true}),\n\n handleTransferConferenceSuccess: assign(({event}: TaskActionArgs) => {\n const taskData = getTaskDataFromEvent(event);\n\n return taskData ? {taskData} : {};\n }),\n\n setHoldState: assign(({context, event}: TaskActionArgs) => {\n if (\n !event ||\n (event.type !== TaskEvent.HOLD_SUCCESS && event.type !== TaskEvent.UNHOLD_SUCCESS)\n ) {\n return {};\n }\n\n const mediaResourceId =\n 'mediaResourceId' in event\n ? (event as {mediaResourceId?: string}).mediaResourceId\n : undefined;\n\n if (!mediaResourceId) {\n return {};\n }\n\n const interaction = context.taskData?.interaction;\n const mediaEntry = interaction?.media?.[mediaResourceId];\n\n if (!interaction || !mediaEntry) {\n return {};\n }\n\n const updatedMedia = {\n ...interaction.media,\n [mediaResourceId]: {\n ...mediaEntry,\n isHold: event.type === TaskEvent.HOLD_SUCCESS,\n },\n };\n\n const updates: Partial<TaskContext> = {\n taskData: {\n ...(context.taskData as TaskData),\n interaction: {\n ...interaction,\n media: updatedMedia,\n },\n },\n };\n\n const consultMediaId = context.taskData?.consultMediaResourceId;\n const isConsultMedia = consultMediaId\n ? mediaResourceId === consultMediaId\n : mediaEntry?.mType === 'consult';\n\n if (isConsultMedia && context.consultInitiator) {\n updates.consultCallHeld = event.type === TaskEvent.HOLD_SUCCESS;\n }\n\n return updates;\n }),\n\n markEnded: assign(() => ({\n recordingControlsAvailable: false,\n recordingInProgress: false,\n })),\n\n requestAutoAnswer: () => undefined,\n requestCleanup: () => undefined,\n cleanupResources: () => undefined,\n\n // Event emitters - placeholders overridden by consumers\n emitTaskIncoming: () => undefined,\n emitTaskHydrate: () => undefined,\n emitTaskOfferContact: () => undefined,\n emitTaskAssigned: () => undefined,\n emitTaskHold: () => undefined,\n emitTaskResume: () => undefined,\n emitTaskEnd: () => undefined,\n emitTaskOfferConsult: () => undefined,\n emitTaskConsultCreated: () => undefined,\n emitTaskConsulting: () => undefined,\n emitTaskConsultAccepted: () => undefined,\n emitTaskConsultEnd: () => undefined,\n emitTaskReject: () => undefined,\n emitTaskWrapup: () => undefined,\n emitTaskRecordingStarted: () => undefined,\n emitTaskRecordingPaused: () => undefined,\n emitTaskRecordingResumed: () => undefined,\n emitTaskWrappedup: () => undefined,\n emitTaskParticipantLeft: () => undefined,\n emitTaskConferenceStarted: () => undefined,\n emitTaskConferenceEnded: () => undefined,\n emitTaskExitConference: () => undefined,\n emitTaskTransferConference: () => undefined,\n emitTaskSwitchCall: () => undefined,\n emitTaskConferenceFailed: () => undefined,\n emitTaskTransferConferenceFailed: () => undefined,\n emitTaskOutdialFailed: () => undefined,\n};\n"],"mappings":"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","ignoreList":[]}
@@ -83,7 +83,14 @@ const guards = exports.guards = {
83
83
  event
84
84
  }) => {
85
85
  const taskData = getTaskDataFromEvent(event);
86
- return taskData?.interaction?.state === 'consulting';
86
+ if (taskData?.interaction?.state === 'consulting') return true;
87
+
88
+ // EP_DN consulted agent: backend reports state as 'connected' but CPD indicates consult
89
+ const cpd = taskData?.interaction?.callProcessingDetails;
90
+ if (cpd?.relationshipType === 'consult' && taskData?.interaction?.state === 'connected') {
91
+ return true;
92
+ }
93
+ return false;
87
94
  },
88
95
  isInteractionHeld: ({
89
96
  event
@@ -1 +1 @@
1
- {"version":3,"names":["_TaskUtils","require","_constants","getTaskDataFromEvent","event","taskData","undefined","exports","getSelfAgentId","context","uiControlConfig","agentId","isSelfConsultingAgent","selfAgentId","consultingAgentId","shouldWrapUpForThisAgent","pending","agentsPendingWrapUp","Array","isArray","length","includes","participantWrapUp","interaction","participants","isWrapUp","wrapUpRequired","owner","isConsulted","guards","isInteractionTerminated","isTerminated","isInteractionConsulting","state","isInteractionHeld","mainMediaId","mainInteractionId","interactionId","media","isHold","isInteractionConnected","isConferencingByParticipants","mainCallId","agentCount","pId","p","pType","hasLeft","conferenceInProgressFromEvent","getIsConferenceInProgress","shouldDowngradeConferenceToConnected","eventTaskData","agentParticipantsCount","getConferenceParticipantsCount","customerInCall","getIsCustomerInCall","selfInMainCall","Boolean","didInitiateConsult","consultInitiator","isConsultingAssignment","relationshipType","callProcessingDetails","shouldWrapUp","type","TaskEvent","CONFERENCE_END","shouldWrapUpOrIsInitiator","didCurrentAgentLeaveConference","participantIdFromEvent","participantId","isPrimaryMediaOnHold","mediaId","mediaResourceId"],"sources":["guards.ts"],"sourcesContent":["/**\n * Task State Machine Guards\n *\n * Guard functions that determine if a state transition is allowed.\n * These functions validate the current context before allowing transitions.\n *\n * All guards are consolidated here for:\n * - Single source of truth\n * - Easy testing\n * - Reusability across state machine transitions\n *\n * Guards are organized by category:\n * 1. Helper Functions - Extract data from events/context\n * 2. Hydrate Guards - For state restoration on page refresh\n * 3. Conference Guards - Conference state checks\n * 4. Customer Guards - Customer presence checks\n * 5. Consult Guards - Consult flow checks\n * 6. Wrapup Guards - End-of-call flow checks\n * 7. Server State Guards - Check backend-reported state\n * 8. Recording Guards - Recording state checks\n */\n\nimport {TaskContext, TaskEventPayload} from './types';\nimport {TaskData} from '../types';\nimport {\n getIsCustomerInCall,\n getConferenceParticipantsCount,\n getIsConferenceInProgress,\n} from '../TaskUtils';\nimport {TaskEvent} from './constants';\n\nexport const getTaskDataFromEvent = (event?: TaskEventPayload): TaskData | undefined =>\n event && typeof event === 'object' && 'taskData' in event\n ? (event as {taskData?: TaskData}).taskData\n : undefined;\n\nexport const getSelfAgentId = (context: TaskContext, taskData?: TaskData): string | undefined =>\n context.uiControlConfig?.agentId ?? context.taskData?.agentId ?? taskData?.agentId;\n\nexport const isSelfConsultingAgent = (context: TaskContext, taskData?: TaskData): boolean => {\n const selfAgentId = getSelfAgentId(context, taskData);\n if (!selfAgentId) return false;\n\n return taskData?.consultingAgentId === selfAgentId;\n};\n\n/**\n * Determines if this agent should enter WRAPPING_UP state.\n * Priority: agentsPendingWrapUp > wrapUpRequired / participant.isWrapUp > ownership > !isConsulted\n */\nexport const shouldWrapUpForThisAgent = (context: TaskContext, taskData: TaskData): boolean => {\n const selfAgentId = getSelfAgentId(context, taskData);\n if (!selfAgentId) return false;\n\n const pending = taskData?.agentsPendingWrapUp;\n if (Array.isArray(pending) && pending.length > 0) {\n return pending.includes(selfAgentId);\n }\n\n const participantWrapUp = taskData?.interaction?.participants?.[selfAgentId]?.isWrapUp === true;\n const wrapUpRequired = taskData?.wrapUpRequired === true;\n if (wrapUpRequired || participantWrapUp) {\n return true;\n }\n\n const owner = taskData?.interaction?.owner;\n if (owner && owner === selfAgentId) {\n return true;\n }\n\n if (taskData?.isConsulted === false) {\n return true;\n }\n\n return false;\n};\n\nexport interface GuardParams {\n context: TaskContext;\n event?: TaskEventPayload;\n}\n\nexport type GuardFunction = (params: GuardParams) => boolean;\n\nexport const guards = {\n // Hydrate Guards\n isInteractionTerminated: ({context, event}: GuardParams): boolean => {\n const taskData = getTaskDataFromEvent(event);\n\n if (taskData?.interaction?.isTerminated === true) return true;\n\n const selfAgentId = getSelfAgentId(context, taskData);\n if (selfAgentId && taskData?.interaction?.participants?.[selfAgentId]?.isWrapUp === true) {\n return true;\n }\n\n return false;\n },\n\n isInteractionConsulting: ({event}: GuardParams): boolean => {\n const taskData = getTaskDataFromEvent(event);\n\n return taskData?.interaction?.state === 'consulting';\n },\n\n isInteractionHeld: ({event}: GuardParams): boolean => {\n const taskData = getTaskDataFromEvent(event);\n\n if (taskData?.interaction?.state === 'hold') return true;\n\n const mainMediaId = taskData?.interaction?.mainInteractionId || taskData?.interactionId;\n if (mainMediaId && taskData?.interaction?.media?.[mainMediaId]?.isHold === true) {\n return true;\n }\n\n return false;\n },\n\n isInteractionConnected: ({event}: GuardParams): boolean => {\n const taskData = getTaskDataFromEvent(event);\n\n return taskData?.interaction?.state === 'connected';\n },\n\n isConferencingByParticipants: ({event}: GuardParams): boolean => {\n const taskData = getTaskDataFromEvent(event);\n if (!taskData) return false;\n const mainCallId = taskData.interaction?.mainInteractionId || taskData.interactionId;\n const media = taskData.interaction?.media?.[mainCallId];\n const participants = taskData.interaction?.participants;\n if (!media?.participants || !participants) return false;\n let agentCount = 0;\n for (const pId of media.participants) {\n const p = participants[pId];\n if (p && p.pType !== 'Customer' && p.pType !== 'Supervisor' && !p.hasLeft) {\n agentCount += 1;\n }\n }\n\n return agentCount >= 2;\n },\n\n // Conference Guards\n conferenceInProgressFromEvent: ({event}: GuardParams): boolean => {\n const taskData = getTaskDataFromEvent(event);\n if (!taskData?.interaction) return false;\n\n return getIsConferenceInProgress(taskData);\n },\n\n /**\n * Conference downgrade check specifically for transitioning back to CONNECTED.\n *\n * Returns true only when:\n * - conference has downgraded (fewer than 2 active agent participants in main call)\n * - customer is still in the call\n * - current agent is still in the main call\n */\n shouldDowngradeConferenceToConnected: ({context, event}: GuardParams): boolean => {\n const eventTaskData = getTaskDataFromEvent(event);\n const taskData = eventTaskData ?? context.taskData;\n if (!taskData?.interaction) return false;\n\n const selfAgentId = getSelfAgentId(context, taskData);\n if (!selfAgentId) return false;\n\n const mainCallId = taskData.interaction.mainInteractionId || taskData.interactionId;\n if (!mainCallId) return false;\n\n // Don't downgrade while backend still reports conference.\n if (taskData.interaction.state === 'conference') return false;\n\n const agentParticipantsCount = getConferenceParticipantsCount(taskData.interaction, mainCallId);\n if (agentParticipantsCount >= 2) return false;\n\n const customerInCall = getIsCustomerInCall(taskData.interaction, mainCallId);\n if (!customerInCall) return false;\n\n const selfInMainCall = Boolean(\n taskData.interaction.media?.[mainCallId]?.participants?.includes(selfAgentId)\n );\n\n return selfInMainCall;\n },\n\n // Consult Guards\n /**\n * Check if this agent initiated the consult (using event data)\n * Handles both consultingAgentId and fallback to context flag\n */\n didInitiateConsult: ({context, event}: GuardParams): boolean => {\n const taskData = getTaskDataFromEvent(event);\n if (taskData?.isConsulted === true) return false;\n\n return taskData?.consultingAgentId\n ? isSelfConsultingAgent(context, taskData)\n : context.consultInitiator === true;\n },\n\n /**\n * EP-DN / consulted consult legs can arrive as AGENT_CONTACT_ASSIGNED without a preceding\n * AgentConsulting event. When that happens, we should enter CONSULTING (not CONNECTED).\n */\n isConsultingAssignment: ({event}: GuardParams): boolean => {\n const taskData = getTaskDataFromEvent(event);\n if (!taskData) return false;\n\n const relationshipType = taskData.interaction?.callProcessingDetails?.relationshipType;\n\n return (\n taskData.isConsulted === true ||\n relationshipType === 'consult' ||\n taskData.interaction?.state === 'consulting'\n );\n },\n\n // Wrapup Guards\n shouldWrapUp: ({context, event}: GuardParams): boolean => {\n const taskData = getTaskDataFromEvent(event);\n if (!taskData) return false;\n\n if (event?.type === TaskEvent.CONFERENCE_END) {\n const selfAgentId = getSelfAgentId(context, taskData);\n if (!selfAgentId) return false;\n\n const pending = taskData?.agentsPendingWrapUp;\n if (Array.isArray(pending) && pending.length > 0) {\n return pending.includes(selfAgentId);\n }\n\n const participantWrapUp =\n taskData?.interaction?.participants?.[selfAgentId]?.isWrapUp === true;\n const wrapUpRequired = taskData?.wrapUpRequired === true;\n\n return wrapUpRequired || participantWrapUp;\n }\n\n return shouldWrapUpForThisAgent(context, taskData);\n },\n\n /**\n * Check if wrapUpRequired in payload OR is consult initiator\n */\n shouldWrapUpOrIsInitiator: ({context, event}: GuardParams): boolean => {\n const taskData = getTaskDataFromEvent(event);\n\n return Boolean(taskData?.wrapUpRequired || context.consultInitiator);\n },\n\n /**\n * True if PARTICIPANT_LEAVE indicates that *this* agent left the conference.\n *\n * Important: PARTICIPANT_LEAVE is broadcast to all agents in the conference.\n * Only the agent whose id matches the leaving participant should transition to\n * TERMINATED / WRAPPING_UP based on wrapup rules.\n */\n didCurrentAgentLeaveConference: ({context, event}: GuardParams): boolean => {\n const taskData = getTaskDataFromEvent(event);\n const selfAgentId = getSelfAgentId(context, taskData);\n if (!selfAgentId) return false;\n\n const participantIdFromEvent =\n event && typeof event === 'object' && 'participantId' in event\n ? (event as {participantId?: string}).participantId\n : undefined;\n const participantId = participantIdFromEvent ?? taskData?.participantId;\n\n if (Boolean(participantId) && participantId === selfAgentId) {\n return true;\n }\n\n // For EP-DN agents the backend removes the leaving participant entirely\n // from the participants map (rather than setting hasLeft). If this task\n // is in CONFERENCING (implied by the guard being evaluated here) but the\n // agent is absent from the updated participants, they have left.\n const participants = taskData?.interaction?.participants;\n if (participants && !(selfAgentId in participants)) {\n return true;\n }\n\n return false;\n },\n\n // Server State Guards\n isPrimaryMediaOnHold: ({event}: GuardParams): boolean => {\n const taskData = getTaskDataFromEvent(event);\n if (!taskData) return false;\n const mediaId = taskData.mediaResourceId;\n if (!mediaId) return false;\n\n return taskData.interaction?.media?.[mediaId]?.isHold === true;\n },\n};\n\nexport type GuardName = keyof typeof guards;\n"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"names":["_TaskUtils","require","_constants","getTaskDataFromEvent","event","taskData","undefined","exports","getSelfAgentId","context","uiControlConfig","agentId","isSelfConsultingAgent","selfAgentId","consultingAgentId","shouldWrapUpForThisAgent","pending","agentsPendingWrapUp","Array","isArray","length","includes","participantWrapUp","interaction","participants","isWrapUp","wrapUpRequired","owner","isConsulted","guards","isInteractionTerminated","isTerminated","isInteractionConsulting","state","cpd","callProcessingDetails","relationshipType","isInteractionHeld","mainMediaId","mainInteractionId","interactionId","media","isHold","isInteractionConnected","isConferencingByParticipants","mainCallId","agentCount","pId","p","pType","hasLeft","conferenceInProgressFromEvent","getIsConferenceInProgress","shouldDowngradeConferenceToConnected","eventTaskData","agentParticipantsCount","getConferenceParticipantsCount","customerInCall","getIsCustomerInCall","selfInMainCall","Boolean","didInitiateConsult","consultInitiator","isConsultingAssignment","shouldWrapUp","type","TaskEvent","CONFERENCE_END","shouldWrapUpOrIsInitiator","didCurrentAgentLeaveConference","participantIdFromEvent","participantId","isPrimaryMediaOnHold","mediaId","mediaResourceId"],"sources":["guards.ts"],"sourcesContent":["/**\n * Task State Machine Guards\n *\n * Guard functions that determine if a state transition is allowed.\n * These functions validate the current context before allowing transitions.\n *\n * All guards are consolidated here for:\n * - Single source of truth\n * - Easy testing\n * - Reusability across state machine transitions\n *\n * Guards are organized by category:\n * 1. Helper Functions - Extract data from events/context\n * 2. Hydrate Guards - For state restoration on page refresh\n * 3. Conference Guards - Conference state checks\n * 4. Customer Guards - Customer presence checks\n * 5. Consult Guards - Consult flow checks\n * 6. Wrapup Guards - End-of-call flow checks\n * 7. Server State Guards - Check backend-reported state\n * 8. Recording Guards - Recording state checks\n */\n\nimport {TaskContext, TaskEventPayload} from './types';\nimport {TaskData} from '../types';\nimport {\n getIsCustomerInCall,\n getConferenceParticipantsCount,\n getIsConferenceInProgress,\n} from '../TaskUtils';\nimport {TaskEvent} from './constants';\n\nexport const getTaskDataFromEvent = (event?: TaskEventPayload): TaskData | undefined =>\n event && typeof event === 'object' && 'taskData' in event\n ? (event as {taskData?: TaskData}).taskData\n : undefined;\n\nexport const getSelfAgentId = (context: TaskContext, taskData?: TaskData): string | undefined =>\n context.uiControlConfig?.agentId ?? context.taskData?.agentId ?? taskData?.agentId;\n\nexport const isSelfConsultingAgent = (context: TaskContext, taskData?: TaskData): boolean => {\n const selfAgentId = getSelfAgentId(context, taskData);\n if (!selfAgentId) return false;\n\n return taskData?.consultingAgentId === selfAgentId;\n};\n\n/**\n * Determines if this agent should enter WRAPPING_UP state.\n * Priority: agentsPendingWrapUp > wrapUpRequired / participant.isWrapUp > ownership > !isConsulted\n */\nexport const shouldWrapUpForThisAgent = (context: TaskContext, taskData: TaskData): boolean => {\n const selfAgentId = getSelfAgentId(context, taskData);\n if (!selfAgentId) return false;\n\n const pending = taskData?.agentsPendingWrapUp;\n if (Array.isArray(pending) && pending.length > 0) {\n return pending.includes(selfAgentId);\n }\n\n const participantWrapUp = taskData?.interaction?.participants?.[selfAgentId]?.isWrapUp === true;\n const wrapUpRequired = taskData?.wrapUpRequired === true;\n if (wrapUpRequired || participantWrapUp) {\n return true;\n }\n\n const owner = taskData?.interaction?.owner;\n if (owner && owner === selfAgentId) {\n return true;\n }\n\n if (taskData?.isConsulted === false) {\n return true;\n }\n\n return false;\n};\n\nexport interface GuardParams {\n context: TaskContext;\n event?: TaskEventPayload;\n}\n\nexport type GuardFunction = (params: GuardParams) => boolean;\n\nexport const guards = {\n // Hydrate Guards\n isInteractionTerminated: ({context, event}: GuardParams): boolean => {\n const taskData = getTaskDataFromEvent(event);\n\n if (taskData?.interaction?.isTerminated === true) return true;\n\n const selfAgentId = getSelfAgentId(context, taskData);\n if (selfAgentId && taskData?.interaction?.participants?.[selfAgentId]?.isWrapUp === true) {\n return true;\n }\n\n return false;\n },\n\n isInteractionConsulting: ({event}: GuardParams): boolean => {\n const taskData = getTaskDataFromEvent(event);\n\n if (taskData?.interaction?.state === 'consulting') return true;\n\n // EP_DN consulted agent: backend reports state as 'connected' but CPD indicates consult\n const cpd = taskData?.interaction?.callProcessingDetails;\n if (cpd?.relationshipType === 'consult' && taskData?.interaction?.state === 'connected') {\n return true;\n }\n\n return false;\n },\n\n isInteractionHeld: ({event}: GuardParams): boolean => {\n const taskData = getTaskDataFromEvent(event);\n\n if (taskData?.interaction?.state === 'hold') return true;\n\n const mainMediaId = taskData?.interaction?.mainInteractionId || taskData?.interactionId;\n if (mainMediaId && taskData?.interaction?.media?.[mainMediaId]?.isHold === true) {\n return true;\n }\n\n return false;\n },\n\n isInteractionConnected: ({event}: GuardParams): boolean => {\n const taskData = getTaskDataFromEvent(event);\n\n return taskData?.interaction?.state === 'connected';\n },\n\n isConferencingByParticipants: ({event}: GuardParams): boolean => {\n const taskData = getTaskDataFromEvent(event);\n if (!taskData) return false;\n const mainCallId = taskData.interaction?.mainInteractionId || taskData.interactionId;\n const media = taskData.interaction?.media?.[mainCallId];\n const participants = taskData.interaction?.participants;\n if (!media?.participants || !participants) return false;\n let agentCount = 0;\n for (const pId of media.participants) {\n const p = participants[pId];\n if (p && p.pType !== 'Customer' && p.pType !== 'Supervisor' && !p.hasLeft) {\n agentCount += 1;\n }\n }\n\n return agentCount >= 2;\n },\n\n // Conference Guards\n conferenceInProgressFromEvent: ({event}: GuardParams): boolean => {\n const taskData = getTaskDataFromEvent(event);\n if (!taskData?.interaction) return false;\n\n return getIsConferenceInProgress(taskData);\n },\n\n /**\n * Conference downgrade check specifically for transitioning back to CONNECTED.\n *\n * Returns true only when:\n * - conference has downgraded (fewer than 2 active agent participants in main call)\n * - customer is still in the call\n * - current agent is still in the main call\n */\n shouldDowngradeConferenceToConnected: ({context, event}: GuardParams): boolean => {\n const eventTaskData = getTaskDataFromEvent(event);\n const taskData = eventTaskData ?? context.taskData;\n if (!taskData?.interaction) return false;\n\n const selfAgentId = getSelfAgentId(context, taskData);\n if (!selfAgentId) return false;\n\n const mainCallId = taskData.interaction.mainInteractionId || taskData.interactionId;\n if (!mainCallId) return false;\n\n // Don't downgrade while backend still reports conference.\n if (taskData.interaction.state === 'conference') return false;\n\n const agentParticipantsCount = getConferenceParticipantsCount(taskData.interaction, mainCallId);\n if (agentParticipantsCount >= 2) return false;\n\n const customerInCall = getIsCustomerInCall(taskData.interaction, mainCallId);\n if (!customerInCall) return false;\n\n const selfInMainCall = Boolean(\n taskData.interaction.media?.[mainCallId]?.participants?.includes(selfAgentId)\n );\n\n return selfInMainCall;\n },\n\n // Consult Guards\n /**\n * Check if this agent initiated the consult (using event data)\n * Handles both consultingAgentId and fallback to context flag\n */\n didInitiateConsult: ({context, event}: GuardParams): boolean => {\n const taskData = getTaskDataFromEvent(event);\n if (taskData?.isConsulted === true) return false;\n\n return taskData?.consultingAgentId\n ? isSelfConsultingAgent(context, taskData)\n : context.consultInitiator === true;\n },\n\n /**\n * EP-DN / consulted consult legs can arrive as AGENT_CONTACT_ASSIGNED without a preceding\n * AgentConsulting event. When that happens, we should enter CONSULTING (not CONNECTED).\n */\n isConsultingAssignment: ({event}: GuardParams): boolean => {\n const taskData = getTaskDataFromEvent(event);\n if (!taskData) return false;\n\n const relationshipType = taskData.interaction?.callProcessingDetails?.relationshipType;\n\n return (\n taskData.isConsulted === true ||\n relationshipType === 'consult' ||\n taskData.interaction?.state === 'consulting'\n );\n },\n\n // Wrapup Guards\n shouldWrapUp: ({context, event}: GuardParams): boolean => {\n const taskData = getTaskDataFromEvent(event);\n if (!taskData) return false;\n\n if (event?.type === TaskEvent.CONFERENCE_END) {\n const selfAgentId = getSelfAgentId(context, taskData);\n if (!selfAgentId) return false;\n\n const pending = taskData?.agentsPendingWrapUp;\n if (Array.isArray(pending) && pending.length > 0) {\n return pending.includes(selfAgentId);\n }\n\n const participantWrapUp =\n taskData?.interaction?.participants?.[selfAgentId]?.isWrapUp === true;\n const wrapUpRequired = taskData?.wrapUpRequired === true;\n\n return wrapUpRequired || participantWrapUp;\n }\n\n return shouldWrapUpForThisAgent(context, taskData);\n },\n\n /**\n * Check if wrapUpRequired in payload OR is consult initiator\n */\n shouldWrapUpOrIsInitiator: ({context, event}: GuardParams): boolean => {\n const taskData = getTaskDataFromEvent(event);\n\n return Boolean(taskData?.wrapUpRequired || context.consultInitiator);\n },\n\n /**\n * True if PARTICIPANT_LEAVE indicates that *this* agent left the conference.\n *\n * Important: PARTICIPANT_LEAVE is broadcast to all agents in the conference.\n * Only the agent whose id matches the leaving participant should transition to\n * TERMINATED / WRAPPING_UP based on wrapup rules.\n */\n didCurrentAgentLeaveConference: ({context, event}: GuardParams): boolean => {\n const taskData = getTaskDataFromEvent(event);\n const selfAgentId = getSelfAgentId(context, taskData);\n if (!selfAgentId) return false;\n\n const participantIdFromEvent =\n event && typeof event === 'object' && 'participantId' in event\n ? (event as {participantId?: string}).participantId\n : undefined;\n const participantId = participantIdFromEvent ?? taskData?.participantId;\n\n if (Boolean(participantId) && participantId === selfAgentId) {\n return true;\n }\n\n // For EP-DN agents the backend removes the leaving participant entirely\n // from the participants map (rather than setting hasLeft). If this task\n // is in CONFERENCING (implied by the guard being evaluated here) but the\n // agent is absent from the updated participants, they have left.\n const participants = taskData?.interaction?.participants;\n if (participants && !(selfAgentId in participants)) {\n return true;\n }\n\n return false;\n },\n\n // Server State Guards\n isPrimaryMediaOnHold: ({event}: GuardParams): boolean => {\n const taskData = getTaskDataFromEvent(event);\n if (!taskData) return false;\n const mediaId = taskData.mediaResourceId;\n if (!mediaId) return false;\n\n return taskData.interaction?.media?.[mediaId]?.isHold === true;\n },\n};\n\nexport type GuardName = keyof typeof guards;\n"],"mappings":"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","ignoreList":[]}
@@ -84,12 +84,18 @@ function computeVoiceInteractionUIControls(state, context, config, fallbackTaskD
84
84
  const {
85
85
  consultInitiator,
86
86
  consultDestinationAgentJoined,
87
+ consultDestinationType,
87
88
  consultCallHeld,
88
89
  consultFromConference
89
90
  } = context;
90
91
  const {
91
92
  recordingControlsAvailable
92
93
  } = context;
94
+
95
+ // EP_DN consults are "ready" as soon as the consult is created (EP accepts routing immediately).
96
+ // Backend sends destinationType as 'EP-DN'; SDK method uses 'entryPoint' — check both.
97
+ const isEpDnConsult = consultDestinationType === 'entryPoint' || consultDestinationType === 'EP-DN';
98
+ const isConsultDestinationReady = consultDestinationAgentJoined || isEpDnConsult;
93
99
  const stateImpliesHeld = state === _constants.TaskState.HELD || state === _constants.TaskState.RESUME_INITIATING;
94
100
  const stateImpliesConnected = state === _constants.TaskState.CONNECTED || state === _constants.TaskState.HOLD_INITIATING;
95
101
  const isHeld = stateImpliesHeld || serverHold === true;
@@ -156,7 +162,9 @@ function computeVoiceInteractionUIControls(state, context, config, fallbackTaskD
156
162
  // End: varies by state; during consulting only on main leg (consult held)
157
163
  end: (() => {
158
164
  if (!config.isEndTaskEnabled) return DISABLED;
159
- if (hasParallelConsultLeg) return VISIBLE_DISABLED;
165
+ if (hasParallelConsultLeg) {
166
+ return isConnected && isEpDnConsult ? VISIBLE_ENABLED : VISIBLE_DISABLED;
167
+ }
160
168
  if (isConsulting) {
161
169
  if (currentLeg === 'consult' && consultCallHeld) return DISABLED;
162
170
  return consultInitiator && consultCallHeld ? VISIBLE_ENABLED : DISABLED;
@@ -179,7 +187,7 @@ function computeVoiceInteractionUIControls(state, context, config, fallbackTaskD
179
187
  if (isConsulting) {
180
188
  if (!consultInitiator) return DISABLED;
181
189
  if (consultLegOnHold) return VISIBLE_DISABLED;
182
- return consultDestinationAgentJoined ? VISIBLE_ENABLED : VISIBLE_DISABLED;
190
+ return isConsultDestinationReady ? VISIBLE_ENABLED : VISIBLE_DISABLED;
183
191
  }
184
192
  if (!hasFullControls || inConference) return DISABLED;
185
193
  if (state === _constants.TaskState.CONNECTED || state === _constants.TaskState.HELD) return VISIBLE_ENABLED;
@@ -238,7 +246,7 @@ function computeVoiceInteractionUIControls(state, context, config, fallbackTaskD
238
246
  if (!hasFullControls || !isConsulting) return DISABLED;
239
247
  if (!consultInitiator) return DISABLED;
240
248
  if (consultLegOnHold) return VISIBLE_DISABLED;
241
- return consultDestinationAgentJoined && !maxParticipants ? VISIBLE_ENABLED : VISIBLE_DISABLED;
249
+ return isConsultDestinationReady && !maxParticipants ? VISIBLE_ENABLED : VISIBLE_DISABLED;
242
250
  })(),
243
251
  // Wrapup: wrapping up state
244
252
  wrapup: isWrappingUp ? VISIBLE_ENABLED : DISABLED,
@@ -254,22 +262,22 @@ function computeVoiceInteractionUIControls(state, context, config, fallbackTaskD
254
262
  if (hasParallelConsultLeg || consultLegOnHold) return DISABLED;
255
263
  if (!inConference || !isConsulting) return DISABLED;
256
264
  if (!consultInitiator || isConsulted) return DISABLED;
257
- return consultDestinationAgentJoined ? VISIBLE_ENABLED : VISIBLE_DISABLED;
265
+ return isConsultDestinationReady ? VISIBLE_ENABLED : VISIBLE_DISABLED;
258
266
  })(),
259
267
  // MergeToConference: mirrors conference control, enabled on both legs
260
268
  mergeToConference: (() => {
261
269
  if (!isConsulting || !consultInitiator) return DISABLED;
262
270
  if (consultLegOnHold) return VISIBLE_DISABLED;
263
- return consultDestinationAgentJoined && !maxParticipants ? VISIBLE_ENABLED : VISIBLE_DISABLED;
271
+ return isConsultDestinationReady && !maxParticipants ? VISIBLE_ENABLED : VISIBLE_DISABLED;
264
272
  })(),
265
273
  // Switch: visible only on the currently active leg
266
274
  switch: (() => {
267
275
  if (currentLeg === 'consult') {
268
276
  if (!isConsulting || !consultInitiator || consultCallHeld) return DISABLED;
269
- return consultDestinationAgentJoined ? VISIBLE_ENABLED : VISIBLE_DISABLED;
277
+ return isConsultDestinationReady ? VISIBLE_ENABLED : VISIBLE_DISABLED;
270
278
  }
271
279
  if (hasParallelConsultLeg && state === _constants.TaskState.CONNECTED) {
272
- return consultDestinationAgentJoined ? VISIBLE_ENABLED : VISIBLE_DISABLED;
280
+ return isConsultDestinationReady ? VISIBLE_ENABLED : VISIBLE_DISABLED;
273
281
  }
274
282
  return DISABLED;
275
283
  })()