@webex/contact-center 3.12.0-next.13 → 3.12.0-next.130

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 (312) hide show
  1. package/.sdd/manifest.json +884 -0
  2. package/AGENTS.md +94 -0
  3. package/ai-docs/ARCHITECTURE.md +168 -0
  4. package/ai-docs/CONTRACTS.md +53 -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 +971 -42
  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 +31 -3
  46. package/dist/constants.js.map +1 -1
  47. package/dist/index.js +45 -15
  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 +205 -0
  52. package/dist/metrics/behavioral-events.js.map +1 -1
  53. package/dist/metrics/constants.js +48 -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 +269 -9
  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 +222 -0
  68. package/dist/services/WebexCrossClientService.js.map +1 -0
  69. package/dist/services/WxAppTelephonyMercurySync.js +108 -0
  70. package/dist/services/WxAppTelephonyMercurySync.js.map +1 -0
  71. package/dist/services/config/Util.js +11 -4
  72. package/dist/services/config/Util.js.map +1 -1
  73. package/dist/services/config/constants.js +41 -7
  74. package/dist/services/config/constants.js.map +1 -1
  75. package/dist/services/config/index.js +51 -0
  76. package/dist/services/config/index.js.map +1 -1
  77. package/dist/services/config/types.js +57 -12
  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 +754 -0
  93. package/dist/services/task/Task.js.map +1 -0
  94. package/dist/services/task/TaskFactory.js +49 -0
  95. package/dist/services/task/TaskFactory.js.map +1 -0
  96. package/dist/services/task/TaskManager.js +1172 -521
  97. package/dist/services/task/TaskManager.js.map +1 -1
  98. package/dist/services/task/TaskUtils.js +211 -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 +12 -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 +228 -5
  127. package/dist/services/task/types.js.map +1 -1
  128. package/dist/services/task/voice/Voice.js +1485 -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/wxAppVoiceMethods.js +354 -0
  133. package/dist/services/task/voice/wxAppVoiceMethods.js.map +1 -0
  134. package/dist/services/wxAppDiagnosticLogging.js +122 -0
  135. package/dist/services/wxAppDiagnosticLogging.js.map +1 -0
  136. package/dist/services/wxAppTelephonyUtils.js +19 -0
  137. package/dist/services/wxAppTelephonyUtils.js.map +1 -0
  138. package/dist/types/cc.d.ts +193 -6
  139. package/dist/types/config.d.ts +13 -0
  140. package/dist/types/constants.d.ts +29 -1
  141. package/dist/types/index.d.ts +35 -8
  142. package/dist/types/metrics/MetricsManager.d.ts +6 -0
  143. package/dist/types/metrics/constants.d.ts +43 -1
  144. package/dist/types/services/AddressBook.d.ts +2 -1
  145. package/dist/types/services/AnswerCallOnWebexService.d.ts +38 -0
  146. package/dist/types/services/ApiAiAssistant.d.ts +56 -5
  147. package/dist/types/services/EntryPoint.d.ts +7 -5
  148. package/dist/types/services/Queue.d.ts +5 -3
  149. package/dist/types/services/UserPreference.d.ts +118 -0
  150. package/dist/types/services/WebexCrossClientService.d.ts +32 -0
  151. package/dist/types/services/WxAppTelephonyMercurySync.d.ts +28 -0
  152. package/dist/types/services/config/constants.d.ts +34 -5
  153. package/dist/types/services/config/types.d.ts +197 -12
  154. package/dist/types/services/core/Err.d.ts +6 -0
  155. package/dist/types/services/core/Utils.d.ts +35 -13
  156. package/dist/types/services/core/WebexRequest.d.ts +1 -0
  157. package/dist/types/services/core/types.d.ts +2 -0
  158. package/dist/types/services/core/websocket/WebSocketManager.d.ts +1 -0
  159. package/dist/types/services/core/websocket/types.d.ts +1 -1
  160. package/dist/types/services/index.d.ts +1 -1
  161. package/dist/types/services/task/Task.d.ts +175 -0
  162. package/dist/types/services/task/TaskFactory.d.ts +13 -0
  163. package/dist/types/services/task/TaskUtils.d.ts +48 -2
  164. package/dist/types/services/task/WebexCallingUtils.d.ts +11 -0
  165. package/dist/types/services/task/constants.d.ts +10 -0
  166. package/dist/types/services/task/contact.d.ts +4 -0
  167. package/dist/types/services/task/dialer.d.ts +30 -0
  168. package/dist/types/services/task/digital/Digital.d.ts +22 -0
  169. package/dist/types/services/task/state-machine/TaskStateMachine.d.ts +1442 -0
  170. package/dist/types/services/task/state-machine/actions.d.ts +10 -0
  171. package/dist/types/services/task/state-machine/constants.d.ts +107 -0
  172. package/dist/types/services/task/state-machine/guards.d.ts +103 -0
  173. package/dist/types/services/task/state-machine/index.d.ts +13 -0
  174. package/dist/types/services/task/state-machine/types.d.ts +277 -0
  175. package/dist/types/services/task/state-machine/uiControlsComputer.d.ts +9 -0
  176. package/dist/types/services/task/taskDataNormalizer.d.ts +10 -0
  177. package/dist/types/services/task/types.d.ts +680 -66
  178. package/dist/types/services/task/voice/Voice.d.ts +227 -0
  179. package/dist/types/services/task/voice/WebRTC.d.ts +53 -0
  180. package/dist/types/services/task/voice/wxAppVoiceMethods.d.ts +55 -0
  181. package/dist/types/services/wxAppDiagnosticLogging.d.ts +51 -0
  182. package/dist/types/services/wxAppTelephonyUtils.d.ts +5 -0
  183. package/dist/types/types.d.ts +205 -9
  184. package/dist/types/utils/PageCache.d.ts +20 -3
  185. package/dist/types/webex.d.ts +1 -0
  186. package/dist/types.js +162 -4
  187. package/dist/types.js.map +1 -1
  188. package/dist/utils/PageCache.js +19 -5
  189. package/dist/utils/PageCache.js.map +1 -1
  190. package/dist/webex.js +22 -2
  191. package/dist/webex.js.map +1 -1
  192. package/package.json +16 -12
  193. package/src/cc.ts +1289 -112
  194. package/src/config.ts +13 -0
  195. package/src/constants.ts +29 -1
  196. package/src/index.ts +36 -5
  197. package/src/metrics/MetricsManager.ts +16 -0
  198. package/src/metrics/ai-docs/AGENTS.md +350 -0
  199. package/src/metrics/ai-docs/ARCHITECTURE.md +338 -0
  200. package/src/metrics/ai-docs/metrics-spec.md +921 -0
  201. package/src/metrics/behavioral-events.ts +212 -0
  202. package/src/metrics/constants.ts +52 -4
  203. package/src/services/AddressBook.ts +17 -6
  204. package/src/services/AnswerCallOnWebexService.ts +239 -0
  205. package/src/services/ApiAiAssistant.ts +356 -9
  206. package/src/services/EntryPoint.ts +59 -60
  207. package/src/services/Queue.ts +29 -12
  208. package/src/services/UserPreference.ts +509 -0
  209. package/src/services/WebexCrossClientService.ts +293 -0
  210. package/src/services/WxAppTelephonyMercurySync.ts +142 -0
  211. package/src/services/agent/ai-docs/AGENTS.md +240 -0
  212. package/src/services/agent/ai-docs/ARCHITECTURE.md +304 -0
  213. package/src/services/agent/ai-docs/agent-spec.md +505 -0
  214. package/src/services/ai-docs/AGENTS.md +386 -0
  215. package/src/services/ai-docs/services-spec.md +505 -0
  216. package/src/services/config/Util.ts +12 -3
  217. package/src/services/config/ai-docs/AGENTS.md +255 -0
  218. package/src/services/config/ai-docs/ARCHITECTURE.md +426 -0
  219. package/src/services/config/ai-docs/config-spec.md +686 -0
  220. package/src/services/config/constants.ts +46 -6
  221. package/src/services/config/index.ts +65 -0
  222. package/src/services/config/types.ts +197 -13
  223. package/src/services/core/Err.ts +3 -0
  224. package/src/services/core/Utils.ts +127 -37
  225. package/src/services/core/WebexRequest.ts +3 -1
  226. package/src/services/core/ai-docs/AGENTS.md +381 -0
  227. package/src/services/core/ai-docs/ARCHITECTURE.md +698 -0
  228. package/src/services/core/ai-docs/core-spec.md +787 -0
  229. package/src/services/core/aqm-reqs.ts +30 -15
  230. package/src/services/core/types.ts +2 -0
  231. package/src/services/core/websocket/WebSocketManager.ts +2 -0
  232. package/src/services/core/websocket/types.ts +1 -1
  233. package/src/services/index.ts +1 -1
  234. package/src/services/task/Task.ts +908 -0
  235. package/src/services/task/TaskFactory.ts +60 -0
  236. package/src/services/task/TaskManager.ts +1419 -608
  237. package/src/services/task/TaskUtils.ts +303 -25
  238. package/src/services/task/WebexCallingUtils.ts +136 -0
  239. package/src/services/task/ai-docs/AGENTS.md +457 -0
  240. package/src/services/task/ai-docs/ARCHITECTURE.md +595 -0
  241. package/src/services/task/ai-docs/task-spec.md +1474 -0
  242. package/src/services/task/constants.ts +10 -0
  243. package/src/services/task/contact.ts +30 -0
  244. package/src/services/task/dialer.ts +80 -0
  245. package/src/services/task/digital/Digital.ts +97 -0
  246. package/src/services/task/state-machine/TaskStateMachine.ts +1320 -0
  247. package/src/services/task/state-machine/actions.ts +741 -0
  248. package/src/services/task/state-machine/ai-docs/AGENTS.md +460 -0
  249. package/src/services/task/state-machine/ai-docs/ARCHITECTURE.md +1156 -0
  250. package/src/services/task/state-machine/ai-docs/task-state-machine-spec.md +2247 -0
  251. package/src/services/task/state-machine/constants.ts +172 -0
  252. package/src/services/task/state-machine/guards.ts +442 -0
  253. package/src/services/task/state-machine/index.ts +28 -0
  254. package/src/services/task/state-machine/types.ts +258 -0
  255. package/src/services/task/state-machine/uiControlsComputer.ts +1135 -0
  256. package/src/services/task/taskDataNormalizer.ts +137 -0
  257. package/src/services/task/types.ts +819 -70
  258. package/src/services/task/voice/Voice.ts +1851 -0
  259. package/src/services/task/voice/WebRTC.ts +191 -0
  260. package/src/services/task/voice/wxAppVoiceMethods.ts +516 -0
  261. package/src/services/wxAppDiagnosticLogging.ts +174 -0
  262. package/src/services/wxAppTelephonyUtils.ts +14 -0
  263. package/src/types.ts +262 -11
  264. package/src/utils/AGENTS.md +289 -0
  265. package/src/utils/PageCache.ts +38 -5
  266. package/src/utils/ai-docs/utils-spec.md +391 -0
  267. package/src/webex.js +10 -0
  268. package/test/unit/spec/cc.ts +2210 -119
  269. package/test/unit/spec/logger-proxy.ts +70 -0
  270. package/test/unit/spec/metrics/MetricsManager.ts +25 -0
  271. package/test/unit/spec/metrics/behavioral-events.ts +60 -0
  272. package/test/unit/spec/services/AddressBook.ts +37 -6
  273. package/test/unit/spec/services/AnswerCallOnWebexService.ts +264 -0
  274. package/test/unit/spec/services/ApiAiAssistant.ts +311 -21
  275. package/test/unit/spec/services/EntryPoint.ts +87 -40
  276. package/test/unit/spec/services/Queue.ts +123 -12
  277. package/test/unit/spec/services/UserPreference.ts +401 -0
  278. package/test/unit/spec/services/WebCallingService.ts +7 -1
  279. package/test/unit/spec/services/WebexCrossClientService.ts +467 -0
  280. package/test/unit/spec/services/WxAppTelephonyMercurySync.ts +136 -0
  281. package/test/unit/spec/services/config/Util.ts +129 -0
  282. package/test/unit/spec/services/config/index.ts +97 -29
  283. package/test/unit/spec/services/core/Utils.ts +425 -8
  284. package/test/unit/spec/services/core/WebexRequest.ts +3 -1
  285. package/test/unit/spec/services/core/aqm-reqs.ts +113 -1
  286. package/test/unit/spec/services/core/websocket/WebSocketManager.ts +66 -40
  287. package/test/unit/spec/services/task/AutoWrapup.ts +63 -0
  288. package/test/unit/spec/services/task/Task.ts +745 -0
  289. package/test/unit/spec/services/task/TaskFactory.ts +99 -0
  290. package/test/unit/spec/services/task/TaskManager.ts +2518 -1494
  291. package/test/unit/spec/services/task/TaskUtils.ts +235 -0
  292. package/test/unit/spec/services/task/WebexCallingUtils.ts +153 -0
  293. package/test/unit/spec/services/task/contact.ts +33 -0
  294. package/test/unit/spec/services/task/dialer.ts +190 -0
  295. package/test/unit/spec/services/task/digital/Digital.ts +105 -0
  296. package/test/unit/spec/services/task/state-machine/TaskStateMachine.ts +4060 -0
  297. package/test/unit/spec/services/task/state-machine/guards.ts +839 -0
  298. package/test/unit/spec/services/task/state-machine/types.ts +18 -0
  299. package/test/unit/spec/services/task/state-machine/uiControlsComputer.ts +3101 -0
  300. package/test/unit/spec/services/task/taskTestUtils.ts +87 -0
  301. package/test/unit/spec/services/task/voice/Voice.ts +2061 -0
  302. package/test/unit/spec/services/task/voice/WebRTC.ts +235 -0
  303. package/test/unit/spec/services/task/voice/wxAppVoiceMethods.ts +603 -0
  304. package/test/unit/spec/services/wxAppDiagnosticLogging.ts +143 -0
  305. package/test/unit/spec/wellnessSampleUtils.ts +288 -0
  306. package/umd/contact-center.min.js +2 -2
  307. package/umd/contact-center.min.js.map +1 -1
  308. package/dist/services/task/index.js +0 -1525
  309. package/dist/services/task/index.js.map +0 -1
  310. package/dist/types/services/task/index.d.ts +0 -650
  311. package/src/services/task/index.ts +0 -1801
  312. package/test/unit/spec/services/task/index.ts +0 -2184
