@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.
- package/ai-docs/CONTRACTS.md +1 -1
- package/dist/services/task/state-machine/TaskStateMachine.js +0 -17
- package/dist/services/task/state-machine/TaskStateMachine.js.map +1 -1
- package/dist/services/task/state-machine/guards.js +7 -37
- package/dist/services/task/state-machine/guards.js.map +1 -1
- package/dist/types/services/task/state-machine/TaskStateMachine.d.ts +0 -42
- package/dist/types/services/task/state-machine/guards.d.ts +4 -4
- package/dist/webex.js +1 -1
- package/package.json +8 -8
- package/src/services/task/ai-docs/task-spec.md +15 -16
- package/src/services/task/state-machine/TaskStateMachine.ts +0 -20
- package/src/services/task/state-machine/ai-docs/AGENTS.md +2 -4
- package/src/services/task/state-machine/ai-docs/ARCHITECTURE.md +8 -9
- package/src/services/task/state-machine/ai-docs/task-state-machine-spec.md +5 -7
- package/src/services/task/state-machine/guards.ts +7 -63
- package/test/unit/spec/services/task/state-machine/TaskStateMachine.ts +72 -46
- package/test/unit/spec/services/task/state-machine/guards.ts +6 -6
- package/umd/contact-center.min.js +2 -2
- package/umd/contact-center.min.js.map +1 -1
|
@@ -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
|
-
*
|
|
84
|
-
*
|
|
85
|
-
*
|
|
86
|
-
*
|
|
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
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.
|
|
50
|
-
"@webex/internal-plugin-mercury": "3.12.0-next.
|
|
51
|
-
"@webex/internal-plugin-metrics": "3.12.0-next.
|
|
52
|
-
"@webex/internal-plugin-support": "3.12.0-next.
|
|
53
|
-
"@webex/plugin-authorization": "3.12.0-next.
|
|
54
|
-
"@webex/plugin-logger": "3.12.0-next.
|
|
55
|
-
"@webex/webex-core": "3.12.0-next.
|
|
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.
|
|
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.
|
|
906
|
-
|
|
907
|
-
`
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
`
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
|
|
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
|
-
//
|
|
278
|
-
//
|
|
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
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
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`
|
|
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` |
|
|
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.
|
|
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
|
-
//
|
|
528
|
-
//
|
|
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`
|
|
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` |
|
|
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
|
-
*
|
|
368
|
-
*
|
|
369
|
-
*
|
|
370
|
-
*
|
|
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
|
-
|
|
388
|
-
|
|
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
|
|