@webex/contact-center 3.12.0-next.15 → 3.12.0-next.150

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 (322) hide show
  1. package/.sdd/manifest.json +887 -0
  2. package/AGENTS.md +94 -0
  3. package/ai-docs/ARCHITECTURE.md +168 -0
  4. package/ai-docs/CONTRACTS.md +62 -0
  5. package/ai-docs/GETTING_STARTED.md +168 -0
  6. package/ai-docs/GLOSSARY.md +43 -0
  7. package/ai-docs/README.md +138 -0
  8. package/ai-docs/REVIEW_CHECKLIST.md +41 -0
  9. package/ai-docs/RULES.md +444 -0
  10. package/ai-docs/SECURITY.md +52 -0
  11. package/ai-docs/SERVICE_STATE.md +52 -0
  12. package/ai-docs/SPEC_INDEX.md +65 -0
  13. package/ai-docs/adr/0001-spec-source-policy.md +55 -0
  14. package/ai-docs/adr/README.md +8 -0
  15. package/ai-docs/adr/_adr-template.md +31 -0
  16. package/ai-docs/contact-center-spec.md +382 -0
  17. package/ai-docs/features/consult-transfer-list-policy/spec/feature-spec.md +362 -0
  18. package/ai-docs/features/contact-owner-change-refactor.md +78 -0
  19. package/ai-docs/features/generated-spec-conformance-fidelity-remediation/spec/feature-spec.md +117 -0
  20. package/ai-docs/features/residual-warning-coverage-completion/spec/feature-spec.md +203 -0
  21. package/ai-docs/features/validator-code-fidelity-drift-fix/spec/feature-spec.md +315 -0
  22. package/ai-docs/patterns/event-driven-patterns.md +485 -0
  23. package/ai-docs/patterns/testing-patterns.md +480 -0
  24. package/ai-docs/patterns/typescript-patterns.md +365 -0
  25. package/ai-docs/templates/README.md +102 -0
  26. package/ai-docs/templates/documentation/create-agents-md.md +240 -0
  27. package/ai-docs/templates/documentation/create-architecture-md.md +295 -0
  28. package/ai-docs/templates/existing-service/bug-fix.md +254 -0
  29. package/ai-docs/templates/existing-service/feature-enhancement.md +450 -0
  30. package/ai-docs/templates/new-method/00-master.md +80 -0
  31. package/ai-docs/templates/new-method/01-requirements.md +232 -0
  32. package/ai-docs/templates/new-method/02-implementation.md +295 -0
  33. package/ai-docs/templates/new-method/03-tests.md +201 -0
  34. package/ai-docs/templates/new-method/04-validation.md +141 -0
  35. package/ai-docs/templates/new-service/00-master.md +109 -0
  36. package/ai-docs/templates/new-service/01-pre-questions.md +159 -0
  37. package/ai-docs/templates/new-service/02-code-generation.md +346 -0
  38. package/ai-docs/templates/new-service/03-integration.md +178 -0
  39. package/ai-docs/templates/new-service/04-test-generation.md +205 -0
  40. package/ai-docs/templates/new-service/05-validation.md +145 -0
  41. package/dist/cc.js +1010 -47
  42. package/dist/cc.js.map +1 -1
  43. package/dist/config.js +13 -0
  44. package/dist/config.js.map +1 -1
  45. package/dist/constants.js +40 -3
  46. package/dist/constants.js.map +1 -1
  47. package/dist/index.js +54 -17
  48. package/dist/index.js.map +1 -1
  49. package/dist/metrics/MetricsManager.js +16 -0
  50. package/dist/metrics/MetricsManager.js.map +1 -1
  51. package/dist/metrics/behavioral-events.js +211 -0
  52. package/dist/metrics/behavioral-events.js.map +1 -1
  53. package/dist/metrics/constants.js +58 -4
  54. package/dist/metrics/constants.js.map +1 -1
  55. package/dist/services/AddressBook.js +18 -15
  56. package/dist/services/AddressBook.js.map +1 -1
  57. package/dist/services/AnswerCallOnWebexService.js +202 -0
  58. package/dist/services/AnswerCallOnWebexService.js.map +1 -0
  59. package/dist/services/ApiAiAssistant.js +351 -14
  60. package/dist/services/ApiAiAssistant.js.map +1 -1
  61. package/dist/services/EntryPoint.js +46 -68
  62. package/dist/services/EntryPoint.js.map +1 -1
  63. package/dist/services/Queue.js +27 -22
  64. package/dist/services/Queue.js.map +1 -1
  65. package/dist/services/UserPreference.js +427 -0
  66. package/dist/services/UserPreference.js.map +1 -0
  67. package/dist/services/WebexCrossClientService.js +225 -0
  68. package/dist/services/WebexCrossClientService.js.map +1 -0
  69. package/dist/services/WxAppTelephonyMercurySync.js +111 -0
  70. package/dist/services/WxAppTelephonyMercurySync.js.map +1 -0
  71. package/dist/services/config/Util.js +48 -48
  72. package/dist/services/config/Util.js.map +1 -1
  73. package/dist/services/config/constants.js +56 -78
  74. package/dist/services/config/constants.js.map +1 -1
  75. package/dist/services/config/index.js +100 -226
  76. package/dist/services/config/index.js.map +1 -1
  77. package/dist/services/config/types.js +97 -24
  78. package/dist/services/config/types.js.map +1 -1
  79. package/dist/services/core/Err.js.map +1 -1
  80. package/dist/services/core/Utils.js +111 -32
  81. package/dist/services/core/Utils.js.map +1 -1
  82. package/dist/services/core/WebexRequest.js +6 -2
  83. package/dist/services/core/WebexRequest.js.map +1 -1
  84. package/dist/services/core/aqm-reqs.js +28 -14
  85. package/dist/services/core/aqm-reqs.js.map +1 -1
  86. package/dist/services/core/types.js.map +1 -1
  87. package/dist/services/core/websocket/WebSocketManager.js +2 -1
  88. package/dist/services/core/websocket/WebSocketManager.js.map +1 -1
  89. package/dist/services/core/websocket/types.js.map +1 -1
  90. package/dist/services/index.js +1 -1
  91. package/dist/services/index.js.map +1 -1
  92. package/dist/services/task/Task.js +955 -0
  93. package/dist/services/task/Task.js.map +1 -0
  94. package/dist/services/task/TaskFactory.js +50 -0
  95. package/dist/services/task/TaskFactory.js.map +1 -0
  96. package/dist/services/task/TaskManager.js +1272 -523
  97. package/dist/services/task/TaskManager.js.map +1 -1
  98. package/dist/services/task/TaskUtils.js +221 -27
  99. package/dist/services/task/TaskUtils.js.map +1 -1
  100. package/dist/services/task/WebexCallingUtils.js +70 -0
  101. package/dist/services/task/WebexCallingUtils.js.map +1 -0
  102. package/dist/services/task/constants.js +21 -2
  103. package/dist/services/task/constants.js.map +1 -1
  104. package/dist/services/task/contact.js +29 -0
  105. package/dist/services/task/contact.js.map +1 -1
  106. package/dist/services/task/dialer.js +78 -0
  107. package/dist/services/task/dialer.js.map +1 -1
  108. package/dist/services/task/digital/Digital.js +78 -0
  109. package/dist/services/task/digital/Digital.js.map +1 -0
  110. package/dist/services/task/state-machine/TaskStateMachine.js +982 -0
  111. package/dist/services/task/state-machine/TaskStateMachine.js.map +1 -0
  112. package/dist/services/task/state-machine/actions.js +572 -0
  113. package/dist/services/task/state-machine/actions.js.map +1 -0
  114. package/dist/services/task/state-machine/constants.js +161 -0
  115. package/dist/services/task/state-machine/constants.js.map +1 -0
  116. package/dist/services/task/state-machine/guards.js +379 -0
  117. package/dist/services/task/state-machine/guards.js.map +1 -0
  118. package/dist/services/task/state-machine/index.js +53 -0
  119. package/dist/services/task/state-machine/index.js.map +1 -0
  120. package/dist/services/task/state-machine/types.js +54 -0
  121. package/dist/services/task/state-machine/types.js.map +1 -0
  122. package/dist/services/task/state-machine/uiControlsComputer.js +703 -0
  123. package/dist/services/task/state-machine/uiControlsComputer.js.map +1 -0
  124. package/dist/services/task/taskDataNormalizer.js +99 -0
  125. package/dist/services/task/taskDataNormalizer.js.map +1 -0
  126. package/dist/services/task/types.js +259 -5
  127. package/dist/services/task/types.js.map +1 -1
  128. package/dist/services/task/voice/Voice.js +1504 -0
  129. package/dist/services/task/voice/Voice.js.map +1 -0
  130. package/dist/services/task/voice/WebRTC.js +152 -0
  131. package/dist/services/task/voice/WebRTC.js.map +1 -0
  132. package/dist/services/task/voice/wxAppOfferObservability.js +145 -0
  133. package/dist/services/task/voice/wxAppOfferObservability.js.map +1 -0
  134. package/dist/services/task/voice/wxAppVoiceMethods.js +395 -0
  135. package/dist/services/task/voice/wxAppVoiceMethods.js.map +1 -0
  136. package/dist/services/wxAppDiagnosticLogging.js +159 -0
  137. package/dist/services/wxAppDiagnosticLogging.js.map +1 -0
  138. package/dist/services/wxAppTelephonyUtils.js +19 -0
  139. package/dist/services/wxAppTelephonyUtils.js.map +1 -0
  140. package/dist/types/cc.d.ts +196 -9
  141. package/dist/types/config.d.ts +13 -0
  142. package/dist/types/constants.d.ts +38 -1
  143. package/dist/types/index.d.ts +54 -20
  144. package/dist/types/metrics/MetricsManager.d.ts +6 -0
  145. package/dist/types/metrics/constants.d.ts +52 -1
  146. package/dist/types/services/AddressBook.d.ts +2 -1
  147. package/dist/types/services/AnswerCallOnWebexService.d.ts +38 -0
  148. package/dist/types/services/ApiAiAssistant.d.ts +58 -5
  149. package/dist/types/services/EntryPoint.d.ts +7 -5
  150. package/dist/types/services/Queue.d.ts +5 -3
  151. package/dist/types/services/UserPreference.d.ts +118 -0
  152. package/dist/types/services/WebexCrossClientService.d.ts +32 -0
  153. package/dist/types/services/WxAppTelephonyMercurySync.d.ts +28 -0
  154. package/dist/types/services/config/Util.d.ts +4 -8
  155. package/dist/types/services/config/constants.d.ts +49 -76
  156. package/dist/types/services/config/index.d.ts +16 -64
  157. package/dist/types/services/config/types.d.ts +248 -114
  158. package/dist/types/services/core/Err.d.ts +6 -0
  159. package/dist/types/services/core/Utils.d.ts +35 -13
  160. package/dist/types/services/core/WebexRequest.d.ts +1 -0
  161. package/dist/types/services/core/types.d.ts +2 -0
  162. package/dist/types/services/core/websocket/WebSocketManager.d.ts +1 -0
  163. package/dist/types/services/core/websocket/types.d.ts +1 -1
  164. package/dist/types/services/index.d.ts +1 -1
  165. package/dist/types/services/task/Task.d.ts +186 -0
  166. package/dist/types/services/task/TaskFactory.d.ts +14 -0
  167. package/dist/types/services/task/TaskUtils.d.ts +54 -2
  168. package/dist/types/services/task/WebexCallingUtils.d.ts +11 -0
  169. package/dist/types/services/task/constants.d.ts +19 -0
  170. package/dist/types/services/task/contact.d.ts +4 -0
  171. package/dist/types/services/task/dialer.d.ts +30 -0
  172. package/dist/types/services/task/digital/Digital.d.ts +23 -0
  173. package/dist/types/services/task/state-machine/TaskStateMachine.d.ts +1442 -0
  174. package/dist/types/services/task/state-machine/actions.d.ts +10 -0
  175. package/dist/types/services/task/state-machine/constants.d.ts +107 -0
  176. package/dist/types/services/task/state-machine/guards.d.ts +103 -0
  177. package/dist/types/services/task/state-machine/index.d.ts +13 -0
  178. package/dist/types/services/task/state-machine/types.d.ts +277 -0
  179. package/dist/types/services/task/state-machine/uiControlsComputer.d.ts +9 -0
  180. package/dist/types/services/task/taskDataNormalizer.d.ts +10 -0
  181. package/dist/types/services/task/types.d.ts +790 -66
  182. package/dist/types/services/task/voice/Voice.d.ts +241 -0
  183. package/dist/types/services/task/voice/WebRTC.d.ts +54 -0
  184. package/dist/types/services/task/voice/wxAppOfferObservability.d.ts +39 -0
  185. package/dist/types/services/task/voice/wxAppVoiceMethods.d.ts +68 -0
  186. package/dist/types/services/wxAppDiagnosticLogging.d.ts +63 -0
  187. package/dist/types/services/wxAppTelephonyUtils.d.ts +5 -0
  188. package/dist/types/types.d.ts +213 -11
  189. package/dist/types/utils/PageCache.d.ts +20 -3
  190. package/dist/types/webex.d.ts +1 -0
  191. package/dist/types.js +168 -6
  192. package/dist/types.js.map +1 -1
  193. package/dist/utils/PageCache.js +19 -5
  194. package/dist/utils/PageCache.js.map +1 -1
  195. package/dist/webex.js +22 -2
  196. package/dist/webex.js.map +1 -1
  197. package/package.json +16 -12
  198. package/src/cc.ts +1338 -121
  199. package/src/config.ts +13 -0
  200. package/src/constants.ts +41 -1
  201. package/src/index.ts +62 -15
  202. package/src/metrics/MetricsManager.ts +16 -0
  203. package/src/metrics/ai-docs/AGENTS.md +350 -0
  204. package/src/metrics/ai-docs/ARCHITECTURE.md +338 -0
  205. package/src/metrics/ai-docs/metrics-spec.md +971 -0
  206. package/src/metrics/behavioral-events.ts +218 -0
  207. package/src/metrics/constants.ts +63 -4
  208. package/src/services/AddressBook.ts +17 -6
  209. package/src/services/AnswerCallOnWebexService.ts +239 -0
  210. package/src/services/ApiAiAssistant.ts +470 -15
  211. package/src/services/EntryPoint.ts +59 -60
  212. package/src/services/Queue.ts +29 -12
  213. package/src/services/UserPreference.ts +509 -0
  214. package/src/services/WebexCrossClientService.ts +298 -0
  215. package/src/services/WxAppTelephonyMercurySync.ts +142 -0
  216. package/src/services/agent/ai-docs/AGENTS.md +240 -0
  217. package/src/services/agent/ai-docs/ARCHITECTURE.md +304 -0
  218. package/src/services/agent/ai-docs/agent-spec.md +505 -0
  219. package/src/services/ai-docs/AGENTS.md +386 -0
  220. package/src/services/ai-docs/services-spec.md +505 -0
  221. package/src/services/config/Util.ts +54 -84
  222. package/src/services/config/ai-docs/AGENTS.md +250 -0
  223. package/src/services/config/ai-docs/ARCHITECTURE.md +413 -0
  224. package/src/services/config/ai-docs/config-spec.md +669 -0
  225. package/src/services/config/constants.ts +63 -85
  226. package/src/services/config/index.ts +116 -277
  227. package/src/services/config/types.ts +233 -125
  228. package/src/services/core/Err.ts +3 -0
  229. package/src/services/core/Utils.ts +127 -37
  230. package/src/services/core/WebexRequest.ts +3 -1
  231. package/src/services/core/ai-docs/AGENTS.md +381 -0
  232. package/src/services/core/ai-docs/ARCHITECTURE.md +698 -0
  233. package/src/services/core/ai-docs/core-spec.md +787 -0
  234. package/src/services/core/aqm-reqs.ts +30 -15
  235. package/src/services/core/types.ts +33 -1
  236. package/src/services/core/websocket/WebSocketManager.ts +2 -0
  237. package/src/services/core/websocket/types.ts +1 -1
  238. package/src/services/index.ts +1 -1
  239. package/src/services/task/Task.ts +1211 -0
  240. package/src/services/task/TaskFactory.ts +82 -0
  241. package/src/services/task/TaskManager.ts +1584 -643
  242. package/src/services/task/TaskUtils.ts +316 -25
  243. package/src/services/task/WebexCallingUtils.ts +136 -0
  244. package/src/services/task/ai-docs/AGENTS.md +457 -0
  245. package/src/services/task/ai-docs/ARCHITECTURE.md +595 -0
  246. package/src/services/task/ai-docs/task-spec.md +1501 -0
  247. package/src/services/task/constants.ts +20 -0
  248. package/src/services/task/contact.ts +30 -0
  249. package/src/services/task/dialer.ts +80 -0
  250. package/src/services/task/digital/Digital.ts +102 -0
  251. package/src/services/task/state-machine/TaskStateMachine.ts +1320 -0
  252. package/src/services/task/state-machine/actions.ts +741 -0
  253. package/src/services/task/state-machine/ai-docs/AGENTS.md +460 -0
  254. package/src/services/task/state-machine/ai-docs/ARCHITECTURE.md +1156 -0
  255. package/src/services/task/state-machine/ai-docs/task-state-machine-spec.md +2247 -0
  256. package/src/services/task/state-machine/constants.ts +172 -0
  257. package/src/services/task/state-machine/guards.ts +442 -0
  258. package/src/services/task/state-machine/index.ts +28 -0
  259. package/src/services/task/state-machine/types.ts +258 -0
  260. package/src/services/task/state-machine/uiControlsComputer.ts +1135 -0
  261. package/src/services/task/taskDataNormalizer.ts +137 -0
  262. package/src/services/task/types.ts +974 -70
  263. package/src/services/task/voice/Voice.ts +1878 -0
  264. package/src/services/task/voice/WebRTC.ts +194 -0
  265. package/src/services/task/voice/wxAppOfferObservability.ts +204 -0
  266. package/src/services/task/voice/wxAppVoiceMethods.ts +575 -0
  267. package/src/services/wxAppDiagnosticLogging.ts +286 -0
  268. package/src/services/wxAppTelephonyUtils.ts +14 -0
  269. package/src/types.ts +272 -13
  270. package/src/utils/AGENTS.md +289 -0
  271. package/src/utils/PageCache.ts +38 -5
  272. package/src/utils/ai-docs/utils-spec.md +391 -0
  273. package/src/webex.js +10 -0
  274. package/test/unit/fixtures/aiSummaryTestUtils.ts +40 -0
  275. package/test/unit/spec/cc.ts +3705 -150
  276. package/test/unit/spec/index.ts +885 -0
  277. package/test/unit/spec/logger-proxy.ts +70 -0
  278. package/test/unit/spec/metrics/MetricsManager.ts +25 -0
  279. package/test/unit/spec/metrics/behavioral-events.ts +60 -0
  280. package/test/unit/spec/services/AddressBook.ts +37 -6
  281. package/test/unit/spec/services/AnswerCallOnWebexService.ts +264 -0
  282. package/test/unit/spec/services/ApiAiAssistant.ts +429 -23
  283. package/test/unit/spec/services/EntryPoint.ts +87 -40
  284. package/test/unit/spec/services/Queue.ts +123 -12
  285. package/test/unit/spec/services/UserPreference.ts +401 -0
  286. package/test/unit/spec/services/WebCallingService.ts +7 -1
  287. package/test/unit/spec/services/WebexCrossClientService.ts +509 -0
  288. package/test/unit/spec/services/WxAppTelephonyMercurySync.ts +136 -0
  289. package/test/unit/spec/services/config/Util.ts +501 -0
  290. package/test/unit/spec/services/config/index.ts +317 -547
  291. package/test/unit/spec/services/core/Utils.ts +425 -8
  292. package/test/unit/spec/services/core/WebexRequest.ts +8 -7
  293. package/test/unit/spec/services/core/aqm-reqs.ts +113 -1
  294. package/test/unit/spec/services/core/websocket/WebSocketManager.ts +66 -40
  295. package/test/unit/spec/services/task/AutoWrapup.ts +63 -0
  296. package/test/unit/spec/services/task/Task.ts +2723 -0
  297. package/test/unit/spec/services/task/TaskFactory.ts +116 -0
  298. package/test/unit/spec/services/task/TaskManager.ts +4781 -1585
  299. package/test/unit/spec/services/task/TaskUtils.ts +307 -0
  300. package/test/unit/spec/services/task/WebexCallingUtils.ts +153 -0
  301. package/test/unit/spec/services/task/contact.ts +33 -0
  302. package/test/unit/spec/services/task/dialer.ts +190 -0
  303. package/test/unit/spec/services/task/digital/Digital.ts +105 -0
  304. package/test/unit/spec/services/task/state-machine/TaskStateMachine.ts +4060 -0
  305. package/test/unit/spec/services/task/state-machine/guards.ts +839 -0
  306. package/test/unit/spec/services/task/state-machine/types.ts +18 -0
  307. package/test/unit/spec/services/task/state-machine/uiControlsComputer.ts +3101 -0
  308. package/test/unit/spec/services/task/taskTestUtils.ts +87 -0
  309. package/test/unit/spec/services/task/voice/Voice.ts +2355 -0
  310. package/test/unit/spec/services/task/voice/WebRTC.ts +235 -0
  311. package/test/unit/spec/services/task/voice/wxAppOfferObservability.ts +361 -0
  312. package/test/unit/spec/services/task/voice/wxAppVoiceMethods.ts +719 -0
  313. package/test/unit/spec/services/wxAppDiagnosticLogging.ts +179 -0
  314. package/test/unit/spec/wellnessSampleUtils.ts +288 -0
  315. package/typedoc.md +1 -1
  316. package/umd/contact-center.min.js +2 -2
  317. package/umd/contact-center.min.js.map +1 -1
  318. package/dist/services/task/index.js +0 -1530
  319. package/dist/services/task/index.js.map +0 -1
  320. package/dist/types/services/task/index.d.ts +0 -650
  321. package/src/services/task/index.ts +0 -1806
  322. package/test/unit/spec/services/task/index.ts +0 -2205
