@webex/contact-center 3.12.0-next.115 → 3.12.0-next.117

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.
@@ -1 +1 @@
1
- {"version":3,"names":["_TaskUtils","require","_constants","getTaskDataFromEvent","event","taskData","undefined","exports","getSelfAgentId","context","uiControlConfig","agentId","isSelfConsultingAgent","selfAgentId","consultingAgentId","hasActiveConsultInPostCall","interaction","state","INTERACTION_STATE","POST_CALL","selfParticipant","participants","hasConsultMedia","Object","values","media","some","mType","MEDIA_TYPE_CONSULT","consultState","CONSULT_STATE","CONSULTING","shouldWrapUpForThisAgent","pending","agentsPendingWrapUp","Array","isArray","length","includes","participantWrapUp","isWrapUp","wrapUpRequired","owner","isConsulted","guards","isInteractionTerminated","isTerminated","isInteractionConsulting","selfActiveConsult","selfPendingConsultInitiated","cpd","callProcessingDetails","relationshipType","CONNECTED","postCallSelfAgentId","postCallSelfParticipant","hasPostCallConsultMedia","isEpDnPendingConferenceMergeHydrate","isEpDnConsultPendingConferenceMerge","isInteractionHeld","mainMediaId","mainInteractionId","interactionId","isHold","isInteractionConnected","isConferencingByParticipants","mainCallId","agentCount","pId","p","pType","hasLeft","conferenceInProgressFromEvent","getIsConferenceInProgress","isConferenceHoldParticipantFromEvent","conferenceHoldParticipant","shouldDowngradeConferenceToConnected","eventTaskData","CONFERENCE","agentParticipantsCount","getConferenceParticipantsCount","customerInCall","getIsCustomerInCall","selfInMainCall","Boolean","didInitiateConsult","consultInitiator","isConsultingAssignment","isCampaignPreviewContactEnded","type","TaskEvent","CONTACT_ENDED","isCampaignPreviewTask","isPendingWrapUp","participantIsWrapUp","explicitWrapUp","shouldWrapUp","CONFERENCE_END","shouldWrapUpOrIsInitiator","didCurrentAgentLeaveMainInteraction","participantIdFromEvent","participantId","currentParticipant","PARTICIPANT_LEAVE","previousParticipants","updatedParticipants","wasPreviouslyActive","previousMainMedia","filter","updatedMainMedia","wasPreviouslyInMainCall","remainsInMainCall","remainsActiveInParticipantMap","remainsOnConsultLeg","CONSULT_END","consultFromConference","isSelfConferenceTransferInitiator","transferConferenceRequested","isPassiveConferenceTransferObserver","isCampaignReservationAccept","TASK_INCOMING","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 isCampaignPreviewTask,\n isEpDnConsultPendingConferenceMerge,\n} from '../TaskUtils';\nimport {TaskEvent, INTERACTION_STATE, CONSULT_STATE, MEDIA_TYPE_CONSULT} from './constants';\n\nexport const getTaskDataFromEvent = (event?: TaskEventPayload): TaskData | undefined =>\n event && typeof event === 'object' && 'taskData' in event\n ? (event as {taskData?: TaskData}).taskData\n : undefined;\n\nexport const getSelfAgentId = (context: TaskContext, taskData?: TaskData): string | undefined =>\n context.uiControlConfig?.agentId ?? context.taskData?.agentId ?? taskData?.agentId;\n\nexport const isSelfConsultingAgent = (context: TaskContext, taskData?: TaskData): boolean => {\n const selfAgentId = getSelfAgentId(context, taskData);\n if (!selfAgentId) return false;\n\n return taskData?.consultingAgentId === selfAgentId;\n};\n\n/**\n * Detects an active consult during post_call state (customer left but agents still consulting).\n * Shared by hydration guard (isInteractionConsulting) and action (deriveTaskDataUpdates).\n */\nexport const hasActiveConsultInPostCall = (\n taskData: TaskData | undefined,\n selfAgentId?: string\n): boolean => {\n if (taskData?.interaction?.state !== INTERACTION_STATE.POST_CALL || !selfAgentId) return false;\n\n const selfParticipant = taskData.interaction?.participants?.[selfAgentId];\n const hasConsultMedia = Object.values(taskData.interaction?.media ?? {}).some(\n (media) => (media as {mType?: string})?.mType === MEDIA_TYPE_CONSULT\n );\n\n return selfParticipant?.consultState === CONSULT_STATE.CONSULTING && hasConsultMedia;\n};\n\n/**\n * Determines if this agent should enter WRAPPING_UP state.\n * Priority: agentsPendingWrapUp > wrapUpRequired / participant.isWrapUp > ownership > !isConsulted\n */\nexport const shouldWrapUpForThisAgent = (context: TaskContext, taskData: TaskData): boolean => {\n const selfAgentId = getSelfAgentId(context, taskData);\n if (!selfAgentId) return false;\n\n const pending = taskData?.agentsPendingWrapUp;\n if (Array.isArray(pending) && pending.length > 0) {\n return pending.includes(selfAgentId);\n }\n\n const participantWrapUp = taskData?.interaction?.participants?.[selfAgentId]?.isWrapUp === true;\n const wrapUpRequired = taskData?.wrapUpRequired === true;\n if (wrapUpRequired || participantWrapUp) {\n return true;\n }\n\n const owner = taskData?.interaction?.owner;\n if (owner && owner === selfAgentId) {\n return true;\n }\n\n if (taskData?.isConsulted === false) {\n return true;\n }\n\n return false;\n};\n\nexport interface GuardParams {\n context: TaskContext;\n event?: TaskEventPayload;\n}\n\nexport type GuardFunction = (params: GuardParams) => boolean;\n\nexport const guards = {\n // Hydrate Guards\n isInteractionTerminated: ({context, event}: GuardParams): boolean => {\n const taskData = getTaskDataFromEvent(event);\n\n if (taskData?.interaction?.isTerminated === true) return true;\n\n const selfAgentId = getSelfAgentId(context, taskData);\n if (selfAgentId && taskData?.interaction?.participants?.[selfAgentId]?.isWrapUp === true) {\n return true;\n }\n\n return false;\n },\n\n isInteractionConsulting: ({event, context}: GuardParams): boolean => {\n const taskData = getTaskDataFromEvent(event);\n\n if (taskData?.interaction?.state === INTERACTION_STATE.CONSULTING) return true;\n\n // Hydrate can report interaction as conference/hold while this agent is actively consulting.\n // Detect consult by participant consultState + consult media, independent of top-level state.\n const selfAgentId = getSelfAgentId(context, taskData);\n const selfParticipant = selfAgentId ? taskData?.interaction?.participants?.[selfAgentId] : null;\n const hasConsultMedia = Object.values(taskData?.interaction?.media ?? {}).some(\n (media: any) => media?.mType === MEDIA_TYPE_CONSULT\n );\n const selfActiveConsult = selfParticipant?.consultState === CONSULT_STATE.CONSULTING;\n const selfPendingConsultInitiated =\n selfParticipant?.consultState === 'consultInitiated' && taskData?.isConsulted === false;\n if ((selfActiveConsult || selfPendingConsultInitiated) && hasConsultMedia) {\n return true;\n }\n\n // EP_DN consulted agent: backend reports state as 'connected' but CPD indicates consult\n const cpd = taskData?.interaction?.callProcessingDetails;\n if (\n cpd?.relationshipType === 'consult' &&\n taskData?.interaction?.state === INTERACTION_STATE.CONNECTED\n ) {\n return true;\n }\n\n // Customer left during consult: interaction state is \"post_call\" but consult\n // between agents is still active. Detect via agent's consultState + consult media.\n if (hasActiveConsultInPostCall(taskData, getSelfAgentId(context, taskData))) {\n return true;\n }\n\n // Customer left during consult: interaction state is \"post_call\" but consult\n // between agents is still active. Detect via agent's consultState + consult media.\n if (taskData?.interaction?.state === INTERACTION_STATE.POST_CALL) {\n const postCallSelfAgentId = getSelfAgentId(context, taskData);\n const postCallSelfParticipant = postCallSelfAgentId\n ? taskData?.interaction?.participants?.[postCallSelfAgentId]\n : null;\n const hasPostCallConsultMedia = Object.values(taskData?.interaction?.media ?? {}).some(\n (media: any) => media?.mType === MEDIA_TYPE_CONSULT\n );\n if (\n postCallSelfParticipant?.consultState === CONSULT_STATE.CONSULTING &&\n hasPostCallConsultMedia\n ) {\n return true;\n }\n }\n\n return false;\n },\n\n isEpDnPendingConferenceMergeHydrate: ({event, context}: GuardParams): boolean => {\n const taskData = getTaskDataFromEvent(event);\n\n return isEpDnConsultPendingConferenceMerge(taskData, getSelfAgentId(context, taskData));\n },\n\n isInteractionHeld: ({event}: GuardParams): boolean => {\n const taskData = getTaskDataFromEvent(event);\n\n if (taskData?.interaction?.state === 'hold') return true;\n\n const mainMediaId = taskData?.interaction?.mainInteractionId || taskData?.interactionId;\n if (mainMediaId && taskData?.interaction?.media?.[mainMediaId]?.isHold === true) {\n return true;\n }\n\n return false;\n },\n\n isInteractionConnected: ({event}: GuardParams): boolean => {\n const taskData = getTaskDataFromEvent(event);\n\n return taskData?.interaction?.state === INTERACTION_STATE.CONNECTED;\n },\n\n isConferencingByParticipants: ({event}: GuardParams): boolean => {\n const taskData = getTaskDataFromEvent(event);\n if (!taskData) return false;\n const mainCallId = taskData.interaction?.mainInteractionId || taskData.interactionId;\n const media = taskData.interaction?.media?.[mainCallId];\n const participants = taskData.interaction?.participants;\n if (!media?.participants || !participants) return false;\n let agentCount = 0;\n for (const pId of media.participants) {\n const p = participants[pId];\n if (p && p.pType !== 'Customer' && p.pType !== 'Supervisor' && !p.hasLeft) {\n agentCount += 1;\n }\n }\n\n return agentCount >= 2;\n },\n\n // Conference Guards\n conferenceInProgressFromEvent: ({event}: GuardParams): boolean => {\n const taskData = getTaskDataFromEvent(event);\n if (!taskData?.interaction) return false;\n\n return getIsConferenceInProgress(taskData);\n },\n\n /**\n * Conference hold signal for conference-downgraded consult-end transitions.\n * Backend can report this as boolean or string.\n */\n isConferenceHoldParticipantFromEvent: ({context, event}: GuardParams): boolean => {\n const taskData = getTaskDataFromEvent(event) ?? context.taskData;\n const callProcessingDetails = taskData?.interaction?.callProcessingDetails as\n | {conferenceHoldParticipant?: boolean | string}\n | undefined;\n const conferenceHoldParticipant = callProcessingDetails?.conferenceHoldParticipant;\n\n return conferenceHoldParticipant === true || conferenceHoldParticipant === 'true';\n },\n\n /**\n * Conference downgrade check specifically for transitioning back to CONNECTED.\n *\n * Returns true only when:\n * - conference has downgraded (fewer than 2 active agent participants in main call)\n * - customer is still in the call\n * - current agent is still in the main call\n */\n shouldDowngradeConferenceToConnected: ({context, event}: GuardParams): boolean => {\n const eventTaskData = getTaskDataFromEvent(event);\n const taskData = eventTaskData ?? context.taskData;\n if (!taskData?.interaction) return false;\n\n const selfAgentId = getSelfAgentId(context, taskData);\n if (!selfAgentId) return false;\n\n const mainCallId = taskData.interaction.mainInteractionId || taskData.interactionId;\n if (!mainCallId) return false;\n\n // Don't downgrade while backend still reports conference.\n if (taskData.interaction.state === INTERACTION_STATE.CONFERENCE) return false;\n\n const agentParticipantsCount = getConferenceParticipantsCount(taskData.interaction, mainCallId);\n if (agentParticipantsCount >= 2) return false;\n\n const customerInCall = getIsCustomerInCall(taskData.interaction, mainCallId);\n if (!customerInCall) return false;\n\n const selfInMainCall = Boolean(\n taskData.interaction.media?.[mainCallId]?.participants?.includes(selfAgentId)\n );\n\n return selfInMainCall;\n },\n\n // Consult Guards\n /**\n * Check if this agent initiated the consult (using event data)\n * Handles both consultingAgentId and fallback to context flag\n */\n didInitiateConsult: ({context, event}: GuardParams): boolean => {\n const taskData = getTaskDataFromEvent(event);\n if (taskData?.isConsulted === true) return false;\n\n return taskData?.consultingAgentId\n ? isSelfConsultingAgent(context, taskData)\n : context.consultInitiator === true;\n },\n\n /**\n * EP-DN / consulted consult legs can arrive as AGENT_CONTACT_ASSIGNED without a preceding\n * AgentConsulting event. When that happens, we should enter CONSULTING (not CONNECTED).\n */\n isConsultingAssignment: ({event}: GuardParams): boolean => {\n const taskData = getTaskDataFromEvent(event);\n if (!taskData) return false;\n\n const relationshipType = taskData.interaction?.callProcessingDetails?.relationshipType;\n\n return (\n taskData.isConsulted === true ||\n relationshipType === 'consult' ||\n taskData.interaction?.state === INTERACTION_STATE.CONSULTING\n );\n },\n\n // Wrapup Guards\n isCampaignPreviewContactEnded: ({context, event}: GuardParams): boolean => {\n if (event?.type !== TaskEvent.CONTACT_ENDED) {\n return false;\n }\n\n const taskData = getTaskDataFromEvent(event);\n if (!isCampaignPreviewTask(taskData)) {\n return false;\n }\n\n const selfAgentId = getSelfAgentId(context, taskData);\n const pending = taskData?.agentsPendingWrapUp;\n const isPendingWrapUp =\n Array.isArray(pending) && !!selfAgentId && pending.includes(selfAgentId);\n const participantIsWrapUp =\n !!selfAgentId && taskData?.interaction?.participants?.[selfAgentId]?.isWrapUp === true;\n const explicitWrapUp =\n taskData?.wrapUpRequired === true ||\n participantIsWrapUp ||\n isPendingWrapUp ||\n taskData?.interaction?.state === 'wrapUp';\n\n return !explicitWrapUp;\n },\n\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 when an updated lifecycle event shows that this agent left the main interaction.\n *\n * Explicit self-participant evidence is authoritative. Main-call membership is used only\n * for the from-conference nested-consult race where CONSULT_END still represents the agent as\n * active on the consult leg after removing them from the main leg. Partial or ordinary call\n * snapshots are not treated as a departure.\n */\n didCurrentAgentLeaveMainInteraction: ({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 // Routing represents self-departure either by naming the participant or by retaining the\n // participant entry with hasLeft set. Agent Desktop treats both representations as terminal.\n const currentParticipant = taskData?.interaction?.participants?.[selfAgentId];\n if (currentParticipant?.hasLeft === true) {\n return true;\n }\n\n // A participant-left event that explicitly identifies somebody else must not use a\n // potentially partial participant or media roster to infer that self also departed.\n if (\n event?.type === TaskEvent.PARTICIPANT_LEAVE &&\n Boolean(participantId) &&\n participantId !== selfAgentId\n ) {\n return false;\n }\n\n const previousParticipants = context.taskData?.interaction?.participants;\n const updatedParticipants = taskData?.interaction?.participants;\n const wasPreviouslyActive = Boolean(\n previousParticipants?.[selfAgentId] && previousParticipants[selfAgentId].hasLeft !== true\n );\n // Some EP-DN lifecycle payloads remove the participant entry instead of setting hasLeft.\n // Requiring a previously active entry prevents an incomplete initial snapshot from ending a task.\n if (updatedParticipants && wasPreviouslyActive && !(selfAgentId in updatedParticipants)) {\n return true;\n }\n\n const previousMainMedia = Object.values(context.taskData?.interaction?.media ?? {}).filter(\n (media) => media?.mType === 'mainCall'\n );\n const updatedMainMedia = Object.values(taskData?.interaction?.media ?? {}).filter(\n (media) => media?.mType === 'mainCall'\n );\n const wasPreviouslyInMainCall = previousMainMedia.some((media) =>\n media.participants?.includes(selfAgentId)\n );\n const remainsInMainCall = updatedMainMedia.some((media) =>\n media.participants?.includes(selfAgentId)\n );\n // A hasLeft participant returned above, so presence here means the updated map keeps self active.\n const remainsActiveInParticipantMap = Boolean(currentParticipant);\n const remainsOnConsultLeg = Object.values(taskData?.interaction?.media ?? {}).some(\n (media) => media?.mType === MEDIA_TYPE_CONSULT && media.participants?.includes(selfAgentId)\n );\n\n // Agent Desktop uses mainCall membership for AgentConsultEnded cleanup. Restrict that fallback\n // to a consult that originated from conference and require corroborating active-map and\n // consult-leg membership so ordinary partial CONNECTED/HELD payloads cannot terminate a task.\n if (\n event?.type === TaskEvent.CONSULT_END &&\n context.consultFromConference === true &&\n updatedMainMedia.length > 0 &&\n wasPreviouslyInMainCall &&\n !remainsInMainCall &&\n remainsActiveInParticipantMap &&\n remainsOnConsultLeg\n ) {\n return true;\n }\n\n return false;\n },\n\n /**\n * True when this agent initiated the conference transfer (widgets or desktop).\n * Mirrors determineConsultInitiator: consultingAgentId === self only (not consultState).\n */\n isSelfConferenceTransferInitiator: ({context, event}: GuardParams): boolean => {\n if (context.transferConferenceRequested === true) return true;\n\n const taskData = getTaskDataFromEvent(event);\n const selfAgentId = getSelfAgentId(context, taskData);\n if (!selfAgentId || !taskData) return false;\n\n return taskData.consultingAgentId === selfAgentId;\n },\n\n /**\n * True when another agent performed conference transfer and this agent should\n * only refresh task data (stay in the current state). False when this agent\n * initiated the transfer (desktop or widgets) or has left the interaction.\n */\n isPassiveConferenceTransferObserver: ({context, event}: GuardParams): boolean => {\n if (guards.isSelfConferenceTransferInitiator({context, event})) return false;\n\n const taskData = getTaskDataFromEvent(event);\n const selfAgentId = getSelfAgentId(context, taskData);\n if (selfAgentId && taskData?.interaction?.participants) {\n if (!(selfAgentId in taskData.interaction.participants)) return false;\n if (taskData.interaction.participants[selfAgentId]?.hasLeft === true) return false;\n }\n\n return true;\n },\n\n isCampaignReservationAccept: ({event}: GuardParams): boolean => {\n return event?.type === TaskEvent.TASK_INCOMING && event.isCampaignReservationAccept === true;\n },\n\n // Server State Guards\n isPrimaryMediaOnHold: ({event}: GuardParams): boolean => {\n const taskData = getTaskDataFromEvent(event);\n if (!taskData) return false;\n const mediaId = taskData.mediaResourceId;\n if (!mediaId) return false;\n\n return taskData.interaction?.media?.[mediaId]?.isHold === true;\n },\n};\n\nexport type GuardName = keyof typeof guards;\n"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"names":["_TaskUtils","require","_constants","getTaskDataFromEvent","event","taskData","undefined","exports","getSelfAgentId","context","uiControlConfig","agentId","isSelfConsultingAgent","selfAgentId","consultingAgentId","hasActiveConsultInPostCall","interaction","state","INTERACTION_STATE","POST_CALL","selfParticipant","participants","hasConsultMedia","Object","values","media","some","mType","MEDIA_TYPE_CONSULT","consultState","CONSULT_STATE","CONSULTING","shouldWrapUpForThisAgent","pending","agentsPendingWrapUp","Array","isArray","length","includes","participantWrapUp","isWrapUp","wrapUpRequired","owner","isConsulted","guards","isInteractionTerminated","isTerminated","isInteractionConsulting","selfActiveConsult","selfPendingConsultInitiated","cpd","callProcessingDetails","relationshipType","CONNECTED","postCallSelfAgentId","postCallSelfParticipant","hasPostCallConsultMedia","isEpDnPendingConferenceMergeHydrate","isEpDnConsultPendingConferenceMerge","isInteractionHeld","mainMediaId","mainInteractionId","interactionId","isHold","isInteractionConnected","isConferencingByParticipants","mainCallId","agentCount","pId","p","pType","hasLeft","conferenceInProgressFromEvent","getIsConferenceInProgress","isConferenceHoldParticipantFromEvent","conferenceHoldParticipant","shouldDowngradeConferenceToConnected","eventTaskData","CONFERENCE","agentParticipantsCount","getConferenceParticipantsCount","customerInCall","getIsCustomerInCall","selfInMainCall","Boolean","didInitiateConsult","consultInitiator","isConsultingAssignment","isCampaignPreviewContactEnded","type","TaskEvent","CONTACT_ENDED","isCampaignPreviewTask","isPendingWrapUp","participantIsWrapUp","explicitWrapUp","shouldWrapUp","CONFERENCE_END","shouldWrapUpOrIsInitiator","didCurrentAgentLeaveMainInteraction","participantIdFromEvent","participantId","isSelfConferenceTransferInitiator","transferConferenceRequested","isPassiveConferenceTransferObserver","isCampaignReservationAccept","TASK_INCOMING","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 isCampaignPreviewTask,\n isEpDnConsultPendingConferenceMerge,\n} from '../TaskUtils';\nimport {TaskEvent, INTERACTION_STATE, CONSULT_STATE, MEDIA_TYPE_CONSULT} from './constants';\n\nexport const getTaskDataFromEvent = (event?: TaskEventPayload): TaskData | undefined =>\n event && typeof event === 'object' && 'taskData' in event\n ? (event as {taskData?: TaskData}).taskData\n : undefined;\n\nexport const getSelfAgentId = (context: TaskContext, taskData?: TaskData): string | undefined =>\n context.uiControlConfig?.agentId ?? context.taskData?.agentId ?? taskData?.agentId;\n\nexport const isSelfConsultingAgent = (context: TaskContext, taskData?: TaskData): boolean => {\n const selfAgentId = getSelfAgentId(context, taskData);\n if (!selfAgentId) return false;\n\n return taskData?.consultingAgentId === selfAgentId;\n};\n\n/**\n * Detects an active consult during post_call state (customer left but agents still consulting).\n * Shared by hydration guard (isInteractionConsulting) and action (deriveTaskDataUpdates).\n */\nexport const hasActiveConsultInPostCall = (\n taskData: TaskData | undefined,\n selfAgentId?: string\n): boolean => {\n if (taskData?.interaction?.state !== INTERACTION_STATE.POST_CALL || !selfAgentId) return false;\n\n const selfParticipant = taskData.interaction?.participants?.[selfAgentId];\n const hasConsultMedia = Object.values(taskData.interaction?.media ?? {}).some(\n (media) => (media as {mType?: string})?.mType === MEDIA_TYPE_CONSULT\n );\n\n return selfParticipant?.consultState === CONSULT_STATE.CONSULTING && hasConsultMedia;\n};\n\n/**\n * Determines if this agent should enter WRAPPING_UP state.\n * Priority: agentsPendingWrapUp > wrapUpRequired / participant.isWrapUp > ownership > !isConsulted\n */\nexport const shouldWrapUpForThisAgent = (context: TaskContext, taskData: TaskData): boolean => {\n const selfAgentId = getSelfAgentId(context, taskData);\n if (!selfAgentId) return false;\n\n const pending = taskData?.agentsPendingWrapUp;\n if (Array.isArray(pending) && pending.length > 0) {\n return pending.includes(selfAgentId);\n }\n\n const participantWrapUp = taskData?.interaction?.participants?.[selfAgentId]?.isWrapUp === true;\n const wrapUpRequired = taskData?.wrapUpRequired === true;\n if (wrapUpRequired || participantWrapUp) {\n return true;\n }\n\n const owner = taskData?.interaction?.owner;\n if (owner && owner === selfAgentId) {\n return true;\n }\n\n if (taskData?.isConsulted === false) {\n return true;\n }\n\n return false;\n};\n\nexport interface GuardParams {\n context: TaskContext;\n event?: TaskEventPayload;\n}\n\nexport type GuardFunction = (params: GuardParams) => boolean;\n\nexport const guards = {\n // Hydrate Guards\n isInteractionTerminated: ({context, event}: GuardParams): boolean => {\n const taskData = getTaskDataFromEvent(event);\n\n if (taskData?.interaction?.isTerminated === true) return true;\n\n const selfAgentId = getSelfAgentId(context, taskData);\n if (selfAgentId && taskData?.interaction?.participants?.[selfAgentId]?.isWrapUp === true) {\n return true;\n }\n\n return false;\n },\n\n isInteractionConsulting: ({event, context}: GuardParams): boolean => {\n const taskData = getTaskDataFromEvent(event);\n\n if (taskData?.interaction?.state === INTERACTION_STATE.CONSULTING) return true;\n\n // Hydrate can report interaction as conference/hold while this agent is actively consulting.\n // Detect consult by participant consultState + consult media, independent of top-level state.\n const selfAgentId = getSelfAgentId(context, taskData);\n const selfParticipant = selfAgentId ? taskData?.interaction?.participants?.[selfAgentId] : null;\n const hasConsultMedia = Object.values(taskData?.interaction?.media ?? {}).some(\n (media: any) => media?.mType === MEDIA_TYPE_CONSULT\n );\n const selfActiveConsult = selfParticipant?.consultState === CONSULT_STATE.CONSULTING;\n const selfPendingConsultInitiated =\n selfParticipant?.consultState === 'consultInitiated' && taskData?.isConsulted === false;\n if ((selfActiveConsult || selfPendingConsultInitiated) && hasConsultMedia) {\n return true;\n }\n\n // EP_DN consulted agent: backend reports state as 'connected' but CPD indicates consult\n const cpd = taskData?.interaction?.callProcessingDetails;\n if (\n cpd?.relationshipType === 'consult' &&\n taskData?.interaction?.state === INTERACTION_STATE.CONNECTED\n ) {\n return true;\n }\n\n // Customer left during consult: interaction state is \"post_call\" but consult\n // between agents is still active. Detect via agent's consultState + consult media.\n if (hasActiveConsultInPostCall(taskData, getSelfAgentId(context, taskData))) {\n return true;\n }\n\n // Customer left during consult: interaction state is \"post_call\" but consult\n // between agents is still active. Detect via agent's consultState + consult media.\n if (taskData?.interaction?.state === INTERACTION_STATE.POST_CALL) {\n const postCallSelfAgentId = getSelfAgentId(context, taskData);\n const postCallSelfParticipant = postCallSelfAgentId\n ? taskData?.interaction?.participants?.[postCallSelfAgentId]\n : null;\n const hasPostCallConsultMedia = Object.values(taskData?.interaction?.media ?? {}).some(\n (media: any) => media?.mType === MEDIA_TYPE_CONSULT\n );\n if (\n postCallSelfParticipant?.consultState === CONSULT_STATE.CONSULTING &&\n hasPostCallConsultMedia\n ) {\n return true;\n }\n }\n\n return false;\n },\n\n isEpDnPendingConferenceMergeHydrate: ({event, context}: GuardParams): boolean => {\n const taskData = getTaskDataFromEvent(event);\n\n return isEpDnConsultPendingConferenceMerge(taskData, getSelfAgentId(context, taskData));\n },\n\n isInteractionHeld: ({event}: GuardParams): boolean => {\n const taskData = getTaskDataFromEvent(event);\n\n if (taskData?.interaction?.state === 'hold') return true;\n\n const mainMediaId = taskData?.interaction?.mainInteractionId || taskData?.interactionId;\n if (mainMediaId && taskData?.interaction?.media?.[mainMediaId]?.isHold === true) {\n return true;\n }\n\n return false;\n },\n\n isInteractionConnected: ({event}: GuardParams): boolean => {\n const taskData = getTaskDataFromEvent(event);\n\n return taskData?.interaction?.state === INTERACTION_STATE.CONNECTED;\n },\n\n isConferencingByParticipants: ({event}: GuardParams): boolean => {\n const taskData = getTaskDataFromEvent(event);\n if (!taskData) return false;\n const mainCallId = taskData.interaction?.mainInteractionId || taskData.interactionId;\n const media = taskData.interaction?.media?.[mainCallId];\n const participants = taskData.interaction?.participants;\n if (!media?.participants || !participants) return false;\n let agentCount = 0;\n for (const pId of media.participants) {\n const p = participants[pId];\n if (p && p.pType !== 'Customer' && p.pType !== 'Supervisor' && !p.hasLeft) {\n agentCount += 1;\n }\n }\n\n return agentCount >= 2;\n },\n\n // Conference Guards\n conferenceInProgressFromEvent: ({event}: GuardParams): boolean => {\n const taskData = getTaskDataFromEvent(event);\n if (!taskData?.interaction) return false;\n\n return getIsConferenceInProgress(taskData);\n },\n\n /**\n * Conference hold signal for conference-downgraded consult-end transitions.\n * Backend can report this as boolean or string.\n */\n isConferenceHoldParticipantFromEvent: ({context, event}: GuardParams): boolean => {\n const taskData = getTaskDataFromEvent(event) ?? context.taskData;\n const callProcessingDetails = taskData?.interaction?.callProcessingDetails as\n | {conferenceHoldParticipant?: boolean | string}\n | undefined;\n const conferenceHoldParticipant = callProcessingDetails?.conferenceHoldParticipant;\n\n return conferenceHoldParticipant === true || conferenceHoldParticipant === 'true';\n },\n\n /**\n * Conference downgrade check specifically for transitioning back to CONNECTED.\n *\n * Returns true only when:\n * - conference has downgraded (fewer than 2 active agent participants in main call)\n * - customer is still in the call\n * - current agent is still in the main call\n */\n shouldDowngradeConferenceToConnected: ({context, event}: GuardParams): boolean => {\n const eventTaskData = getTaskDataFromEvent(event);\n const taskData = eventTaskData ?? context.taskData;\n if (!taskData?.interaction) return false;\n\n const selfAgentId = getSelfAgentId(context, taskData);\n if (!selfAgentId) return false;\n\n const mainCallId = taskData.interaction.mainInteractionId || taskData.interactionId;\n if (!mainCallId) return false;\n\n // Don't downgrade while backend still reports conference.\n if (taskData.interaction.state === INTERACTION_STATE.CONFERENCE) return false;\n\n const agentParticipantsCount = getConferenceParticipantsCount(taskData.interaction, mainCallId);\n if (agentParticipantsCount >= 2) return false;\n\n const customerInCall = getIsCustomerInCall(taskData.interaction, mainCallId);\n if (!customerInCall) return false;\n\n const selfInMainCall = Boolean(\n taskData.interaction.media?.[mainCallId]?.participants?.includes(selfAgentId)\n );\n\n return selfInMainCall;\n },\n\n // Consult Guards\n /**\n * Check if this agent initiated the consult (using event data)\n * Handles both consultingAgentId and fallback to context flag\n */\n didInitiateConsult: ({context, event}: GuardParams): boolean => {\n const taskData = getTaskDataFromEvent(event);\n if (taskData?.isConsulted === true) return false;\n\n return taskData?.consultingAgentId\n ? isSelfConsultingAgent(context, taskData)\n : context.consultInitiator === true;\n },\n\n /**\n * EP-DN / consulted consult legs can arrive as AGENT_CONTACT_ASSIGNED without a preceding\n * AgentConsulting event. When that happens, we should enter CONSULTING (not CONNECTED).\n */\n isConsultingAssignment: ({event}: GuardParams): boolean => {\n const taskData = getTaskDataFromEvent(event);\n if (!taskData) return false;\n\n const relationshipType = taskData.interaction?.callProcessingDetails?.relationshipType;\n\n return (\n taskData.isConsulted === true ||\n relationshipType === 'consult' ||\n taskData.interaction?.state === INTERACTION_STATE.CONSULTING\n );\n },\n\n // Wrapup Guards\n isCampaignPreviewContactEnded: ({context, event}: GuardParams): boolean => {\n if (event?.type !== TaskEvent.CONTACT_ENDED) {\n return false;\n }\n\n const taskData = getTaskDataFromEvent(event);\n if (!isCampaignPreviewTask(taskData)) {\n return false;\n }\n\n const selfAgentId = getSelfAgentId(context, taskData);\n const pending = taskData?.agentsPendingWrapUp;\n const isPendingWrapUp =\n Array.isArray(pending) && !!selfAgentId && pending.includes(selfAgentId);\n const participantIsWrapUp =\n !!selfAgentId && taskData?.interaction?.participants?.[selfAgentId]?.isWrapUp === true;\n const explicitWrapUp =\n taskData?.wrapUpRequired === true ||\n participantIsWrapUp ||\n isPendingWrapUp ||\n taskData?.interaction?.state === 'wrapUp';\n\n return !explicitWrapUp;\n },\n\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 when an updated lifecycle event shows that this agent left the main interaction.\n *\n * Returns true when the event names this agent, or when this agent is absent from the\n * updated participants map. EP-DN payloads remove the leaving participant instead of\n * setting hasLeft. Remaining in the map with hasLeft, or disappearing only from\n * mainCall media, is not treated as departure.\n */\n didCurrentAgentLeaveMainInteraction: ({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 // EP-DN payloads remove the leaving participant from the map instead of setting hasLeft.\n const participants = taskData?.interaction?.participants;\n if (participants && !(selfAgentId in participants)) {\n return true;\n }\n\n return false;\n },\n\n /**\n * True when this agent initiated the conference transfer (widgets or desktop).\n * Mirrors determineConsultInitiator: consultingAgentId === self only (not consultState).\n */\n isSelfConferenceTransferInitiator: ({context, event}: GuardParams): boolean => {\n if (context.transferConferenceRequested === true) return true;\n\n const taskData = getTaskDataFromEvent(event);\n const selfAgentId = getSelfAgentId(context, taskData);\n if (!selfAgentId || !taskData) return false;\n\n return taskData.consultingAgentId === selfAgentId;\n },\n\n /**\n * True when another agent performed conference transfer and this agent should\n * only refresh task data (stay in the current state). False when this agent\n * initiated the transfer (desktop or widgets) or has left the interaction.\n */\n isPassiveConferenceTransferObserver: ({context, event}: GuardParams): boolean => {\n if (guards.isSelfConferenceTransferInitiator({context, event})) return false;\n\n const taskData = getTaskDataFromEvent(event);\n const selfAgentId = getSelfAgentId(context, taskData);\n if (selfAgentId && taskData?.interaction?.participants) {\n if (!(selfAgentId in taskData.interaction.participants)) return false;\n if (taskData.interaction.participants[selfAgentId]?.hasLeft === true) return false;\n }\n\n return true;\n },\n\n isCampaignReservationAccept: ({event}: GuardParams): boolean => {\n return event?.type === TaskEvent.TASK_INCOMING && event.isCampaignReservationAccept === true;\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":[]}
@@ -199,13 +199,6 @@ export declare function getTaskStateMachineConfig(uiControlConfig: UIControlConf
199
199
  }) => boolean;
200
200
  actions: string[];
201
201
  })[];
