@webex/contact-center 3.10.0-next.9 → 3.10.0-set-bitrate.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (89) hide show
  1. package/dist/cc.js +2 -1
  2. package/dist/cc.js.map +1 -1
  3. package/dist/config.js.map +1 -1
  4. package/dist/constants.js.map +1 -1
  5. package/dist/index.js +17 -1
  6. package/dist/index.js.map +1 -1
  7. package/dist/logger-proxy.js.map +1 -1
  8. package/dist/metrics/MetricsManager.js +2 -1
  9. package/dist/metrics/MetricsManager.js.map +1 -1
  10. package/dist/metrics/behavioral-events.js +12 -0
  11. package/dist/metrics/behavioral-events.js.map +1 -1
  12. package/dist/metrics/constants.js +4 -0
  13. package/dist/metrics/constants.js.map +1 -1
  14. package/dist/services/AddressBook.js +2 -3
  15. package/dist/services/AddressBook.js.map +1 -1
  16. package/dist/services/EntryPoint.js +2 -3
  17. package/dist/services/EntryPoint.js.map +1 -1
  18. package/dist/services/Queue.js +2 -3
  19. package/dist/services/Queue.js.map +1 -1
  20. package/dist/services/WebCallingService.js +1 -1
  21. package/dist/services/WebCallingService.js.map +1 -1
  22. package/dist/services/agent/index.js +1 -2
  23. package/dist/services/agent/index.js.map +1 -1
  24. package/dist/services/agent/types.js +10 -0
  25. package/dist/services/agent/types.js.map +1 -1
  26. package/dist/services/config/Util.js.map +1 -1
  27. package/dist/services/config/constants.js.map +1 -1
  28. package/dist/services/config/index.js +1 -1
  29. package/dist/services/config/index.js.map +1 -1
  30. package/dist/services/config/types.js.map +1 -1
  31. package/dist/services/constants.js.map +1 -1
  32. package/dist/services/core/Err.js.map +1 -1
  33. package/dist/services/core/GlobalTypes.js.map +1 -1
  34. package/dist/services/core/Utils.js +2 -3
  35. package/dist/services/core/Utils.js.map +1 -1
  36. package/dist/services/core/WebexRequest.js +1 -2
  37. package/dist/services/core/WebexRequest.js.map +1 -1
  38. package/dist/services/core/aqm-reqs.js +2 -3
  39. package/dist/services/core/aqm-reqs.js.map +1 -1
  40. package/dist/services/core/constants.js.map +1 -1
  41. package/dist/services/core/types.js.map +1 -1
  42. package/dist/services/core/websocket/WebSocketManager.js +1 -2
  43. package/dist/services/core/websocket/WebSocketManager.js.map +1 -1
  44. package/dist/services/core/websocket/connection-service.js +1 -1
  45. package/dist/services/core/websocket/connection-service.js.map +1 -1
  46. package/dist/services/core/websocket/keepalive.worker.js.map +1 -1
  47. package/dist/services/core/websocket/types.js.map +1 -1
  48. package/dist/services/index.js +1 -1
  49. package/dist/services/index.js.map +1 -1
  50. package/dist/services/task/AutoWrapup.js +1 -1
  51. package/dist/services/task/AutoWrapup.js.map +1 -1
  52. package/dist/services/task/TaskManager.js +121 -33
  53. package/dist/services/task/TaskManager.js.map +1 -1
  54. package/dist/services/task/TaskUtils.js +90 -1
  55. package/dist/services/task/TaskUtils.js.map +1 -1
  56. package/dist/services/task/constants.js +3 -1
  57. package/dist/services/task/constants.js.map +1 -1
  58. package/dist/services/task/contact.js +0 -2
  59. package/dist/services/task/contact.js.map +1 -1
  60. package/dist/services/task/dialer.js.map +1 -1
  61. package/dist/services/task/index.js +1 -1
  62. package/dist/services/task/index.js.map +1 -1
  63. package/dist/services/task/types.js +375 -0
  64. package/dist/services/task/types.js.map +1 -1
  65. package/dist/types/metrics/constants.d.ts +4 -0
  66. package/dist/types/services/task/TaskUtils.d.ts +42 -0
  67. package/dist/types/services/task/constants.d.ts +2 -0
  68. package/dist/types/services/task/types.d.ts +32 -0
  69. package/dist/types.js +5 -0
  70. package/dist/types.js.map +1 -1
  71. package/dist/utils/PageCache.js +1 -1
  72. package/dist/utils/PageCache.js.map +1 -1
  73. package/dist/webex-config.js.map +1 -1
  74. package/dist/webex.js +2 -2
  75. package/dist/webex.js.map +1 -1
  76. package/package.json +9 -9
  77. package/src/cc.ts +1 -0
  78. package/src/metrics/behavioral-events.ts +12 -0
  79. package/src/metrics/constants.ts +4 -0
  80. package/src/services/task/TaskManager.ts +135 -22
  81. package/src/services/task/TaskUtils.ts +109 -1
  82. package/src/services/task/constants.ts +2 -0
  83. package/src/services/task/types.ts +34 -0
  84. package/test/unit/spec/cc.ts +1 -0
  85. package/test/unit/spec/metrics/behavioral-events.ts +14 -0
  86. package/test/unit/spec/services/task/TaskManager.ts +378 -4
  87. package/test/unit/spec/services/task/TaskUtils.ts +305 -3
  88. package/umd/contact-center.min.js +2 -2
  89. package/umd/contact-center.min.js.map +1 -1
