@webex/contact-center 3.12.0-task-refactor.7 → 3.12.0-task-refactor.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/dist/cc.js +3 -4
- package/dist/cc.js.map +1 -1
- package/dist/constants.js +1 -0
- package/dist/constants.js.map +1 -1
- package/dist/metrics/constants.js +2 -0
- package/dist/metrics/constants.js.map +1 -1
- package/dist/services/ApiAiAssistant.js +74 -3
- package/dist/services/ApiAiAssistant.js.map +1 -1
- package/dist/services/config/types.js +9 -1
- package/dist/services/config/types.js.map +1 -1
- package/dist/services/task/Task.js +32 -0
- package/dist/services/task/Task.js.map +1 -1
- package/dist/services/task/TaskManager.js +7 -2
- package/dist/services/task/TaskManager.js.map +1 -1
- package/dist/services/task/TaskUtils.js +3 -1
- package/dist/services/task/TaskUtils.js.map +1 -1
- package/dist/services/task/state-machine/TaskStateMachine.js +76 -0
- package/dist/services/task/state-machine/TaskStateMachine.js.map +1 -1
- package/dist/services/task/state-machine/actions.js +113 -23
- package/dist/services/task/state-machine/actions.js.map +1 -1
- package/dist/services/task/state-machine/uiControlsComputer.js +99 -21
- package/dist/services/task/state-machine/uiControlsComputer.js.map +1 -1
- package/dist/types/constants.d.ts +1 -0
- package/dist/types/metrics/constants.d.ts +2 -0
- package/dist/types/services/ApiAiAssistant.d.ts +10 -2
- package/dist/types/services/config/types.d.ts +16 -0
- package/dist/types/services/task/Task.d.ts +10 -0
- package/dist/types/services/task/state-machine/TaskStateMachine.d.ts +110 -0
- package/dist/types/services/task/state-machine/actions.d.ts +2 -0
- package/dist/types/types.d.ts +24 -0
- package/dist/types.js +15 -0
- package/dist/types.js.map +1 -1
- package/dist/webex.js +1 -1
- package/package.json +1 -1
- package/src/cc.ts +6 -4
- package/src/constants.ts +1 -0
- package/src/metrics/constants.ts +2 -0
- package/src/services/ApiAiAssistant.ts +102 -2
- package/src/services/config/types.ts +8 -0
- package/src/services/task/Task.ts +34 -0
- package/src/services/task/TaskManager.ts +7 -2
- package/src/services/task/TaskUtils.ts +5 -3
- package/src/services/task/ai-docs/AGENTS.md +7 -0
- package/src/services/task/ai-docs/ARCHITECTURE.md +12 -0
- package/src/services/task/state-machine/TaskStateMachine.ts +104 -0
- package/src/services/task/state-machine/actions.ts +151 -25
- package/src/services/task/state-machine/uiControlsComputer.ts +173 -30
- package/src/types.ts +25 -0
- package/test/unit/spec/cc.ts +2 -0
- package/test/unit/spec/services/ApiAiAssistant.ts +105 -17
- package/test/unit/spec/services/task/Task.ts +61 -0
- package/test/unit/spec/services/task/TaskManager.ts +42 -0
- package/test/unit/spec/services/task/TaskUtils.ts +65 -0
- package/test/unit/spec/services/task/state-machine/TaskStateMachine.ts +676 -0
- package/test/unit/spec/services/task/state-machine/uiControlsComputer.ts +597 -0
- package/test/unit/spec/services/task/voice/WebRTC.ts +99 -106
- package/umd/contact-center.min.js +2 -2
- package/umd/contact-center.min.js.map +1 -1
|
@@ -5,6 +5,7 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
5
5
|
});
|
|
6
6
|
exports.actions = void 0;
|
|
7
7
|
exports.createInitialContext = createInitialContext;
|
|
8
|
+
exports.getTaskStateForUiControls = void 0;
|
|
8
9
|
exports.updateUIControls = updateUIControls;
|
|
9
10
|
var _xstate = require("xstate");
|
|
10
11
|
var _constants = require("./constants");
|
|
@@ -59,8 +60,11 @@ const isActiveConsultState = (taskData, selfAgentId) => {
|
|
|
59
60
|
if (selfAgentId) {
|
|
60
61
|
const selfParticipant = taskData?.interaction?.participants?.[selfAgentId];
|
|
61
62
|
const hasConsultMedia = Object.values(taskData?.interaction?.media ?? {}).some(media => media?.mType === _constants.MEDIA_TYPE_CONSULT);
|
|
62
|
-
|
|
63
|
-
if (
|
|
63
|
+
// Pending consult before destination joins stays HELD, not CONSULTING.
|
|
64
|
+
if (selfParticipant?.consultState === 'consultInitiated' && !hasJoinedConsultDestination(taskData, selfAgentId) && hasConsultMedia && taskData?.isConsulted === false) {
|
|
65
|
+
return false;
|
|
66
|
+
}
|
|
67
|
+
if (selfParticipant?.consultState === _constants.CONSULT_STATE.CONSULTING && hasConsultMedia && taskData?.isConsulted === false) {
|
|
64
68
|
return true;
|
|
65
69
|
}
|
|
66
70
|
}
|
|
@@ -76,13 +80,38 @@ const isSelfConsultingOrPending = (taskData, selfAgentId) => {
|
|
|
76
80
|
const selfParticipant = taskData?.interaction?.participants?.[selfAgentId];
|
|
77
81
|
return selfParticipant?.consultState === _constants.CONSULT_STATE.CONSULTING || selfParticipant?.consultState === 'consultInitiated';
|
|
78
82
|
};
|
|
79
|
-
const
|
|
83
|
+
const isDnOnConsultMedia = (taskData, selfAgentId) => {
|
|
84
|
+
if (!taskData?.interaction?.participants) return false;
|
|
85
|
+
const consultMedia = taskData.consultMediaResourceId ? taskData.interaction.media?.[taskData.consultMediaResourceId] : Object.values(taskData.interaction.media ?? {}).find(m => m?.mType === _constants.MEDIA_TYPE_CONSULT);
|
|
86
|
+
const consultParticipantIds = new Set(consultMedia?.participants ?? []);
|
|
87
|
+
if (consultParticipantIds.size === 0) return false;
|
|
88
|
+
return Object.values(taskData.interaction.participants).some(p => {
|
|
89
|
+
if (!p || p.hasLeft || p.id === selfAgentId) return false;
|
|
90
|
+
if (!consultParticipantIds.has(p.id)) return false;
|
|
91
|
+
const pType = String(p.pType ?? '').toUpperCase();
|
|
92
|
+
return pType === 'DN' || pType === 'EP-DN' || pType === 'EP_DN';
|
|
93
|
+
});
|
|
94
|
+
};
|
|
95
|
+
const mapConsultDestinationType = destinationType => {
|
|
96
|
+
if (!destinationType) return undefined;
|
|
97
|
+
const normalized = String(destinationType).toUpperCase();
|
|
98
|
+
if (normalized === 'DN' || normalized === 'EP-DN' || normalized === 'EP_DN') {
|
|
99
|
+
return 'entryPoint';
|
|
100
|
+
}
|
|
101
|
+
return destinationType;
|
|
102
|
+
};
|
|
103
|
+
const hasJoinedConsultDestination = (taskData, selfAgentId) => {
|
|
80
104
|
if (!taskData?.interaction) return false;
|
|
81
105
|
const participants = taskData.interaction.participants;
|
|
82
106
|
const cpd = taskData.interaction.callProcessingDetails;
|
|
83
107
|
const backendSaysJoined = cpd?.consultDestinationAgentJoined === 'true';
|
|
84
108
|
if (backendSaysJoined) return true;
|
|
85
109
|
if (!participants) return false;
|
|
110
|
+
const effectiveSelfAgentId = selfAgentId ?? taskData.agentId;
|
|
111
|
+
const selfParticipant = effectiveSelfAgentId ? participants[effectiveSelfAgentId] : undefined;
|
|
112
|
+
if (taskData.type === 'AgentConsulting' && selfParticipant?.consultState === _constants.CONSULT_STATE.CONSULTING && taskData.isConsulted === false && isDnOnConsultMedia(taskData, effectiveSelfAgentId)) {
|
|
113
|
+
return true;
|
|
114
|
+
}
|
|
86
115
|
return Object.values(participants).some(p => {
|
|
87
116
|
if (!p || p.isConsulted !== true || p.hasLeft) return false;
|
|
88
117
|
return p.hasJoined === true || p.consultState === _constants.CONSULT_STATE.CONSULTING;
|
|
@@ -118,6 +147,7 @@ const getTaskStateForUiControls = (taskData, selfAgentId) => {
|
|
|
118
147
|
}
|
|
119
148
|
return _constants.TaskState.CONNECTED;
|
|
120
149
|
};
|
|
150
|
+
exports.getTaskStateForUiControls = getTaskStateForUiControls;
|
|
121
151
|
const deriveTaskDataUpdates = (context, taskData) => taskData ? (() => {
|
|
122
152
|
const updates = {
|
|
123
153
|
taskData,
|
|
@@ -134,10 +164,20 @@ const deriveTaskDataUpdates = (context, taskData) => taskData ? (() => {
|
|
|
134
164
|
updates.consultDestinationAgentId = taskData.destAgentId;
|
|
135
165
|
}
|
|
136
166
|
}
|
|
167
|
+
const isConsultTerminalEvent = taskData.type === 'AgentConsultEnded' || taskData.type === 'AgentConsultFailed';
|
|
168
|
+
if (isConsultTerminalEvent) {
|
|
169
|
+
updates.consultInitiator = false;
|
|
170
|
+
updates.consultFromConference = false;
|
|
171
|
+
updates.consultDestinationAgentJoined = false;
|
|
172
|
+
updates.consultCallHeld = false;
|
|
173
|
+
updates.consultDestinationType = null;
|
|
174
|
+
updates.consultDestinationAgentId = null;
|
|
175
|
+
updates.transferConferenceRequested = false;
|
|
176
|
+
}
|
|
137
177
|
if (consultingActive && taskData.destinationType) {
|
|
138
|
-
updates.consultDestinationType = taskData.destinationType;
|
|
178
|
+
updates.consultDestinationType = mapConsultDestinationType(taskData.destinationType);
|
|
139
179
|
}
|
|
140
|
-
if (!context.consultInitiator) {
|
|
180
|
+
if (!isConsultTerminalEvent && !context.consultInitiator) {
|
|
141
181
|
const consultInitiator = determineConsultInitiator(taskData, selfAgentId);
|
|
142
182
|
if (consultInitiator !== undefined) {
|
|
143
183
|
updates.consultInitiator = consultInitiator;
|
|
@@ -146,14 +186,24 @@ const deriveTaskDataUpdates = (context, taskData) => taskData ? (() => {
|
|
|
146
186
|
}
|
|
147
187
|
}
|
|
148
188
|
const effectiveConsultInitiator = updates.consultInitiator ?? context.consultInitiator;
|
|
149
|
-
if (effectiveConsultInitiator && conferenceFromPayload && (consultingActive || selfConsultingOrPending || Boolean(taskData?.consultMediaResourceId))) {
|
|
189
|
+
if (!isConsultTerminalEvent && effectiveConsultInitiator && conferenceFromPayload && (consultingActive || selfConsultingOrPending || Boolean(taskData?.consultMediaResourceId))) {
|
|
150
190
|
updates.consultFromConference = true;
|
|
151
191
|
}
|
|
152
|
-
if (consultingActive && taskData.interaction) {
|
|
153
|
-
const joinedConsultee = hasJoinedConsultDestination(taskData);
|
|
154
|
-
|
|
192
|
+
if (!isConsultTerminalEvent && (consultingActive || selfConsultingOrPending) && taskData.interaction) {
|
|
193
|
+
const joinedConsultee = hasJoinedConsultDestination(taskData, selfAgentId);
|
|
194
|
+
const selfParticipant = selfAgentId ? taskData.interaction.participants?.[selfAgentId] : undefined;
|
|
195
|
+
const agentConsultingSelfJoined = taskData.type === 'AgentConsulting' && effectiveConsultInitiator && selfParticipant?.consultState === _constants.CONSULT_STATE.CONSULTING;
|
|
196
|
+
if (joinedConsultee || agentConsultingSelfJoined) {
|
|
197
|
+
updates.consultDestinationAgentJoined = true;
|
|
198
|
+
} else if (selfParticipant?.consultState === 'consultInitiated') {
|
|
199
|
+
updates.consultDestinationAgentJoined = false;
|
|
200
|
+
}
|
|
155
201
|
if (!context.consultDestinationType && !updates.consultDestinationType) {
|
|
156
|
-
const hasEpDnParticipant = Boolean(taskData.interaction.participants && Object.values(taskData.interaction.participants).some(p =>
|
|
202
|
+
const hasEpDnParticipant = Boolean(taskData.interaction.participants && Object.values(taskData.interaction.participants).some(p => {
|
|
203
|
+
if (p?.hasLeft) return false;
|
|
204
|
+
const pType = String(p?.pType ?? '').toUpperCase();
|
|
205
|
+
return pType === 'EP-DN' || pType === 'EP_DN' || pType === 'DN';
|
|
206
|
+
}));
|
|
157
207
|
if (hasEpDnParticipant) updates.consultDestinationType = 'entryPoint';
|
|
158
208
|
}
|
|
159
209
|
if (effectiveConsultInitiator) {
|
|
@@ -195,7 +245,7 @@ function updateUIControls(currentState) {
|
|
|
195
245
|
return (0, _xstate.assign)(({
|
|
196
246
|
context
|
|
197
247
|
}) => ({
|
|
198
|
-
uiControls: (0, _uiControlsComputer.computeUIControls)(currentState, context)
|
|
248
|
+
uiControls: (0, _uiControlsComputer.computeUIControls)(currentState, context, context.taskData ?? undefined)
|
|
199
249
|
}));
|
|
200
250
|
}
|
|
201
251
|
const actions = exports.actions = {
|
|
@@ -248,9 +298,32 @@ const actions = exports.actions = {
|
|
|
248
298
|
};
|
|
249
299
|
return {};
|
|
250
300
|
}),
|
|
251
|
-
handleConsultFailed: (0, _xstate.assign)({
|
|
252
|
-
|
|
253
|
-
|
|
301
|
+
handleConsultFailed: (0, _xstate.assign)(({
|
|
302
|
+
context,
|
|
303
|
+
event
|
|
304
|
+
}) => {
|
|
305
|
+
const taskData = getTaskDataFromEvent(event) ?? context.taskData;
|
|
306
|
+
const cleared = {
|
|
307
|
+
consultDestinationType: null,
|
|
308
|
+
consultDestinationAgentId: null,
|
|
309
|
+
consultDestinationAgentJoined: false,
|
|
310
|
+
consultInitiator: false,
|
|
311
|
+
exitingConference: false,
|
|
312
|
+
consultCallHeld: false,
|
|
313
|
+
consultFromConference: false,
|
|
314
|
+
transferConferenceRequested: false
|
|
315
|
+
};
|
|
316
|
+
const selfAgentId = context.uiControlConfig.agentId ?? taskData?.agentId;
|
|
317
|
+
const nextContext = {
|
|
318
|
+
...context,
|
|
319
|
+
...cleared,
|
|
320
|
+
taskData
|
|
321
|
+
};
|
|
322
|
+
const inferredState = getTaskStateForUiControls(taskData, selfAgentId);
|
|
323
|
+
return {
|
|
324
|
+
...cleared,
|
|
325
|
+
uiControls: (0, _uiControlsComputer.computeUIControls)(inferredState, nextContext, taskData)
|
|
326
|
+
};
|
|
254
327
|
}),
|
|
255
328
|
handleConferenceStarted: (0, _xstate.assign)({
|
|
256
329
|
consultInitiator: false
|
|
@@ -316,15 +389,32 @@ const actions = exports.actions = {
|
|
|
316
389
|
}
|
|
317
390
|
return {};
|
|
318
391
|
}),
|
|
319
|
-
clearConsultState: (0, _xstate.assign)({
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
392
|
+
clearConsultState: (0, _xstate.assign)(({
|
|
393
|
+
context,
|
|
394
|
+
event
|
|
395
|
+
}) => {
|
|
396
|
+
const cleared = {
|
|
397
|
+
consultDestinationType: null,
|
|
398
|
+
consultDestinationAgentId: null,
|
|
399
|
+
consultDestinationAgentJoined: false,
|
|
400
|
+
consultInitiator: false,
|
|
401
|
+
exitingConference: false,
|
|
402
|
+
consultCallHeld: false,
|
|
403
|
+
consultFromConference: false,
|
|
404
|
+
transferConferenceRequested: false
|
|
405
|
+
};
|
|
406
|
+
const taskData = context.taskData ?? getTaskDataFromEvent(event);
|
|
407
|
+
const selfAgentId = context.uiControlConfig.agentId ?? taskData?.agentId;
|
|
408
|
+
const nextContext = {
|
|
409
|
+
...context,
|
|
410
|
+
...cleared,
|
|
411
|
+
taskData
|
|
412
|
+
};
|
|
413
|
+
const inferredState = getTaskStateForUiControls(taskData, selfAgentId);
|
|
414
|
+
return {
|
|
415
|
+
...cleared,
|
|
416
|
+
uiControls: (0, _uiControlsComputer.computeUIControls)(inferredState, nextContext, taskData)
|
|
417
|
+
};
|
|
328
418
|
}),
|
|
329
419
|
setTransferConferenceRequested: (0, _xstate.assign)({
|
|
330
420
|
transferConferenceRequested: true
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["_xstate","require","_constants","_uiControlsComputer","_TaskUtils","_guards","determineConsultInitiator","taskData","selfAgentId","undefined","consultingAgentId","isConsulted","deriveRecordingState","callProcessingDetails","interaction","update","recordingStarted","recordInProgress","isPaused","recordingControlsAvailable","recordingInProgress","isActiveConsultState","state","INTERACTION_STATE","CONSULTING","selfParticipant","participants","hasConsultMedia","Object","values","media","some","mType","MEDIA_TYPE_CONSULT","isPendingOrActiveSelfConsult","consultState","CONSULT_STATE","POST_CALL","isSelfConsultingOrPending","hasJoinedConsultDestination","cpd","backendSaysJoined","consultDestinationAgentJoined","p","hasLeft","hasJoined","deriveConsultCallHeldFromTaskData","eventType","type","consultMediaId","consultMediaResourceId","consultMedia","find","m","Boolean","isHold","getTaskStateForUiControls","TaskState","IDLE","isTerminated","WRAPPING_UP","CONFERENCE","getIsConferenceInProgress","CONFERENCING","mainMediaId","mainInteractionId","interactionId","isMainHeld","HELD","CONNECTED","deriveTaskDataUpdates","context","updates","uiControlConfig","agentId","consultingActive","hasActiveConsultInPostCall","conferenceFromPayload","selfConsultingOrPending","inferredConsultingInitiator","destAgentId","isEpDnWithStoredId","consultDestinationType","consultDestinationAgentId","destinationType","consultInitiator","effectiveConsultInitiator","consultFromConference","joinedConsultee","hasEpDnParticipant","pType","consultCallHeld","nextContext","inferredState","uiControls","computeUIControls","getTaskDataFromEvent","event","createInitialContext","initialState","baseContext","exitingConference","transferConferenceRequested","getDefaultUIControls","updateUIControls","currentState","assign","actions","exports","initializeTask","updateTaskData","setConsultInitiator","TaskEvent","CONSULT","handleConsultFailed","handleConferenceStarted","setConsultDestination","destination","setConsultFromConference","forceConsultInitiator","setConsultAgentJoined","CONSULTING_ACTIVE","eventValue","setRecordingState","PAUSE_RECORDING","RESUME_RECORDING","clearConsultState","setTransferConferenceRequested","clearTransferConferenceRequested","setConsultCallHeld","clearConsultCallHeld","handleSwitchToMainCall","handleSwitchToConsult","handleConferenceFailed","handleParticipantLeft","setExitingConference","handleTransferConferenceSuccess","setHoldState","HOLD_SUCCESS","UNHOLD_SUCCESS","mediaResourceId","mediaEntry","updatedMedia","isConsultMedia","markEnded","requestAutoAnswer","requestCleanup","cleanupResources","emitTaskIncoming","emitTaskHydrate","emitTaskOfferContact","emitTaskAssigned","emitTaskHold","emitTaskResume","emitTaskEnd","emitTaskOfferConsult","emitTaskConsultCreated","emitTaskConsulting","emitTaskConsultAccepted","emitTaskConsultEnd","emitTaskReject","emitTaskWrapup","emitTaskRecordingStarted","emitTaskRecordingPaused","emitTaskRecordingResumed","emitTaskWrappedup","emitTaskParticipantLeft","emitTaskConferenceStarted","emitTaskConferenceEnded","emitTaskExitConference","emitTaskTransferConference","emitTaskSwitchCall","emitTaskConferenceFailed","emitTaskTransferConferenceFailed","emitTaskOutdialFailed"],"sources":["actions.ts"],"sourcesContent":["/**\n * Task State Machine Actions - Action implementations executed during state transitions\n */\n\nimport {assign} from 'xstate';\nimport {\n TaskContext,\n TaskEventPayload,\n UIControlConfig,\n TaskActionsMap,\n TaskActionArgs,\n RecordingStateUpdate,\n} from './types';\nimport {\n TaskEvent,\n TaskState,\n INTERACTION_STATE,\n CONSULT_STATE,\n MEDIA_TYPE_CONSULT,\n} from './constants';\nimport {DestinationType, TaskData} from '../types';\nimport {computeUIControls, getDefaultUIControls} from './uiControlsComputer';\nimport {getIsConferenceInProgress} from '../TaskUtils';\nimport {hasActiveConsultInPostCall} from './guards';\n\nconst determineConsultInitiator = (\n taskData: TaskData | undefined,\n selfAgentId: string | undefined\n): boolean | undefined => {\n if (!selfAgentId) return undefined;\n\n if (taskData?.consultingAgentId) {\n return taskData.consultingAgentId === selfAgentId;\n }\n\n if (taskData?.isConsulted === true) return false;\n\n return undefined;\n};\n\nconst deriveRecordingState = (taskData?: TaskData | null): RecordingStateUpdate => {\n const callProcessingDetails = taskData?.interaction?.callProcessingDetails;\n\n if (!callProcessingDetails) {\n return {};\n }\n\n const update: RecordingStateUpdate = {};\n const {recordingStarted, recordInProgress, isPaused} = callProcessingDetails as {\n recordingStarted?: boolean;\n recordInProgress?: boolean;\n isPaused?: boolean;\n };\n\n if (recordingStarted !== undefined) {\n update.recordingControlsAvailable = recordingStarted;\n if (!recordingStarted) {\n update.recordingInProgress = false;\n }\n }\n\n if (recordInProgress !== undefined) {\n update.recordingControlsAvailable = recordInProgress || recordingStarted || false;\n update.recordingInProgress = recordInProgress;\n }\n\n if (\n update.recordingControlsAvailable === undefined &&\n update.recordingInProgress === undefined &&\n recordingStarted\n ) {\n update.recordingControlsAvailable = true;\n update.recordingInProgress = true;\n }\n\n if (isPaused !== undefined) {\n update.recordingControlsAvailable = true;\n update.recordingInProgress = !isPaused;\n }\n\n return update;\n};\n\nconst isActiveConsultState = (taskData: TaskData | undefined, selfAgentId?: string): boolean => {\n if (taskData?.interaction?.state === INTERACTION_STATE.CONSULTING) return true;\n if (selfAgentId) {\n const selfParticipant = taskData?.interaction?.participants?.[selfAgentId] as any;\n const hasConsultMedia = Object.values(taskData?.interaction?.media ?? {}).some(\n (media: any) => media?.mType === MEDIA_TYPE_CONSULT\n );\n const isPendingOrActiveSelfConsult =\n selfParticipant?.consultState === CONSULT_STATE.CONSULTING ||\n selfParticipant?.consultState === 'consultInitiated';\n if (isPendingOrActiveSelfConsult && hasConsultMedia && taskData?.isConsulted === false) {\n return true;\n }\n }\n if (taskData?.interaction?.state === INTERACTION_STATE.POST_CALL && selfAgentId) {\n const selfParticipant = taskData.interaction?.participants?.[selfAgentId] as any;\n const hasConsultMedia = Object.values(taskData.interaction?.media ?? {}).some(\n (media: any) => media?.mType === MEDIA_TYPE_CONSULT\n );\n if (selfParticipant?.consultState === CONSULT_STATE.CONSULTING && hasConsultMedia) return true;\n }\n\n return false;\n};\n\nconst isSelfConsultingOrPending = (\n taskData: TaskData | undefined,\n selfAgentId?: string\n): boolean => {\n if (!taskData || !selfAgentId) return false;\n const selfParticipant = taskData?.interaction?.participants?.[selfAgentId] as any;\n\n return (\n selfParticipant?.consultState === CONSULT_STATE.CONSULTING ||\n selfParticipant?.consultState === 'consultInitiated'\n );\n};\n\nconst hasJoinedConsultDestination = (taskData: TaskData | undefined): boolean => {\n if (!taskData?.interaction) return false;\n const participants = taskData.interaction.participants as any;\n const cpd = taskData.interaction.callProcessingDetails as any;\n const backendSaysJoined = cpd?.consultDestinationAgentJoined === 'true';\n if (backendSaysJoined) return true;\n if (!participants) return false;\n\n return Object.values(participants).some((p: any) => {\n if (!p || p.isConsulted !== true || p.hasLeft) return false;\n\n return p.hasJoined === true || p.consultState === CONSULT_STATE.CONSULTING;\n });\n};\n\nconst deriveConsultCallHeldFromTaskData = (taskData: TaskData | undefined): boolean | undefined => {\n if (!taskData?.interaction) return undefined;\n\n const eventType = taskData.type;\n if (eventType === 'AgentContactHeld') return true;\n if (eventType === 'AgentContactUnheld') return false;\n\n const consultMediaId = taskData.consultMediaResourceId;\n\n const consultMedia: any = consultMediaId\n ? taskData.interaction.media?.[consultMediaId]\n : Object.values(taskData.interaction.media ?? {}).find(\n (m: any) => m?.mType === MEDIA_TYPE_CONSULT\n );\n\n if (!consultMedia) return undefined;\n\n return Boolean(consultMedia.isHold);\n};\n\nconst getTaskStateForUiControls = (\n taskData: TaskData | undefined,\n selfAgentId: string | undefined\n): TaskState => {\n if (!taskData?.interaction) {\n return TaskState.IDLE;\n }\n\n if (taskData.interaction.isTerminated === true) {\n return TaskState.WRAPPING_UP;\n }\n\n if (isActiveConsultState(taskData, selfAgentId)) {\n return TaskState.CONSULTING;\n }\n\n if (\n taskData.interaction.state === INTERACTION_STATE.CONFERENCE ||\n getIsConferenceInProgress(taskData)\n ) {\n return TaskState.CONFERENCING;\n }\n\n const mainMediaId = taskData.interaction.mainInteractionId || taskData.interactionId;\n const isMainHeld = Boolean(\n mainMediaId && taskData.interaction.media?.[mainMediaId]?.isHold === true\n );\n if (taskData.interaction.state === 'hold' || isMainHeld) {\n return TaskState.HELD;\n }\n\n return TaskState.CONNECTED;\n};\n\nconst deriveTaskDataUpdates = (context: TaskContext, taskData: TaskData | undefined) =>\n taskData\n ? (() => {\n const updates: Partial<TaskContext> = {\n taskData,\n ...deriveRecordingState(taskData),\n };\n\n const selfAgentId = context.uiControlConfig.agentId ?? taskData?.agentId;\n const consultingActive =\n isActiveConsultState(taskData, selfAgentId) ||\n hasActiveConsultInPostCall(taskData, selfAgentId);\n const conferenceFromPayload =\n taskData?.interaction?.state === INTERACTION_STATE.CONFERENCE ||\n getIsConferenceInProgress(taskData);\n const selfConsultingOrPending = isSelfConsultingOrPending(taskData, selfAgentId);\n const inferredConsultingInitiator =\n selfConsultingOrPending && taskData?.isConsulted === false;\n\n if (taskData.destAgentId) {\n const isEpDnWithStoredId =\n context.consultDestinationType === 'entryPoint' && context.consultDestinationAgentId;\n if (!isEpDnWithStoredId) {\n updates.consultDestinationAgentId = taskData.destAgentId;\n }\n }\n if (consultingActive && taskData.destinationType) {\n updates.consultDestinationType = taskData.destinationType as DestinationType;\n }\n\n if (!context.consultInitiator) {\n const consultInitiator = determineConsultInitiator(taskData, selfAgentId);\n if (consultInitiator !== undefined) {\n updates.consultInitiator = consultInitiator;\n } else if (\n inferredConsultingInitiator ||\n (consultingActive && taskData.isConsulted === false)\n ) {\n updates.consultInitiator = true;\n }\n }\n\n const effectiveConsultInitiator = updates.consultInitiator ?? context.consultInitiator;\n if (\n effectiveConsultInitiator &&\n conferenceFromPayload &&\n (consultingActive || selfConsultingOrPending || Boolean(taskData?.consultMediaResourceId))\n ) {\n updates.consultFromConference = true;\n }\n\n if (consultingActive && taskData.interaction) {\n const joinedConsultee = hasJoinedConsultDestination(taskData);\n if (joinedConsultee) updates.consultDestinationAgentJoined = true;\n\n if (!context.consultDestinationType && !updates.consultDestinationType) {\n const hasEpDnParticipant = Boolean(\n taskData.interaction.participants &&\n Object.values(taskData.interaction.participants).some(\n (p: any) => p?.pType === 'EP-DN' && !p?.hasLeft\n )\n );\n if (hasEpDnParticipant) updates.consultDestinationType = 'entryPoint' as any;\n }\n\n if (effectiveConsultInitiator) {\n const consultCallHeld = deriveConsultCallHeldFromTaskData(taskData);\n if (consultCallHeld !== undefined) {\n updates.consultCallHeld = consultCallHeld;\n }\n }\n }\n\n const nextContext = {\n ...context,\n ...updates,\n } as TaskContext;\n const inferredState = getTaskStateForUiControls(taskData, selfAgentId);\n\n updates.uiControls = computeUIControls(inferredState, nextContext, taskData);\n\n return updates;\n })()\n : {};\n\nconst getTaskDataFromEvent = (event?: TaskEventPayload): TaskData | undefined =>\n event && typeof event === 'object' ? (event as any).taskData : undefined;\n\nexport function createInitialContext(\n uiControlConfig: UIControlConfig,\n initialState: TaskState = TaskState.IDLE\n): TaskContext {\n const baseContext: TaskContext = {\n taskData: null,\n consultInitiator: false,\n exitingConference: false,\n consultFromConference: false,\n transferConferenceRequested: false,\n consultDestinationType: null,\n consultDestinationAgentId: null,\n consultDestinationAgentJoined: false,\n consultCallHeld: false,\n recordingControlsAvailable: false,\n recordingInProgress: false,\n uiControlConfig,\n uiControls: getDefaultUIControls(),\n };\n\n baseContext.uiControls = computeUIControls(initialState, baseContext);\n\n return baseContext;\n}\n\nexport function updateUIControls(currentState: TaskState) {\n return assign(({context}: TaskActionArgs) => ({\n uiControls: computeUIControls(currentState, context),\n }));\n}\n\nexport const actions: TaskActionsMap = {\n initializeTask: assign(({context, event}: {context: TaskContext; event: TaskEventPayload}) => {\n return {\n consultInitiator: false,\n exitingConference: false,\n consultDestinationType: null,\n consultDestinationAgentJoined: false,\n ...deriveTaskDataUpdates(context, getTaskDataFromEvent(event)),\n };\n }),\n\n /**\n * Update task data from ASSIGN event\n */\n updateTaskData: assign(({context, event}: TaskActionArgs) => {\n return deriveTaskDataUpdates(context, getTaskDataFromEvent(event));\n }),\n\n /**\n * Set consult initiator flag\n *\n * IMPORTANT: This action is called for CONSULT (user action) and CONSULT_CREATED (backend event).\n * For CONSULT (user action): The user explicitly clicked Consult, so they ARE the initiator.\n * For CONSULT_CREATED (backend event): Check taskData.isConsulted to determine if this agent\n * is the initiator. If isConsulted === true, this is Agent B (the consulted party), NOT the initiator.\n *\n * This prevents all agents in a conference from becoming consultInitiator when one agent\n * starts a new consult.\n */\n setConsultInitiator: assign(({event}: TaskActionArgs) => {\n const taskData = getTaskDataFromEvent(event);\n\n if (event.type === TaskEvent.CONSULT) return {consultInitiator: true};\n\n const selfAgentId = taskData?.agentId;\n const consultInitiator = determineConsultInitiator(taskData, selfAgentId);\n if (consultInitiator === true) return {consultInitiator: true};\n if (consultInitiator === false) return {consultInitiator: false};\n\n return {};\n }),\n\n handleConsultFailed: assign({consultDestinationAgentJoined: false, consultInitiator: false}),\n handleConferenceStarted: assign({consultInitiator: false}),\n\n setConsultDestination: assign(({event}: TaskActionArgs) => {\n if (!event || event.type !== TaskEvent.CONSULT) {\n return {};\n }\n\n const taskData = getTaskDataFromEvent(event);\n const consultDestinationType =\n 'destinationType' in event ? event.destinationType ?? null : null;\n const consultDestinationAgentId =\n ('destAgentId' in event ? event.destAgentId : null) ??\n ('destination' in event ? (event as any).destination : null) ??\n null;\n\n return {\n consultDestinationType,\n consultDestinationAgentId,\n consultDestinationAgentJoined: false,\n consultFromConference: false,\n taskData: {\n ...taskData,\n destAgentId: consultDestinationAgentId,\n },\n };\n }),\n\n setConsultFromConference: assign({consultFromConference: true}),\n\n forceConsultInitiator: assign({consultInitiator: true}),\n\n setConsultAgentJoined: assign(\n ({context, event}: {context: TaskContext; event: TaskEventPayload}) => {\n if (context.consultDestinationAgentJoined) {\n return {};\n }\n\n if (\n !event ||\n event.type !== TaskEvent.CONSULTING_ACTIVE ||\n !('consultDestinationAgentJoined' in event)\n ) {\n return {};\n }\n\n const eventValue = (event as {consultDestinationAgentJoined: boolean})\n .consultDestinationAgentJoined;\n\n return eventValue ? {consultDestinationAgentJoined: true} : {};\n }\n ),\n\n setRecordingState: assign(({event}: TaskActionArgs) => {\n if (!event || !('type' in event)) {\n return {};\n }\n\n if (event.type === TaskEvent.PAUSE_RECORDING) {\n return {\n recordingControlsAvailable: true,\n recordingInProgress: false,\n };\n }\n if (event.type === TaskEvent.RESUME_RECORDING) {\n return {\n recordingControlsAvailable: true,\n recordingInProgress: true,\n };\n }\n\n return {};\n }),\n\n clearConsultState: assign({\n consultDestinationType: null,\n consultDestinationAgentId: null,\n consultDestinationAgentJoined: false,\n consultInitiator: false,\n exitingConference: false,\n consultCallHeld: false,\n consultFromConference: false,\n transferConferenceRequested: false,\n }),\n\n setTransferConferenceRequested: assign({transferConferenceRequested: true}),\n clearTransferConferenceRequested: assign({transferConferenceRequested: false}),\n\n setConsultCallHeld: assign({consultCallHeld: true}),\n clearConsultCallHeld: assign({consultCallHeld: false}),\n handleSwitchToMainCall: assign({consultCallHeld: true}),\n handleSwitchToConsult: assign({consultCallHeld: false}),\n\n handleConferenceFailed: assign(({event}: TaskActionArgs) => {\n const taskData = getTaskDataFromEvent(event);\n\n return taskData ? {taskData} : {};\n }),\n handleParticipantLeft: assign(({event}: TaskActionArgs) => {\n const taskData = getTaskDataFromEvent(event);\n\n return taskData ? {taskData} : {};\n }),\n\n setExitingConference: assign({exitingConference: true}),\n\n handleTransferConferenceSuccess: assign(({event}: TaskActionArgs) => {\n const taskData = getTaskDataFromEvent(event);\n\n return taskData ? {taskData} : {};\n }),\n\n setHoldState: assign(({context, event}: TaskActionArgs) => {\n if (\n !event ||\n (event.type !== TaskEvent.HOLD_SUCCESS && event.type !== TaskEvent.UNHOLD_SUCCESS)\n ) {\n return {};\n }\n\n const mediaResourceId =\n 'mediaResourceId' in event\n ? (event as {mediaResourceId?: string}).mediaResourceId\n : undefined;\n\n if (!mediaResourceId) {\n return {};\n }\n\n const interaction = context.taskData?.interaction;\n const mediaEntry = interaction?.media?.[mediaResourceId];\n\n if (!interaction || !mediaEntry) {\n return {};\n }\n\n const updatedMedia = {\n ...interaction.media,\n [mediaResourceId]: {\n ...mediaEntry,\n isHold: event.type === TaskEvent.HOLD_SUCCESS,\n },\n };\n\n const updates: Partial<TaskContext> = {\n taskData: {\n ...(context.taskData as TaskData),\n interaction: {\n ...interaction,\n media: updatedMedia,\n },\n },\n };\n\n const consultMediaId = context.taskData?.consultMediaResourceId;\n const isConsultMedia = consultMediaId\n ? mediaResourceId === consultMediaId\n : mediaEntry?.mType === 'consult';\n\n if (isConsultMedia && context.consultInitiator) {\n updates.consultCallHeld = event.type === TaskEvent.HOLD_SUCCESS;\n }\n\n return updates;\n }),\n\n markEnded: assign(() => ({\n recordingControlsAvailable: false,\n recordingInProgress: false,\n })),\n\n requestAutoAnswer: () => undefined,\n requestCleanup: () => undefined,\n cleanupResources: () => undefined,\n\n // Event emitters - placeholders overridden by consumers\n emitTaskIncoming: () => undefined,\n emitTaskHydrate: () => undefined,\n emitTaskOfferContact: () => undefined,\n emitTaskAssigned: () => undefined,\n emitTaskHold: () => undefined,\n emitTaskResume: () => undefined,\n emitTaskEnd: () => undefined,\n emitTaskOfferConsult: () => undefined,\n emitTaskConsultCreated: () => undefined,\n emitTaskConsulting: () => undefined,\n emitTaskConsultAccepted: () => undefined,\n emitTaskConsultEnd: () => undefined,\n emitTaskReject: () => undefined,\n emitTaskWrapup: () => undefined,\n emitTaskRecordingStarted: () => undefined,\n emitTaskRecordingPaused: () => undefined,\n emitTaskRecordingResumed: () => undefined,\n emitTaskWrappedup: () => undefined,\n emitTaskParticipantLeft: () => undefined,\n emitTaskConferenceStarted: () => undefined,\n emitTaskConferenceEnded: () => undefined,\n emitTaskExitConference: () => undefined,\n emitTaskTransferConference: () => undefined,\n emitTaskSwitchCall: () => undefined,\n emitTaskConferenceFailed: () => undefined,\n emitTaskTransferConferenceFailed: () => undefined,\n emitTaskOutdialFailed: () => undefined,\n};\n"],"mappings":"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","ignoreList":[]}
|
|
1
|
+
{"version":3,"names":["_xstate","require","_constants","_uiControlsComputer","_TaskUtils","_guards","determineConsultInitiator","taskData","selfAgentId","undefined","consultingAgentId","isConsulted","deriveRecordingState","callProcessingDetails","interaction","update","recordingStarted","recordInProgress","isPaused","recordingControlsAvailable","recordingInProgress","isActiveConsultState","state","INTERACTION_STATE","CONSULTING","selfParticipant","participants","hasConsultMedia","Object","values","media","some","mType","MEDIA_TYPE_CONSULT","consultState","hasJoinedConsultDestination","CONSULT_STATE","POST_CALL","isSelfConsultingOrPending","isDnOnConsultMedia","consultMedia","consultMediaResourceId","find","m","consultParticipantIds","Set","size","p","hasLeft","id","has","pType","String","toUpperCase","mapConsultDestinationType","destinationType","normalized","cpd","backendSaysJoined","consultDestinationAgentJoined","effectiveSelfAgentId","agentId","type","hasJoined","deriveConsultCallHeldFromTaskData","eventType","consultMediaId","Boolean","isHold","getTaskStateForUiControls","TaskState","IDLE","isTerminated","WRAPPING_UP","CONFERENCE","getIsConferenceInProgress","CONFERENCING","mainMediaId","mainInteractionId","interactionId","isMainHeld","HELD","CONNECTED","exports","deriveTaskDataUpdates","context","updates","uiControlConfig","consultingActive","hasActiveConsultInPostCall","conferenceFromPayload","selfConsultingOrPending","inferredConsultingInitiator","destAgentId","isEpDnWithStoredId","consultDestinationType","consultDestinationAgentId","isConsultTerminalEvent","consultInitiator","consultFromConference","consultCallHeld","transferConferenceRequested","effectiveConsultInitiator","joinedConsultee","agentConsultingSelfJoined","hasEpDnParticipant","nextContext","inferredState","uiControls","computeUIControls","getTaskDataFromEvent","event","createInitialContext","initialState","baseContext","exitingConference","getDefaultUIControls","updateUIControls","currentState","assign","actions","initializeTask","updateTaskData","setConsultInitiator","TaskEvent","CONSULT","handleConsultFailed","cleared","handleConferenceStarted","setConsultDestination","destination","setConsultFromConference","forceConsultInitiator","setConsultAgentJoined","CONSULTING_ACTIVE","eventValue","setRecordingState","PAUSE_RECORDING","RESUME_RECORDING","clearConsultState","setTransferConferenceRequested","clearTransferConferenceRequested","setConsultCallHeld","clearConsultCallHeld","handleSwitchToMainCall","handleSwitchToConsult","handleConferenceFailed","handleParticipantLeft","setExitingConference","handleTransferConferenceSuccess","setHoldState","HOLD_SUCCESS","UNHOLD_SUCCESS","mediaResourceId","mediaEntry","updatedMedia","isConsultMedia","markEnded","requestAutoAnswer","requestCleanup","cleanupResources","emitTaskIncoming","emitTaskHydrate","emitTaskOfferContact","emitTaskAssigned","emitTaskHold","emitTaskResume","emitTaskEnd","emitTaskOfferConsult","emitTaskConsultCreated","emitTaskConsulting","emitTaskConsultAccepted","emitTaskConsultEnd","emitTaskReject","emitTaskWrapup","emitTaskRecordingStarted","emitTaskRecordingPaused","emitTaskRecordingResumed","emitTaskWrappedup","emitTaskParticipantLeft","emitTaskConferenceStarted","emitTaskConferenceEnded","emitTaskExitConference","emitTaskTransferConference","emitTaskSwitchCall","emitTaskConferenceFailed","emitTaskTransferConferenceFailed","emitTaskOutdialFailed"],"sources":["actions.ts"],"sourcesContent":["/**\n * Task State Machine Actions - Action implementations executed during state transitions\n */\n\nimport {assign} from 'xstate';\nimport {\n TaskContext,\n TaskEventPayload,\n UIControlConfig,\n TaskActionsMap,\n TaskActionArgs,\n RecordingStateUpdate,\n} from './types';\nimport {\n TaskEvent,\n TaskState,\n INTERACTION_STATE,\n CONSULT_STATE,\n MEDIA_TYPE_CONSULT,\n} from './constants';\nimport {DestinationType, TaskData} from '../types';\nimport {computeUIControls, getDefaultUIControls} from './uiControlsComputer';\nimport {getIsConferenceInProgress} from '../TaskUtils';\nimport {hasActiveConsultInPostCall} from './guards';\n\nconst determineConsultInitiator = (\n taskData: TaskData | undefined,\n selfAgentId: string | undefined\n): boolean | undefined => {\n if (!selfAgentId) return undefined;\n\n if (taskData?.consultingAgentId) {\n return taskData.consultingAgentId === selfAgentId;\n }\n\n if (taskData?.isConsulted === true) return false;\n\n return undefined;\n};\n\nconst deriveRecordingState = (taskData?: TaskData | null): RecordingStateUpdate => {\n const callProcessingDetails = taskData?.interaction?.callProcessingDetails;\n\n if (!callProcessingDetails) {\n return {};\n }\n\n const update: RecordingStateUpdate = {};\n const {recordingStarted, recordInProgress, isPaused} = callProcessingDetails as {\n recordingStarted?: boolean;\n recordInProgress?: boolean;\n isPaused?: boolean;\n };\n\n if (recordingStarted !== undefined) {\n update.recordingControlsAvailable = recordingStarted;\n if (!recordingStarted) {\n update.recordingInProgress = false;\n }\n }\n\n if (recordInProgress !== undefined) {\n update.recordingControlsAvailable = recordInProgress || recordingStarted || false;\n update.recordingInProgress = recordInProgress;\n }\n\n if (\n update.recordingControlsAvailable === undefined &&\n update.recordingInProgress === undefined &&\n recordingStarted\n ) {\n update.recordingControlsAvailable = true;\n update.recordingInProgress = true;\n }\n\n if (isPaused !== undefined) {\n update.recordingControlsAvailable = true;\n update.recordingInProgress = !isPaused;\n }\n\n return update;\n};\n\nconst isActiveConsultState = (taskData: TaskData | undefined, selfAgentId?: string): boolean => {\n if (taskData?.interaction?.state === INTERACTION_STATE.CONSULTING) return true;\n if (selfAgentId) {\n const selfParticipant = taskData?.interaction?.participants?.[selfAgentId] as any;\n const hasConsultMedia = Object.values(taskData?.interaction?.media ?? {}).some(\n (media: any) => media?.mType === MEDIA_TYPE_CONSULT\n );\n // Pending consult before destination joins stays HELD, not CONSULTING.\n if (\n selfParticipant?.consultState === 'consultInitiated' &&\n !hasJoinedConsultDestination(taskData, selfAgentId) &&\n hasConsultMedia &&\n taskData?.isConsulted === false\n ) {\n return false;\n }\n if (\n selfParticipant?.consultState === CONSULT_STATE.CONSULTING &&\n hasConsultMedia &&\n taskData?.isConsulted === false\n ) {\n return true;\n }\n }\n if (taskData?.interaction?.state === INTERACTION_STATE.POST_CALL && selfAgentId) {\n const selfParticipant = taskData.interaction?.participants?.[selfAgentId] as any;\n const hasConsultMedia = Object.values(taskData.interaction?.media ?? {}).some(\n (media: any) => media?.mType === MEDIA_TYPE_CONSULT\n );\n if (selfParticipant?.consultState === CONSULT_STATE.CONSULTING && hasConsultMedia) return true;\n }\n\n return false;\n};\n\nconst isSelfConsultingOrPending = (\n taskData: TaskData | undefined,\n selfAgentId?: string\n): boolean => {\n if (!taskData || !selfAgentId) return false;\n const selfParticipant = taskData?.interaction?.participants?.[selfAgentId] as any;\n\n return (\n selfParticipant?.consultState === CONSULT_STATE.CONSULTING ||\n selfParticipant?.consultState === 'consultInitiated'\n );\n};\n\nconst isDnOnConsultMedia = (taskData: TaskData | undefined, selfAgentId?: string): boolean => {\n if (!taskData?.interaction?.participants) return false;\n\n const consultMedia: any = taskData.consultMediaResourceId\n ? taskData.interaction.media?.[taskData.consultMediaResourceId]\n : Object.values(taskData.interaction.media ?? {}).find(\n (m: any) => m?.mType === MEDIA_TYPE_CONSULT\n );\n const consultParticipantIds = new Set(consultMedia?.participants ?? []);\n if (consultParticipantIds.size === 0) return false;\n\n return Object.values(taskData.interaction.participants).some((p: any) => {\n if (!p || p.hasLeft || p.id === selfAgentId) return false;\n if (!consultParticipantIds.has(p.id)) return false;\n const pType = String(p.pType ?? '').toUpperCase();\n\n return pType === 'DN' || pType === 'EP-DN' || pType === 'EP_DN';\n });\n};\n\nconst mapConsultDestinationType = (\n destinationType: string | undefined\n): DestinationType | undefined => {\n if (!destinationType) return undefined;\n const normalized = String(destinationType).toUpperCase();\n if (normalized === 'DN' || normalized === 'EP-DN' || normalized === 'EP_DN') {\n return 'entryPoint' as DestinationType;\n }\n\n return destinationType as DestinationType;\n};\n\nconst hasJoinedConsultDestination = (\n taskData: TaskData | undefined,\n selfAgentId?: string\n): boolean => {\n if (!taskData?.interaction) return false;\n const participants = taskData.interaction.participants as any;\n const cpd = taskData.interaction.callProcessingDetails as any;\n const backendSaysJoined = cpd?.consultDestinationAgentJoined === 'true';\n if (backendSaysJoined) return true;\n if (!participants) return false;\n\n const effectiveSelfAgentId = selfAgentId ?? taskData.agentId;\n const selfParticipant = effectiveSelfAgentId\n ? (participants[effectiveSelfAgentId] as {consultState?: string} | undefined)\n : undefined;\n\n if (\n taskData.type === 'AgentConsulting' &&\n selfParticipant?.consultState === CONSULT_STATE.CONSULTING &&\n taskData.isConsulted === false &&\n isDnOnConsultMedia(taskData, effectiveSelfAgentId)\n ) {\n return true;\n }\n\n return Object.values(participants).some((p: any) => {\n if (!p || p.isConsulted !== true || p.hasLeft) return false;\n\n return p.hasJoined === true || p.consultState === CONSULT_STATE.CONSULTING;\n });\n};\n\nconst deriveConsultCallHeldFromTaskData = (taskData: TaskData | undefined): boolean | undefined => {\n if (!taskData?.interaction) return undefined;\n\n const eventType = taskData.type;\n if (eventType === 'AgentContactHeld') return true;\n if (eventType === 'AgentContactUnheld') return false;\n\n const consultMediaId = taskData.consultMediaResourceId;\n\n const consultMedia: any = consultMediaId\n ? taskData.interaction.media?.[consultMediaId]\n : Object.values(taskData.interaction.media ?? {}).find(\n (m: any) => m?.mType === MEDIA_TYPE_CONSULT\n );\n\n if (!consultMedia) return undefined;\n\n return Boolean(consultMedia.isHold);\n};\n\nexport const getTaskStateForUiControls = (\n taskData: TaskData | undefined,\n selfAgentId: string | undefined\n): TaskState => {\n if (!taskData?.interaction) {\n return TaskState.IDLE;\n }\n\n if (taskData.interaction.isTerminated === true) {\n return TaskState.WRAPPING_UP;\n }\n\n if (isActiveConsultState(taskData, selfAgentId)) {\n return TaskState.CONSULTING;\n }\n\n if (\n taskData.interaction.state === INTERACTION_STATE.CONFERENCE ||\n getIsConferenceInProgress(taskData)\n ) {\n return TaskState.CONFERENCING;\n }\n\n const mainMediaId = taskData.interaction.mainInteractionId || taskData.interactionId;\n const isMainHeld = Boolean(\n mainMediaId && taskData.interaction.media?.[mainMediaId]?.isHold === true\n );\n if (taskData.interaction.state === 'hold' || isMainHeld) {\n return TaskState.HELD;\n }\n\n return TaskState.CONNECTED;\n};\n\nconst deriveTaskDataUpdates = (context: TaskContext, taskData: TaskData | undefined) =>\n taskData\n ? (() => {\n const updates: Partial<TaskContext> = {\n taskData,\n ...deriveRecordingState(taskData),\n };\n\n const selfAgentId = context.uiControlConfig.agentId ?? taskData?.agentId;\n const consultingActive =\n isActiveConsultState(taskData, selfAgentId) ||\n hasActiveConsultInPostCall(taskData, selfAgentId);\n const conferenceFromPayload =\n taskData?.interaction?.state === INTERACTION_STATE.CONFERENCE ||\n getIsConferenceInProgress(taskData);\n const selfConsultingOrPending = isSelfConsultingOrPending(taskData, selfAgentId);\n const inferredConsultingInitiator =\n selfConsultingOrPending && taskData?.isConsulted === false;\n\n if (taskData.destAgentId) {\n const isEpDnWithStoredId =\n context.consultDestinationType === 'entryPoint' && context.consultDestinationAgentId;\n if (!isEpDnWithStoredId) {\n updates.consultDestinationAgentId = taskData.destAgentId;\n }\n }\n\n const isConsultTerminalEvent =\n taskData.type === 'AgentConsultEnded' || taskData.type === 'AgentConsultFailed';\n\n if (isConsultTerminalEvent) {\n updates.consultInitiator = false;\n updates.consultFromConference = false;\n updates.consultDestinationAgentJoined = false;\n updates.consultCallHeld = false;\n updates.consultDestinationType = null;\n updates.consultDestinationAgentId = null;\n updates.transferConferenceRequested = false;\n }\n\n if (consultingActive && taskData.destinationType) {\n updates.consultDestinationType = mapConsultDestinationType(taskData.destinationType);\n }\n\n if (!isConsultTerminalEvent && !context.consultInitiator) {\n const consultInitiator = determineConsultInitiator(taskData, selfAgentId);\n if (consultInitiator !== undefined) {\n updates.consultInitiator = consultInitiator;\n } else if (\n inferredConsultingInitiator ||\n (consultingActive && taskData.isConsulted === false)\n ) {\n updates.consultInitiator = true;\n }\n }\n\n const effectiveConsultInitiator = updates.consultInitiator ?? context.consultInitiator;\n if (\n !isConsultTerminalEvent &&\n effectiveConsultInitiator &&\n conferenceFromPayload &&\n (consultingActive || selfConsultingOrPending || Boolean(taskData?.consultMediaResourceId))\n ) {\n updates.consultFromConference = true;\n }\n\n if (\n !isConsultTerminalEvent &&\n (consultingActive || selfConsultingOrPending) &&\n taskData.interaction\n ) {\n const joinedConsultee = hasJoinedConsultDestination(taskData, selfAgentId);\n const selfParticipant = selfAgentId\n ? (taskData.interaction.participants?.[selfAgentId] as\n | {consultState?: string}\n | undefined)\n : undefined;\n const agentConsultingSelfJoined =\n taskData.type === 'AgentConsulting' &&\n effectiveConsultInitiator &&\n selfParticipant?.consultState === CONSULT_STATE.CONSULTING;\n\n if (joinedConsultee || agentConsultingSelfJoined) {\n updates.consultDestinationAgentJoined = true;\n } else if (selfParticipant?.consultState === 'consultInitiated') {\n updates.consultDestinationAgentJoined = false;\n }\n\n if (!context.consultDestinationType && !updates.consultDestinationType) {\n const hasEpDnParticipant = Boolean(\n taskData.interaction.participants &&\n Object.values(taskData.interaction.participants).some((p: any) => {\n if (p?.hasLeft) return false;\n const pType = String(p?.pType ?? '').toUpperCase();\n\n return pType === 'EP-DN' || pType === 'EP_DN' || pType === 'DN';\n })\n );\n if (hasEpDnParticipant) updates.consultDestinationType = 'entryPoint' as any;\n }\n\n if (effectiveConsultInitiator) {\n const consultCallHeld = deriveConsultCallHeldFromTaskData(taskData);\n if (consultCallHeld !== undefined) {\n updates.consultCallHeld = consultCallHeld;\n }\n }\n }\n\n const nextContext = {\n ...context,\n ...updates,\n } as TaskContext;\n const inferredState = getTaskStateForUiControls(taskData, selfAgentId);\n\n updates.uiControls = computeUIControls(inferredState, nextContext, taskData);\n\n return updates;\n })()\n : {};\n\nconst getTaskDataFromEvent = (event?: TaskEventPayload): TaskData | undefined =>\n event && typeof event === 'object' ? (event as any).taskData : undefined;\n\nexport function createInitialContext(\n uiControlConfig: UIControlConfig,\n initialState: TaskState = TaskState.IDLE\n): TaskContext {\n const baseContext: TaskContext = {\n taskData: null,\n consultInitiator: false,\n exitingConference: false,\n consultFromConference: false,\n transferConferenceRequested: false,\n consultDestinationType: null,\n consultDestinationAgentId: null,\n consultDestinationAgentJoined: false,\n consultCallHeld: false,\n recordingControlsAvailable: false,\n recordingInProgress: false,\n uiControlConfig,\n uiControls: getDefaultUIControls(),\n };\n\n baseContext.uiControls = computeUIControls(initialState, baseContext);\n\n return baseContext;\n}\n\nexport function updateUIControls(currentState: TaskState) {\n return assign(({context}: TaskActionArgs) => ({\n uiControls: computeUIControls(currentState, context, context.taskData ?? undefined),\n }));\n}\n\nexport const actions: TaskActionsMap = {\n initializeTask: assign(({context, event}: {context: TaskContext; event: TaskEventPayload}) => {\n return {\n consultInitiator: false,\n exitingConference: false,\n consultDestinationType: null,\n consultDestinationAgentJoined: false,\n ...deriveTaskDataUpdates(context, getTaskDataFromEvent(event)),\n };\n }),\n\n /**\n * Update task data from ASSIGN event\n */\n updateTaskData: assign(({context, event}: TaskActionArgs) => {\n return deriveTaskDataUpdates(context, getTaskDataFromEvent(event));\n }),\n\n /**\n * Set consult initiator flag\n *\n * IMPORTANT: This action is called for CONSULT (user action) and CONSULT_CREATED (backend event).\n * For CONSULT (user action): The user explicitly clicked Consult, so they ARE the initiator.\n * For CONSULT_CREATED (backend event): Check taskData.isConsulted to determine if this agent\n * is the initiator. If isConsulted === true, this is Agent B (the consulted party), NOT the initiator.\n *\n * This prevents all agents in a conference from becoming consultInitiator when one agent\n * starts a new consult.\n */\n setConsultInitiator: assign(({event}: TaskActionArgs) => {\n const taskData = getTaskDataFromEvent(event);\n\n if (event.type === TaskEvent.CONSULT) return {consultInitiator: true};\n\n const selfAgentId = taskData?.agentId;\n const consultInitiator = determineConsultInitiator(taskData, selfAgentId);\n if (consultInitiator === true) return {consultInitiator: true};\n if (consultInitiator === false) return {consultInitiator: false};\n\n return {};\n }),\n\n handleConsultFailed: assign(({context, event}: TaskActionArgs) => {\n const taskData = getTaskDataFromEvent(event) ?? context.taskData;\n const cleared = {\n consultDestinationType: null,\n consultDestinationAgentId: null,\n consultDestinationAgentJoined: false,\n consultInitiator: false,\n exitingConference: false,\n consultCallHeld: false,\n consultFromConference: false,\n transferConferenceRequested: false,\n };\n const selfAgentId = context.uiControlConfig.agentId ?? taskData?.agentId;\n const nextContext = {...context, ...cleared, taskData} as TaskContext;\n const inferredState = getTaskStateForUiControls(taskData, selfAgentId);\n\n return {\n ...cleared,\n uiControls: computeUIControls(inferredState, nextContext, taskData),\n };\n }),\n handleConferenceStarted: assign({consultInitiator: false}),\n\n setConsultDestination: assign(({event}: TaskActionArgs) => {\n if (!event || event.type !== TaskEvent.CONSULT) {\n return {};\n }\n\n const taskData = getTaskDataFromEvent(event);\n const consultDestinationType =\n 'destinationType' in event ? event.destinationType ?? null : null;\n const consultDestinationAgentId =\n ('destAgentId' in event ? event.destAgentId : null) ??\n ('destination' in event ? (event as any).destination : null) ??\n null;\n\n return {\n consultDestinationType,\n consultDestinationAgentId,\n consultDestinationAgentJoined: false,\n consultFromConference: false,\n taskData: {\n ...taskData,\n destAgentId: consultDestinationAgentId,\n },\n };\n }),\n\n setConsultFromConference: assign({consultFromConference: true}),\n\n forceConsultInitiator: assign({consultInitiator: true}),\n\n setConsultAgentJoined: assign(\n ({context, event}: {context: TaskContext; event: TaskEventPayload}) => {\n if (context.consultDestinationAgentJoined) {\n return {};\n }\n\n if (\n !event ||\n event.type !== TaskEvent.CONSULTING_ACTIVE ||\n !('consultDestinationAgentJoined' in event)\n ) {\n return {};\n }\n\n const eventValue = (event as {consultDestinationAgentJoined: boolean})\n .consultDestinationAgentJoined;\n\n return eventValue ? {consultDestinationAgentJoined: true} : {};\n }\n ),\n\n setRecordingState: assign(({event}: TaskActionArgs) => {\n if (!event || !('type' in event)) {\n return {};\n }\n\n if (event.type === TaskEvent.PAUSE_RECORDING) {\n return {\n recordingControlsAvailable: true,\n recordingInProgress: false,\n };\n }\n if (event.type === TaskEvent.RESUME_RECORDING) {\n return {\n recordingControlsAvailable: true,\n recordingInProgress: true,\n };\n }\n\n return {};\n }),\n\n clearConsultState: assign(({context, event}: TaskActionArgs) => {\n const cleared = {\n consultDestinationType: null,\n consultDestinationAgentId: null,\n consultDestinationAgentJoined: false,\n consultInitiator: false,\n exitingConference: false,\n consultCallHeld: false,\n consultFromConference: false,\n transferConferenceRequested: false,\n };\n const taskData = context.taskData ?? getTaskDataFromEvent(event);\n const selfAgentId = context.uiControlConfig.agentId ?? taskData?.agentId;\n const nextContext = {...context, ...cleared, taskData} as TaskContext;\n const inferredState = getTaskStateForUiControls(taskData, selfAgentId);\n\n return {\n ...cleared,\n uiControls: computeUIControls(inferredState, nextContext, taskData),\n };\n }),\n\n setTransferConferenceRequested: assign({transferConferenceRequested: true}),\n clearTransferConferenceRequested: assign({transferConferenceRequested: false}),\n\n setConsultCallHeld: assign({consultCallHeld: true}),\n clearConsultCallHeld: assign({consultCallHeld: false}),\n handleSwitchToMainCall: assign({consultCallHeld: true}),\n handleSwitchToConsult: assign({consultCallHeld: false}),\n\n handleConferenceFailed: assign(({event}: TaskActionArgs) => {\n const taskData = getTaskDataFromEvent(event);\n\n return taskData ? {taskData} : {};\n }),\n handleParticipantLeft: assign(({event}: TaskActionArgs) => {\n const taskData = getTaskDataFromEvent(event);\n\n return taskData ? {taskData} : {};\n }),\n\n setExitingConference: assign({exitingConference: true}),\n\n handleTransferConferenceSuccess: assign(({event}: TaskActionArgs) => {\n const taskData = getTaskDataFromEvent(event);\n\n return taskData ? {taskData} : {};\n }),\n\n setHoldState: assign(({context, event}: TaskActionArgs) => {\n if (\n !event ||\n (event.type !== TaskEvent.HOLD_SUCCESS && event.type !== TaskEvent.UNHOLD_SUCCESS)\n ) {\n return {};\n }\n\n const mediaResourceId =\n 'mediaResourceId' in event\n ? (event as {mediaResourceId?: string}).mediaResourceId\n : undefined;\n\n if (!mediaResourceId) {\n return {};\n }\n\n const interaction = context.taskData?.interaction;\n const mediaEntry = interaction?.media?.[mediaResourceId];\n\n if (!interaction || !mediaEntry) {\n return {};\n }\n\n const updatedMedia = {\n ...interaction.media,\n [mediaResourceId]: {\n ...mediaEntry,\n isHold: event.type === TaskEvent.HOLD_SUCCESS,\n },\n };\n\n const updates: Partial<TaskContext> = {\n taskData: {\n ...(context.taskData as TaskData),\n interaction: {\n ...interaction,\n media: updatedMedia,\n },\n },\n };\n\n const consultMediaId = context.taskData?.consultMediaResourceId;\n const isConsultMedia = consultMediaId\n ? mediaResourceId === consultMediaId\n : mediaEntry?.mType === 'consult';\n\n if (isConsultMedia && context.consultInitiator) {\n updates.consultCallHeld = event.type === TaskEvent.HOLD_SUCCESS;\n }\n\n return updates;\n }),\n\n markEnded: assign(() => ({\n recordingControlsAvailable: false,\n recordingInProgress: false,\n })),\n\n requestAutoAnswer: () => undefined,\n requestCleanup: () => undefined,\n cleanupResources: () => undefined,\n\n // Event emitters - placeholders overridden by consumers\n emitTaskIncoming: () => undefined,\n emitTaskHydrate: () => undefined,\n emitTaskOfferContact: () => undefined,\n emitTaskAssigned: () => undefined,\n emitTaskHold: () => undefined,\n emitTaskResume: () => undefined,\n emitTaskEnd: () => undefined,\n emitTaskOfferConsult: () => undefined,\n emitTaskConsultCreated: () => undefined,\n emitTaskConsulting: () => undefined,\n emitTaskConsultAccepted: () => undefined,\n emitTaskConsultEnd: () => undefined,\n emitTaskReject: () => undefined,\n emitTaskWrapup: () => undefined,\n emitTaskRecordingStarted: () => undefined,\n emitTaskRecordingPaused: () => undefined,\n emitTaskRecordingResumed: () => undefined,\n emitTaskWrappedup: () => undefined,\n emitTaskParticipantLeft: () => undefined,\n emitTaskConferenceStarted: () => undefined,\n emitTaskConferenceEnded: () => undefined,\n emitTaskExitConference: () => undefined,\n emitTaskTransferConference: () => undefined,\n emitTaskSwitchCall: () => undefined,\n emitTaskConferenceFailed: () => undefined,\n emitTaskTransferConferenceFailed: () => undefined,\n emitTaskOutdialFailed: () => undefined,\n};\n"],"mappings":"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","ignoreList":[]}
|
|
@@ -55,14 +55,23 @@ function createTaskUIControls(main, consult, activeLeg) {
|
|
|
55
55
|
function getDefaultUIControls() {
|
|
56
56
|
return createTaskUIControls(getDefaultInteractionUIControls(), getDefaultInteractionUIControls(), 'main');
|
|
57
57
|
}
|
|
58
|
+
|
|
59
|
+
/** Consult media must exist on the interaction payload, not only as a stale resource id. */
|
|
60
|
+
function hasConsultMediaInInteraction(interaction, consultMediaResourceId) {
|
|
61
|
+
const media = interaction?.media ?? {};
|
|
62
|
+
const hasConsultLeg = Object.values(media).some(entry => entry?.mType === 'consult');
|
|
63
|
+
if (hasConsultLeg) return true;
|
|
64
|
+
if (!consultMediaResourceId) return false;
|
|
65
|
+
return Boolean(media[consultMediaResourceId]);
|
|
66
|
+
}
|
|
58
67
|
function computeVoiceInteractionUIControls(state, context, config, fallbackTaskData, currentLeg = 'main') {
|
|
59
68
|
// Early exit for idle
|
|
60
69
|
if (state === _constants.TaskState.IDLE) {
|
|
61
70
|
return getDefaultInteractionUIControls();
|
|
62
71
|
}
|
|
63
72
|
|
|
64
|
-
//
|
|
65
|
-
const taskData = context.taskData ??
|
|
73
|
+
// Prefer live task.data (fallback) over stale state-machine snapshot during multi-login sync.
|
|
74
|
+
const taskData = fallbackTaskData ?? context.taskData ?? null;
|
|
66
75
|
const interaction = taskData?.interaction;
|
|
67
76
|
const mainCallId = interaction?.mainInteractionId || taskData?.interactionId;
|
|
68
77
|
const isWebrtc = config.voiceVariant === _types.VOICE_VARIANT.WEBRTC;
|
|
@@ -95,7 +104,6 @@ function computeVoiceInteractionUIControls(state, context, config, fallbackTaskD
|
|
|
95
104
|
// EP_DN consults are "ready" as soon as the consult is created (EP accepts routing immediately).
|
|
96
105
|
// Backend sends destinationType as 'EP-DN'; SDK method uses 'entryPoint' — check both.
|
|
97
106
|
const isEpDnConsult = consultDestinationType === 'entryPoint' || consultDestinationType === 'EP-DN';
|
|
98
|
-
const isConsultDestinationReady = consultDestinationAgentJoined || isEpDnConsult;
|
|
99
107
|
const stateImpliesHeld = state === _constants.TaskState.HELD || state === _constants.TaskState.RESUME_INITIATING;
|
|
100
108
|
const stateImpliesConnected = state === _constants.TaskState.CONNECTED || state === _constants.TaskState.HOLD_INITIATING;
|
|
101
109
|
const isHeld = stateImpliesHeld || serverHold === true;
|
|
@@ -109,22 +117,32 @@ function computeVoiceInteractionUIControls(state, context, config, fallbackTaskD
|
|
|
109
117
|
const consultMedia = Object.values(interaction?.media ?? {}).find(media => media?.mediaResourceId === taskData?.consultMediaResourceId || media?.mType === 'consult');
|
|
110
118
|
const selfParticipant = selfAgentId ? interaction?.participants?.[selfAgentId] : null;
|
|
111
119
|
const selfInConsultCall = Boolean(selfAgentId) && Boolean(consultMedia?.participants?.includes(selfAgentId));
|
|
112
|
-
const
|
|
120
|
+
const hasConsultMedia = hasConsultMediaInInteraction(interaction, taskData?.consultMediaResourceId);
|
|
121
|
+
const isConsultEndedForSelf = taskData?.type === 'AgentConsultEnded' || taskData?.type === 'AgentConsultFailed' || selfParticipant?.consultState === 'consultCompleted' && !hasConsultMedia && taskData?.isConsulted === false;
|
|
122
|
+
const effectiveConsultInitiator = isConsultEndedForSelf ? false : consultInitiator;
|
|
123
|
+
const effectiveConsultCallHeld = isConsultEndedForSelf ? false : consultCallHeld;
|
|
124
|
+
const effectiveConsultFromConference = isConsultEndedForSelf ? false : consultFromConference;
|
|
125
|
+
const effectiveConsultDestinationAgentJoined = isConsultEndedForSelf ? false : consultDestinationAgentJoined;
|
|
126
|
+
// After a consult ends for self, the backend stops sending consult media but the merged
|
|
127
|
+
// task.data can still carry the stale consult-media entry (reconcileData never deletes keys).
|
|
128
|
+
// Treat it as gone so post-consult main-leg controls (consult retry) are not blocked.
|
|
129
|
+
const effectiveHasConsultMedia = isConsultEndedForSelf ? false : hasConsultMedia;
|
|
130
|
+
const isConsultDestinationReady = effectiveConsultDestinationAgentJoined || isEpDnConsult;
|
|
131
|
+
const conferenceActive = isConferencing || conferenceFromBackend || effectiveConsultFromConference;
|
|
113
132
|
// Treat consult initiator as "in conference" even if mainCall participant list lags while consulting.
|
|
114
|
-
const inConference = conferenceActive && (isConferencing || selfInMainCall ||
|
|
133
|
+
const inConference = conferenceActive && (isConferencing || selfInMainCall || effectiveConsultInitiator);
|
|
115
134
|
|
|
116
135
|
// Check if this is a consulted agent (must be after isConsulting is computed).
|
|
117
136
|
const isSoleAgentOnCall = participantCount <= 1 && selfInMainCall && !isConsulting && !inConference;
|
|
118
|
-
const isConsulted = inConference || isSoleAgentOnCall ? false : (0, _TaskUtils.getIsConsultedAgentForControls)(taskData, context, isConsulting) || !
|
|
137
|
+
const isConsulted = inConference || isSoleAgentOnCall ? false : (0, _TaskUtils.getIsConsultedAgentForControls)(taskData, context, isConsulting) || !effectiveConsultInitiator && (selfParticipant?.isConsulted === true || selfParticipant?.consultState === 'consulting');
|
|
119
138
|
|
|
120
139
|
// Active call = can perform call operations
|
|
121
140
|
const isActive = state === _constants.TaskState.CONNECTED || state === _constants.TaskState.HELD || state === _constants.TaskState.HOLD_INITIATING || state === _constants.TaskState.RESUME_INITIATING || isConsulting || isConferencing;
|
|
122
141
|
|
|
123
142
|
// Consulted agents have limited controls until they're in conference or wrapup
|
|
124
143
|
// Use inConference (not isConferencing) so controls remain enabled after state downgrade
|
|
125
|
-
const hasFullControls = !isConsulted ||
|
|
126
|
-
const consultOwnedBySelf =
|
|
127
|
-
const hasConsultMedia = Boolean(taskData?.consultMediaResourceId || Object.values(interaction?.media ?? {}).some(media => media?.mType === 'consult'));
|
|
144
|
+
const hasFullControls = !isConsulted || effectiveConsultInitiator || inConference || isWrappingUp;
|
|
145
|
+
const consultOwnedBySelf = effectiveConsultInitiator || Boolean(selfAgentId) && taskData?.consultingAgentId === selfAgentId;
|
|
128
146
|
const selfConsultPendingOnConsultMedia = selfParticipant?.consultState === 'consultInitiated' && !taskData?.isConsulted && hasConsultMedia;
|
|
129
147
|
const ownerParticipant = interaction?.owner ? interaction.participants?.[interaction.owner] : undefined;
|
|
130
148
|
const otherAgentConsultInProgress = Boolean(interaction?.participants && Object.values(interaction.participants).some(participant => {
|
|
@@ -133,12 +151,12 @@ function computeVoiceInteractionUIControls(state, context, config, fallbackTaskD
|
|
|
133
151
|
if (participant.pType !== 'AGENT') return false;
|
|
134
152
|
return participant.consultState === 'consultInitiated' || participant.consultState === 'consultReserved' || participant.consultState === 'consulting' || participant.currentState === 'consulting';
|
|
135
153
|
}));
|
|
136
|
-
const isHydratedConferenceConsultPending = inConference && selfConsultPendingOnConsultMedia && !
|
|
137
|
-
const hasParallelConsultLeg = consultOwnedBySelf && !isConsulting && !isConsulted && (consultInProgress ||
|
|
138
|
-
const activeLegForConferenceConsult =
|
|
154
|
+
const isHydratedConferenceConsultPending = inConference && selfConsultPendingOnConsultMedia && !effectiveConsultDestinationAgentJoined;
|
|
155
|
+
const hasParallelConsultLeg = !isConsultEndedForSelf && consultOwnedBySelf && !isConsulting && !isConsulted && (consultInProgress || effectiveConsultCallHeld || hasConsultMedia);
|
|
156
|
+
const activeLegForConferenceConsult = effectiveConsultCallHeld ? 'main' : 'consult';
|
|
139
157
|
const isCurrentLegActive = currentLeg === activeLegForConferenceConsult;
|
|
140
|
-
const isConferenceConsultTransferContext = inConference &&
|
|
141
|
-
const consultLegOnHold = isConsulting &&
|
|
158
|
+
const isConferenceConsultTransferContext = inConference && effectiveConsultInitiator && hasConsultMedia && isConsultDestinationReady;
|
|
159
|
+
const consultLegOnHold = isConsulting && effectiveConsultCallHeld;
|
|
142
160
|
const callProcessingDetails = interaction?.callProcessingDetails;
|
|
143
161
|
const conferenceHoldParticipant = callProcessingDetails?.conferenceHoldParticipant === true || callProcessingDetails?.conferenceHoldParticipant === 'true';
|
|
144
162
|
const postDeclineHeldMainLeg = consultInitiator && !consultDestinationAgentJoined && isHeld && inConference && conferenceHoldParticipant;
|
|
@@ -152,6 +170,39 @@ function computeVoiceInteractionUIControls(state, context, config, fallbackTaskD
|
|
|
152
170
|
const selfOnConsultLeg = selfParticipant?.consultState === 'consulting' || selfParticipant?.currentState === 'consulting';
|
|
153
171
|
const showMainLegConferenceControlsDuringConsult = currentLeg === 'main' && inConference && consultInProgress && !selfOnConsultLeg;
|
|
154
172
|
const allowHeldMainLegControlsForNonInitiator = showMainLegConferenceControlsDuringConsult && !isHydratedConferenceConsultPending;
|
|
173
|
+
const isConsultRequestedPhase = isConsultPendingBeforeJoin && !isConsulted && (consultInitiator || Boolean(selfAgentId) && selfParticipant?.consultState === 'consultInitiated' && taskData?.agentId === selfAgentId);
|
|
174
|
+
const isConsultUnansweredFailure = currentLeg === 'main' && !inConference && !taskData?.isConsulted && !effectiveHasConsultMedia && isHeld && selfParticipant?.consultState === 'consultCompleted' && (taskData?.type === 'AgentConsultFailed' || taskData?.type === 'AgentConsultEnded' || isConsultEndedForSelf);
|
|
175
|
+
if (isConsultUnansweredFailure) {
|
|
176
|
+
const recordingControl = recordingControlsAvailable && config.isRecordingEnabled && !inConference ? VISIBLE_ENABLED : DISABLED;
|
|
177
|
+
return {
|
|
178
|
+
...getDefaultInteractionUIControls(),
|
|
179
|
+
hold: VISIBLE_ENABLED,
|
|
180
|
+
transfer: VISIBLE_ENABLED,
|
|
181
|
+
consult: VISIBLE_ENABLED,
|
|
182
|
+
recording: recordingControl,
|
|
183
|
+
end: VISIBLE_DISABLED
|
|
184
|
+
};
|
|
185
|
+
}
|
|
186
|
+
if (isConsultRequestedPhase) {
|
|
187
|
+
if (currentLeg === 'main') {
|
|
188
|
+
return {
|
|
189
|
+
...getDefaultInteractionUIControls(),
|
|
190
|
+
transfer: VISIBLE_DISABLED,
|
|
191
|
+
conference: VISIBLE_DISABLED,
|
|
192
|
+
end: VISIBLE_DISABLED
|
|
193
|
+
};
|
|
194
|
+
}
|
|
195
|
+
if (currentLeg === 'consult') {
|
|
196
|
+
return {
|
|
197
|
+
...getDefaultInteractionUIControls(),
|
|
198
|
+
endConsult: VISIBLE_ENABLED,
|
|
199
|
+
switch: VISIBLE_DISABLED,
|
|
200
|
+
transfer: VISIBLE_DISABLED,
|
|
201
|
+
transferConference: inConference ? VISIBLE_DISABLED : DISABLED,
|
|
202
|
+
mergeToConference: VISIBLE_DISABLED
|
|
203
|
+
};
|
|
204
|
+
}
|
|
205
|
+
}
|
|
155
206
|
return {
|
|
156
207
|
// Accept/Decline: Voice tasks in offered state
|
|
157
208
|
// Desktop/WebRTC + inbound: accept enabled (agent manually accepts)
|
|
@@ -169,7 +220,7 @@ function computeVoiceInteractionUIControls(state, context, config, fallbackTaskD
|
|
|
169
220
|
hold: (() => {
|
|
170
221
|
if (!hasFullControls) return DISABLED;
|
|
171
222
|
if (forceHeldPostConsultControls) return VISIBLE_ENABLED;
|
|
172
|
-
if (consultOwnedBySelf && (isConsulting || hasParallelConsultLeg ||
|
|
223
|
+
if (consultOwnedBySelf && (isConsulting || hasParallelConsultLeg || effectiveConsultCallHeld)) {
|
|
173
224
|
return DISABLED;
|
|
174
225
|
}
|
|
175
226
|
if (hasParallelConsultLeg) return DISABLED;
|
|
@@ -186,7 +237,13 @@ function computeVoiceInteractionUIControls(state, context, config, fallbackTaskD
|
|
|
186
237
|
if (!isWebrtc) return DISABLED;
|
|
187
238
|
if (isWrappingUp) return DISABLED;
|
|
188
239
|
if (currentLeg === 'consult' && !selfInConsultCall) return DISABLED;
|
|
189
|
-
|
|
240
|
+
// The consulted agent has no separate consult leg; their main leg is the active call, so
|
|
241
|
+
// mute stays available while they consult (the heuristic below targets the initiator's
|
|
242
|
+
// inactive leg, not the consultee's only leg).
|
|
243
|
+
const isConsultedActiveMainLeg = isConsulted && currentLeg === 'main';
|
|
244
|
+
if ((isConsulting || hasParallelConsultLeg) && !isCurrentLegActive && !isConsultedActiveMainLeg) {
|
|
245
|
+
return VISIBLE_DISABLED;
|
|
246
|
+
}
|
|
190
247
|
if (isConsulting) return VISIBLE_ENABLED;
|
|
191
248
|
if (isConnected || isHeld || isConferencing) {
|
|
192
249
|
if (inConference) return VISIBLE_ENABLED;
|
|
@@ -247,6 +304,13 @@ function computeVoiceInteractionUIControls(state, context, config, fallbackTaskD
|
|
|
247
304
|
// Consult: connected/held/conference when conditions met
|
|
248
305
|
consult: (() => {
|
|
249
306
|
const isConnectedOrHeld = state === _constants.TaskState.CONNECTED || state === _constants.TaskState.HELD;
|
|
307
|
+
if (isHeld && !inConference && !effectiveHasConsultMedia && selfParticipant?.consultState === 'consultCompleted' && !taskData?.isConsulted) {
|
|
308
|
+
const canRetryConsult = !maxParticipants && customerPresent && !otherAgentConsultInProgress;
|
|
309
|
+
return {
|
|
310
|
+
isVisible: true,
|
|
311
|
+
isEnabled: canRetryConsult
|
|
312
|
+
};
|
|
313
|
+
}
|
|
250
314
|
if (inConference && nonOwnerPostConsultCompletedHeldMainLeg) return VISIBLE_DISABLED;
|
|
251
315
|
if (hasParallelConsultLeg) return DISABLED;
|
|
252
316
|
if (!hasFullControls || !(isConnectedOrHeld || inConference)) {
|
|
@@ -405,23 +469,37 @@ function getVoiceLegState(currentState, context, config, fallbackTaskData) {
|
|
|
405
469
|
consultState: _constants.TaskState.CONSULTING
|
|
406
470
|
};
|
|
407
471
|
}
|
|
408
|
-
const taskData = context.taskData ??
|
|
472
|
+
const taskData = fallbackTaskData ?? context.taskData ?? null;
|
|
409
473
|
const interaction = taskData?.interaction;
|
|
410
474
|
const mainCallId = interaction?.mainInteractionId || taskData?.interactionId;
|
|
411
475
|
const selfAgentId = config.agentId ?? taskData?.agentId;
|
|
476
|
+
const selfParticipant = selfAgentId ? interaction?.participants?.[selfAgentId] : null;
|
|
477
|
+
const hasConsultMedia = hasConsultMediaInInteraction(interaction, taskData?.consultMediaResourceId);
|
|
478
|
+
const isConsultEndedForSelf = taskData?.type === 'AgentConsultEnded' || taskData?.type === 'AgentConsultFailed' || selfParticipant?.consultState === 'consultCompleted' && !hasConsultMedia && taskData?.isConsulted === false;
|
|
412
479
|
const consultInProgress = (0, _TaskUtils.getIsConsultInProgressForConferenceControls)(interaction, mainCallId, selfAgentId);
|
|
413
480
|
const isConsultingState = currentState === _constants.TaskState.CONSULTING || currentState === _constants.TaskState.CONSULT_INITIATING || currentState === _constants.TaskState.CONF_INITIATING;
|
|
414
481
|
const consultOwnedBySelf = context.consultInitiator || Boolean(selfAgentId) && taskData?.consultingAgentId === selfAgentId;
|
|
415
|
-
const hasConsultMedia = Boolean(taskData?.consultMediaResourceId || Object.values(interaction?.media ?? {}).some(media => media?.mType === 'consult'));
|
|
416
|
-
const selfParticipant = selfAgentId ? interaction?.participants?.[selfAgentId] : null;
|
|
417
482
|
const selfConsultPendingOnConsultMedia = selfParticipant?.consultState === 'consultInitiated' && !taskData?.isConsulted && hasConsultMedia;
|
|
418
483
|
const selfConsultingOnConsultMedia = selfParticipant?.consultState === 'consulting' && hasConsultMedia;
|
|
419
|
-
const
|
|
484
|
+
const isConsultUnansweredFailure = !taskData?.isConsulted && !hasConsultMedia && selfParticipant?.consultState === 'consultCompleted' && Boolean(mainCallId && taskData?.interaction?.media?.[mainCallId]?.isHold === true) && taskData?.interaction?.state !== 'conference' && !(0, _TaskUtils.getIsConferenceInProgress)(taskData);
|
|
485
|
+
const hasConsultLeg = Boolean(!isConsultEndedForSelf && !interaction?.isTerminated && !isConsultUnansweredFailure && (consultOwnedBySelf || selfConsultingOnConsultMedia || selfConsultPendingOnConsultMedia) && (consultInProgress || isConsultingState || context.consultCallHeld || hasConsultMedia));
|
|
420
486
|
if (!hasConsultLeg) {
|
|
487
|
+
let mainState = currentState;
|
|
488
|
+
if (isConsultEndedForSelf && taskData?.interaction) {
|
|
489
|
+
const resolvedMainId = taskData.interaction.mainInteractionId || taskData.interactionId;
|
|
490
|
+
const isMainHeld = Boolean(resolvedMainId && taskData.interaction.media?.[resolvedMainId]?.isHold === true);
|
|
491
|
+
if (taskData.interaction.state === 'conference' || (0, _TaskUtils.getIsConferenceInProgress)(taskData)) {
|
|
492
|
+
mainState = _constants.TaskState.CONFERENCING;
|
|
493
|
+
} else if (isMainHeld || taskData.interaction.state === 'hold') {
|
|
494
|
+
mainState = _constants.TaskState.HELD;
|
|
495
|
+
} else {
|
|
496
|
+
mainState = _constants.TaskState.CONNECTED;
|
|
497
|
+
}
|
|
498
|
+
}
|
|
421
499
|
return {
|
|
422
500
|
hasConsultLeg: false,
|
|
423
501
|
activeLeg: 'main',
|
|
424
|
-
mainState
|
|
502
|
+
mainState,
|
|
425
503
|
consultState: _constants.TaskState.CONSULTING
|
|
426
504
|
};
|
|
427
505
|
}
|