@@ -0,0 +1,505 @@
1
+ # Services — SPEC
2
+
3
+ > Start here → root [`AGENTS.md`](../../../AGENTS.md) · router [`SPEC_INDEX.md`](../../../ai-docs/SPEC_INDEX.md) · system [`ARCHITECTURE.md`](../../../ai-docs/ARCHITECTURE.md). This is the module's canonical specification.
4
+
5
+ ## Metadata
6
+
7
+ | Field | Value |
8
+ |---|---|
9
+ | Module id | `services` |
10
+ | Source path(s) | `src/services` |
11
+ | Doc kind | Module spec |
12
+ | Coverage score | Partial (manifest-authoritative); 15/15 required document fields present |
13
+ | Generated from | `module-spec` @ SDLC template library `0.2.1` |
14
+ | generated_by / approved_by / updated_at | Codex generator / Agent Wellness Break v0.4 intake audit / 2026-09-07 |
15
+ | Validation status | Agent Wellness Break v0.4 delta independently validated by claude-code on 2026-09-07; coverage remains Partial until the remaining baseline promotion criteria are satisfied |
16
+
17
+ ## Evidence Rules
18
+ Every requirement cites stable source and test file paths. Code/tests are the behavioral referee; routed source text supplies explicit intent and rationale. Missing or contradictory evidence blocks promotion.
19
+
20
+ ## Source Material Register
21
+ | Source material | Scope | Decision | Detail location or disposition |
22
+ |---|---|---|---|
23
+ | Reviewed prior module guides and architecture material | overview / architecture / API / tests | used and code-checked | Content is placed by meaning throughout this specification; exact routing remains in the manifest. |
24
+
25
+ ## Overview
26
+ Services is one of nine confirmed Contact Center SDK modules. Own composition and bootstrap order for backend request, realtime, data, and WebRTC service collaborators. Existing reviewed documentation is migrated by meaning and code/tests remain the behavioral referee.
27
+
28
+ The `src/services/` directory is the service layer of the `@webex/contact-center` SDK. It sits between the public plugin class (`cc.ts`) and the backend APIs/WebSocket. Every backend interaction — HTTP requests, WebSocket messages, agent operations, task lifecycle, configuration fetching — flows through this layer.
29
+
30
+ - Understanding service composition and which service owns which responsibility
31
+
32
+ - Determining the correct instantiation/bootstrap order for services
33
+
34
+ - Tracing request flow from `cc.ts` through services to the backend
35
+
36
+ - Choosing between AqmReqs and direct REST patterns for a new method
37
+
38
+ - Adding a new paginated data service (AddressBook/Queue/EntryPoint pattern) or a direct REST service such as UserPreference
39
+
40
+ - Adding a new AqmReqs method to agent, task, or dialer factories
41
+
42
+ - Routing to the correct service-level docs for task/agent/config/core changes
43
+
44
+ - Clarifying what the Services singleton creates vs what `cc.ts` creates
45
+
46
+ | Capability | Owner | Description |
47
+ |---|---|---|
48
+ | **Service Singleton** | [`index.ts`](../index.ts) | Central `Services` class that instantiates and provides access to all service modules via `Services.getInstance()` |
49
+ | **Agent Operations** | [`agent/`](../agent/index.ts) | Station login/logout, state changes, buddy agents — uses AqmReqs factory pattern |
50
+ | **Task Management** | [`task/`](../task/TaskManager.ts) | Task lifecycle (accept, hold, transfer, conference, wrapup), Task state machine, contact operations, outbound dialing |
51
+ | **Configuration** | [`config/`](../config/index.ts) | Agent profile aggregation from 8+ API endpoints, org settings, teams, aux codes, dial plans |
52
+ | **Core Infrastructure** | [`core/`](../core/WebexRequest.ts) | HTTP requests (`WebexRequest`), WebSocket management (`WebSocketManager`), connection lifecycle (`ConnectionService`), AQM request/response correlation (`AqmReqs`), error handling (`Utils`, `Err`) |
53
+ | **Data Services** | [`AddressBook.ts`](../AddressBook.ts), [`Queue.ts`](../Queue.ts), [`EntryPoint.ts`](../EntryPoint.ts) | Standalone REST-based data services with pagination and caching for address books, queues, and entry points |
54
+ | **User Preferences** | [`UserPreference.ts`](../UserPreference.ts) | Direct REST CRUD service exposed as `cc.userPreference`; it resolves the default user from agent configuration and does not use PageCache |
55
+ | **Utilities** | [`src/utils/PageCache.ts`](../../utils/PageCache.ts) | Shared `PageCache<T>` generic class for pagination caching, plus `BaseSearchParams`, `PaginatedResponse`, and `PaginationMeta` types used by all data services |
56
+ | **WebRTC Calling** | [`WebCallingService.ts`](../WebCallingService.ts) | Browser-based voice calling via `@webex/calling`, line registration, call answer/mute/decline |
57
+ | **WxApp Better Together** | [`WebexCrossClientService.ts`](../WebexCrossClientService.ts), [`AnswerCallOnWebexService.ts`](../AnswerCallOnWebexService.ts), [`WxAppTelephonyMercurySync.ts`](../WxAppTelephonyMercurySync.ts) | usersub cross-client publish (`answer-calls-on-wxcc`), Hydra telephony REST (answer/reject/mute/DTMF/GET call), Mercury mute sync — orchestrated from `cc.ts` when `enableWxBetterTogether` is active |
58
+ | **AI Assistant / Wellness** | [`ApiAiAssistant.ts`](../ApiAiAssistant.ts) | Existing transcript/suggestion requests plus direct, session-validated wellness custom-event reporting. |
59
+
60
+ Each service folder contains its own `ai-docs/` with detailed documentation. **Always load the relevant service docs before making changes.**
61
+
62
+ | Service | Scope / Keywords | AGENTS.md | ARCHITECTURE.md |
63
+ |---|---|---|---|
64
+ | **Agent** | login, logout, state change, buddy agents, station, RONA | [`agent/ai-docs/agent-spec.md`](../agent/ai-docs/agent-spec.md) | [`agent/ai-docs/agent-spec.md`](../agent/ai-docs/agent-spec.md) |
65
+ | **Task** | task, hold, transfer, conference, wrapup, outdial, consult, accept, decline, state machine, XState, task states, guards, actions | [`task/ai-docs/task-spec.md`](../task/ai-docs/task-spec.md) | [`task/ai-docs/task-spec.md`](../task/ai-docs/task-spec.md) |
66
+ | **Config** | profile, register, teams, aux codes, desktop profile, org settings, dial plan | [`config/ai-docs/config-spec.md`](../config/ai-docs/config-spec.md) | [`config/ai-docs/config-spec.md`](../config/ai-docs/config-spec.md) |
67
+ | **Core** | websocket, HTTP, connection, reconnect, aqm, utils, errors, keepalive | [`core/ai-docs/core-spec.md`](../core/ai-docs/core-spec.md) | [`core/ai-docs/core-spec.md`](../core/ai-docs/core-spec.md) |
68
+
69
+ > **Note**: The task state machine (`task/state-machine/`) is part of the Task service, not a separate service. Its dedicated docs live at [`task/state-machine/ai-docs/task-state-machine-spec.md`](../task/state-machine/ai-docs/task-state-machine-spec.md) and [`ARCHITECTURE.md`](../task/state-machine/ai-docs/task-state-machine-spec.md). Load these when working on state transitions, guards, or actions.
70
+
71
+ **Paginated data services** (AddressBook, Queue, EntryPoint) do not have dedicated ai-docs. Read their source files directly — they follow shared REST/pagination/caching patterns documented in [`ai-docs/patterns/typescript-patterns.md`](../../../ai-docs/patterns/typescript-patterns.md). `UserPreference` is also a direct REST service, but it has CRUD semantics and does not use their PageCache pattern.
72
+
73
+ **WebCallingService** also has no dedicated ai-docs, but it follows a different pattern: EventEmitter-based call lifecycle orchestration around `@webex/calling` (`createClient`, line registration/deregistration, `ICall` events), `callTaskMap` tracking, and async registration flows with timeout handling. Read [`WebCallingService.ts`](../WebCallingService.ts) directly when changing browser calling behavior.
74
+
75
+ The `ContactCenter` plugin class (`cc.ts`) is the **only public entry point**. It delegates all backend work to the services layer:
76
+
77
+ ```text
78
+ ContactCenter (cc.ts) — public API surface
79
+ │
80
+ ├── WebexRequest.getInstance({webex}) ← initialized FIRST (singleton)
81
+ ├── Services.getInstance({webex, connectionConfig}) ← initialized SECOND (singleton)
82
+ │ │
83
+ │ ├── webSocketManager ← primary Contact Center WebSocket transport
84
+ │ ├── rtdWebSocketManager ← separate RTD/transcription WebSocket transport
85
+ │ ├── AqmReqs ← HTTP request + WebSocket notification correlation
86
+ │ ├── ConnectionService ← WebSocket lifecycle, reconnection, keepalive
87
+ │ ├── AgentConfigService (config) ← profile aggregation via REST APIs
88
+ │ ├── routingAgent (agent) ← agent operations via AqmReqs factory
89
+ │ ├── routingContact (contact) ← task/contact operations via AqmReqs factory
90
+ │ └── aqmDialer (dialer) ← outbound dialing via AqmReqs factory
91
+ │
92
+ ├── TaskManager ← task lifecycle, created in the Webex READY callback
93
+ ├── WebCallingService ← WebRTC calling, created in READY (line registration remains conditional)
94
+ ├── ApiAIAssistant ← AI transcript/suggestion API, created in READY
95
+ ├── AddressBook ← REST data service, created in READY
96
+ ├── EntryPoint ← REST data service, created in READY
97
+ ├── Queue ← REST data service, created in READY
98
+ ├── UserPreference ← REST user-preference CRUD service, created in READY
99
+ └── MetricsManager.getInstance({webex}) ← telemetry singleton
100
+ ```
101
+
102
+ ## Purpose / Responsibility
103
+ Own composition and bootstrap order for backend request, realtime, data, and WebRTC service collaborators.
104
+
105
+ ## Stack
106
+ TypeScript 5.4, singleton composition, REST/WebSocket/AQM integrations, @webex/calling, Jest 27.
107
+
108
+ ## Folder / Package Structure
109
+ ```text
110
+ src/services/
111
+ ├── AddressBook.ts
112
+ ├── ApiAiAssistant.ts
113
+ ├── EntryPoint.ts
114
+ ├── Queue.ts
115
+ ├── UserPreference.ts
116
+ ├── WebCallingService.ts
117
+ ├── agent/
118
+ ├── config/
119
+ ├── constants.ts
120
+ ├── core/
121
+ ├── index.ts
122
+ ├── task/
123
+ ```
124
+
125
+ ```text
126
+ src/services/
127
+ ├── index.ts # Services singleton — composes all services
128
+ ├── constants.ts # Shared constants (gateway id, API paths, WebRTC domains/prefixes, timeout, method-name constants)
129
+ ├── ai-docs/
130
+ │ └── AGENTS.md # Preserved legacy migration source (non-canonical)
131
+ │
132
+ ├── agent/ # Agent operations service
133
+ │ ├── index.ts # routingAgent factory — stationLogin, stateChange, logout, buddyAgents
134
+ │ ├── types.ts # Agent types: StateChange, Logout, AGENT_EVENTS, LoginOption
135
+ │ └── ai-docs/ # Agent-specific documentation
136
+ │ ├── AGENTS.md
137
+ │ └── ARCHITECTURE.md
138
+ │
139
+ ├── task/ # Task management service
140
+ │ ├── TaskManager.ts # Task lifecycle manager — creates/destroys Task instances
141
+ │ ├── Task.ts # Individual task — hold, transfer, conference, wrapup
142
+ │ ├── TaskFactory.ts # Creates Task with config flags
143
+ │ ├── contact.ts # routingContact factory — task operations via AqmReqs
144
+ │ ├── dialer.ts # aqmDialer factory — outbound dialing
145
+ │ ├── AutoWrapup.ts # Auto wrapup timer handler
146
+ │ ├── TaskUtils.ts # Task utility functions
147
+ │ ├── taskDataNormalizer.ts # Normalizes task data from events
148
+ │ ├── types.ts # Task types: ITask, TASK_EVENTS, TaskResponse
149
+ │ ├── constants.ts # Task constants
150
+ │ ├── voice/ # Voice-specific task handling
151
+ │ │ ├── Voice.ts # Voice task operations
152
+ │ │ └── WebRTC.ts # WebRTC-specific voice operations
153
+ │ ├── digital/ # Digital channel task handling
154
+ │ │ └── Digital.ts # Digital task operations
155
+ │ ├── state-machine/ # XState-based task state machine
156
+ │ │ ├── TaskStateMachine.ts # State machine definition
157
+ │ │ ├── index.ts # Barrel export for state machine public API
158
+ │ │ ├── constants.ts # TaskState, TaskEvent enums
159
+ │ │ ├── types.ts # TaskContext type
160
+ │ │ ├── guards.ts # State transition guards
161
+ │ │ ├── actions.ts # State transition actions
162
+ │ │ ├── uiControlsComputer.ts # Computes UI controls from state
163
+ │ │ └── ai-docs/ # State machine documentation
164
+ │ │ ├── AGENTS.md
165
+ │ │ └── ARCHITECTURE.md
166
+ │ └── ai-docs/ # Task-specific documentation
167
+ │ ├── AGENTS.md
168
+ │ └── ARCHITECTURE.md
169
+ │
170
+ ├── config/ # Configuration service
171
+ │ ├── index.ts # AgentConfigService — getAgentConfig(), profile aggregation
172
+ │ ├── Util.ts # parseAgentConfigs, getFilterAuxCodes, helper functions
173
+ │ ├── types.ts # CC_EVENTS, Profile, CC_AGENT_EVENTS, CC_TASK_EVENTS
174
+ │ ├── constants.ts # endPointMap (API URL builders), pagination defaults
175
+ │ └── ai-docs/ # Config-specific documentation
176
+ │ ├── AGENTS.md
177
+ │ └── ARCHITECTURE.md
178
+ │
179
+ ├── core/ # Core infrastructure
180
+ │ ├── WebexRequest.ts # HTTP client singleton — request(), uploadLogs()
181
+ │ ├── aqm-reqs.ts # AqmReqs — HTTP request + WebSocket notification correlation
182
+ │ ├── Utils.ts # getErrorDetails, generateTaskErrorObject, isValidDialNumber
183
+ │ ├── Err.ts # Err.Details error class with structured metadata
184
+ │ ├── GlobalTypes.ts # Msg<T>, Failure, AugmentedError, TaskError
185
+ │ ├── types.ts # Req, Conf, Res types for AqmReqs
186
+ │ ├── constants.ts # Core constants
187
+ │ ├── websocket/
188
+ │ │ ├── WebSocketManager.ts # WebSocket connection handler
189
+ │ │ ├── connection-service.ts # Connection lifecycle, reconnection, keepalive
190
+ │ │ └── types.ts # WebSocket types
191
+ │ └── ai-docs/ # Core-specific documentation
192
+ │ ├── AGENTS.md
193
+ │ └── ARCHITECTURE.md
194
+ │
195
+ ├── AddressBook.ts # Address book entries — getEntries() with pagination/cache
196
+ ├── EntryPoint.ts # Entry points — getEntryPoints() with pagination/cache
197
+ ├── Queue.ts # Queues — getQueues() with pagination/cache
198
+ └── WebCallingService.ts # WebRTC calling — register/deregister line, answer/mute/decline
199
+ ```
200
+
201
+ Note: The `src/utils/` folder (sibling to `src/services/`) contains shared utilities like [`PageCache.ts`](../../utils/PageCache.ts) which provides generic pagination caching with `BaseSearchParams`, `PaginatedResponse`, and `PaginationMeta` types used by all data services.
202
+
203
+ Use [`constants.ts`](../constants.ts) as the canonical source for service-level naming and routing constants:
204
+
205
+ - `WCC_API_GATEWAY` — service identifier used by `WebexRequest` calls
206
+
207
+ - `SUBSCRIBE_API`, `LOGIN_API`, `STATE_CHANGE_API` — common API path constants
208
+
209
+ - `WEB_RTC_PREFIX` — path prefix for WebRTC-related endpoints
210
+
211
+ - `WEBSOCKET_EVENT_TIMEOUT` — defined as `20000` ms in `src/services/constants.ts` but not used by AqmReqs; active AQM correlation defaults to Core's `TIMEOUT_REQ = 20000`
212
+
213
+ - `DEFAULT_RTMS_DOMAIN`, `WCC_CALLING_RTMS_DOMAIN` — RTMS/WebRTC domain constants
214
+
215
+ - `METHODS` — method name constants used by `WebCallingService`
216
+
217
+ ## Key Files (source of truth)
218
+ | File | Holds |
219
+ |---|---|
220
+ | `src/services/index.ts` | Authoritative Services implementation or contract source. |
221
+ | `src/services/constants.ts` | Authoritative Services implementation or contract source. |
222
+ | `src/services/AddressBook.ts` | Authoritative Services implementation or contract source. |
223
+ | `src/services/EntryPoint.ts` | Authoritative Services implementation or contract source. |
224
+ | `src/services/Queue.ts` | Authoritative Services implementation or contract source. |
225
+ | `src/services/UserPreference.ts` | Direct REST user-preference CRUD exposed through `cc.userPreference`. |
226
+ | `src/services/WebCallingService.ts` | Authoritative Services implementation or contract source. |
227
+
228
+ ## Public Surface
229
+ | Contract ID | Type | Surface | Purpose | Compatibility / deprecation | Schema / detail link | Root index |
230
+ |---|---|---|---|---|---|---|
231
+ | `services.surface` | SDK / event / internal API | Internal `Services.getInstance()` composition root plus data-service and calling collaborators consumed by `ContactCenter`. | Stable module consumption boundary. | Additive changes by default; breaking package exports require a major-version transition. | `src/services/index.ts` | `../../../ai-docs/CONTRACTS.md` |
232
+ | `services.destination-lists` | SDK data API | Existing `Queue.getQueues(ContactServiceQueueSearchParams)` and `EntryPoint.getEntryPoints(EntryPointSearchParams)` methods with full-record paginated responses. | Apply consult/transfer telephony eligibility, profile views, and backend name ordering as overridable defaults. | Behavioral default correction on existing methods; no specialized method, projected response, or replacement signature. | `src/services/Queue.ts`, `src/services/EntryPoint.ts`, `src/types.ts` | `../../../ai-docs/CONTRACTS.md` |
233
+ | `services.user-preference` | SDK data API | `UserPreference` and `cc.userPreference`. | Direct REST CRUD for user preferences; separate from PageCache-based pagination services. | Additive semver-public API; removals or signature changes are breaking. | `src/services/UserPreference.ts`, `src/services/config/types.ts` | `../../../ai-docs/CONTRACTS.md` |
234
+ | `services.agent-wellness-break` | SDK data / action API | `ApiAIAssistant.requestWellnessBreak` and `respondToWellnessBreak`, invoked through `ContactCenter`. | Submit validated `WellnessBreakAction` custom events through direct HTTP. | Additive semver-public behavior; exact action/event payload is backend-owned. | `src/services/ApiAiAssistant.ts`, `src/types.ts` | `../../../ai-docs/CONTRACTS.md` |
235
+
236
+ Compatibility notes:
237
+ - Do not remove or reinterpret exported symbols/events without a documented consumer migration.
238
+
239
+ ## Requires (dependencies)
240
+ - Host Webex SDK READY lifecycle and authenticated request facilities.
241
+ - `WebexRequest` initialized by ContactCenter before `Services.getInstance()`.
242
+ - WCC REST endpoints plus primary Contact Center and RTD WebSocket transports.
243
+ - `ApiAIAssistant`, `WebCallingService`, `MetricsManager`, TaskManager, and PageCache-consuming data services constructed by ContactCenter.
244
+ - `@webex/calling` for browser calling.
245
+
246
+ ```text
247
+ ContactCenter READY callback
248
+ ├── WebexRequest.getInstance(webex)
249
+ ├── Services.getInstance(webex, connectionConfig)
250
+ │ ├── webSocketManager + rtdWebSocketManager
251
+ │ ├── AqmReqs(primary WebSocket)
252
+ │ ├── config + agent + contact + dialer
253
+ │ └── ConnectionService(primary WebSocket)
254
+ ├── WebCallingService + ApiAIAssistant + MetricsManager
255
+ ├── TaskManager(ApiAIAssistant, contact, calling, primary WS, RTD WS)
256
+ └── AddressBook + EntryPoint + Queue + UserPreference
257
+ ```
258
+
259
+ ## Requirements
260
+ | ID | WHAT | WHY | Source Evidence | Test / Example Evidence | Assumptions / Gaps | Confidence |
261
+ |---|---|---|---|---|---|---|
262
+ | SERVICES-R-001 | Build the Services singleton with agent/config/contact/dialer, two WebSocket managers, AqmReqs, and ConnectionService after WebexRequest is initialized. | Every AQM and transport collaborator depends on one shared authenticated host and primary message stream. | `src/services/index.ts` | `test/unit/spec/cc.ts` | None; source and test evidence rechecked during the 2026-07-09 remediation; independent document revalidation pending. | PRESENT |
263
+ | SERVICES-R-002 | Keep direct REST services, including UserPreference, separate from AQM request factories. | Direct data/config/user-preference calls complete from HTTP while AQM operations require correlated WebSocket completion. | `src/services/index.ts`, `src/services/UserPreference.ts` | `test/unit/spec/services/AddressBook.ts`, `test/unit/spec/services/UserPreference.ts` | None; UserPreference's direct-REST/no-PageCache behavior was independently validated by claude-code on 2026-07-15. | PRESENT |
264
+ | SERVICES-R-003 | Construct TaskManager, UserPreference, and other non-Services collaborators in ContactCenter's READY callback, not in `register()`. | Registration is a connection boundary; changing construction timing can duplicate listeners or access uninitialized host services. | `src/cc.ts` | `test/unit/spec/cc.ts`, `test/unit/spec/services/UserPreference.ts` | None; READY-time UserPreference ownership was independently validated by claude-code on 2026-07-15. | PRESENT |
265
+ | SERVICES-R-004 | Pass ApiAIAssistant, contact routing, WebCallingService, primary WebSocket, and RTD WebSocket into TaskManager. | Voice, task, transcript, and suggestion behavior depend on the complete collaborator set. | `src/cc.ts` | `test/unit/spec/services/task/TaskManager.ts` | None; source and test evidence rechecked during the 2026-07-09 remediation; independent document revalidation pending. | PRESENT |
266
+ | SERVICES-R-005 | Inherit authenticated request identity from the host Webex SDK through Core/WebexRequest; Services must not store, parse, or refresh credentials. | One host-owned authentication boundary avoids duplicate token handling and credential leakage across composed services. | `src/services/index.ts`, `src/services/core/WebexRequest.ts` | `test/unit/spec/services/core/WebexRequest.ts` | None; authentication ownership is explicit. | PRESENT |
267
+ | SERVICES-R-006 | Treat Services composition as unconditionally created by the ContactCenter READY callback; Services owns no rollout or feature-flag decision. | Capability flags belong to the consuming config/task/calling collaborators, so the composition root must not silently gate construction. | `src/services/index.ts`, `src/cc.ts` | `test/unit/spec/cc.ts` | None; rollout applicability is explicitly N/A for Services. | PRESENT |
268
+ | SERVICES-R-007 | Existing Queue and EntryPoint list methods must apply inbound, active, telephony, profile/agent-view, and `name,ASC` defaults while retaining their established parameter and full-record response types. Caller-supplied existing filter, sort, or profile inputs override defaults. Queue must also treat `sortOrder` without `sortBy` as a name sort and bypass the simple-page cache. | Defaults on the established methods let thin consumers request lists without a parallel API, while existing parameters preserve specialized behavior for other consumers and full-record types remain truthful because no field projection is requested. | `src/services/Queue.ts`, `src/services/EntryPoint.ts`, `src/types.ts` | `test/unit/spec/services/Queue.ts`, `test/unit/spec/services/EntryPoint.ts`, `test/unit/spec/cc.ts` | The backend honors the view flags and combined CMS sort value. | PRESENT |
269
+ | SERVICES-R-008 | ApiAIAssistant wellness requests must accept no public identity or context-mutating input, read effective enablement and non-empty SDK-owned organization/agent/session context from a read-only provider supplied at construction, then POST the exact `WellnessBreakAction` custom-event body directly to `/event`; only HTTP 202 resolves successfully. Public action unions derive from exported `as const` action-value objects. | SDK-owned live context prevents callers from supplying stale/different login identities to action calls, one value/type source prevents wire drift, and direct HTTP matches the AI event endpoint rather than AQM completion semantics. | `src/services/ApiAiAssistant.ts`, `src/types.ts`, `src/index.ts`, `src/cc.ts` | `test/unit/spec/services/ApiAiAssistant.ts`, `test/unit/spec/cc.ts` | None. | PRESENT |
270
+
271
+ ## Design Overview
272
+ `Services` is a singleton composition root for transport-facing capabilities only. It constructs two `WebSocketManager` instances (primary Contact Center and RTD), creates `AqmReqs` on the primary manager, then creates config, agent, contact, dialer, and ConnectionService collaborators.
273
+
274
+ ContactCenter owns the broader READY-time graph: WebCallingService, ApiAIAssistant, MetricsManager, TaskManager, EntryPoint, AddressBook, Queue, and UserPreference. TaskManager receives ApiAIAssistant, contact routing, calling, and both WebSocket managers. None of these collaborators is created by `register()`; registration attaches runtime listeners and connects the primary socket after READY initialization.
275
+
276
+ AQM factories return functions whose HTTP request is initiation and whose promise settles on correlated primary-WebSocket notifications. Direct config/data services return authenticated REST responses.
277
+
278
+ ApiAIAssistant wellness reporting is also direct REST, but it reads live context through a read-only provider supplied by ContactCenter at construction rather than a separate factory or context setter. It fails closed unless wellness is effectively enabled and the SDK owns a current organization, agent, and session; public action calls do not accept identity fields.
279
+
280
+ ## Data Flow
281
+ ```mermaid
282
+ flowchart TD
283
+ Ready[Host READY] --> WR[WebexRequest singleton]
284
+ WR --> S[Services singleton]
285
+ S --> PWS[Primary WebSocketManager]
286
+ S --> RTD[RTD WebSocketManager]
287
+ PWS --> AQM[AqmReqs]
288
+ AQM --> Agent[routingAgent]
289
+ AQM --> Contact[routingContact]
290
+ AQM --> Dialer[aqmDialer]
291
+ S --> Config[AgentConfigService]
292
+ PWS --> CS[ConnectionService]
293
+ Ready --> AI[ApiAIAssistant]
294
+ Ready --> Calling[WebCallingService]
295
+ Ready --> TM[TaskManager]
296
+ Ready --> UP[UserPreference]
297
+ AI --> TM
298
+ Contact --> TM
299
+ Calling --> TM
300
+ PWS --> TM
301
+ RTD --> TM
302
+ ```
303
+
304
+ Direct REST: caller → AgentConfigService/AddressBook/EntryPoint/Queue/UserPreference → WebexRequest → response.
305
+
306
+ AQM: caller → routing factory → AqmReqs → WebexRequest HTTP acknowledgement → matching primary-WebSocket success/failure → promise settlement.
307
+
308
+ Realtime task/AI: primary or RTD WebSocket → TaskManager → Task/state machine → typed application event.
309
+
310
+ ## Sequence Diagram(s)
311
+ Sequence coverage:
312
+
313
+ | Operation group | Diagram | Failure / recovery coverage |
314
+ |---|---|---|
315
+ | READY-time composition | READY composition | Invalid initialization prevents use of the incomplete graph. |
316
+ | Direct REST | Direct REST request | HTTP/service rejection is returned directly to the caller. |
317
+ | AQM | Correlated AQM operation | HTTP rejection, matching failure notification, and timeout reject the operation. |
318
+
319
+ ### READY composition
320
+
321
+ ```mermaid
322
+ sequenceDiagram
323
+ participant Host
324
+ participant CC as ContactCenter
325
+ participant S as Services
326
+ participant TM as TaskManager
327
+ Host-->>CC: READY
328
+ CC->>CC: initialize WebexRequest
329
+ CC->>S: getInstance(webex, connectionConfig)
330
+ S->>S: primary WS + RTD WS + AqmReqs + config/agent/contact/dialer + ConnectionService
331
+ CC->>CC: create calling + AI assistant + metrics + data services + UserPreference
332
+ CC->>TM: getTaskManager(AI, contact, calling, primary WS, RTD WS)
333
+ ```
334
+
335
+ ### Direct REST request
336
+
337
+ ```mermaid
338
+ sequenceDiagram
339
+ participant Caller
340
+ participant Service as Config/data service
341
+ participant WR as WebexRequest
342
+ participant Host as Authenticated Webex request
343
+ Caller->>Service: typed REST operation
344
+ Service->>WR: request(service + resource + method)
345
+ WR->>Host: resolve service and send request
346
+ alt HTTP success
347
+ Host-->>WR: response
348
+ WR-->>Service: typed response
349
+ Service-->>Caller: result
350
+ else service/HTTP rejection
351
+ Host-->>WR: error
352
+ WR-->>Service: same rejection
353
+ Service-->>Caller: reject
354
+ end
355
+ ```
356
+
357
+ ### Correlated AQM operation
358
+
359
+ ```mermaid
360
+ sequenceDiagram
361
+ participant Caller
362
+ participant Factory as agent/contact/dialer
363
+ participant AQM as AqmReqs
364
+ participant HTTP as WebexRequest
365
+ participant WS as Primary WebSocket
366
+ Caller->>Factory: typed operation
367
+ Factory->>AQM: generated request function(payload)
368
+ AQM->>HTTP: authenticated request(config)
369
+ HTTP-->>AQM: acknowledgement
370
+ alt matching success notification
371
+ WS-->>AQM: notifSuccess.bind match
372
+ AQM-->>Caller: typed response
373
+ else matching failure or timeout
374
+ WS-->>AQM: notifFail.bind match
375
+ AQM-->>Caller: structured rejection
376
+ end
377
+ ```
378
+
379
+ ## Class / Component Relationships
380
+ ```mermaid
381
+ classDiagram
382
+ class ContactCenter
383
+ class Services
384
+ class WebSocketManager
385
+ class AqmReqs
386
+ class ConnectionService
387
+ class AgentConfigService
388
+ class TaskManager
389
+ class ApiAIAssistant
390
+ ContactCenter --> Services
391
+ Services --> WebSocketManager : primary + RTD
392
+ Services --> AqmReqs : primary WS correlation
393
+ Services --> ConnectionService
394
+ Services --> AgentConfigService
395
+ ContactCenter --> ApiAIAssistant
396
+ ContactCenter --> TaskManager
397
+ ContactCenter --> UserPreference
398
+ TaskManager --> ApiAIAssistant
399
+ TaskManager --> WebSocketManager : primary + RTD
400
+ ```
401
+
402
+ ## Use Cases
403
+ - **UC-1 Compose services:** create the transport/factory singleton once per SDK host. Evidence: `src/services/index.ts`, `test/unit/spec/cc.ts`.
404
+ - **UC-2 Direct REST:** configuration, data, and user-preference services return authenticated HTTP results directly. Evidence: `src/services/config/index.ts`, `src/services/UserPreference.ts`, `test/unit/spec/services/config/index.ts`, `test/unit/spec/services/UserPreference.ts`.
405
+ - **UC-3 AQM operation:** initiate HTTP and settle only on matching WebSocket notification or timeout. Evidence: `src/services/core/aqm-reqs.ts`, `test/unit/spec/services/core/aqm-reqs.ts`.
406
+ - **UC-4 Task/AI realtime:** TaskManager consumes primary and RTD streams with ApiAIAssistant/calling collaborators. Evidence: `src/services/task/TaskManager.ts`, `test/unit/spec/services/task/TaskManager.ts`.
407
+ - **UC-5 Wellness action reporting:** validate the current profile/session context and submit a direct AI custom event that completes only on HTTP 202. Evidence: `src/services/ApiAiAssistant.ts`, `test/unit/spec/services/ApiAiAssistant.ts`.
408
+
409
+ ## State Model
410
+ `Services` is a process-local singleton. Its first `getInstance({webex, connectionConfig})` call synchronously constructs the two WebSocket managers, AqmReqs-backed factories, config service, and ConnectionService; later calls return that same composed graph. Socket lifecycle and domain records are owned by the corresponding collaborators, not by a Services state machine.
411
+
412
+ ## Business Rules & Invariants
413
+ - The first singleton construction fixes the host SDK and connection configuration for that Services instance.
414
+ - The primary WebSocket manager is used for AQM correlation and Contact Center events; the RTD manager remains a distinct TaskManager dependency.
415
+ - ApiAIAssistant, TaskManager, and UserPreference are READY-time ContactCenter collaborators, not fields constructed by Services.
416
+ - Authentication is inherited from the host SDK through Core/WebexRequest; Services owns no credential lifecycle.
417
+ - Rollout applicability is N/A for the Services composition root: it is created at READY and does not evaluate a feature flag.
418
+ - ApiAIAssistant evaluates the current effective wellness flag and identities through its constructor-supplied read-only provider; the public object exposes no context mutator, and the Services singleton itself remains unconditionally composed.
419
+
420
+ ## Concurrency & Reactive Flow
421
+ - `getInstance` composition is synchronous in the JavaScript execution turn. Direct REST promises can proceed independently, while each AQM promise remains pending until its matching primary-WebSocket notification, HTTP failure, or timeout.
422
+
423
+ These three services share an identical pattern. Use any one as a reference when creating similar services:
424
+
425
+ | Aspect | Pattern |
426
+ |---|---|
427
+ | **Class structure** | Standalone class with `WebexRequest`, `WebexSDK`, `MetricsManager`, `PageCache` |
428
+ | **Constructor** | `constructor(webex: WebexSDK)` — gets singletons via `.getInstance()` |
429
+ | **HTTP calls** | `this.webexRequest.request({service: WCC_API_GATEWAY, resource, method: HTTP_METHODS.GET})` |
430
+ | **Endpoints** | Uses `endPointMap` functions from `config/constants.ts` to build URL paths |
431
+ | **Pagination** | Query params with `page`, `pageSize`; uses `PageCache` for caching |
432
+ | **Caching** | `PageCache<T>` — caches pages for simple pagination and bypasses cache for result/shape variants, including an effective Queue sort |
433
+ | **Consult/transfer policy** | Existing Queue and EntryPoint methods apply telephony eligibility, profile views, and backend name ordering by default, accept overrides through their existing query parameters, and return full-record responses unchanged |
434
+ | **Metrics** | `timeEvent` on API call start, `trackEvent` on success/failure |
435
+ | **Logging** | `LoggerProxy` with `{module: 'ClassName', method: 'methodName'}` context |
436
+ | **Error handling** | try/catch with `LoggerProxy.error` + `metricsManager.trackEvent` for failures, then re-throw so callers receive the error |
437
+
438
+ Reference files:
439
+
440
+ - [`AddressBook.ts`](../AddressBook.ts) — includes `addressBookId` parameter
441
+
442
+ - [`Queue.ts`](../Queue.ts) — includes additional query params (sortBy, sortOrder, etc.)
443
+
444
+ - [`EntryPoint.ts`](../EntryPoint.ts) — simplest example
445
+
446
+ `UserPreference.ts` is a separate direct REST CRUD pattern. It resolves a default user id from `agentConfig`, supports explicit user ids where applicable, and intentionally does not share PageCache behavior with the three paginated services.
447
+
448
+ ## State Machine
449
+ ```mermaid
450
+ stateDiagram-v2
451
+ [*] --> NotCreated
452
+ NotCreated --> Composed: first getInstance(options)
453
+ Composed --> Composed: later getInstance returns singleton
454
+ ```
455
+
456
+ ## Protocol / Wire Format
457
+ - Request, response, and event payload ownership is anchored in `src/services/index.ts`. HTTP initiates backend work where applicable; WebSocket messages provide realtime events and, for AQM flows, correlated completion. Wellness actions POST `CUSTOM_EVENT` / `WellnessBreakAction` bodies directly to `/event` and accept only status 202; wellness offers arrive as primary `Wellness_Break_Handler` notifications.
458
+
459
+ ## Error Handling & Failure Modes
460
+ | Condition | Signal (error/code/result) | Caller recovery |
461
+ |---|---|---|
462
+ | Dependency rejection | Typed/rethrown error or failure event | Inspect structured details, preserve tracking id, and retry only when the operation is safe. |
463
+ | Timeout or missing async completion | Timeout/recovery state | Follow the module-specific recovery path; never synthesize success. |
464
+
465
+ ## Pitfalls
466
+ - Direct REST services complete from HTTP, while agent/contact/dialer AQM factories complete from correlated WebSocket notifications; treating them as the same transport model returns too early.
467
+ - The singleton must share one primary WebSocket with AqmReqs and a distinct RTD WebSocket with TaskManager; swapping or omitting either stream loses task or AI events.
468
+ - TaskManager and calling/AI/data/UserPreference collaborators are created by ContactCenter after READY, not by the Services constructor or `register()`.
469
+
470
+ ## Module Do's / Don'ts
471
+ - DO initialize `WebexRequest` before obtaining the Services singleton.
472
+ - DO preserve separate primary and RTD WebSocket ownership when changing composition.
473
+ - DON'T wrap direct REST services in AqmReqs or treat HTTP acknowledgement as AQM completion.
474
+ - DON'T add feature-flag decisions to the Services composition root.
475
+
476
+ ## Key Design Trade-off
477
+ - Two backend interaction patterns coexist: direct REST for immediate responses and AQM HTTP-plus-WebSocket correlation for asynchronous completion.
478
+
479
+ ## Test-Case Strategy (module)
480
+ Unit tests mirror module paths under `test/unit/spec/services`. Preserve positive and negative paths, event ordering, timeout/recovery behavior, and the package's 85% global branch/function/line/statement threshold.
481
+
482
+ | Behavior / Requirement | Existing test evidence | Gap |
483
+ |---|---|---|
484
+ | `SERVICES-R-001` | `test/unit/spec/cc.ts` | Add a focused Services singleton composition test if constructor wiring changes. |
485
+ | `SERVICES-R-002` | `test/unit/spec/services/config/index.ts`, `test/unit/spec/services/UserPreference.ts`, `test/unit/spec/services/core/aqm-reqs.ts` | Coverage is split across direct and AQM owners. |
486
+ | `SERVICES-R-003` | `test/unit/spec/cc.ts`, `test/unit/spec/services/UserPreference.ts` | None. |
487
+ | `SERVICES-R-004` | `test/unit/spec/services/task/TaskManager.ts`, `test/unit/spec/cc.ts` | None. |
488
+ | `SERVICES-R-005` | `test/unit/spec/services/core/WebexRequest.ts` | None. |
489
+ | `SERVICES-R-006` | `test/unit/spec/cc.ts` | None. |
490
+ | `SERVICES-R-007` | `test/unit/spec/services/Queue.ts`, `test/unit/spec/services/EntryPoint.ts`, `test/unit/spec/cc.ts` | None. |
491
+ | `SERVICES-R-008` | `test/unit/spec/services/ApiAiAssistant.ts` | None. |
492
+
493
+ ## Traceability
494
+ - Repo architecture: `../../../ai-docs/ARCHITECTURE.md` · Registry: `../../../ai-docs/SPEC_INDEX.md`
495
+ - Coverage state and contracts baseline: `../../../.sdd/manifest.json`
496
+
497
+ - [Root orchestrator AGENTS.md](../../../AGENTS.md) — repository rules; use [`SPEC_INDEX.md`](../../../ai-docs/SPEC_INDEX.md) for canonical module routing
498
+
499
+ - [ai-docs/RULES.md](../../../ai-docs/RULES.md) — coding standards
500
+
501
+ - [ai-docs/patterns/](../../../ai-docs/patterns/) — TypeScript, testing, and event patterns
502
+
503
+ - [types.ts](../../types.ts) — public type definitions
504
+
505
+ - [cc.ts](../../cc.ts) — main plugin class (public API surface)
@@ -1,4 +1,5 @@
1
1
  import {LOST_CONNECTION_RECOVERY_TIMEOUT} from '../core/constants';
