@webex/contact-center 3.12.0-llmrefactor.7 → 3.12.0-llmrefactor.9
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/.sdd/manifest.json +3 -2
- package/ai-docs/CONTRACTS.md +3 -2
- package/dist/cc.js +108 -6
- package/dist/cc.js.map +1 -1
- package/dist/metrics/MetricsManager.js +16 -0
- package/dist/metrics/MetricsManager.js.map +1 -1
- package/dist/metrics/behavioral-events.js +91 -0
- package/dist/metrics/behavioral-events.js.map +1 -1
- package/dist/metrics/constants.js +16 -0
- package/dist/metrics/constants.js.map +1 -1
- package/dist/services/AnswerCallOnWebexService.js +34 -6
- package/dist/services/AnswerCallOnWebexService.js.map +1 -1
- package/dist/services/WebexCrossClientService.js +54 -3
- package/dist/services/WebexCrossClientService.js.map +1 -1
- package/dist/services/WxAppTelephonyMercurySync.js +21 -6
- package/dist/services/WxAppTelephonyMercurySync.js.map +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/services/task/voice/Voice.js +81 -14
- package/dist/services/task/voice/Voice.js.map +1 -1
- package/dist/services/task/voice/wxAppVoiceMethods.js +154 -1
- package/dist/services/task/voice/wxAppVoiceMethods.js.map +1 -1
- package/dist/services/wxAppDiagnosticLogging.js +122 -0
- package/dist/services/wxAppDiagnosticLogging.js.map +1 -0
- package/dist/types/cc.d.ts +1 -0
- package/dist/types/metrics/MetricsManager.d.ts +6 -0
- package/dist/types/metrics/constants.d.ts +15 -0
- package/dist/types/services/AnswerCallOnWebexService.d.ts +1 -0
- package/dist/types/services/WebexCrossClientService.d.ts +4 -0
- 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/types/services/task/voice/Voice.d.ts +5 -1
- package/dist/types/services/task/voice/wxAppVoiceMethods.d.ts +3 -0
- package/dist/types/services/wxAppDiagnosticLogging.d.ts +51 -0
- package/dist/webex.js +1 -1
- package/package.json +8 -8
- package/src/cc.ts +155 -7
- package/src/metrics/MetricsManager.ts +16 -0
- package/src/metrics/ai-docs/metrics-spec.md +71 -9
- package/src/metrics/behavioral-events.ts +92 -0
- package/src/metrics/constants.ts +18 -0
- package/src/services/AnswerCallOnWebexService.ts +41 -8
- package/src/services/WebexCrossClientService.ts +85 -4
- package/src/services/WxAppTelephonyMercurySync.ts +31 -4
- package/src/services/agent/ai-docs/agent-spec.md +1 -0
- package/src/services/task/ai-docs/task-spec.md +17 -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/src/services/task/voice/Voice.ts +115 -26
- package/src/services/task/voice/wxAppVoiceMethods.ts +211 -2
- package/src/services/wxAppDiagnosticLogging.ts +174 -0
- package/test/unit/spec/cc.ts +251 -22
- package/test/unit/spec/metrics/MetricsManager.ts +25 -0
- package/test/unit/spec/metrics/behavioral-events.ts +42 -0
- package/test/unit/spec/services/AnswerCallOnWebexService.ts +41 -0
- package/test/unit/spec/services/WebexCrossClientService.ts +207 -1
- package/test/unit/spec/services/WxAppTelephonyMercurySync.ts +23 -0
- 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/test/unit/spec/services/task/voice/Voice.ts +380 -0
- package/test/unit/spec/services/task/voice/wxAppVoiceMethods.ts +145 -1
- package/test/unit/spec/services/wxAppDiagnosticLogging.ts +143 -0
- 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":[]}
|
|
@@ -15,6 +15,7 @@ var _stateMachine = require("../state-machine");
|
|
|
15
15
|
var _TaskUtils = require("../TaskUtils");
|
|
16
16
|
var _wxAppTelephonyUtils = require("../../wxAppTelephonyUtils");
|
|
17
17
|
var _wxAppVoiceMethods = require("./wxAppVoiceMethods");
|
|
18
|
+
var _wxAppDiagnosticLogging = require("../../wxAppDiagnosticLogging");
|
|
18
19
|
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
|
|
19
20
|
class Voice extends _Task.default {
|
|
20
21
|
static WXAPP_MUTE_SYNC_RETRY_DELAY_MS = 50;
|
|
@@ -23,6 +24,8 @@ class Voice extends _Task.default {
|
|
|
23
24
|
wxAppMuted = false;
|
|
24
25
|
wxAppAnswerPending = false;
|
|
25
26
|
wxAppAcceptInFlight = false;
|
|
27
|
+
wxAppMuteToggleTail = Promise.resolve();
|
|
28
|
+
wxAppDtmfTail = Promise.resolve();
|
|
26
29
|
constructor(contact, data, callOptions, wrapupData, agentId) {
|
|
27
30
|
const resolvedOptions = {
|
|
28
31
|
isEndTaskEnabled: callOptions?.isEndTaskEnabled ?? true,
|
|
@@ -43,6 +46,7 @@ class Voice extends _Task.default {
|
|
|
43
46
|
enableWxBetterTogether: this.enableWxBetterTogether,
|
|
44
47
|
answerCallOnWebexService: this.answerCallOnWebexService,
|
|
45
48
|
agentId: this.agentId,
|
|
49
|
+
metricsManager: this.metricsManager,
|
|
46
50
|
getTaskData: () => this.data,
|
|
47
51
|
getTaskState: () => this.stateMachineService?.getSnapshot?.()?.value,
|
|
48
52
|
getWxAppMuted: () => this.wxAppMuted,
|
|
@@ -86,15 +90,84 @@ class Voice extends _Task.default {
|
|
|
86
90
|
};
|
|
87
91
|
this.updateUiControls(true);
|
|
88
92
|
}
|
|
93
|
+
updateUiControls(forceEmit = false) {
|
|
94
|
+
super.updateUiControls(forceEmit);
|
|
95
|
+
this.logWxAppOfferDecisionIfNeeded();
|
|
96
|
+
}
|
|
97
|
+
logWxAppOfferDecisionIfNeeded() {
|
|
98
|
+
if (!this.enableWxBetterTogether) {
|
|
99
|
+
return;
|
|
100
|
+
}
|
|
101
|
+
const state = this.stateMachineService?.getSnapshot?.()?.value;
|
|
102
|
+
if (state !== _stateMachine.TaskState.OFFERED) {
|
|
103
|
+
return;
|
|
104
|
+
}
|
|
105
|
+
const accept = this.currentUiControls?.main?.accept;
|
|
106
|
+
if (!accept?.isVisible) {
|
|
107
|
+
return;
|
|
108
|
+
}
|
|
109
|
+
const deps = this.getWxAppVoiceDependencies();
|
|
110
|
+
const isOutdial = this.data?.interaction?.outboundType === 'OUTDIAL';
|
|
111
|
+
const isWxAppInboundOffer = this.isWebexAppInboundCallingOffer();
|
|
112
|
+
const isWxAppOutdialOffer = this.isWebexAppCallingOffer() && isOutdial;
|
|
113
|
+
const deviceDetails = (0, _wxAppVoiceMethods.getCallingDeviceDetails)(deps);
|
|
114
|
+
const acceptReason = (0, _wxAppDiagnosticLogging.deriveWxAppAcceptReason)({
|
|
115
|
+
isWxAppInboundOffer,
|
|
116
|
+
isWxAppOutdialOffer,
|
|
117
|
+
isWebrtc: this.uiControlConfig.voiceVariant === _types.VOICE_VARIANT.WEBRTC,
|
|
118
|
+
isOutdial,
|
|
119
|
+
wxAppAcceptInFlight: this.wxAppAcceptInFlight,
|
|
120
|
+
wxAppAnswerPending: this.wxAppAnswerPending,
|
|
121
|
+
enableWxBetterTogether: this.enableWxBetterTogether,
|
|
122
|
+
hasDeviceCallId: Boolean(deviceDetails?.deviceCallId)
|
|
123
|
+
});
|
|
124
|
+
if (acceptReason === this.lastLoggedWxAppAcceptReason) {
|
|
125
|
+
return;
|
|
126
|
+
}
|
|
127
|
+
this.lastLoggedWxAppAcceptReason = acceptReason;
|
|
128
|
+
(0, _wxAppDiagnosticLogging.logWxAppOfferDecision)({
|
|
129
|
+
interactionId: this.data.interactionId,
|
|
130
|
+
acceptVisible: accept.isVisible,
|
|
131
|
+
acceptEnabled: accept.isEnabled,
|
|
132
|
+
acceptReason,
|
|
133
|
+
wxAppParticipantDeviceType: deviceDetails?.deviceType,
|
|
134
|
+
hasDeviceCallId: Boolean(deviceDetails?.deviceCallId)
|
|
135
|
+
});
|
|
136
|
+
}
|
|
89
137
|
applyWxAppMuteStateFromSync(incomingCallId, muted) {
|
|
90
138
|
if (!this.enableWxBetterTogether) {
|
|
91
139
|
return;
|
|
92
140
|
}
|
|
93
141
|
const activeCallId = this.getWebexCallingCallId();
|
|
94
|
-
|
|
142
|
+
const incomingSuffix = (0, _wxAppDiagnosticLogging.callIdSuffix)(incomingCallId);
|
|
143
|
+
const activeSuffix = (0, _wxAppDiagnosticLogging.callIdSuffix)(activeCallId);
|
|
144
|
+
if (!activeCallId || !incomingCallId.endsWith(activeCallId)) {
|
|
145
|
+
(0, _wxAppDiagnosticLogging.logWxAppMercuryMuteSync)({
|
|
146
|
+
phase: 'dropped',
|
|
147
|
+
muted,
|
|
148
|
+
callIdSuffix: incomingSuffix,
|
|
149
|
+
interactionId: this.data.interactionId,
|
|
150
|
+
dropReason: !activeCallId ? 'no_active_wxApp_call' : 'call_id_mismatch'
|
|
151
|
+
});
|
|
152
|
+
return;
|
|
153
|
+
}
|
|
154
|
+
if (this.wxAppMuted === muted) {
|
|
155
|
+
(0, _wxAppDiagnosticLogging.logWxAppMercuryMuteSync)({
|
|
156
|
+
phase: 'dropped',
|
|
157
|
+
muted,
|
|
158
|
+
callIdSuffix: incomingSuffix,
|
|
159
|
+
interactionId: this.data.interactionId,
|
|
160
|
+
dropReason: 'mute_state_unchanged'
|
|
161
|
+
});
|
|
95
162
|
return;
|
|
96
163
|
}
|
|
97
164
|
this.wxAppMuted = muted;
|
|
165
|
+
(0, _wxAppDiagnosticLogging.logWxAppMercuryMuteSync)({
|
|
166
|
+
phase: 'applied',
|
|
167
|
+
muted,
|
|
168
|
+
callIdSuffix: activeSuffix,
|
|
169
|
+
interactionId: this.data.interactionId
|
|
170
|
+
});
|
|
98
171
|
this.emit(_types.TASK_EVENTS.TASK_WXAPP_MUTE_STATE_UPDATED, {
|
|
99
172
|
muted
|
|
100
173
|
});
|
|
@@ -261,9 +334,9 @@ class Voice extends _Task.default {
|
|
|
261
334
|
try {
|
|
262
335
|
this.metricsManager.timeEvent([_constants2.METRIC_EVENT_NAMES.TASK_DECLINE_SUCCESS, _constants2.METRIC_EVENT_NAMES.TASK_DECLINE_FAILED]);
|
|
263
336
|
this.setWxAppAnswerPending(false);
|
|
264
|
-
const response = await this.contact.cancelTask({
|
|
337
|
+
const response = await (0, _wxAppVoiceMethods.runWxAppOutdialDecline)(this.getWxAppVoiceDependencies(), () => this.contact.cancelTask({
|
|
265
338
|
interactionId
|
|
266
|
-
});
|
|
339
|
+
}));
|
|
267
340
|
this.metricsManager.trackEvent(_constants2.METRIC_EVENT_NAMES.TASK_DECLINE_SUCCESS, {
|
|
268
341
|
taskId: interactionId,
|
|
269
342
|
..._MetricsManager.default.getCommonTrackingFieldForAQMResponse(response)
|
|
@@ -287,16 +360,8 @@ class Voice extends _Task.default {
|
|
|
287
360
|
*/
|
|
288
361
|
async toggleMute(options) {
|
|
289
362
|
if (this.enableWxBetterTogether && this.getWebexCallingCallId()) {
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
}
|
|
293
|
-
const togglePromise = (0, _wxAppVoiceMethods.runWxAppToggleMute)(this.getWxAppVoiceDependencies(), this.createWxAppLifecycle(), options);
|
|
294
|
-
this.wxAppMuteToggleInFlight = togglePromise;
|
|
295
|
-
togglePromise.finally(() => {
|
|
296
|
-
if (this.wxAppMuteToggleInFlight === togglePromise) {
|
|
297
|
-
this.wxAppMuteToggleInFlight = undefined;
|
|
298
|
-
}
|
|
299
|
-
}).catch(() => undefined);
|
|
363
|
+
const togglePromise = this.wxAppMuteToggleTail.catch(() => undefined).then(() => (0, _wxAppVoiceMethods.runWxAppToggleMute)(this.getWxAppVoiceDependencies(), this.createWxAppLifecycle(), options));
|
|
364
|
+
this.wxAppMuteToggleTail = togglePromise.catch(() => undefined);
|
|
300
365
|
await togglePromise;
|
|
301
366
|
return;
|
|
302
367
|
}
|
|
@@ -308,7 +373,9 @@ class Voice extends _Task.default {
|
|
|
308
373
|
*/
|
|
309
374
|
async transmitDtmf(options) {
|
|
310
375
|
if (this.enableWxBetterTogether && this.getWebexCallingCallId()) {
|
|
311
|
-
|
|
376
|
+
const dtmfPromise = this.wxAppDtmfTail.catch(() => undefined).then(() => (0, _wxAppVoiceMethods.runWxAppTransmitDtmf)(this.getWxAppVoiceDependencies(), this.createWxAppLifecycle(), options));
|
|
377
|
+
this.wxAppDtmfTail = dtmfPromise.catch(() => undefined);
|
|
378
|
+
await dtmfPromise;
|
|
312
379
|
return;
|
|
313
380
|
}
|
|
314
381
|
super.unsupportedMethodError(_constants.METHODS.TRANSMIT_DTMF);
|