@webex/contact-center 3.12.0-next.85 → 3.12.0-next.87

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.
@@ -2,7 +2,7 @@ import ApiAIAssistant from '../../../../src/services/ApiAiAssistant';
2
2
  import MetricsManager from '../../../../src/metrics/MetricsManager';
3
3
  import LoggerProxy from '../../../../src/logger-proxy';
4
4
  import WebexRequest from '../../../../src/services/core/WebexRequest';
5
- import {HTTP_METHODS, WebexSDK} from '../../../../src/types';
5
+ import {HTTP_METHODS, RealTimeAssistanceUserActionId, WebexSDK} from '../../../../src/types';
6
6
 
7
7
  jest.mock('../../../../src/metrics/MetricsManager');
8
8
  jest.mock('../../../../src/logger-proxy');
@@ -54,7 +54,7 @@ describe('ApiAIAssistant', () => {
54
54
  'interaction-1',
55
55
  'CUSTOM_EVENT',
56
56
  'GET_TRANSCRIPTS',
57
- 'START'
57
+ {action: 'START'}
58
58
  );
59
59
 
60
60
  expect(mockWebex.request).toHaveBeenCalledTimes(1);
@@ -92,51 +92,49 @@ describe('ApiAIAssistant', () => {
92
92
  expect(result).toEqual(responseBody as any);
93
93
  });
94
94
 
95
- it('should request suggested response without extra context using sendEvent', async () => {
95
+ it('should request real-time assistance without extra context using sendEvent', async () => {
96
96
  const sendEventSpy = jest.spyOn(apiAIAssistant, 'sendEvent').mockResolvedValue({ok: true});
97
97
  apiAIAssistant.setAIFeatureFlags({suggestedResponses: {enable: true}} as any);
98
98
 
99
- const result = await apiAIAssistant.getSuggestedResponse({
99
+ const result = await apiAIAssistant.getRealTimeAssistance({
100
100
  agentId: 'test-agent-id',
101
101
  interactionId: 'interaction-1',
102
102
  });
103
103
 
104
104
  expect(sendEventSpy).toHaveBeenCalledTimes(1);
105
- const [agentId, interactionId, eventType, eventName, action, context, languageCode, trackingId] =
105
+ const [agentId, interactionId, eventType, eventName, metadata, languageCode, trackingId] =
106
106
  sendEventSpy.mock.calls[0];
107
107
 
108
108
  expect(agentId).toBe('test-agent-id');
109
109
  expect(interactionId).toBe('interaction-1');
110
110
  expect(eventType).toBe('CUSTOM_EVENT');
111
111
  expect(eventName).toBe('GET_SUGGESTIONS');
112
- expect(action).toBeUndefined();
113
- expect(context).toBeUndefined();
112
+ expect(metadata).toBeUndefined();
114
113
  expect(languageCode).toBe('en');
115
114
  expect(typeof trackingId).toBe('string');
116
115
  expect(trackingId.startsWith('WX_CC_SDK_')).toBe(true);
117
116
  expect(result).toEqual({ok: true});
118
117
  });
119
118
 
120
- it('should request suggested response with extra context using sendEvent', async () => {
119
+ it('should request real-time assistance with extra context using sendEvent', async () => {
121
120
  const sendEventSpy = jest.spyOn(apiAIAssistant, 'sendEvent').mockResolvedValue({ok: true});
122
121
  apiAIAssistant.setAIFeatureFlags({suggestedResponses: {enable: true}} as any);
123
122
 
124
- const result = await apiAIAssistant.getSuggestedResponse({
123
+ const result = await apiAIAssistant.getRealTimeAssistance({
125
124
  agentId: 'test-agent-id',
126
125
  interactionId: 'interaction-1',
127
126
  context: 'Need assistance with credit card payment due date',
128
127
  });
129
128
 
130
129
  expect(sendEventSpy).toHaveBeenCalledTimes(1);
131
- const [agentId, interactionId, eventType, eventName, action, context, languageCode, trackingId] =
130
+ const [agentId, interactionId, eventType, eventName, metadata, languageCode, trackingId] =
132
131
  sendEventSpy.mock.calls[0];
133
132
 
134
133
  expect(agentId).toBe('test-agent-id');
135
134
  expect(interactionId).toBe('interaction-1');
136
135
  expect(eventType).toBe('CUSTOM_EVENT');
137
136
  expect(eventName).toBe('ADD_SUGGESTIONS_EXTRA_CONTEXT');
138
- expect(action).toBeUndefined();
139
- expect(context).toBe('Need assistance with credit card payment due date');
137
+ expect(metadata).toEqual({context: 'Need assistance with credit card payment due date'});
140
138
  expect(languageCode).toBe('en');
141
139
  expect(typeof trackingId).toBe('string');
142
140
  expect(trackingId.startsWith('WX_CC_SDK_')).toBe(true);
@@ -147,28 +145,65 @@ describe('ApiAIAssistant', () => {
147
145
  const sendEventSpy = jest.spyOn(apiAIAssistant, 'sendEvent').mockResolvedValue({ok: true});
148
146
  apiAIAssistant.setAIFeatureFlags({suggestedResponses: {enable: true}} as any);
149
147
 
150
- const result = await apiAIAssistant.getSuggestedResponse({
148
+ const result = await apiAIAssistant.getRealTimeAssistance({
151
149
  agentId: 'test-agent-id',
152
150
  interactionId: 'interaction-1',
153
151
  context: ' ',
154
152
  });
155
153
 
156
154
  expect(sendEventSpy).toHaveBeenCalledTimes(1);
157
- const [agentId, interactionId, eventType, eventName, action, context, languageCode, trackingId] =
155
+ const [agentId, interactionId, eventType, eventName, metadata, languageCode, trackingId] =
158
156
  sendEventSpy.mock.calls[0];
159
157
 
160
158
  expect(agentId).toBe('test-agent-id');
161
159
  expect(interactionId).toBe('interaction-1');
162
160
  expect(eventType).toBe('CUSTOM_EVENT');
163
161
  expect(eventName).toBe('GET_SUGGESTIONS');
164
- expect(action).toBeUndefined();
165
- expect(context).toBe('');
162
+ expect(metadata).toEqual({context: ''});
166
163
  expect(languageCode).toBe('en');
167
164
  expect(typeof trackingId).toBe('string');
168
165
  expect(trackingId.startsWith('WX_CC_SDK_')).toBe(true);
169
166
  expect(result).toEqual({ok: true});
170
167
  });
171
168
 
169
+ [
170
+ RealTimeAssistanceUserActionId.LIKE,
171
+ RealTimeAssistanceUserActionId.DISLIKE,
172
+ RealTimeAssistanceUserActionId.COPY,
173
+ ].forEach((actionId) => {
174
+ it(`should send real-time assistance user action for ${actionId}`, async () => {
175
+ (mockWebex.request as jest.Mock).mockResolvedValue({body: {ok: true}});
176
+ apiAIAssistant.setAIFeatureFlags({suggestedResponses: {enable: true}} as any);
177
+
178
+ const result = await apiAIAssistant.sendRealTimeAssistanceUserAction({
179
+ agentId: 'test-agent-id',
180
+ interactionId: 'interaction-1',
181
+ adaptiveCardId: 'adaptive-card-1',
182
+ actionId,
183
+ });
184
+
185
+ expect(mockWebex.request).toHaveBeenCalledTimes(1);
186
+ const requestArgs = (mockWebex.request as jest.Mock).mock.calls[0][0];
187
+ const eventData = requestArgs.body.eventDetails.data;
188
+
189
+ expect(requestArgs.uri).toBe('https://api-ai-assistant.produs1.ciscoccservice.com/event');
190
+ expect(requestArgs.method).toBe(HTTP_METHODS.POST);
191
+ expect(requestArgs.addAuthHeader).toBe(true);
192
+ expect(requestArgs.body.agentId).toBe('test-agent-id');
193
+ expect(requestArgs.body.orgId).toBe('test-org-id');
194
+ expect(requestArgs.body.eventType).toBe('CUSTOM_EVENT');
195
+ expect(requestArgs.body.eventName).toBe('SUGGESTED_RESPONSES_USER_ACTION');
196
+ expect(eventData.interactionId).toBe('interaction-1');
197
+ expect(eventData.adaptiveCardId).toBe('adaptive-card-1');
198
+ expect(eventData.userAction.actionType).toBe('Action.Submit');
199
+ expect(eventData.userAction.actionId).toBe(actionId);
200
+ expect(eventData.languageCode).toBe('en');
201
+ expect(typeof eventData.actionTimeStamp).toBe('string');
202
+ expect(eventData.trackingId.startsWith('WX_CC_SDK_')).toBe(true);
203
+ expect(result).toEqual({ok: true});
204
+ });
205
+ });
206
+
172
207
  it('should fail when base URL mapping is not available', async () => {
173
208
  (mockWebex.internal.services.get as jest.Mock).mockReturnValue('https://unknown-host.invalid');
174
209
 
@@ -179,7 +214,7 @@ describe('ApiAIAssistant', () => {
179
214
  'interaction-1',
180
215
  'CUSTOM_EVENT',
181
216
  'GET_TRANSCRIPTS',
182
- 'STOP'
217
+ {action: 'STOP'}
183
218
  );
184
219
  } catch (_error) {
185
220
  failed = true;
@@ -202,19 +237,37 @@ describe('ApiAIAssistant', () => {
202
237
  expect(errorMessage).toBe('Error while performing fetchHistoricTranscripts');
203
238
  });
204
239
 
205
- it('should fail when suggested responses feature is disabled', async () => {
240
+ it('should fail when real-time assistance feature is disabled', async () => {
241
+ apiAIAssistant.setAIFeatureFlags({suggestedResponses: {enable: false}} as any);
242
+ let errorMessage = '';
243
+
244
+ try {
245
+ await apiAIAssistant.getRealTimeAssistance({
246
+ agentId: 'test-agent-id',
247
+ interactionId: 'interaction-1',
248
+ });
249
+ } catch (error) {
250
+ errorMessage = (error as Error)?.message || '';
251
+ }
252
+
253
+ expect(errorMessage).toBe('Error while performing getRealTimeAssistance');
254
+ });
255
+
256
+ it('should fail to send real-time assistance user action when feature is disabled', async () => {
206
257
  apiAIAssistant.setAIFeatureFlags({suggestedResponses: {enable: false}} as any);
207
258
  let errorMessage = '';
208
259
 
209
260
  try {
210
- await apiAIAssistant.getSuggestedResponse({
261
+ await apiAIAssistant.sendRealTimeAssistanceUserAction({
211
262
  agentId: 'test-agent-id',
212
263
  interactionId: 'interaction-1',
264
+ adaptiveCardId: 'adaptive-card-1',
265
+ actionId: RealTimeAssistanceUserActionId.LIKE,
213
266
  });
214
267
  } catch (error) {
215
268
  errorMessage = (error as Error)?.message || '';
216
269
  }
217
270
 
218
- expect(errorMessage).toBe('Error while performing getSuggestedResponse');
271
+ expect(errorMessage).toBe('Error while performing sendRealTimeAssistanceUserAction');
219
272
  });
220
273
  });
@@ -293,14 +293,14 @@ describe('TaskManager', () => {
293
293
  interactionId,
294
294
  'CUSTOM_EVENT',
295
295
  'GET_TRANSCRIPTS',
296
- 'START'
296
+ {action: 'START'}
297
297
  );
298
298
  expect(mockApiAIAssistant.sendEvent).toHaveBeenCalledWith(
299
299
  'test-agent-id',
300
300
  interactionId,
301
301
  'CUSTOM_EVENT',
302
302
  'GET_TRANSCRIPTS',
303
- 'STOP'
303
+ {action: 'STOP'}
304
304
  );
305
305
  });
306
306