@webex/contact-center 3.12.0-next.9 → 3.12.0-task-refactor.1

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 (200) hide show
  1. package/AGENTS.md +438 -0
  2. package/ai-docs/README.md +131 -0
  3. package/ai-docs/RULES.md +455 -0
  4. package/ai-docs/patterns/event-driven-patterns.md +485 -0
  5. package/ai-docs/patterns/testing-patterns.md +480 -0
  6. package/ai-docs/patterns/typescript-patterns.md +365 -0
  7. package/ai-docs/templates/README.md +102 -0
  8. package/ai-docs/templates/documentation/create-agents-md.md +240 -0
  9. package/ai-docs/templates/documentation/create-architecture-md.md +295 -0
  10. package/ai-docs/templates/existing-service/bug-fix.md +254 -0
  11. package/ai-docs/templates/existing-service/feature-enhancement.md +450 -0
  12. package/ai-docs/templates/new-method/00-master.md +80 -0
  13. package/ai-docs/templates/new-method/01-requirements.md +232 -0
  14. package/ai-docs/templates/new-method/02-implementation.md +295 -0
  15. package/ai-docs/templates/new-method/03-tests.md +201 -0
  16. package/ai-docs/templates/new-method/04-validation.md +141 -0
  17. package/ai-docs/templates/new-service/00-master.md +109 -0
  18. package/ai-docs/templates/new-service/01-pre-questions.md +159 -0
  19. package/ai-docs/templates/new-service/02-code-generation.md +346 -0
  20. package/ai-docs/templates/new-service/03-integration.md +178 -0
  21. package/ai-docs/templates/new-service/04-test-generation.md +205 -0
  22. package/ai-docs/templates/new-service/05-validation.md +145 -0
  23. package/dist/cc.js +65 -123
  24. package/dist/cc.js.map +1 -1
  25. package/dist/constants.js +13 -2
  26. package/dist/constants.js.map +1 -1
  27. package/dist/index.js +13 -5
  28. package/dist/index.js.map +1 -1
  29. package/dist/metrics/behavioral-events.js +26 -13
  30. package/dist/metrics/behavioral-events.js.map +1 -1
  31. package/dist/metrics/constants.js +7 -6
  32. package/dist/metrics/constants.js.map +1 -1
  33. package/dist/services/ApiAiAssistant.js +0 -3
  34. package/dist/services/ApiAiAssistant.js.map +1 -1
  35. package/dist/services/config/Util.js +2 -3
  36. package/dist/services/config/Util.js.map +1 -1
  37. package/dist/services/config/types.js +16 -14
  38. package/dist/services/config/types.js.map +1 -1
  39. package/dist/services/constants.js +0 -1
  40. package/dist/services/constants.js.map +1 -1
  41. package/dist/services/core/Err.js.map +1 -1
  42. package/dist/services/core/Utils.js +79 -55
  43. package/dist/services/core/Utils.js.map +1 -1
  44. package/dist/services/core/aqm-reqs.js +17 -92
  45. package/dist/services/core/aqm-reqs.js.map +1 -1
  46. package/dist/services/core/websocket/WebSocketManager.js +5 -25
  47. package/dist/services/core/websocket/WebSocketManager.js.map +1 -1
  48. package/dist/services/core/websocket/types.js.map +1 -1
  49. package/dist/services/index.js +1 -2
  50. package/dist/services/index.js.map +1 -1
  51. package/dist/services/task/Task.js +644 -0
  52. package/dist/services/task/Task.js.map +1 -0
  53. package/dist/services/task/TaskFactory.js +45 -0
  54. package/dist/services/task/TaskFactory.js.map +1 -0
  55. package/dist/services/task/TaskManager.js +556 -532
  56. package/dist/services/task/TaskManager.js.map +1 -1
  57. package/dist/services/task/TaskUtils.js +132 -28
  58. package/dist/services/task/TaskUtils.js.map +1 -1
  59. package/dist/services/task/constants.js +7 -6
  60. package/dist/services/task/constants.js.map +1 -1
  61. package/dist/services/task/dialer.js +0 -51
  62. package/dist/services/task/dialer.js.map +1 -1
  63. package/dist/services/task/digital/Digital.js +77 -0
  64. package/dist/services/task/digital/Digital.js.map +1 -0
  65. package/dist/services/task/state-machine/TaskStateMachine.js +634 -0
  66. package/dist/services/task/state-machine/TaskStateMachine.js.map +1 -0
  67. package/dist/services/task/state-machine/actions.js +366 -0
  68. package/dist/services/task/state-machine/actions.js.map +1 -0
  69. package/dist/services/task/state-machine/constants.js +139 -0
  70. package/dist/services/task/state-machine/constants.js.map +1 -0
  71. package/dist/services/task/state-machine/guards.js +256 -0
  72. package/dist/services/task/state-machine/guards.js.map +1 -0
  73. package/dist/services/task/state-machine/index.js +53 -0
  74. package/dist/services/task/state-machine/index.js.map +1 -0
  75. package/dist/services/task/state-machine/types.js +54 -0
  76. package/dist/services/task/state-machine/types.js.map +1 -0
  77. package/dist/services/task/state-machine/uiControlsComputer.js +369 -0
  78. package/dist/services/task/state-machine/uiControlsComputer.js.map +1 -0
  79. package/dist/services/task/taskDataNormalizer.js +99 -0
  80. package/dist/services/task/taskDataNormalizer.js.map +1 -0
  81. package/dist/services/task/types.js +157 -18
  82. package/dist/services/task/types.js.map +1 -1
  83. package/dist/services/task/voice/Voice.js +1031 -0
  84. package/dist/services/task/voice/Voice.js.map +1 -0
  85. package/dist/services/task/voice/WebRTC.js +149 -0
  86. package/dist/services/task/voice/WebRTC.js.map +1 -0
  87. package/dist/types/cc.d.ts +4 -33
  88. package/dist/types/constants.d.ts +13 -2
  89. package/dist/types/index.d.ts +11 -5
  90. package/dist/types/metrics/constants.d.ts +5 -3
  91. package/dist/types/services/ApiAiAssistant.d.ts +1 -1
  92. package/dist/types/services/config/types.d.ts +97 -25
  93. package/dist/types/services/core/Err.d.ts +0 -2
  94. package/dist/types/services/core/Utils.d.ts +25 -23
  95. package/dist/types/services/core/aqm-reqs.d.ts +0 -49
  96. package/dist/types/services/core/websocket/WebSocketManager.d.ts +1 -1
  97. package/dist/types/services/core/websocket/connection-service.d.ts +0 -1
  98. package/dist/types/services/core/websocket/types.d.ts +1 -1
  99. package/dist/types/services/index.d.ts +1 -1
  100. package/dist/types/services/task/Task.d.ts +146 -0
  101. package/dist/types/services/task/TaskFactory.d.ts +12 -0
  102. package/dist/types/services/task/TaskUtils.d.ts +39 -8
  103. package/dist/types/services/task/constants.d.ts +5 -4
  104. package/dist/types/services/task/dialer.d.ts +0 -15
  105. package/dist/types/services/task/digital/Digital.d.ts +22 -0
  106. package/dist/types/services/task/state-machine/TaskStateMachine.d.ts +906 -0
  107. package/dist/types/services/task/state-machine/actions.d.ts +8 -0
  108. package/dist/types/services/task/state-machine/constants.d.ts +91 -0
  109. package/dist/types/services/task/state-machine/guards.d.ts +78 -0
  110. package/dist/types/services/task/state-machine/index.d.ts +13 -0
  111. package/dist/types/services/task/state-machine/types.d.ts +256 -0
  112. package/dist/types/services/task/state-machine/uiControlsComputer.d.ts +9 -0
  113. package/dist/types/services/task/taskDataNormalizer.d.ts +10 -0
  114. package/dist/types/services/task/types.d.ts +539 -88
  115. package/dist/types/services/task/voice/Voice.d.ts +183 -0
  116. package/dist/types/services/task/voice/WebRTC.d.ts +53 -0
  117. package/dist/types/types.d.ts +68 -0
  118. package/dist/types/webex.d.ts +1 -0
  119. package/dist/types.js +70 -0
  120. package/dist/types.js.map +1 -1
  121. package/dist/webex.js +14 -2
  122. package/dist/webex.js.map +1 -1
  123. package/package.json +14 -11
  124. package/src/cc.ts +91 -177
  125. package/src/constants.ts +13 -2
  126. package/src/index.ts +14 -5
  127. package/src/metrics/ai-docs/AGENTS.md +348 -0
  128. package/src/metrics/ai-docs/ARCHITECTURE.md +336 -0
  129. package/src/metrics/behavioral-events.ts +28 -14
  130. package/src/metrics/constants.ts +7 -8
  131. package/src/services/ApiAiAssistant.ts +2 -4
  132. package/src/services/agent/ai-docs/AGENTS.md +238 -0
  133. package/src/services/agent/ai-docs/ARCHITECTURE.md +302 -0
  134. package/src/services/ai-docs/AGENTS.md +384 -0
  135. package/src/services/config/Util.ts +2 -3
  136. package/src/services/config/ai-docs/AGENTS.md +253 -0
  137. package/src/services/config/ai-docs/ARCHITECTURE.md +424 -0
  138. package/src/services/config/types.ts +108 -20
  139. package/src/services/constants.ts +0 -1
  140. package/src/services/core/Err.ts +0 -1
  141. package/src/services/core/Utils.ts +90 -67
  142. package/src/services/core/ai-docs/AGENTS.md +379 -0
  143. package/src/services/core/ai-docs/ARCHITECTURE.md +696 -0
  144. package/src/services/core/aqm-reqs.ts +22 -100
  145. package/src/services/core/websocket/WebSocketManager.ts +4 -23
  146. package/src/services/core/websocket/types.ts +1 -1
  147. package/src/services/index.ts +1 -2
  148. package/src/services/task/Task.ts +785 -0
  149. package/src/services/task/TaskFactory.ts +55 -0
  150. package/src/services/task/TaskManager.ts +567 -633
  151. package/src/services/task/TaskUtils.ts +175 -31
  152. package/src/services/task/ai-docs/AGENTS.md +448 -0
  153. package/src/services/task/ai-docs/ARCHITECTURE.md +573 -0
  154. package/src/services/task/constants.ts +5 -4
  155. package/src/services/task/dialer.ts +1 -56
  156. package/src/services/task/digital/Digital.ts +95 -0
  157. package/src/services/task/state-machine/TaskStateMachine.ts +793 -0
  158. package/src/services/task/state-machine/actions.ts +409 -0
  159. package/src/services/task/state-machine/ai-docs/AGENTS.md +495 -0
  160. package/src/services/task/state-machine/ai-docs/ARCHITECTURE.md +1135 -0
  161. package/src/services/task/state-machine/constants.ts +150 -0
  162. package/src/services/task/state-machine/guards.ts +295 -0
  163. package/src/services/task/state-machine/index.ts +28 -0
  164. package/src/services/task/state-machine/types.ts +228 -0
  165. package/src/services/task/state-machine/uiControlsComputer.ts +529 -0
  166. package/src/services/task/taskDataNormalizer.ts +137 -0
  167. package/src/services/task/types.ts +641 -95
  168. package/src/services/task/voice/Voice.ts +1255 -0
  169. package/src/services/task/voice/WebRTC.ts +187 -0
  170. package/src/types.ts +88 -5
  171. package/src/utils/AGENTS.md +276 -0
  172. package/src/webex.js +2 -0
  173. package/test/unit/spec/cc.ts +59 -142
  174. package/test/unit/spec/logger-proxy.ts +70 -0
  175. package/test/unit/spec/services/ApiAiAssistant.ts +17 -0
  176. package/test/unit/spec/services/config/index.ts +26 -55
  177. package/test/unit/spec/services/core/Utils.ts +103 -52
  178. package/test/unit/spec/services/core/websocket/WebSocketManager.ts +48 -112
  179. package/test/unit/spec/services/core/websocket/connection-service.ts +5 -4
  180. package/test/unit/spec/services/task/AutoWrapup.ts +63 -0
  181. package/test/unit/spec/services/task/Task.ts +416 -0
  182. package/test/unit/spec/services/task/TaskFactory.ts +62 -0
  183. package/test/unit/spec/services/task/TaskManager.ts +781 -1735
  184. package/test/unit/spec/services/task/TaskUtils.ts +125 -0
  185. package/test/unit/spec/services/task/dialer.ts +112 -198
  186. package/test/unit/spec/services/task/digital/Digital.ts +105 -0
  187. package/test/unit/spec/services/task/state-machine/TaskStateMachine.ts +473 -0
  188. package/test/unit/spec/services/task/state-machine/guards.ts +288 -0
  189. package/test/unit/spec/services/task/state-machine/types.ts +18 -0
  190. package/test/unit/spec/services/task/state-machine/uiControlsComputer.ts +147 -0
  191. package/test/unit/spec/services/task/taskTestUtils.ts +87 -0
  192. package/test/unit/spec/services/task/voice/Voice.ts +587 -0
  193. package/test/unit/spec/services/task/voice/WebRTC.ts +242 -0
  194. package/umd/contact-center.min.js +2 -2
  195. package/umd/contact-center.min.js.map +1 -1
  196. package/dist/services/task/index.js +0 -1525
  197. package/dist/services/task/index.js.map +0 -1
  198. package/dist/types/services/task/index.d.ts +0 -650
  199. package/src/services/task/index.ts +0 -1801
  200. package/test/unit/spec/services/task/index.ts +0 -2184