2
+ import {WELLNESS_BREAK_REMINDERS_ENABLED} from './constants';
2
3
  import {
3
4
  AgentResponse,
4
5
  AuxCode,
@@ -185,11 +186,15 @@ function parseAgentConfigs(profileData: {
185
186
 
186
187
  const defaultWrapUpData = getDefaultWrapUpCode(wrapupCodes);
187
188
  const aiFeature: AIFeatureFlags | undefined =
188
- aiFeatureFlags?.data && aiFeatureFlags.data.length > 0 ? aiFeatureFlags.data[0] : undefined;
189
+ aiFeatureFlags?.data?.length > 0 ? aiFeatureFlags.data[0] : undefined;
190
+ const isWellnessConfigured =
191
+ aiFeature?.agentWellbeing?.enable === true &&
192
+ aiFeature.agentWellbeing.wellnessBreakReminders === WELLNESS_BREAK_REMINDERS_ENABLED;
193
+ const hasAIAssistantLicense = (orgSettingsData.aiAssistantQuantity ?? 0) > 0;
189
194
 
190
195
  const finalData = {
191
196
  teams: teamData,
192
- defaultDn: userData.defaultDialledNumber,
197
+ defaultDn: userData.deafultDialledNumber,
193
198
  forceDefaultDn: tenantData.forceDefaultDn,
194
199
  forceDefaultDnForAgent: getDefaultAgentDN(agentProfileData.agentDNValidation),
195
200
  regexUS: tenantData.dnDefaultRegex,
@@ -233,11 +238,14 @@ function parseAgentConfigs(profileData: {
233
238
  isAgentAvailableAfterOutdial: agentProfileData.agentAvailableAfterOutdial,
234
239
  outDialEp: agentProfileData.outdialEntryPointId,
235
240
  isCampaignManagementEnabled: orgSettingsData.campaignManagerEnabled,
236
- isEndCallEnabled: tenantData.endCallEnabled,
241
+ isEndTaskEnabled: tenantData.endCallEnabled,
237
242
  isEndConsultEnabled: tenantData.endConsultEnabled,
238
243
  callVariablesSuppressed: tenantData.callVariablesSuppressed,
239
244
  agentDbId: userData.dbId,
240
245
  allowConsultToQueue: agentProfileData.consultToQueue,
246
+ accessQueue: agentProfileData.accessQueue,
247
+ accessEntryPoint: agentProfileData.accessEntryPoint,
248
+ accessBuddyTeam: agentProfileData.accessBuddyTeam,
241
249
  agentPersonalStatsEnabled: agentProfileData.viewableStatistics
242
250
  ? agentProfileData.viewableStatistics.agentStats
243
251
  : false,
@@ -261,6 +269,7 @@ function parseAgentConfigs(profileData: {
261
269
  lostConnectionRecoveryTimeout:
262
270
  tenantData.lostConnectionRecoveryTimeout || LOST_CONNECTION_RECOVERY_TIMEOUT,
263
271
  aiFeature,
272
+ isWellnessBreakEnabled: isWellnessConfigured && hasAIAssistantLicense,
264
273
  };
265
274
 
266
275
  return finalData;