@@ -18,6 +18,7 @@ import {
18
18
  isParticipantInMainInteraction,
19
19
  isPrimary,
20
20
  isSecondaryEpDnAgent,
21
+ shouldAutoAnswerTask,
21
22
  } from './TaskUtils';
22
23
 
23
24
  /** @internal */
@@ -36,6 +37,7 @@ export default class TaskManager extends EventEmitter {
36
37
  private static taskManager;
37
38
  private wrapupData: WrapupData;
38
39
  private agentId: string;
40
+ private webRtcEnabled: boolean;
39
41
  /**
40
42
  * @param contact - Routing Contact layer. Talks to AQMReq layer to convert events to promises
41
43
  * @param webCallingService - Webrtc Service Layer
@@ -73,6 +75,10 @@ export default class TaskManager extends EventEmitter {
73
75
  return this.agentId;
74
76
  }
75
77
 
78
+ public setWebRtcEnabled(webRtcEnabled: boolean) {
79
+ this.webRtcEnabled = webRtcEnabled;
80
+ }
81
+
76
82
  private handleIncomingWebCall = (call: ICall) => {
77
83
  const currentTask = Object.values(this.taskCollection).find(
78
84
  (task) => task.data.interaction.mediaType === 'telephony'
@@ -130,6 +136,14 @@ export default class TaskManager extends EventEmitter {
130
136
  interactionId: payload.data.interactionId,
131
137
  });
132
138
 
139
+ // Check if auto-answer should happen for this task
140
+ const shouldAutoAnswer = shouldAutoAnswerTask(
141
+ payload.data,
142
+ this.agentId,
143
+ this.webCallingService.loginOption,
144
+ this.webRtcEnabled
145
+ );
146
+
133
147
  task = new Task(
134
148
  this.contact,
135
149
  this.webCallingService,
@@ -138,6 +152,7 @@ export default class TaskManager extends EventEmitter {
138
152
  wrapUpRequired:
139
153
  payload.data.interaction?.participants?.[this.agentId]?.isWrapUp || false,
140
154
  isConferenceInProgress: getIsConferenceInProgress(payload.data),
155
+ isAutoAnswering: shouldAutoAnswer, // Set flag before emitting
141
156
  },
142
157
  this.wrapupData,
143
158
  this.agentId
@@ -169,13 +184,22 @@ export default class TaskManager extends EventEmitter {
169
184
  }
170
185
  break;
171
186
 
172
- case CC_EVENTS.AGENT_CONTACT_RESERVED:
187
+ case CC_EVENTS.AGENT_CONTACT_RESERVED: {
188
+ // Check if auto-answer should happen for this task
189
+ const shouldAutoAnswerReserved = shouldAutoAnswerTask(
190
+ payload.data,
191
+ this.agentId,
192
+ this.webCallingService.loginOption,
193
+ this.webRtcEnabled
194
+ );
195
+
173
196
  task = new Task(
174
197
  this.contact,
175
198
  this.webCallingService,
176
199
  {
177
200
  ...payload.data,
178
201
  isConsulted: false,
202
+ isAutoAnswering: shouldAutoAnswerReserved, // Set flag before emitting
179
203
  },
180
204
  this.wrapupData,
181
205
  this.agentId
@@ -190,6 +214,7 @@ export default class TaskManager extends EventEmitter {
190
214
  this.emit(TASK_EVENTS.TASK_INCOMING, task);
191
215
  }
192
216
  break;
217
+ }
193
218
  case CC_EVENTS.AGENT_OFFER_CONTACT:
194
219
  // We don't have to emit any event here since this will be result of promise.
195
220
  task = this.updateTaskData(task, payload.data);
@@ -199,17 +224,29 @@ export default class TaskManager extends EventEmitter {
199
224
  interactionId: payload.data?.interactionId,
200
225
  });
201
226
  this.emit(TASK_EVENTS.TASK_OFFER_CONTACT, task);
227
+
228
+ // Handle auto-answer for offer contact
229
+ this.handleAutoAnswer(task);
202
230
  break;
203
231
  case CC_EVENTS.AGENT_OUTBOUND_FAILED:
204
- // We don't have to emit any event here since this will be result of promise.
205
- if (task.data) {
206
- this.removeTaskFromCollection(task);
232
+ if (task) {
233
+ task = this.updateTaskData(task, payload.data);
234
+ this.metricsManager.trackEvent(
235
+ METRIC_EVENT_NAMES.TASK_OUTDIAL_FAILED,
236
+ {
237
+ ...MetricsManager.getCommonTrackingFieldForAQMResponse(payload.data),
238
+ taskId: payload.data.interactionId,
239
+ reason: payload.data.reasonCode || payload.data.reason,
240
+ },
241
+ ['behavioral', 'operational']
242
+ );
243
+ LoggerProxy.log(`Agent outbound failed for task`, {
244
+ module: TASK_MANAGER_FILE,
245
+ method: METHODS.REGISTER_TASK_LISTENERS,
246
+ interactionId: payload.data.interactionId,
247
+ });
248
+ task.emit(TASK_EVENTS.TASK_OUTDIAL_FAILED, payload.data.reason ?? 'UNKNOWN_REASON');
207
249
  }
208
- LoggerProxy.log(`Agent outbound failed for task`, {
209
- module: TASK_MANAGER_FILE,
210
- method: METHODS.REGISTER_TASK_LISTENERS,
211
- interactionId: payload.data?.interactionId,
212
- });
213
250
  break;
214
251
  case CC_EVENTS.AGENT_CONTACT_ASSIGNED:
215
252
  task = this.updateTaskData(task, payload.data);
@@ -249,18 +286,19 @@ export default class TaskManager extends EventEmitter {
249
286
  }
250
287
  case CC_EVENTS.CONTACT_ENDED:
251
288
  // Update task data
252
- task = this.updateTaskData(task, {
253
- ...payload.data,
254
- wrapUpRequired:
255
- payload.data.interaction.state !== 'new' &&
256
- !isSecondaryEpDnAgent(payload.data.interaction),
257
- });
258
-
259
- // Handle cleanup based on whether task should be deleted
260
- this.handleTaskCleanup(task);
289
+ if (task) {
290
+ task = this.updateTaskData(task, {
291
+ ...payload.data,
292
+ wrapUpRequired:
293
+ payload.data.interaction.state !== 'new' &&
294
+ !isSecondaryEpDnAgent(payload.data.interaction),
295
+ });
261
296
 
262
- task?.emit(TASK_EVENTS.TASK_END, task);
297
+ // Handle cleanup based on whether task should be deleted
298
+ this.handleTaskCleanup(task);
263
299
 
300
+ task?.emit(TASK_EVENTS.TASK_END, task);
301
+ }
264
302
  break;
265
303
  case CC_EVENTS.CONTACT_MERGED:
266
304
  task = this.handleContactMerged(task, payload.data);
@@ -301,6 +339,9 @@ export default class TaskManager extends EventEmitter {
301
339
  isConsulted: true, // This ensures that the task is marked as us being requested for a consult
302
340
  });
303
341
  task.emit(TASK_EVENTS.TASK_OFFER_CONSULT, task);
342
+
343
+ // Handle auto-answer for consult offer
344
+ this.handleAutoAnswer(task);
304
345
  break;
305
346
  case CC_EVENTS.AGENT_CONSULTING:
306
347
  // Received when agent is in an active consult state
@@ -538,6 +579,72 @@ export default class TaskManager extends EventEmitter {
538
579
  }
539
580
  }
540
581
 
582
+ /**
583
+ * Handles auto-answer logic for incoming tasks
584
+ * Automatically accepts tasks when isAutoAnswering flag is set
585
+ * The flag is set during task creation based on:
586
+ * 1. WebRTC calls with auto-answer enabled in agent profile
587
+ * 2. Agent-initiated WebRTC outdial calls
588
+ * 3. Agent-initiated digital outbound (Email/SMS) without previous transfers
589
+ *
590
+ * @param task - The task to auto-answer
591
+ * @private
592
+ */
593
+ private async handleAutoAnswer(task: ITask): Promise<void> {
594
+ if (!task || !task.data || !task.data.isAutoAnswering) {
595
+ return;
596
+ }
597
+
598
+ LoggerProxy.info(`Auto-answering task`, {
599
+ module: TASK_MANAGER_FILE,
600
+ method: 'handleAutoAnswer',
601
+ interactionId: task.data.interactionId,
602
+ });
603
+
604
+ try {
605
+ await task.accept();
606
+ LoggerProxy.info(`Task auto-answered successfully`, {
607
+ module: TASK_MANAGER_FILE,
608
+ method: 'handleAutoAnswer',
609
+ interactionId: task.data.interactionId,
610
+ });
611
+
612
+ // Track successful auto-answer
613
+ this.metricsManager.trackEvent(
614
+ METRIC_EVENT_NAMES.TASK_AUTO_ANSWER_SUCCESS,
615
+ {
616
+ taskId: task.data.interactionId,
617
+ mediaType: task.data.interaction.mediaType,
618
+ isAutoAnswered: true,
619
+ },
620
+ ['behavioral', 'operational']
621
+ );
622
+ // Emit task:autoAnswered event for widgets/UI to react
623
+ task.emit(TASK_EVENTS.TASK_AUTO_ANSWERED, task);
624
+ } catch (error) {
625
+ // Reset isAutoAnswering flag on failure
626
+ task.updateTaskData({...task.data, isAutoAnswering: false});
627
+ LoggerProxy.error(`Failed to auto-answer task`, {
628
+ module: TASK_MANAGER_FILE,
629
+ method: 'handleAutoAnswer',
630
+ interactionId: task.data.interactionId,
631
+ error,
632
+ });
633
+
634
+ // Track auto-answer failure
635
+ this.metricsManager.trackEvent(
636
+ METRIC_EVENT_NAMES.TASK_AUTO_ANSWER_FAILED,
637
+ {
638
+ taskId: task.data.interactionId,
639
+ mediaType: task.data.interaction.mediaType,
640
+ error: error?.message || 'Unknown error',
641
+ isAutoAnswered: false,
642
+ },
643
+ ['behavioral', 'operational']
644
+ );
645
+ }
646
+ }
647
+
541
648
  /**
542
649
  * Handles cleanup of task resources including Desktop/WebRTC call cleanup and task removal
543
650
  * @param task - The task to clean up
@@ -553,9 +660,15 @@ export default class TaskManager extends EventEmitter {
553
660
  this.webCallingService.cleanUpCall();
554
661
  }
555
662
 
556
- if (task.data.interaction.state === 'new' || isSecondaryEpDnAgent(task.data.interaction)) {
557
- // Only remove tasks in 'new' state or isSecondaryEpDnAgent immediately. For other states,
558
- // retain tasks until they complete wrap-up, unless the task disconnected before being answered.
663
+ const isOutdial = task.data.interaction.outboundType === 'OUTDIAL';
664
+ const isNew = task.data.interaction.state === 'new';
665
+ const needsWrapUp = task.data.agentsPendingWrapUp?.length > 0;
666
+
667
+ // For OUTDIAL: only remove if NOT terminated (user-declined, no wrap-up follows)
668
+ // If terminated, keep task for wrap-up flow (CONTACT_ENDED → AGENT_WRAPUP)
669
+ // For non-OUTDIAL: remove if state is 'new'
670
+ // Always remove if secondary EpDn agent
671
+ if ((isNew && !(isOutdial && needsWrapUp)) || isSecondaryEpDnAgent(task.data.interaction)) {
559
672
  this.removeTaskFromCollection(task);
560
673
  }
561
674
  }
@@ -1,5 +1,7 @@
1
1
  /* eslint-disable import/prefer-default-export */
2
- import {Interaction, ITask, TaskData} from './types';
2
+ import {Interaction, ITask, TaskData, MEDIA_CHANNEL} from './types';
3
+ import {OUTDIAL_DIRECTION, OUTDIAL_MEDIA_TYPE, OUTBOUND_TYPE} from '../../constants';
4
+ import {LoginOption} from '../../types';
3
5
 
4
6
  /**
5
7
  * Determines if the given agent is the primary agent (owner) of the task
@@ -111,3 +113,109 @@ export const isSecondaryEpDnAgent = (interaction: Interaction): boolean => {
111
113
 
112
114
  return interaction.mediaType === 'telephony' && isSecondaryAgent(interaction);
113
115
  };
116
+
117
+ /**
118
+ * Checks if auto-answer is enabled for the agent participant
119
+ * @param interaction - The interaction object
120
+ * @param agentId - Current agent ID
121
+ * @returns true if auto-answer is enabled, false otherwise
122
+ */
123
+ export const isAutoAnswerEnabled = (interaction: Interaction, agentId: string): boolean => {
124
+ return interaction.participants?.[agentId]?.autoAnswerEnabled === true;
125
+ };
126
+
127
+ /**
128
+ * Checks if the interaction is a WebRTC call eligible for auto-answer
129
+ * @param interaction - The interaction object
130
+ * @param loginOption - The agent's login option (BROWSER, AGENT_DN, etc.)
131
+ * @param webRtcEnabled - Whether WebRTC is enabled for the agent
132
+ * @returns true if this is a WebRTC call, false otherwise
133
+ */
134
+ export const isWebRTCCall = (
135
+ interaction: Interaction,
136
+ loginOption: string,
137
+ webRtcEnabled: boolean
138
+ ): boolean => {
139
+ return (
140
+ webRtcEnabled &&
141
+ loginOption === LoginOption.BROWSER &&
142
+ interaction.mediaType === OUTDIAL_MEDIA_TYPE
143
+ );
144
+ };
145
+
146
+ /**
147
+ * Checks if the interaction is a digital outbound (Email/SMS)
148
+ * @param interaction - The interaction object
149
+ * @returns true if this is a digital outbound, false otherwise
150
+ */
151
+ export const isDigitalOutbound = (interaction: Interaction): boolean => {
152
+ return (
153
+ interaction.contactDirection?.type === OUTDIAL_DIRECTION &&
154
+ interaction.outboundType === OUTBOUND_TYPE &&
155
+ (interaction.mediaChannel === MEDIA_CHANNEL.EMAIL ||
156
+ interaction.mediaChannel === MEDIA_CHANNEL.SMS)
157
+ );
158
+ };
159
+
160
+ /**
161
+ * Checks if the outdial was initiated by the current agent
162
+ * @param interaction - The interaction object
163
+ * @param agentId - Current agent ID
164
+ * @returns true if agent initiated the outdial, false otherwise
165
+ */
166
+ export const hasAgentInitiatedOutdial = (interaction: Interaction, agentId: string): boolean => {
167
+ return (
168
+ interaction.contactDirection?.type === OUTDIAL_DIRECTION &&
169
+ interaction.outboundType === OUTBOUND_TYPE &&
170
+ interaction.callProcessingDetails?.outdialAgentId === agentId &&
171
+ interaction.owner === agentId &&
172
+ !interaction.callProcessingDetails?.BLIND_TRANSFER_IN_PROGRESS
173
+ );
174
+ };
175
+
176
+ /**
177
+ * Determines if a task should be auto-answered based on interaction data
178
+ * Auto-answer logic handles:
179
+ * 1. WebRTC calls with auto-answer enabled in agent profile
180
+ * 2. Agent-initiated WebRTC outdial calls
181
+ * 3. Agent-initiated digital outbound (Email/SMS) without previous transfers
182
+ *
183
+ * @param taskData - The task data
184
+ * @param agentId - Current agent ID
185
+ * @param loginOption - Agent's login option
186
+ * @param webRtcEnabled - Whether WebRTC is enabled for the agent
187
+ * @returns true if task should be auto-answered, false otherwise
188
+ */
189
+ export const shouldAutoAnswerTask = (
190
+ taskData: TaskData,
191
+ agentId: string,
192
+ loginOption: string,
193
+ webRtcEnabled: boolean
194
+ ): boolean => {
195
+ const {interaction} = taskData;
196
+
197
+ if (!interaction || !agentId) {
198
+ return false;
199
+ }
200
+
201
+ // Check if auto-answer is enabled for this agent
202
+ const autoAnswerEnabled = isAutoAnswerEnabled(interaction, agentId);
203
+
204
+ // Check if this is an agent-initiated outdial
205
+ const agentInitiatedOutdial = hasAgentInitiatedOutdial(interaction, agentId);
206
+
207
+ // WebRTC telephony calls
208
+ if (isWebRTCCall(interaction, loginOption, webRtcEnabled)) {
209
+ return autoAnswerEnabled || agentInitiatedOutdial;
210
+ }
211
+
212
+ // Digital outbound (Email/SMS)
213
+ if (isDigitalOutbound(interaction) && agentInitiatedOutdial) {
214
+ // Don't auto-answer if task has been transferred (has previous vteams)
215
+ const hasPreviousVteams = interaction.previousVTeams && interaction.previousVTeams.length > 0;
216
+
217
+ return !hasPreviousVteams;
218
+ }
219
+
220
+ return false;
221
+ };
@@ -34,6 +34,8 @@ export const PRESERVED_TASK_DATA_FIELDS = {
34
34
  WRAP_UP_REQUIRED: 'wrapUpRequired',
35
35
  /** Indicates if a conference is currently in progress (2+ active agents) */
36
36
  IS_CONFERENCE_IN_PROGRESS: 'isConferenceInProgress',
37
+ /** Indicates if auto-answer is in progress for this task */
38
+ IS_AUTO_ANSWERING: 'isAutoAnswering',
37
39
  };
38
40
 
39
41
  /**
@@ -347,6 +347,18 @@ export enum TASK_EVENTS {
347
347
  */
348
348
  TASK_REJECT = 'task:rejected',
349
349
 
350
+ /**
351
+ * Triggered when an outdial call fails
352
+ * @example
353
+ * ```typescript
354
+ * task.on(TASK_EVENTS.TASK_OUTDIAL_FAILED, (reason: string) => {
355
+ * console.log('Outdial failed:', reason);
356
+ * // Handle outdial failure
357
+ * });
358
+ * ```
359
+ */
360
+ TASK_OUTDIAL_FAILED = 'task:outdialFailed',
361
+
350
362
  /**
351
363
  * Triggered when a task is populated with data
352
364
  * @example
@@ -371,6 +383,22 @@ export enum TASK_EVENTS {
371
383
  */
372
384
  TASK_OFFER_CONTACT = 'task:offerContact',
373
385
 
386
+ /**
387
+ * Triggered when a task has been successfully auto-answered
388
+ * This event is emitted after the SDK automatically accepts a task due to:
389
+ * - WebRTC calls with auto-answer enabled
390
+ * - Agent-initiated outdial calls
391
+ * - Other auto-answer scenarios
392
+ * @example
393
+ * ```typescript
394
+ * task.on(TASK_EVENTS.TASK_AUTO_ANSWERED, (task: ITask) => {
395
+ * console.log('Task auto-answered:', task.data.interactionId);
396
+ * // Update UI - enable cancel button, etc.
397
+ * });
398
+ * ```
399
+ */
400
+ TASK_AUTO_ANSWERED = 'task:autoAnswered',
401
+
374
402
  /**
375
403
  * Triggered when a conference is being established
376
404
  * @example
@@ -660,6 +688,8 @@ export type Interaction = {
660
688
  BLIND_TRANSFER_IN_PROGRESS?: boolean;
661
689
  /** Desktop view configuration for Flow Control */
662
690
  fcDesktopView?: string;
691
+ /** Agent ID who initiated the outdial call */
692
+ outdialAgentId?: string;
663
693
  };