@@ -1,17 +1,24 @@
1
+ import {v4 as uuidv4} from 'uuid';
1
2
  import LoggerProxy from '../logger-proxy';
2
3
  import MetricsManager from '../metrics/MetricsManager';
3
4
  import {METRIC_EVENT_NAMES} from '../metrics/constants';
4
- import {CC_FILE, METHODS} from '../constants';
5
+ import {AI_SUMMARY_ERROR_CODES, CC_FILE, METHODS} from '../constants';
5
6
  import {
6
7
  HTTP_METHODS,
7
8
  WebexSDK,
8
9
  IHttpResponse,
9
- TranscriptAction,
10
10
  AIAssistantEventType,
11
11
  AIAssistantEventName,
12
12
  HistoricTranscriptsResponse,
13
+ RealTimeAssistanceParams,
14
+ RealTimeAssistanceUserActionParams,
15
+ RespondToWellnessBreakParams,
16
+ WellnessBreakUserAction,
17
+ WELLNESS_BREAK_USER_ACTIONS,
18
+ GenericError,
13
19
  } from '../types';
14
20
  import {getErrorDetails} from './core/Utils';
21
+ import type {PendingRtdRequest, RtdRequestOptions} from './core/types';
15
22
  import {
16
23
  AI_ASSISTANT_BASE_URL_TEMPLATE,
17
24
  AI_ASSISTANT_ENV_MAP,
@@ -20,6 +27,12 @@ import {
20
27
  } from './constants';
21
28
  import {AIFeatureFlags} from './config/types';
22
29
 
30
+ type WellnessBreakContextProvider = () => {
31
+ isWellnessBreakEnabled: boolean;
32
+ agentId?: string;
33
+ agentSessionId?: string;
34
+ };
35
+
23
36
  /**
24
37
  * ApiAIAssistant provides AI Assistant APIs for transcript controls.
25
38
  * @public
@@ -27,10 +40,26 @@ import {AIFeatureFlags} from './config/types';
27
40
  export class ApiAIAssistant {
28
41
  private webex: WebexSDK;
29
42
  private metricsManager: MetricsManager;
43
+ /** @internal Current AI flags from the agent configuration. */
30
44
  public aiFeature: AIFeatureFlags;
45
+ private pendingRtdRequests = new Map<string, PendingRtdRequest<unknown>>();
46
+ private readonly wellnessContextProvider?: WellnessBreakContextProvider;
47
+
48
+ private createWellnessError(reason: string): GenericError {
49
+ const error = new Error(reason) as GenericError;
50
+ error.details = {
51
+ type: 'SDK_VALIDATION_ERROR',
52
+ orgId: this.webex.credentials.getOrgId(),
53
+ trackingId: '',
54
+ data: {reason},
55
+ };
56
+
57
+ return error;
58
+ }
31
59
 
32
- constructor(webex: WebexSDK) {
60
+ constructor(webex: WebexSDK, wellnessContextProvider?: WellnessBreakContextProvider) {
33
61
  this.webex = webex;
62
+ this.wellnessContextProvider = wellnessContextProvider;
34
63
  this.metricsManager = MetricsManager.getInstance({webex});
35
64
  }
36
65
 
@@ -38,12 +67,140 @@ export class ApiAIAssistant {
38
67
  this.aiFeature = aiFeature;
39
68
  }
40
69
 
70
+ private async sendWellnessBreakAction(
71
+ action: WellnessBreakUserAction,
72
+ method: string
73
+ ): Promise<void> {
74
+ this.metricsManager.timeEvent([
75
+ METRIC_EVENT_NAMES.AI_ASSISTANT_WELLNESS_ACTION_ACCEPTED,
76
+ METRIC_EVENT_NAMES.AI_ASSISTANT_WELLNESS_ACTION_FAILED,
77
+ ]);
78
+
79
+ try {
80
+ const context = this.wellnessContextProvider?.();
81
+ const agentId = context?.agentId?.trim();
82
+ const agentSessionId = context?.agentSessionId?.trim();
83
+ const orgId = this.webex.credentials.getOrgId()?.trim();
84
+
85
+ if (context?.isWellnessBreakEnabled !== true) {
86
+ throw this.createWellnessError('WELLNESS_BREAK_NOT_ENABLED');
87
+ }
88
+ if (!orgId) {
89
+ throw this.createWellnessError('WELLNESS_BREAK_ORG_ID_REQUIRED');
90
+ }
91
+ if (!agentId) {
92
+ throw this.createWellnessError('WELLNESS_BREAK_AGENT_ID_REQUIRED');
93
+ }
94
+ if (!agentSessionId) {
95
+ throw this.createWellnessError('WELLNESS_BREAK_AGENT_SESSION_REQUIRED');
96
+ }
97
+
98
+ const baseUrl = this.getBaseUrl();
99
+ const response = (await this.webex.request({
100
+ uri: `${baseUrl}${AI_ASSISTANT_API_URLS.EVENT}`,
101
+ method: HTTP_METHODS.POST,
102
+ addAuthHeader: true,
103
+ body: {
104
+ agentId,
105
+ orgId,
106
+ eventType: AIAssistantEventType.CUSTOM_EVENT,
107
+ eventName: AIAssistantEventName.WELLNESS_BREAK_ACTION,
108
+ eventDetails: {
109
+ data: {
110
+ action,
111
+ agentSessionId,
112
+ actionTimeStamp: Date.now(),
113
+ },
114
+ },
115
+ },
116
+ })) as IHttpResponse;
117
+
118
+ if (response.statusCode !== 202) {
119
+ throw this.createWellnessError(
120
+ `WELLNESS_BREAK_ACTION_UNEXPECTED_STATUS_${response.statusCode}`
121
+ );
122
+ }
123
+
124
+ this.metricsManager.trackEvent(
125
+ METRIC_EVENT_NAMES.AI_ASSISTANT_WELLNESS_ACTION_ACCEPTED,
126
+ {action},
127
+ ['operational']
128
+ );
129
+ LoggerProxy.log('Wellness action accepted by AI Assistant', {
130
+ module: CC_FILE,
131
+ method,
132
+ data: {action},
133
+ });
134
+ } catch (error) {
135
+ this.metricsManager.trackEvent(
136
+ METRIC_EVENT_NAMES.AI_ASSISTANT_WELLNESS_ACTION_FAILED,
137
+ {
138
+ action,
139
+ error: error instanceof Error ? error.message : String(error),
140
+ },
141
+ ['operational']
142
+ );
143
+ const {error: detailedError} = getErrorDetails(error, method, CC_FILE);
144
+ throw detailedError;
145
+ }
146
+ }
147
+
148
+ /**
149
+ * Requests an Agent Wellness Break.
150
+ * The promise resolves when the HTTP request is accepted with status 202; the later
151
+ * approval or denial is delivered independently through a wellness notification.
152
+ * @returns A promise that resolves with no value after HTTP acceptance
153
+ * @throws Structured Contact Center error when disabled, stale, invalid, or delivery fails
154
+ * @example
155
+ * await webex.cc.apiAIAssistant.requestWellnessBreak();
156
+ * @public
157
+ */
158
+ public async requestWellnessBreak(): Promise<void> {
159
+ return this.sendWellnessBreakAction(
160
+ WELLNESS_BREAK_USER_ACTIONS.REQUESTED,
161
+ METHODS.REQUEST_WELLNESS_BREAK
162
+ );
163
+ }
164
+
165
+ /**
166
+ * Responds to a backend-provided Agent Wellness Break offer.
167
+ * The promise resolves when the HTTP request is accepted with status 202 and does not
168
+ * wait for a WebSocket completion event.
169
+ * @param params - ACCEPTED, REJECTED, or NO_RESPONSE
170
+ * @returns A promise that resolves with no value after HTTP acceptance
171
+ * @throws Structured Contact Center error when disabled, stale, invalid, or delivery fails
172
+ * @example
173
+ * await webex.cc.apiAIAssistant.respondToWellnessBreak({
174
+ * action: WELLNESS_BREAK_USER_ACTIONS.ACCEPTED,
175
+ * });
176
+ * @public
177
+ */
178
+ public async respondToWellnessBreak(params: RespondToWellnessBreakParams): Promise<void> {
179
+ const {action} = params;
180
+ if (
181
+ ![
182
+ WELLNESS_BREAK_USER_ACTIONS.ACCEPTED,
183
+ WELLNESS_BREAK_USER_ACTIONS.REJECTED,
184
+ WELLNESS_BREAK_USER_ACTIONS.NO_RESPONSE,
185
+ ].includes(action)
186
+ ) {
187
+ const {error} = getErrorDetails(
188
+ this.createWellnessError('WELLNESS_BREAK_ACTION_INVALID'),
189
+ METHODS.RESPOND_TO_WELLNESS_BREAK,
190
+ CC_FILE
191
+ );
192
+ throw error;
193
+ }
194
+
195
+ return this.sendWellnessBreakAction(action, METHODS.RESPOND_TO_WELLNESS_BREAK);
196
+ }
197
+
41
198
  private getBaseUrl(): string {
42
199
  const wccApiGatewayUrl = this.webex.internal.services.get(WCC_API_GATEWAY) || '';
43
200
 
44
201
  if (!wccApiGatewayUrl) {
45
202
  const {error: detailedError} = getErrorDetails(
46
- new Error('AI_ASSISTANT_BASE_URL_NOT_AVAILABLE'),
203
+ new Error(AI_SUMMARY_ERROR_CODES.AI_ASSISTANT_BASE_URL_NOT_AVAILABLE),
47
204
  METHODS.GET_BASE_URL,
48
205
  CC_FILE
49
206
  );
@@ -58,9 +215,10 @@ export class ApiAIAssistant {
58
215
  }
59
216
 
60
217
  const resolvedEnv = AI_ASSISTANT_ENV_MAP[hostname];
218
+
61
219
  if (!resolvedEnv) {
62
220
  const {error: detailedError} = getErrorDetails(
63
- new Error('AI_ASSISTANT_BASE_URL_NOT_AVAILABLE'),
221
+ new Error(AI_SUMMARY_ERROR_CODES.AI_ASSISTANT_BASE_URL_NOT_AVAILABLE),
64
222
  METHODS.GET_BASE_URL,
65
223
  CC_FILE
66
224
  );
@@ -70,26 +228,131 @@ export class ApiAIAssistant {
70
228
  return AI_ASSISTANT_BASE_URL_TEMPLATE.replace('%s', resolvedEnv);
71
229
  }
72
230
 
231
+ private static getRtdRequestKey(rtdEventType: string, correlationId: string): string {
232
+ return JSON.stringify([rtdEventType, correlationId]);
233
+ }
234
+
235
+ private removeRtdRequest<T>(
236
+ rtdEventType: string,
237
+ correlationId: string,
238
+ settle?: (request: PendingRtdRequest<T>) => void
239
+ ): PendingRtdRequest<T> | undefined {
240
+ const key = ApiAIAssistant.getRtdRequestKey(rtdEventType, correlationId);
241
+ const request = this.pendingRtdRequests.get(key) as PendingRtdRequest<T> | undefined;
242
+
243
+ if (!request) {
244
+ return undefined;
245
+ }
246
+
247
+ if (request.timeoutId) {
248
+ clearTimeout(request.timeoutId);
249
+ }
250
+
251
+ settle?.(request);
252
+ this.pendingRtdRequests.delete(key);
253
+
254
+ return request;
255
+ }
256
+
257
+ /** Sends an AI event and waits for its matching RTD response. @internal */
258
+ public async requestAndWaitForRtd<T>(options: RtdRequestOptions): Promise<T> {
259
+ const key = ApiAIAssistant.getRtdRequestKey(options.rtdEventType, options.correlationId);
260
+ let resolveResult: (payload: T) => void = () => undefined;
261
+ let rejectResult: (error: Error) => void = () => undefined;
262
+ const result = new Promise<T>((resolve, reject) => {
263
+ resolveResult = resolve;
264
+ rejectResult = reject;
265
+ });
266
+ const previousRequest = this.pendingRtdRequests.get(key);
267
+ if (previousRequest?.timeoutId) {
268
+ clearTimeout(previousRequest.timeoutId);
269
+ }
270
+ const request: PendingRtdRequest<T> = {
271
+ correlationId: options.correlationId,
272
+ rtdEventType: options.rtdEventType,
273
+ resolve: resolveResult,
274
+ reject: rejectResult,
275
+ };
276
+
277
+ request.timeoutId = setTimeout(() => {
278
+ this.removeRtdRequest<T>(options.rtdEventType, options.correlationId, (currentRequest) => {
279
+ currentRequest.reject(options.createTimeoutError());
280
+ });
281
+ }, options.timeoutMs);
282
+ this.pendingRtdRequests.set(key, request as PendingRtdRequest<unknown>);
283
+ const publishTimestamp = options.publishTimestamp ?? Date.now();
284
+ const acknowledgement = Promise.resolve()
285
+ .then(() =>
286
+ this.sendEvent(
287
+ options.agentId,
288
+ options.interactionId,
289
+ options.eventType,
290
+ options.eventName,
291
+ options.eventMetaData,
292
+ undefined,
293
+ undefined,
294
+ publishTimestamp,
295
+ options.timeout
296
+ )
297
+ )
298
+ .catch((error) => {
299
+ this.removeRtdRequest(options.rtdEventType, options.correlationId);
300
+ throw error;
301
+ });
302
+
303
+ const [payload] = await Promise.all([result, acknowledgement]);
304
+
305
+ return payload;
306
+ }
307
+
308
+ /** Resolves a pending request from a parsed RTD event. @internal */
309
+ public resolveFromRtdEvent<T>(
310
+ rtdEventType: string,
311
+ correlationId: string,
312
+ payload: T
313
+ ): 'resolved' | 'not-found' {
314
+ const request = this.removeRtdRequest<T>(rtdEventType, correlationId, (currentRequest) => {
315
+ currentRequest.resolve(payload);
316
+ });
317
+
318
+ return request ? 'resolved' : 'not-found';
319
+ }
320
+
321
+ /** Clears pending RTD requests when the RTD lifecycle ends. @internal */
322
+ public clearAllRtdRequests(): void {
323
+ Array.from(this.pendingRtdRequests.values()).forEach((request) => {
324
+ this.removeRtdRequest(request.rtdEventType, request.correlationId, (currentRequest) => {
325
+ currentRequest.reject(new Error('RTD request cleared'));
326
+ });
327
+ });
328
+ }
329
+
73
330
  /**
74
331
  * Sends an event to the AI Assistant service.
75
332
  * @param agentId - agent identifier
76
333
  * @param interactionId - interaction/conversation identifier
77
334
  * @param eventType - the type of event (e.g. 'CUSTOM_EVENT')
78
335
  * @param eventName - the name of the event (e.g. 'GET_TRANSCRIPTS')
79
- * @param action - action within eventDetails (e.g. 'START' or 'STOP')
336
+ * @param eventMetaData - event-specific fields to include in eventDetails.data
337
+ * @param languageCode - language code within eventDetails.data
338
+ * @param trackingId - tracking identifier within eventDetails.data
80
339
  */
81
340
  public async sendEvent(
82
341
  agentId: string,
83
342
  interactionId: string,
84
343
  eventType: AIAssistantEventType,
85
344
  eventName: AIAssistantEventName,
86
- action: TranscriptAction
345
+ eventMetaData?: Record<string, unknown>,
346
+ languageCode?: string,
347
+ trackingId?: string,
348
+ publishTimestamp?: number,
349
+ timeout?: number
87
350
  ): Promise<Record<string, unknown>> {
88
351
  LoggerProxy.info('Sending event', {
89
352
  module: CC_FILE,
90
353
  method: METHODS.SEND_EVENT,
91
354
  interactionId,
92
- data: {eventType, eventName, action},
355
+ data: {eventType, eventName, eventMetaData},
93
356
  });
94
357
  this.metricsManager.timeEvent([
95
358
  METRIC_EVENT_NAMES.AI_ASSISTANT_SEND_EVENT_SUCCESS,
@@ -99,28 +362,33 @@ export class ApiAIAssistant {
99
362
  try {
100
363
  const baseUrl = this.getBaseUrl();
101
364
  const orgId = this.webex.credentials.getOrgId();
365
+ const data = {
366
+ ...eventMetaData,
367
+ interactionId,
368
+ actionTimeStamp: String(Date.now()),
369
+ languageCode,
370
+ trackingId,
371
+ };
102
372
  const response = (await this.webex.request({
103
373
  uri: `${baseUrl}${AI_ASSISTANT_API_URLS.EVENT}`,
104
374
  method: HTTP_METHODS.POST,
105
375
  addAuthHeader: true,
376
+ ...(timeout !== undefined ? {timeout} : {}),
106
377
  body: {
107
378
  agentId,
108
379
  orgId,
109
380
  eventType,
110
381
  eventName,
382
+ ...(publishTimestamp !== undefined ? {publishTimestamp} : {}),
111
383
  eventDetails: {
112
- data: {
113
- interactionId,
114
- action,
115
- actionTimeStamp: String(Date.now()),
116
- },
384
+ data,
117
385
  },
118
386
  },
119
387
  })) as IHttpResponse;
120
388
 
121
389
  this.metricsManager.trackEvent(
122
390
  METRIC_EVENT_NAMES.AI_ASSISTANT_SEND_EVENT_SUCCESS,
123
- {agentId, orgId, interactionId, eventType, eventName, action},
391
+ {agentId, orgId, interactionId, eventType, eventName},
124
392
  ['operational']
125
393
  );
126
394
 
@@ -132,7 +400,6 @@ export class ApiAIAssistant {
132
400
  interactionId,
133
401
  eventType,
134
402
  eventName,
135
- action,
136
403
  error: error instanceof Error ? error.message : String(error),
137
404
  },
138
405
  ['operational']
@@ -143,6 +410,193 @@ export class ApiAIAssistant {
143
410
  }
144
411
  }
145
412
 
413
+ /**
414
+ * Requests real-time assistance for an interaction.
415
+ *
416
+ * @param params - Real-time assistance request parameters
417
+ * @returns HTTP response body from the AI Assistant event API
418
+ * @public
419
+ */
420
+ public async getRealTimeAssistance(params: RealTimeAssistanceParams) {
421
+ const {agentId, interactionId, context} = params;
422
+ const trimmedContext = context?.trim();
423
+ const languageCode = params.languageCode ?? 'en';
424
+ const trackingId = `WX_CC_SDK_${uuidv4()}`;
425
+ const eventName = trimmedContext
426
+ ? AIAssistantEventName.ADD_SUGGESTIONS_EXTRA_CONTEXT
427
+ : AIAssistantEventName.GET_SUGGESTIONS;
428
+
429
+ const loggerContext = {
430
+ module: CC_FILE,
431
+ method: METHODS.GET_REAL_TIME_ASSISTANCE,
432
+ interactionId,
433
+ trackingId,
434
+ data: {eventName},
435
+ };
436
+
437
+ LoggerProxy.info('Requesting real-time assistance', loggerContext);
438
+
439
+ this.metricsManager.timeEvent([
440
+ METRIC_EVENT_NAMES.AI_ASSISTANT_GET_REAL_TIME_ASSISTANCE_SUCCESS,
441
+ METRIC_EVENT_NAMES.AI_ASSISTANT_GET_REAL_TIME_ASSISTANCE_FAILED,
442
+ ]);
443
+
444
+ try {
445
+ if (!this.aiFeature?.suggestedResponses?.enable) {
446
+ const {error: detailedError} = getErrorDetails(
447
+ new Error('SUGGESTED_RESPONSES_NOT_ENABLED'),
448
+ METHODS.GET_REAL_TIME_ASSISTANCE,
449
+ CC_FILE
450
+ );
451
+ throw detailedError;
452
+ }
453
+
454
+ const orgId = this.webex.credentials.getOrgId();
455
+
456
+ const response = await this.sendEvent(
457
+ agentId,
458
+ interactionId,
459
+ AIAssistantEventType.CUSTOM_EVENT,
460
+ eventName,
461
+ trimmedContext !== undefined ? {context: trimmedContext} : undefined,
462
+ languageCode,
463
+ trackingId
464
+ );
465
+
466
+ this.metricsManager.trackEvent(
467
+ METRIC_EVENT_NAMES.AI_ASSISTANT_GET_REAL_TIME_ASSISTANCE_SUCCESS,
468
+ {
469
+ agentId,
470
+ orgId,
471
+ interactionId,
472
+ eventName,
473
+ trackingId,
474
+ context,
475
+ },
476
+ ['operational']
477
+ );
478
+ LoggerProxy.log('Real-time assistance request succeeded', loggerContext);
479
+
480
+ return response;
481
+ } catch (error) {
482
+ LoggerProxy.error('Real-time assistance request failed', {...loggerContext, error});
483
+ this.metricsManager.trackEvent(
484
+ METRIC_EVENT_NAMES.AI_ASSISTANT_GET_REAL_TIME_ASSISTANCE_FAILED,
485
+ {
486
+ agentId,
487
+ interactionId,
488
+ trackingId,
489
+ eventName,
490
+ error: error instanceof Error ? error.message : String(error),
491
+ },
492
+ ['operational']
493
+ );
494
+
495
+ const {error: detailedError} = getErrorDetails(
496
+ error,
497
+ METHODS.GET_REAL_TIME_ASSISTANCE,
498
+ CC_FILE
499
+ );
500
+ throw detailedError;
501
+ }
502
+ }
503
+
504
+ /**
505
+ * Sends user action feedback for a real-time assistance adaptive card.
506
+ *
507
+ * @param params - Real-time assistance user action parameters
508
+ * @returns HTTP response body from the AI Assistant event API
509
+ * @public
510
+ */
511
+ public async sendRealTimeAssistanceUserAction(
512
+ params: RealTimeAssistanceUserActionParams
513
+ ): Promise<Record<string, unknown>> {
514
+ const {agentId, interactionId, adaptiveCardId, actionId} = params;
515
+ const actionType = 'Action.Submit';
516
+ const languageCode = params.languageCode ?? 'en';
517
+ const trackingId = `WX_CC_SDK_${uuidv4()}`;
518
+
519
+ const loggerContext = {
520
+ module: CC_FILE,
521
+ method: METHODS.SEND_REAL_TIME_ASSISTANCE_USER_ACTION,
522
+ interactionId,
523
+ trackingId,
524
+ data: {actionId, adaptiveCardId},
525
+ };
526
+
527
+ LoggerProxy.info('Sending real-time assistance user action', loggerContext);
528
+
529
+ this.metricsManager.timeEvent([
530
+ METRIC_EVENT_NAMES.AI_ASSISTANT_SEND_REAL_TIME_ASSISTANCE_USER_ACTION_SUCCESS,
531
+ METRIC_EVENT_NAMES.AI_ASSISTANT_SEND_REAL_TIME_ASSISTANCE_USER_ACTION_FAILED,
532
+ ]);
533
+
534
+ try {
535
+ if (!this.aiFeature?.suggestedResponses?.enable) {
536
+ const {error: detailedError} = getErrorDetails(
537
+ new Error('SUGGESTED_RESPONSES_NOT_ENABLED'),
538
+ METHODS.SEND_REAL_TIME_ASSISTANCE_USER_ACTION,
539
+ CC_FILE
540
+ );
541
+ throw detailedError;
542
+ }
543
+
544
+ const orgId = this.webex.credentials.getOrgId();
545
+ const response = await this.sendEvent(
546
+ agentId,
547
+ interactionId,
548
+ AIAssistantEventType.CUSTOM_EVENT,
549
+ AIAssistantEventName.SUGGESTED_RESPONSES_USER_ACTION,
550
+ {
551
+ adaptiveCardId,
552
+ userAction: {
553
+ actionType,
554
+ actionId,
555
+ },
556
+ },
557
+ languageCode,
558
+ trackingId
559
+ );
560
+
561
+ this.metricsManager.trackEvent(
562
+ METRIC_EVENT_NAMES.AI_ASSISTANT_SEND_REAL_TIME_ASSISTANCE_USER_ACTION_SUCCESS,
563
+ {
564
+ agentId,
565
+ orgId,
566
+ interactionId,
567
+ adaptiveCardId,
568
+ actionId,
569
+ trackingId,
570
+ },
571
+ ['operational']
572
+ );
573
+ LoggerProxy.log('Real-time assistance user action sent', loggerContext);
574
+
575
+ return response;
576
+ } catch (error) {
577
+ LoggerProxy.error('Real-time assistance user action failed', {...loggerContext, error});
578
+ this.metricsManager.trackEvent(
579
+ METRIC_EVENT_NAMES.AI_ASSISTANT_SEND_REAL_TIME_ASSISTANCE_USER_ACTION_FAILED,
580
+ {
581
+ agentId,
582
+ interactionId,
583
+ adaptiveCardId,
584
+ actionId,
585
+ trackingId,
586
+ error: error instanceof Error ? error.message : String(error),
587
+ },
588
+ ['operational']
589
+ );
590
+
591
+ const {error: detailedError} = getErrorDetails(
592
+ error,
593
+ METHODS.SEND_REAL_TIME_ASSISTANCE_USER_ACTION,
594
+ CC_FILE
595
+ );
596
+ throw detailedError;
597
+ }
598
+ }
599
+
146
600
  /**
147
601
  * Fetches historic transcripts for an interaction.
148
602
  * This API is allowed only when real-time transcription feature is enabled.
@@ -201,6 +655,7 @@ export class ApiAIAssistant {
201
655
  },
202
656
  ['operational']
203
657
  );
658
+
204
659
  if (error instanceof Error) {
205
660
  throw error;
206
661
  }