202
- PARTICIPANT_LEAVE: ({
203
- guard: (params: any) => boolean;
204
- target: TaskState;
205
- actions: string[];
206
- } | {
207
- actions: string[];
208
- })[];
209
202
  CONTACT_ENDED: ({
210
203
  guard: ({ context, event }: import("./guards").GuardParams) => boolean;
211
204
  target: TaskState;
@@ -246,13 +239,6 @@ export declare function getTaskStateMachineConfig(uiControlConfig: UIControlConf
246
239
  target: TaskState;
247
240
  actions: string[];
248
241
  };
249
- PARTICIPANT_LEAVE: ({
250
- guard: (params: any) => boolean;
251
- target: TaskState;
252
- actions: string[];
253
- } | {
254
- actions: string[];
255
- })[];
256
242
  OUTBOUND_FAILED: ({
257
243
  guard: ({ context, event }: import("./guards").GuardParams) => boolean;
258
244
  target: TaskState;
@@ -549,13 +535,6 @@ export declare function getTaskStateMachineConfig(uiControlConfig: UIControlConf
549
535
  target: TaskState;
550
536
  actions: string[];
551
537
  })[];
552
- PARTICIPANT_LEAVE: ({
553
- guard: (params: any) => boolean;
554
- target: TaskState;
555
- actions: string[];
556
- } | {
557
- actions: string[];
558
- })[];
559
538
  OUTBOUND_FAILED: ({
560
539
  guard: ({ context, event }: import("./guards").GuardParams) => boolean;
561
540
  target: TaskState;
@@ -897,13 +876,6 @@ export declare function createTaskStateMachine(uiControlConfig: UIControlConfig,
897
876
  }) => boolean;
898
877
  actions: string[];
899
878
  })[];
900
- PARTICIPANT_LEAVE: ({
901
- guard: (params: any) => boolean;
902
- target: TaskState;
903
- actions: string[];
904
- } | {
905
- actions: string[];
906
- })[];
907
879
  CONTACT_ENDED: ({
908
880
  guard: ({ context, event }: import("./guards").GuardParams) => boolean;
909
881
  target: TaskState;
@@ -944,13 +916,6 @@ export declare function createTaskStateMachine(uiControlConfig: UIControlConfig,
944
916
  target: TaskState;
945
917
  actions: string[];
946
918
  };
947
- PARTICIPANT_LEAVE: ({
948
- guard: (params: any) => boolean;
949
- target: TaskState;
950
- actions: string[];
951
- } | {
952
- actions: string[];
953
- })[];
954
919
  OUTBOUND_FAILED: ({
955
920
  guard: ({ context, event }: import("./guards").GuardParams) => boolean;
956
921
  target: TaskState;
@@ -1247,13 +1212,6 @@ export declare function createTaskStateMachine(uiControlConfig: UIControlConfig,
1247
1212
  target: TaskState;
1248
1213
  actions: string[];
1249
1214
  })[];
1250
- PARTICIPANT_LEAVE: ({
1251
- guard: (params: any) => boolean;
1252
- target: TaskState;
1253
- actions: string[];
1254
- } | {
1255
- actions: string[];
1256
- })[];
1257
1215
  OUTBOUND_FAILED: ({
1258
1216
  guard: ({ context, event }: import("./guards").GuardParams) => boolean;
1259
1217
  target: TaskState;
@@ -80,10 +80,10 @@ export declare const guards: {
80
80
  /**
81
81
  * True when an updated lifecycle event shows that this agent left the main interaction.
82
82
  *
83
- * Explicit self-participant evidence is authoritative. Main-call membership is used only
84
- * for the from-conference nested-consult race where CONSULT_END still represents the agent as
85
- * active on the consult leg after removing them from the main leg. Partial or ordinary call
86
- * snapshots are not treated as a departure.
83
+ * Returns true when the event names this agent, or when this agent is absent from the
84
+ * updated participants map. EP-DN payloads remove the leaving participant instead of
85
+ * setting hasLeft. Remaining in the map with hasLeft, or disappearing only from
86
+ * mainCall media, is not treated as departure.
87
87
  */
88
88
  didCurrentAgentLeaveMainInteraction: ({ context, event }: GuardParams) => boolean;
89
89
  /**
package/dist/webex.js CHANGED
@@ -41,7 +41,7 @@ if (!global.Buffer) {
41
41
  */
42
42
  const Webex = _webexCore.default.extend({
43
43
  webex: true,
44
- version: `3.12.0-next.115`
44
+ version: `3.12.0-next.117`
45
45
  });
46
46
 
47
47
  /**
package/package.json CHANGED
@@ -46,13 +46,13 @@
46
46
  },
47
47
  "dependencies": {
48
48
  "@types/platform": "1.3.4",
49
- "@webex/calling": "3.12.0-next.94",
50
- "@webex/internal-plugin-mercury": "3.12.0-next.48",
51
- "@webex/internal-plugin-metrics": "3.12.0-next.44",
52
- "@webex/internal-plugin-support": "3.12.0-next.51",
53
- "@webex/plugin-authorization": "3.12.0-next.44",
54
- "@webex/plugin-logger": "3.12.0-next.44",
55
- "@webex/webex-core": "3.12.0-next.44",
49
+ "@webex/calling": "3.12.0-next.95",
50
+ "@webex/internal-plugin-mercury": "3.12.0-next.49",
51
+ "@webex/internal-plugin-metrics": "3.12.0-next.45",
52
+ "@webex/internal-plugin-support": "3.12.0-next.52",
53
+ "@webex/plugin-authorization": "3.12.0-next.45",
54
+ "@webex/plugin-logger": "3.12.0-next.45",
55
+ "@webex/webex-core": "3.12.0-next.45",
56
56
  "jest-html-reporters": "3.0.11",
57
57
  "lodash": "^4.17.21",
58
58
  "uuid": "^3.3.2",
@@ -84,5 +84,5 @@
84
84
  "typedoc": "^0.25.0",
85
85
  "typescript": "5.4.5"
86
86
  },
87
- "version": "3.12.0-next.115"
87
+ "version": "3.12.0-next.117"
88
88
  }
@@ -902,22 +902,21 @@ event so consumers can rebind to the surviving task object.
902
902
 
903
903
  Dropping an Agent while that Agent is consulting continues through the existing
904
904
  `PARTICIPANT_LEAVE` transition, which clears consult state and emits the normal
905
- participant-left and task-end lifecycle. This self-departure check applies in
906
- every active call-control state and uses an explicit self participant ID,
907
- `hasLeft`, or removal of a previously active Agent from the participant map. A
908
- participant-left event naming somebody else never infers self-departure from a
909
- partial media roster. A consulted Agent receiving
910
- `AgentConsultEnded` continues through `CONSULT_END`; current-agent departure is
911
- evaluated before consult-initiator recovery. For the from-conference nested-consult
912
- ordering race only, the guard also compares `mainCall` membership (located by
913
- `mType`) when the Agent remains active in the participant map and is still present
914
- on the consult leg. Missing, contradictory, or ordinary CONNECTED/HELD media snapshots
915
- are non-terminal. Accepted consultees emit
916
- `task:consultEnd` and `task:end`, while an unaccepted OFFERED consultee retains
917
- the existing consult-end-only signal. A surviving consult initiator still
918
- returns to the main-call state selected by the existing guards. Starting a
919
- consult preserves the prior task snapshot so this membership comparison remains
920
- available while the consult is initiating.
905
+ participant-left and task-end lifecycle. `PARTICIPANT_LEAVE` is handled in
906
+ `HELD`, `RESUME_INITIATING`, `CONSULTING`, `CONSULT_INITIATING`, and
907
+ `CONFERENCING`; `CONNECTED`, `HOLD_INITIATING`, and `CONF_INITIATING` ignore the
908
+ event. The current Agent is treated as departed only when the event names that
909
+ Agent or the updated participants map omits that Agent (EP-DN removal). Remaining
910
+ in the map with `hasLeft`, or disappearing only from `mainCall` media, is
911
+ non-terminal. A consulted Agent receiving `AgentConsultEnded` continues through
912
+ `CONSULT_END`; current-agent departure is evaluated before consult-initiator
913
+ recovery and does not use mainCall membership as self-departure evidence.
914
+ Accepted consultees emit `task:consultEnd` and `task:end`, while an unaccepted
915
+ OFFERED consultee retains the existing consult-end-only signal. A surviving
916
+ consult initiator still returns to the main-call state selected by the existing
917
+ guards. The state-machine transition table lives in
918
+ `src/services/task/state-machine/ai-docs/task-state-machine-spec.md`
919
+ `TASK_STATE_MACHINE-R-008`.
921
920
 
922
921
  Primary-Agent promotion remains backend-authoritative and follows the two-event
923
922
  desktop contract. `ContactOwnerChanged` updates the promoted Agent; TaskManager
@@ -416,14 +416,6 @@ export function getTaskStateMachineConfig(uiControlConfig: UIControlConfig) {
416
416
  actions: ['updateTaskData', 'clearConsultState', 'emitTaskConsultEnd'],
417
417
  },
418
418
  ],
419
- // Routing lifecycle events can arrive out of order in child-task/EP-DN flows. The
420
- // local actor may still be CONNECTED when ParticipantLeftConference reports that this
421
- // agent left the main interaction. Handle that self-departure race; for another
422
- // participant, the action-only fallback updates data while preserving CONNECTED.
423
- [TaskEvent.PARTICIPANT_LEAVE]: [
424
- ...currentAgentParticipantLeaveTransitions(),
425
- {actions: ['updateTaskData', 'handleParticipantLeft', 'emitTaskParticipantLeft']},
426
- ],
427
419
  // AgentContactEnded Event
428
420
  [TaskEvent.CONTACT_ENDED]: [
429
421
  {
@@ -486,13 +478,6 @@ export function getTaskStateMachineConfig(uiControlConfig: UIControlConfig) {
486
478
  target: TaskState.CONNECTED,
487
479
  actions: ['updateTaskData'],
488
480
  },
489
- // Another agent can remove this agent while the local hold request is awaiting its
490
- // routing acknowledgement. Process that backend lifecycle event independently of
491
- // whether Drop was initiated from this task; another-participant event preserves state.
492
- [TaskEvent.PARTICIPANT_LEAVE]: [
493
- ...currentAgentParticipantLeaveTransitions(),
494
- {actions: ['updateTaskData', 'handleParticipantLeft', 'emitTaskParticipantLeft']},
495
- ],
496
481
  [TaskEvent.OUTBOUND_FAILED]: [
497
482
  {
498
483
  guard: guards.shouldWrapUp,
@@ -626,7 +611,6 @@ export function getTaskStateMachineConfig(uiControlConfig: UIControlConfig) {
626
611
  [TaskEvent.UNHOLD_FAILED]: {
627
612
  target: TaskState.HELD,
628
613
  },
629
- // The same remote-removal race can occur while an unhold request is in flight.
630
614
  [TaskEvent.PARTICIPANT_LEAVE]: [
631
615
  ...currentAgentParticipantLeaveTransitions(),
632
616
  {actions: ['updateTaskData', 'handleParticipantLeft', 'emitTaskParticipantLeft']},
@@ -1020,10 +1004,6 @@ export function getTaskStateMachineConfig(uiControlConfig: UIControlConfig) {
1020
1004
  actions: ['updateTaskData', 'clearConsultState'],
1021
1005
  },
1022
1006
  ],
1023
- [TaskEvent.PARTICIPANT_LEAVE]: [
1024
- ...currentAgentParticipantLeaveTransitions(),
1025
- {actions: ['updateTaskData', 'handleParticipantLeft', 'emitTaskParticipantLeft']},
1026
- ],
1027
1007
  [TaskEvent.OUTBOUND_FAILED]: [
1028
1008
  {
1029
1009
  guard: guards.shouldWrapUp,
@@ -274,10 +274,8 @@ didCurrentAgentLeaveMainInteraction(context, event) {
274
274
  const participantIdFromEvent = 'participantId' in event ? event.participantId : undefined;
275
275
  const participantId = participantIdFromEvent ?? event.taskData?.participantId;
276
276
  if (Boolean(participantId) && participantId === selfAgentId) return true;
277
- // Explicit hasLeft or removal of a previously active self from the participant map is terminal.
278
- // PARTICIPANT_LEAVE naming another participant does not infer self departure from media.
279
- // Only a from-conference CONSULT_END may compare mainCall membership, and only when self
280
- // remains active in the participant map and on the consult leg. Partial ordinary calls are false.
277
+ // Self missing from the updated participants map is terminal (EP-DN removal).
278
+ // Remaining in the map with hasLeft, or disappearing only from mainCall media, is not.
281
279
  }
282
280
  ```
283
281
 
@@ -476,13 +476,12 @@ It is instantiated by `Task` and receives mapped backend/user events through `se
476
476
  - Guard: default
477
477
  - Actions: `updateTaskData`, `handleParticipantLeft`, `emitTaskParticipantLeft`
478
478
 
479
- `didCurrentAgentLeaveMainInteraction` treats an explicit self participant ID,
480
- self `hasLeft`, or removal from a previously active participant map as terminal.
481
- A `PARTICIPANT_LEAVE` event naming another participant does not infer departure
482
- from media membership. The previous-versus-updated `mainCall` comparison is
483
- restricted to from-conference `CONSULT_END` nested-consult cleanup when self
484
- remains active in the participant map and on the consult leg; partial ordinary CONNECTED/HELD
485
- snapshots remain non-terminal.
479
+ `didCurrentAgentLeaveMainInteraction` treats an explicit self participant ID
480
+ or absence from the updated participants map as terminal (EP-DN removal).
481
+ Remaining in the map with `hasLeft`, or disappearing only from `mainCall` media,
482
+ is not treated as departure. `PARTICIPANT_LEAVE` is handled in `HELD`,
483
+ `RESUME_INITIATING`, `CONSULTING`, `CONSULT_INITIATING`, and `CONFERENCING`;
484
+ `CONNECTED`, `HOLD_INITIATING`, and `CONF_INITIATING` ignore the event.
486
485
 
487
486
  - `CONFERENCE_END` -> `WRAPPING_UP`
488
487
  - Guard: `guards.shouldWrapUp`
@@ -758,7 +757,7 @@ Complete mapping from backend CC_EVENTS to internal TaskEvent types.
758
757
  | `PARTICIPANT_JOINED_CONFERENCE` | `CONFERENCE_START` | `CONSULTING` / `CONF_INITIATING` / `CONFERENCING` | `CONFERENCING` / same | Conference participant joined |
759
758
  | `AGENT_CONSULT_CONFERENCE_FAILED` | `CONFERENCE_FAILED` | `CONF_INITIATING` | `CONSULTING` | Merge fail fallback |
760
759
  | `AGENT_CONSULT_CONFERENCE_ENDED` | `CONFERENCE_END` | `CONFERENCING` | `WRAPPING_UP` / `CONNECTED` / `TERMINATED` | Guard-driven |
761
- | `PARTICIPANT_LEFT_CONFERENCE` | `PARTICIPANT_LEAVE` | `CONFERENCING` | `WRAPPING_UP` / `TERMINATED` / `CONNECTED` / same | Ownership + downgrade guards |
760
+ | `PARTICIPANT_LEFT_CONFERENCE` | `PARTICIPANT_LEAVE` | `HELD` / `RESUME_INITIATING` / `CONSULTING` / `CONSULT_INITIATING` / `CONFERENCING` | `WRAPPING_UP` / `TERMINATED` / `CONNECTED` / same | Named self or omitted from participant map; `CONNECTED` / `HOLD_INITIATING` / `CONF_INITIATING` ignore |
762
761
  | `AGENT_CONFERENCE_TRANSFERRED` | `TRANSFER_CONFERENCE_SUCCESS` | `CONSULTING` / `CONFERENCING` | `WRAPPING_UP` / `CONFERENCING` / `TERMINATED` / same | Initiator/receiver dependent |
763
762
 
764
763
  ### Explicitly not mapped to state machine
@@ -818,7 +817,7 @@ Complete mapping from backend CC_EVENTS to internal TaskEvent types.
818
817
  | API `task.consultConference()` | `MERGE_TO_CONFERENCE` | CONSULTING → CONF_INITIATING | Starts merge flow |
819
818
  | `AgentConsultConferenced` | `CONFERENCE_START` | CONSULTING/CONF_INITIATING → CONFERENCING | `handleConferenceStarted` path |
820
819
  | `ParticipantJoinedConference` | `CONFERENCE_START` | CONFERENCING → CONFERENCING | Refresh + emit conference started |
821
- | `ParticipantLeftConference` | `PARTICIPANT_LEAVE` | Any active call-control state → WRAPPING_UP / TERMINATED / CONNECTED / stay | Uses `didCurrentAgentLeaveMainInteraction`, `shouldWrapUp`, `shouldDowngradeConferenceToConnected` |
820
+ | `ParticipantLeftConference` | `PARTICIPANT_LEAVE` | HELD / RESUME_INITIATING / CONSULTING / CONSULT_INITIATING / CONFERENCING → WRAPPING_UP / TERMINATED / CONNECTED / stay; CONNECTED / HOLD_INITIATING / CONF_INITIATING ignore | Uses `didCurrentAgentLeaveMainInteraction` (named self or omitted from participant map), `shouldWrapUp`, `shouldDowngradeConferenceToConnected` |
822
821
  | `AgentConsultConferenceEnded` | `CONFERENCE_END` | CONFERENCING → WRAPPING_UP / CONNECTED / TERMINATED | Guard-based branch |
823
822
  | `AgentConsultConferenceFailed` | `CONFERENCE_FAILED` | CONF_INITIATING → CONSULTING | Merge failed fallback |
824
823
  | `AgentConferenceTransferred` | `TRANSFER_CONFERENCE_SUCCESS` | CONSULTING/CONFERENCING branch logic | Initiator/receiver dependent |
@@ -78,7 +78,7 @@ See root `CONTRACTS.md` for the package-level state-control export.
78
78
  | TASK_STATE_MACHINE-R-005 | Keep authentication and credentials outside the state-machine layer; it receives typed Task data/events and never invokes authenticated transport. | Pure transition logic remains reusable and cannot leak or mutate host authentication state. | `src/services/task/state-machine/TaskStateMachine.ts`, `src/services/task/state-machine/types.ts` | `test/unit/spec/services/task/state-machine/TaskStateMachine.ts` | None; security/auth applicability is explicitly N/A. | PRESENT |
79
79
  | TASK_STATE_MACHINE-R-006 | Treat `UIControlConfig` values as Task-supplied capability configuration, not rollout flags evaluated or owned by the state machine. | Rollout and profile policy must be resolved before actor construction so transitions remain deterministic. | `src/services/task/state-machine/types.ts`, `src/services/task/Task.ts` | `test/unit/spec/services/task/Task.ts` | None; rollout ownership is explicit. | PRESENT |
80
80
  | TASK_STATE_MACHINE-R-007 | Keep logging and metrics in Task/TaskManager integration; the state-machine implementation has no LoggerProxy or MetricsManager dependency. | Separating observability side effects from guards/actions preserves deterministic transition tests. | `src/services/task/state-machine/TaskStateMachine.ts`, `src/services/task/Task.ts` | `test/unit/spec/services/task/state-machine/TaskStateMachine.ts`, `test/unit/spec/services/task/Task.ts` | None; observability ownership is explicit. | PRESENT |
81
- | TASK_STATE_MACHINE-R-008 | `CONTACT_OWNER_CHANGED` must synchronize task/context data and emit `task:hydrate` without transitioning state. A TaskManager-recovered promoted-Agent task first receives an internal IDLE `HYDRATE` before listener installation, then the original owner-change event produces exactly one external hydrate and no incoming event. TaskManager maps an owner-changing `ContactUpdated` for an existing task to that owner-change event, while same-owner or owner-less updates remain `CONTACT_UPDATED`; missing-task `ContactUpdated` does not create a task. It also preserves an already confirmed active owner from a late participant-left snapshot that still names the departed owner. Participant Drop must rely on the existing `ParticipantLeftConference` mapping rather than adding an initiating state event. From every active call-control state, `PARTICIPANT_LEAVE` terminates or wraps the current Agent only when the event names that Agent, marks that Agent `hasLeft`, or removes a previously active Agent from the participant map; an event naming another participant cannot infer self-departure from a partial media roster. `CONSULT_END` evaluates the same explicit evidence before initiator recovery and additionally supports the narrow from-conference nested-consult race where a previously main-leg Agent is absent from the updated `mainCall` but remains active in the participant map and present on the consult leg. Removed accepted Agents emit `task:consultEnd` plus `task:end`, surviving initiators recover to their main call, and an unaccepted OFFERED consultee emits only `task:consultEnd`. Missing, partial, contradictory, or ordinary CONNECTED/HELD media membership is non-terminal, and starting Consult must preserve the prior task snapshot used by the guard. | Owner-sensitive consumers must rerender promptly while owner selection, participant removal, consult removal, and narrowly scoped desynchronization recovery remain backend-authoritative and compatible with existing incoming-task callback behavior. | `src/services/task/state-machine/TaskStateMachine.ts`, `src/services/task/state-machine/actions.ts`, `src/services/task/state-machine/guards.ts`, `src/services/task/TaskManager.ts` | `test/unit/spec/services/task/Task.ts`, `test/unit/spec/services/task/TaskManager.ts`, `test/unit/spec/services/task/state-machine/TaskStateMachine.ts`, `test/unit/spec/services/task/state-machine/guards.ts` | Backend ownership-successor selection and delivery of complete recovery payloads are outside this module. | PRESENT |
81
+ | TASK_STATE_MACHINE-R-008 | `CONTACT_OWNER_CHANGED` must synchronize task/context data and emit `task:hydrate` without transitioning state. A TaskManager-recovered promoted-Agent task first receives an internal IDLE `HYDRATE` before listener installation, then the original owner-change event produces exactly one external hydrate and no incoming event. TaskManager maps an owner-changing `ContactUpdated` for an existing task to that owner-change event, while same-owner or owner-less updates remain `CONTACT_UPDATED`; missing-task `ContactUpdated` does not create a task. It also preserves an already confirmed active owner from a late participant-left snapshot that still names the departed owner. Participant Drop must rely on the existing `ParticipantLeftConference` mapping rather than adding an initiating state event. `PARTICIPANT_LEAVE` is handled in `HELD`, `RESUME_INITIATING`, `CONSULTING`, `CONSULT_INITIATING`, and `CONFERENCING`; `CONNECTED`, `HOLD_INITIATING`, and `CONF_INITIATING` ignore the event. The current Agent is treated as departed only when the event names that Agent or the updated participants map omits that Agent (EP-DN removal). Remaining in the map with `hasLeft`, or disappearing only from `mainCall` media, is non-terminal. `CONSULT_END` does not use mainCall membership as self-departure evidence. Removed accepted Agents emit `task:consultEnd` plus `task:end`, surviving initiators recover to their main call, and an unaccepted OFFERED consultee emits only `task:consultEnd`. Starting Consult must preserve the prior task snapshot used by the guard. | Owner-sensitive consumers must rerender promptly while owner selection, participant removal, consult removal, and narrowly scoped desynchronization recovery remain backend-authoritative and compatible with existing incoming-task callback behavior. | `src/services/task/state-machine/TaskStateMachine.ts`, `src/services/task/state-machine/actions.ts`, `src/services/task/state-machine/guards.ts`, `src/services/task/TaskManager.ts` | `test/unit/spec/services/task/Task.ts`, `test/unit/spec/services/task/TaskManager.ts`, `test/unit/spec/services/task/state-machine/TaskStateMachine.ts`, `test/unit/spec/services/task/state-machine/guards.ts` | Backend ownership-successor selection and delivery of complete recovery payloads are outside this module. | PRESENT |
82
82
 
83
83
  ## Design Overview
84
84
  TaskManager maps Contact Center notifications to `TaskEvent` values. Each Task sends those events to its XState actor built by `createTaskStateMachine()`. The configuration applies guards and named actions, updates `TaskContext`, and computes UI controls. Task supplies the integration-specific `syncTaskDataFromEvent` implementation through machine options; it is not a default action in `actions.ts`.
@@ -524,10 +524,8 @@ didCurrentAgentLeaveMainInteraction(context, event) {
524
524
  const participantIdFromEvent = 'participantId' in event ? event.participantId : undefined;
525
525
  const participantId = participantIdFromEvent ?? event.taskData?.participantId;
526
526
  if (Boolean(participantId) && participantId === selfAgentId) return true;
527
- // Explicit hasLeft or removal of a previously active self from the participant map is terminal.
528
- // PARTICIPANT_LEAVE naming another participant does not infer self departure from media.
529
- // Only a from-conference CONSULT_END may compare mainCall membership, and only when self
530
- // remains active in the participant map and on the consult leg. Partial ordinary calls are false.
527
+ // Self missing from the updated participants map is terminal (EP-DN removal).
528
+ // Remaining in the map with hasLeft, or disappearing only from mainCall media, is not.
531
529
  }
532
530
 
533
531
  // True when this agent initiated the conference transfer (widgets or desktop).
@@ -1791,7 +1789,7 @@ Complete mapping from backend CC_EVENTS to internal TaskEvent types.
1791
1789
  | `PARTICIPANT_JOINED_CONFERENCE` | `CONFERENCE_START` | `CONSULTING` / `CONF_INITIATING` / `CONFERENCING` | `CONFERENCING` / same | Conference participant joined |
1792
1790
  | `AGENT_CONSULT_CONFERENCE_FAILED` | `CONFERENCE_FAILED` | `CONF_INITIATING` | `CONSULTING` | Merge fail fallback |
1793
1791
  | `AGENT_CONSULT_CONFERENCE_ENDED` | `CONFERENCE_END` | `CONFERENCING` | `WRAPPING_UP` / `CONNECTED` / `TERMINATED` | Guard-driven |
1794
- | `PARTICIPANT_LEFT_CONFERENCE` | `PARTICIPANT_LEAVE` | `CONSULTING` / `CONFERENCING` | `WRAPPING_UP` / `TERMINATED` / `CONNECTED` / same | Ownership + downgrade guards |
1792
+ | `PARTICIPANT_LEFT_CONFERENCE` | `PARTICIPANT_LEAVE` | `HELD` / `RESUME_INITIATING` / `CONSULTING` / `CONSULT_INITIATING` / `CONFERENCING` | `WRAPPING_UP` / `TERMINATED` / `CONNECTED` / same | Named self or omitted from participant map; `CONNECTED` / `HOLD_INITIATING` / `CONF_INITIATING` ignore |
1795
1793
  | `AGENT_CONFERENCE_TRANSFERRED` | `TRANSFER_CONFERENCE_SUCCESS` | `CONSULTING` / `CONFERENCING` | `WRAPPING_UP` / `CONFERENCING` / `TERMINATED` / same | Initiator/receiver dependent |
1796
1794
 
1797
1795
  - `AGENT_CONTACT_UNASSIGNED` -> returns `null` in mapper (`TaskManager.mapEventToTaskStateMachineEvent`)
@@ -1840,7 +1838,7 @@ Complete mapping from backend CC_EVENTS to internal TaskEvent types.
1840
1838
  | API `task.dropConferenceParticipant()` | None | No direct state transition | AQM waits for backend `ParticipantLeftConference`; that event follows the existing `PARTICIPANT_LEAVE` path |
1841
1839
  | `AgentConsultConferenced` | `CONFERENCE_START` | CONSULTING/CONF_INITIATING → CONFERENCING | `handleConferenceStarted` path |
1842
1840
  | `ParticipantJoinedConference` | `CONFERENCE_START` | CONFERENCING → CONFERENCING | Refresh + emit conference started |
1843
- | `ParticipantLeftConference` | `PARTICIPANT_LEAVE` | Any active call-control state → WRAPPING_UP / TERMINATED / CONNECTED / stay | Uses `didCurrentAgentLeaveMainInteraction`, `shouldWrapUp`, `shouldDowngradeConferenceToConnected` |
1841
+ | `ParticipantLeftConference` | `PARTICIPANT_LEAVE` | HELD / RESUME_INITIATING / CONSULTING / CONSULT_INITIATING / CONFERENCING → WRAPPING_UP / TERMINATED / CONNECTED / stay; CONNECTED / HOLD_INITIATING / CONF_INITIATING ignore | Uses `didCurrentAgentLeaveMainInteraction` (named self or omitted from participant map), `shouldWrapUp`, `shouldDowngradeConferenceToConnected` |
1844
1842
  | `AgentConsultConferenceEnded` | `CONFERENCE_END` | CONFERENCING → WRAPPING_UP / CONNECTED / TERMINATED | Guard-based branch |
1845
1843
  | `AgentConsultConferenceFailed` | `CONFERENCE_FAILED` | CONF_INITIATING → CONSULTING | Merge failed fallback |
1846
1844
  | `AgentConferenceTransferred` | `TRANSFER_CONFERENCE_SUCCESS` | CONSULTING/CONFERENCING branch logic | Initiator/receiver dependent |
@@ -364,10 +364,10 @@ export const guards = {
364
364
  /**
365
365
  * True when an updated lifecycle event shows that this agent left the main interaction.
366
366
  *
367
- * Explicit self-participant evidence is authoritative. Main-call membership is used only
368
- * for the from-conference nested-consult race where CONSULT_END still represents the agent as
369
- * active on the consult leg after removing them from the main leg. Partial or ordinary call
370
- * snapshots are not treated as a departure.
367
+ * Returns true when the event names this agent, or when this agent is absent from the
368
+ * updated participants map. EP-DN payloads remove the leaving participant instead of
369
+ * setting hasLeft. Remaining in the map with hasLeft, or disappearing only from
370
+ * mainCall media, is not treated as departure.
371
371
  */
372
372
  didCurrentAgentLeaveMainInteraction: ({context, event}: GuardParams): boolean => {
373
373
  const taskData = getTaskDataFromEvent(event);
@@ -383,65 +383,9 @@ export const guards = {
383
383
  if (Boolean(participantId) && participantId === selfAgentId) {
384
384
  return true;
385
385
  }
386
-
387
- // Routing represents self-departure either by naming the participant or by retaining the
388
- // participant entry with hasLeft set. Agent Desktop treats both representations as terminal.
389
- const currentParticipant = taskData?.interaction?.participants?.[selfAgentId];
390
- if (currentParticipant?.hasLeft === true) {
391
- return true;
392
- }
393
-
394
- // A participant-left event that explicitly identifies somebody else must not use a
395
- // potentially partial participant or media roster to infer that self also departed.
396
- if (
397
- event?.type === TaskEvent.PARTICIPANT_LEAVE &&
398
- Boolean(participantId) &&
399
- participantId !== selfAgentId
400
- ) {
401
- return false;
402
- }
403
-
404
- const previousParticipants = context.taskData?.interaction?.participants;
405
- const updatedParticipants = taskData?.interaction?.participants;
406
- const wasPreviouslyActive = Boolean(
407
- previousParticipants?.[selfAgentId] && previousParticipants[selfAgentId].hasLeft !== true
408
- );
409
- // Some EP-DN lifecycle payloads remove the participant entry instead of setting hasLeft.
410
- // Requiring a previously active entry prevents an incomplete initial snapshot from ending a task.
411
- if (updatedParticipants && wasPreviouslyActive && !(selfAgentId in updatedParticipants)) {
412
- return true;
413
- }
414
-
415
- const previousMainMedia = Object.values(context.taskData?.interaction?.media ?? {}).filter(
416
- (media) => media?.mType === 'mainCall'
417
- );
418
- const updatedMainMedia = Object.values(taskData?.interaction?.media ?? {}).filter(
419
- (media) => media?.mType === 'mainCall'
420
- );
421
- const wasPreviouslyInMainCall = previousMainMedia.some((media) =>
422
- media.participants?.includes(selfAgentId)
423
- );
424
- const remainsInMainCall = updatedMainMedia.some((media) =>
425
- media.participants?.includes(selfAgentId)
426
- );
427
- // A hasLeft participant returned above, so presence here means the updated map keeps self active.
428
- const remainsActiveInParticipantMap = Boolean(currentParticipant);
429
- const remainsOnConsultLeg = Object.values(taskData?.interaction?.media ?? {}).some(
430
- (media) => media?.mType === MEDIA_TYPE_CONSULT && media.participants?.includes(selfAgentId)
431
- );
432
-
433
- // Agent Desktop uses mainCall membership for AgentConsultEnded cleanup. Restrict that fallback
434
- // to a consult that originated from conference and require corroborating active-map and
435
- // consult-leg membership so ordinary partial CONNECTED/HELD payloads cannot terminate a task.
436
- if (
437
- event?.type === TaskEvent.CONSULT_END &&
438
- context.consultFromConference === true &&
439
- updatedMainMedia.length > 0 &&
440
- wasPreviouslyInMainCall &&
441
- !remainsInMainCall &&
442
- remainsActiveInParticipantMap &&
443
- remainsOnConsultLeg
444
- ) {
386
+ // EP-DN payloads remove the leaving participant from the map instead of setting hasLeft.
387
+ const participants = taskData?.interaction?.participants;
388
+ if (participants && !(selfAgentId in participants)) {
445
389
  return true;
446
390
  }
447
391