664
694
  /** Main interaction identifier for related interactions */
665
695
  mainInteractionId?: string;
@@ -785,6 +815,10 @@ export type TaskData = {
785
815
  reservedAgentChannelId?: string;
786
816
  /** Indicates if wrap-up is required for this task */
787
817
  wrapUpRequired?: boolean;
818
+ /** Indicates if auto-answer is in progress for this task */
819
+ isAutoAnswering?: boolean;
820
+ /** Indicates if wrap-up is required for this task */
821
+ agentsPendingWrapUp?: string[];
788
822
  };
789
823
 
790
824
  /**
@@ -141,6 +141,7 @@ describe('webex.cc', () => {
141
141
  task: undefined,
142
142
  setWrapupData: jest.fn(),
143
143
  setAgentId: jest.fn(),
144
+ setWebRtcEnabled: jest.fn(),
144
145
  registerIncomingCallEvent: jest.fn(),
145
146
  registerTaskListeners: jest.fn(),
146
147
  getTask: jest.fn(),
@@ -152,6 +152,20 @@ describe('metrics/behavioral-events', () => {
152
152
  verb: 'fail',
153
153
  });
154
154
 
155
+ expect(getEventTaxonomy(METRIC_EVENT_NAMES.TASK_AUTO_ANSWER_SUCCESS)).toEqual({
156
+ product,
157
+ agent: 'user',
158
+ target: 'task_auto_answer',
159
+ verb: 'complete',
160
+ });
161
+
162
+ expect(getEventTaxonomy(METRIC_EVENT_NAMES.TASK_AUTO_ANSWER_FAILED)).toEqual({
163
+ product,
164
+ agent: 'user',
165
+ target: 'task_auto_answer',
166
+ verb: 'fail',
167
+ });
168
+
155
169
  expect(getEventTaxonomy('' as METRIC_EVENT_NAMES)).toEqual(undefined);
156
170
  });
157
171
  });