@@ -20,40 +20,18 @@ export default class AqmReqs {
20
20
  this.webSocketManager.on('message', this.onMessage.bind(this));
21
21
  }
22
22
 
23
- /**
24
- * Creates a request function for an API call with parameters
25
- * @param c - The configuration for the request
26
- * @returns A function that makes the API request
27
- */
28
23
  req<TRes, TErr, TReq>(c: Conf<TRes, TErr, TReq>): Res<TRes, TReq> {
29
24
  return (p: TReq, cbRes?: CbRes<TRes>) => this.makeAPIRequest(c(p), cbRes);
30
25
  }
31
26
 
32
- /**
33
- * Creates a request function for an API call with no parameters
34
- * @param c - The configuration for the request
35
- * @returns A function that makes the API request
36
- */
37
27
  reqEmpty<TRes, TErr>(c: ConfEmpty<TRes, TErr>): ResEmpty<TRes> {
38
28
  return (cbRes?: CbRes<TRes>) => this.makeAPIRequest(c(), cbRes);
39
29
  }
40
30
 
41
- /**
42
- * Makes an API request
43
- * @param c - The request configuration
44
- * @param cbRes - The callback for the response
45
- * @returns A promise that resolves with the response or rejects with an error
46
- */
47
31
  private async makeAPIRequest<TRes, TErr>(c: Req<TRes, TErr>, cbRes?: CbRes<TRes>): Promise<TRes> {
48
32
  return this.createPromise(c, cbRes);
49
33
  }
50
34
 
51
- /**
52
- * Creates a promise for an API request
53
- * @param c - The request configuration
54
- * @param cbRes - The callback for the response
55
- * @returns A promise that resolves with the response or rejects with an error
56
- */
57
35
  private createPromise<TRes, TErr>(c: Req<TRes, TErr>, cbRes?: CbRes<TRes>) {
58
36
  return new Promise<TRes>((resolve, reject) => {
59
37
  const keySuccess = this.bindPrint(c.notifSuccess.bind);
@@ -176,13 +154,10 @@ export default class AqmReqs {
176
154
  if (response?.headers) {
177
155
  response.headers.Authorization = '*';
178
156
  }
179
- LoggerProxy.error(
180
- `Routing request timeout${keySuccess}${JSON.stringify(response)}${c.url}`,
181
- {
182
- module: AQM_REQS_FILE,
183
- method: METHODS.CREATE_PROMISE,
184
- }
185
- );
157
+ LoggerProxy.error(`Routing request timeout${keySuccess}${response!}${c.url}`, {
158
+ module: AQM_REQS_FILE,
159
+ method: METHODS.CREATE_PROMISE,
160
+ });
186
161
  reject(
187
162
  new Err.Details('Service.aqm.reqs.Timeout', {
188
163
  key: keySuccess,
@@ -196,60 +171,39 @@ export default class AqmReqs {
196
171
  });
197
172
  }
198
173
 
199
- /**
200
- * Converts a bind object to a string representation
201
- * @param bind - The bind object to convert
202
- * @returns A string representation of the bind object
203
- */
204
- private bindPrint(bind: any): string {
174
+ private bindPrint(bind: any) {
205
175
  let result = '';
206
- for (const key of Object.keys(bind).filter((prop) => prop !== '__typeMap')) {
207
- const value = bind[key];
208
-
209
- if (Array.isArray(value)) {
210
- result += `${key}=[${value.join(',')}],`;
211
- } else if (typeof value === 'object' && value !== null) {
212
- result += `${key}=(${this.bindPrint(value)}),`;
176
+ // eslint-disable-next-line no-restricted-syntax
177
+ for (const k in bind) {
178
+ if (Array.isArray(bind[k])) {
179
+ result += `${k}=[${bind[k].join(',')}],`;
180
+ } else if (typeof bind[k] === 'object' && bind[k] !== null) {
181
+ result += `${k}=(${this.bindPrint(bind[k])}),`;
213
182
  } else {
214
- result += `${key}=${value},`;
183
+ result += `${k}=${bind[k]},`;
215
184
  }
216
185
  }
217
186
 
218
187
  return result ? result.slice(0, -1) : result;
219
188
  }
220
189
 
221
- /**
222
- * Checks if a message matches a bind object
223
- * @param bind - The bind object to check against
224
- * @param msg - The message to check
225
- * @returns True if the message matches the bind object, false otherwise
226
- */
227
- private bindCheck(bind: any, msg: any): boolean {
228
- // Handle type-dependent field matching if __typeMap is present
229
- if (bind.__typeMap && typeof bind.__typeMap === 'object') {
230
- if (!AqmReqs.typeMapCheck(bind.__typeMap, msg)) {
231
- return false;
232
- }
233
- }
234
-
235
- for (const key of Object.keys(bind).filter((prop) => prop !== '__typeMap')) {
236
- const bindValue = bind[key];
237
- const msgValue = msg[key];
238
-
239
- if (Array.isArray(bindValue)) {
190
+ private bindCheck(bind: any, msg: any) {
191
+ // eslint-disable-next-line no-restricted-syntax
192
+ for (const k in bind) {
193
+ if (Array.isArray(bind[k])) {
240
194
  // Check if the message value matches any of the values in the array
241
- if (!bindValue.includes(msgValue)) {
195
+ if (!bind[k].includes(msg[k])) {
242
196
  return false;
243
197
  }
244
- } else if (typeof bindValue === 'object' && bindValue !== null) {
245
- if (typeof msgValue === 'object' && msgValue !== null) {
246
- if (!this.bindCheck(bindValue, msgValue)) {
198
+ } else if (typeof bind[k] === 'object' && bind[k] !== null) {
199
+ if (typeof msg[k] === 'object' && msg[k] !== null) {
200
+ if (!this.bindCheck(bind[k], msg[k])) {
247
201
  return false;
248
202
  }
249
203
  } else {
250
204
  return false;
251
205
  }
252
- } else if (!msgValue || msgValue !== bindValue) {
206
+ } else if (!msg[k] || msg[k] !== bind[k]) {
253
207
  return false;
254
208
  }
255
209
  }
@@ -257,39 +211,7 @@ export default class AqmReqs {
257
211
  return true;
258
212
  }
259
213
 
260
- /**
261
- * Checks type-dependent field conditions defined in __typeMap.
262
- * @param typeMap - The type map to check against
263
- * @param msg - The message to check
264
- * @returns True if the message matches the type map, false otherwise
265
- * The typeMap has the shape:
266
- * { typeField: "type", conditions: { EventA: { field: value }, EventB: { field: value } } }
267
- * It reads msg[typeField] to determine which condition set to apply,
268
- * then verifies all fields in that condition match the message.
269
- */
270
- private static typeMapCheck(typeMap: any, msg: any): boolean {
271
- const typeField = typeMap.typeField || 'type';
272
- const msgType = msg[typeField];
273
-
274
- if (typeMap.conditions && typeMap.conditions[msgType]) {
275
- const condition = typeMap.conditions[msgType];
276
- for (const field of Object.keys(condition)) {
277
- if (!msg[field] || msg[field] !== condition[field]) {
278
- return false;
279
- }
280
- }
281
-
282
- return true;
283
- }
284
-
285
- return false;
286
- }
287
-
288
- /**
289
- * Handles incoming messages from the WebSocket (must be a lambda fn)
290
- * @param msg - The message to handle
291
- * @returns
292
- */
214
+ // must be lambda
293
215
  private readonly onMessage = (msg: any) => {
294
216
  const event = JSON.parse(msg);
295
217
  if (event.type === 'Welcome') {
@@ -48,16 +48,8 @@ export class WebSocketManager extends EventEmitter {
48
48
  body: SubscribeRequest;
49
49
  resource: string;
50
50
  }): Promise<WelcomeResponse> {
51
- const {body: connectionConfig, resource} = options;
52
- try {
53
- await this.register(connectionConfig, resource);
54
- } catch (error) {
55
- LoggerProxy.error(`[WebSocketStatus] | Error in registering Websocket ${error}`, {
56
- module: WEB_SOCKET_MANAGER_FILE,
57
- method: METHODS.INIT_WEB_SOCKET,
58
- });
59
- throw error;
60
- }
51
+ const {body, resource} = options;
52
+ await this.register(body, resource);
61
53
 
62
54
  return new Promise((resolve, reject) => {
63
55
  this.welcomePromiseResolve = resolve;
@@ -89,23 +81,11 @@ export class WebSocketManager extends EventEmitter {
89
81
 
90
82
  private async register(connectionConfig: SubscribeRequest, resource: string) {
91
83
  try {
92
- // X-ORGANIZATION-ID header is only required for INT environments
93
- const isIntEnv = this.webex.internal?.services?.isIntegrationEnvironment() || false;
94
- const orgId = this.webex.credentials.getOrgId();
95
-
96
- if (isIntEnv && orgId) {
97
- LoggerProxy.log(`[WebSocketManager] Adding X-ORGANIZATION-ID header for INT environment`, {
98
- module: WEB_SOCKET_MANAGER_FILE,
99
- method: METHODS.REGISTER,
100
- });
101
- }
102
-
103
84
  const subscribeResponse: SubscribeResponse = await this.webex.request({
104
85
  service: WCC_API_GATEWAY,
105
86
  resource,
106
87
  method: HTTP_METHODS.POST,
107
88
  body: connectionConfig,
108
- headers: isIntEnv && orgId ? {'X-ORGANIZATION-ID': orgId} : undefined,
109
89
  });
110
90
  this.url = subscribeResponse.body.webSocketUrl;
111
91
  } catch (e) {
@@ -113,7 +93,6 @@ export class WebSocketManager extends EventEmitter {
113
93
  `Register API Failed, Request to RoutingNotifs websocket registration API failed ${e}`,
114
94
  {module: WEB_SOCKET_MANAGER_FILE, method: METHODS.REGISTER}
115
95
  );
116
- throw e;
117
96
  }
118
97
  }
119
98
 
@@ -214,3 +193,5 @@ export class WebSocketManager extends EventEmitter {
214
193
  }
215
194
  }
216
195
  }
196
+
197
+ export default WebSocketManager;
@@ -1,5 +1,5 @@
1
1
  import {SubscribeRequest} from '../../../types';
2
- import {WebSocketManager} from './WebSocketManager';
2
+ import type WebSocketManager from './WebSocketManager';
3
3
 
4
4
  /**
5
5
  * Options for initializing a connection service.
@@ -25,7 +25,7 @@ export default class Services {
25
25
  public readonly dialer: ReturnType<typeof aqmDialer>;
26
26
  /** WebSocket manager for handling real-time communications */
27
27
  public readonly webSocketManager: WebSocketManager;
28
- /** RTD WebSocket manager for handling realtime transcription */
28
+ /** RTD WebSocket manager for handling real-time transcription */
29
29
  public readonly rtdWebSocketManager: WebSocketManager;
30
30
  /** Connection service for managing websocket connections */
31
31
  public readonly connectionService: ConnectionService;
@@ -41,7 +41,6 @@ export default class Services {
41
41
  constructor(options: {webex: WebexSDK; connectionConfig: SubscribeRequest}) {
42
42
  const {webex, connectionConfig} = options;
43
43
  this.webSocketManager = new WebSocketManager({webex});
44
- // TODO: Implement reconnection logic for this websocket in upcoming PR
45
44
  this.rtdWebSocketManager = new WebSocketManager({webex});
46
45
  const aqmReq = new AqmReqs(this.webSocketManager);
47
46
  this.config = new AgentConfigService();