@webex/contact-center 3.11.0 → 3.12.0-llmrefactor.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (267) hide show
  1. package/.sdd/manifest.json +882 -0
  2. package/AGENTS.md +94 -0
  3. package/ai-docs/ARCHITECTURE.md +168 -0
  4. package/ai-docs/CONTRACTS.md +46 -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 +48 -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 +341 -0
  17. package/ai-docs/features/generated-spec-conformance-fidelity-remediation/spec/feature-spec.md +117 -0
  18. package/ai-docs/features/residual-warning-coverage-completion/spec/feature-spec.md +203 -0
  19. package/ai-docs/features/validator-code-fidelity-drift-fix/spec/feature-spec.md +315 -0
  20. package/ai-docs/patterns/event-driven-patterns.md +485 -0
  21. package/ai-docs/patterns/testing-patterns.md +480 -0
  22. package/ai-docs/patterns/typescript-patterns.md +365 -0
  23. package/ai-docs/templates/README.md +102 -0
  24. package/ai-docs/templates/documentation/create-agents-md.md +240 -0
  25. package/ai-docs/templates/documentation/create-architecture-md.md +295 -0
  26. package/ai-docs/templates/existing-service/bug-fix.md +254 -0
  27. package/ai-docs/templates/existing-service/feature-enhancement.md +450 -0
  28. package/ai-docs/templates/new-method/00-master.md +80 -0
  29. package/ai-docs/templates/new-method/01-requirements.md +232 -0
  30. package/ai-docs/templates/new-method/02-implementation.md +295 -0
  31. package/ai-docs/templates/new-method/03-tests.md +201 -0
  32. package/ai-docs/templates/new-method/04-validation.md +141 -0
  33. package/ai-docs/templates/new-service/00-master.md +109 -0
  34. package/ai-docs/templates/new-service/01-pre-questions.md +159 -0
  35. package/ai-docs/templates/new-service/02-code-generation.md +346 -0
  36. package/ai-docs/templates/new-service/03-integration.md +178 -0
  37. package/ai-docs/templates/new-service/04-test-generation.md +205 -0
  38. package/ai-docs/templates/new-service/05-validation.md +145 -0
  39. package/dist/cc.js +379 -50
  40. package/dist/cc.js.map +1 -1
  41. package/dist/config.js +6 -0
  42. package/dist/config.js.map +1 -1
  43. package/dist/constants.js +22 -2
  44. package/dist/constants.js.map +1 -1
  45. package/dist/index.js +27 -5
  46. package/dist/index.js.map +1 -1
  47. package/dist/metrics/behavioral-events.js +114 -0
  48. package/dist/metrics/behavioral-events.js.map +1 -1
  49. package/dist/metrics/constants.js +32 -3
  50. package/dist/metrics/constants.js.map +1 -1
  51. package/dist/services/ApiAiAssistant.js +318 -0
  52. package/dist/services/ApiAiAssistant.js.map +1 -0
  53. package/dist/services/UserPreference.js +427 -0
  54. package/dist/services/UserPreference.js.map +1 -0
  55. package/dist/services/agent/types.js.map +1 -1
  56. package/dist/services/config/Util.js +8 -4
  57. package/dist/services/config/Util.js.map +1 -1
  58. package/dist/services/config/constants.js +35 -2
  59. package/dist/services/config/constants.js.map +1 -1
  60. package/dist/services/config/index.js +41 -2
  61. package/dist/services/config/index.js.map +1 -1
  62. package/dist/services/config/types.js +66 -8
  63. package/dist/services/config/types.js.map +1 -1
  64. package/dist/services/constants.js +27 -1
  65. package/dist/services/constants.js.map +1 -1
  66. package/dist/services/core/Err.js.map +1 -1
  67. package/dist/services/core/Utils.js +122 -25
  68. package/dist/services/core/Utils.js.map +1 -1
  69. package/dist/services/core/aqm-reqs.js +92 -17
  70. package/dist/services/core/aqm-reqs.js.map +1 -1
  71. package/dist/services/core/websocket/WebSocketManager.js +22 -6
  72. package/dist/services/core/websocket/WebSocketManager.js.map +1 -1
  73. package/dist/services/core/websocket/connection-service.js +3 -1
  74. package/dist/services/core/websocket/connection-service.js.map +1 -1
  75. package/dist/services/core/websocket/types.js.map +1 -1
  76. package/dist/services/index.js +6 -0
  77. package/dist/services/index.js.map +1 -1
  78. package/dist/services/task/Task.js +688 -0
  79. package/dist/services/task/Task.js.map +1 -0
  80. package/dist/services/task/TaskFactory.js +45 -0
  81. package/dist/services/task/TaskFactory.js.map +1 -0
  82. package/dist/services/task/TaskManager.js +751 -457
  83. package/dist/services/task/TaskManager.js.map +1 -1
  84. package/dist/services/task/TaskUtils.js +220 -23
  85. package/dist/services/task/TaskUtils.js.map +1 -1
  86. package/dist/services/task/constants.js +23 -2
  87. package/dist/services/task/constants.js.map +1 -1
  88. package/dist/services/task/dialer.js +129 -0
  89. package/dist/services/task/dialer.js.map +1 -1
  90. package/dist/services/task/digital/Digital.js +77 -0
  91. package/dist/services/task/digital/Digital.js.map +1 -0
  92. package/dist/services/task/state-machine/TaskStateMachine.js +873 -0
  93. package/dist/services/task/state-machine/TaskStateMachine.js.map +1 -0
  94. package/dist/services/task/state-machine/actions.js +567 -0
  95. package/dist/services/task/state-machine/actions.js.map +1 -0
  96. package/dist/services/task/state-machine/constants.js +161 -0
  97. package/dist/services/task/state-machine/constants.js.map +1 -0
  98. package/dist/services/task/state-machine/guards.js +382 -0
  99. package/dist/services/task/state-machine/guards.js.map +1 -0
  100. package/dist/services/task/state-machine/index.js +53 -0
  101. package/dist/services/task/state-machine/index.js.map +1 -0
  102. package/dist/services/task/state-machine/types.js +54 -0
  103. package/dist/services/task/state-machine/types.js.map +1 -0
  104. package/dist/services/task/state-machine/uiControlsComputer.js +603 -0
  105. package/dist/services/task/state-machine/uiControlsComputer.js.map +1 -0
  106. package/dist/services/task/taskDataNormalizer.js +99 -0
  107. package/dist/services/task/taskDataNormalizer.js.map +1 -0
  108. package/dist/services/task/types.js +227 -4
  109. package/dist/services/task/types.js.map +1 -1
  110. package/dist/services/task/voice/Voice.js +1044 -0
  111. package/dist/services/task/voice/Voice.js.map +1 -0
  112. package/dist/services/task/voice/WebRTC.js +149 -0
  113. package/dist/services/task/voice/WebRTC.js.map +1 -0
  114. package/dist/types/cc.d.ts +894 -0
  115. package/dist/types/config.d.ts +72 -0
  116. package/dist/types/constants.d.ts +66 -0
  117. package/dist/types/index.d.ts +199 -0
  118. package/dist/types/logger-proxy.d.ts +71 -0
  119. package/dist/types/metrics/MetricsManager.d.ts +223 -0
  120. package/dist/types/metrics/behavioral-events.d.ts +29 -0
  121. package/dist/types/metrics/constants.d.ts +181 -0
  122. package/dist/types/services/AddressBook.d.ts +74 -0
  123. package/dist/types/services/ApiAiAssistant.d.ts +49 -0
  124. package/dist/types/services/EntryPoint.d.ts +67 -0
  125. package/dist/types/services/Queue.d.ts +76 -0
  126. package/dist/types/services/UserPreference.d.ts +118 -0
  127. package/dist/types/services/WebCallingService.d.ts +1 -0
  128. package/dist/types/services/agent/index.d.ts +46 -0
  129. package/dist/types/services/agent/types.d.ts +413 -0
  130. package/dist/types/services/config/Util.d.ts +20 -0
  131. package/dist/types/services/config/constants.d.ts +270 -0
  132. package/dist/types/services/config/index.d.ts +177 -0
  133. package/dist/types/services/config/types.d.ts +1368 -0
  134. package/dist/types/services/constants.d.ts +110 -0
  135. package/dist/types/services/core/Err.d.ts +125 -0
  136. package/dist/types/services/core/GlobalTypes.d.ts +58 -0
  137. package/dist/types/services/core/Utils.d.ts +121 -0
  138. package/dist/types/services/core/WebexRequest.d.ts +22 -0
  139. package/dist/types/services/core/aqm-reqs.d.ts +65 -0
  140. package/dist/types/services/core/constants.d.ts +99 -0
  141. package/dist/types/services/core/types.d.ts +47 -0
  142. package/dist/types/services/core/websocket/WebSocketManager.d.ts +36 -0
  143. package/dist/types/services/core/websocket/connection-service.d.ts +27 -0
  144. package/dist/types/services/core/websocket/keepalive.worker.d.ts +2 -0
  145. package/dist/types/services/core/websocket/types.d.ts +37 -0
  146. package/dist/types/services/index.d.ts +54 -0
  147. package/dist/types/services/task/AutoWrapup.d.ts +40 -0
  148. package/dist/types/services/task/Task.d.ts +157 -0
  149. package/dist/types/services/task/TaskFactory.d.ts +12 -0
  150. package/dist/types/services/task/TaskManager.d.ts +1 -0
  151. package/dist/types/services/task/TaskUtils.d.ts +138 -0
  152. package/dist/types/services/task/constants.d.ts +91 -0
  153. package/dist/types/services/task/contact.d.ts +69 -0
  154. package/dist/types/services/task/dialer.d.ts +73 -0
  155. package/dist/types/services/task/digital/Digital.d.ts +22 -0
  156. package/dist/types/services/task/state-machine/TaskStateMachine.d.ts +1194 -0
  157. package/dist/types/services/task/state-machine/actions.d.ts +10 -0
  158. package/dist/types/services/task/state-machine/constants.d.ts +107 -0
  159. package/dist/types/services/task/state-machine/guards.d.ts +102 -0
  160. package/dist/types/services/task/state-machine/index.d.ts +13 -0
  161. package/dist/types/services/task/state-machine/types.d.ts +269 -0
  162. package/dist/types/services/task/state-machine/uiControlsComputer.d.ts +9 -0
  163. package/dist/types/services/task/taskDataNormalizer.d.ts +10 -0
  164. package/dist/types/services/task/types.d.ts +1856 -0
  165. package/dist/types/services/task/voice/Voice.d.ts +184 -0
  166. package/dist/types/services/task/voice/WebRTC.d.ts +53 -0
  167. package/dist/types/types.d.ts +778 -0
  168. package/dist/types/utils/PageCache.d.ts +173 -0
  169. package/dist/types/webex-config.d.ts +53 -0
  170. package/dist/types/webex.d.ts +8 -0
  171. package/dist/types.js +130 -1
  172. package/dist/types.js.map +1 -1
  173. package/dist/webex.js +14 -2
  174. package/dist/webex.js.map +1 -1
  175. package/package.json +16 -12
  176. package/src/cc.ts +477 -51
  177. package/src/config.ts +6 -0
  178. package/src/constants.ts +21 -1
  179. package/src/index.ts +24 -5
  180. package/src/metrics/ai-docs/AGENTS.md +350 -0
  181. package/src/metrics/ai-docs/ARCHITECTURE.md +338 -0
  182. package/src/metrics/ai-docs/metrics-spec.md +854 -0
  183. package/src/metrics/behavioral-events.ts +120 -0
  184. package/src/metrics/constants.ts +37 -3
  185. package/src/services/ApiAiAssistant.ts +412 -0
  186. package/src/services/UserPreference.ts +509 -0
  187. package/src/services/agent/ai-docs/AGENTS.md +240 -0
  188. package/src/services/agent/ai-docs/ARCHITECTURE.md +304 -0
  189. package/src/services/agent/ai-docs/agent-spec.md +504 -0
  190. package/src/services/agent/types.ts +1 -1
  191. package/src/services/ai-docs/AGENTS.md +386 -0
  192. package/src/services/ai-docs/services-spec.md +492 -0
  193. package/src/services/config/Util.ts +10 -2
  194. package/src/services/config/ai-docs/AGENTS.md +255 -0
  195. package/src/services/config/ai-docs/ARCHITECTURE.md +426 -0
  196. package/src/services/config/ai-docs/config-spec.md +669 -0
  197. package/src/services/config/constants.ts +37 -1
  198. package/src/services/config/index.ts +45 -1
  199. package/src/services/config/types.ts +241 -11
  200. package/src/services/constants.ts +29 -0
  201. package/src/services/core/Err.ts +3 -0
  202. package/src/services/core/Utils.ts +143 -30
  203. package/src/services/core/ai-docs/AGENTS.md +381 -0
  204. package/src/services/core/ai-docs/ARCHITECTURE.md +698 -0
  205. package/src/services/core/ai-docs/core-spec.md +783 -0
  206. package/src/services/core/aqm-reqs.ts +100 -22
  207. package/src/services/core/websocket/WebSocketManager.ts +23 -6
  208. package/src/services/core/websocket/connection-service.ts +5 -1
  209. package/src/services/core/websocket/types.ts +1 -1
  210. package/src/services/index.ts +4 -0
  211. package/src/services/task/Task.ts +837 -0
  212. package/src/services/task/TaskFactory.ts +55 -0
  213. package/src/services/task/TaskManager.ts +793 -521
  214. package/src/services/task/TaskUtils.ts +314 -24
  215. package/src/services/task/ai-docs/AGENTS.md +457 -0
  216. package/src/services/task/ai-docs/ARCHITECTURE.md +594 -0
  217. package/src/services/task/ai-docs/task-spec.md +1319 -0
  218. package/src/services/task/constants.ts +23 -0
  219. package/src/services/task/dialer.ts +136 -1
  220. package/src/services/task/digital/Digital.ts +95 -0
  221. package/src/services/task/state-machine/TaskStateMachine.ts +1166 -0
  222. package/src/services/task/state-machine/actions.ts +738 -0
  223. package/src/services/task/state-machine/ai-docs/AGENTS.md +458 -0
  224. package/src/services/task/state-machine/ai-docs/ARCHITECTURE.md +1137 -0
  225. package/src/services/task/state-machine/ai-docs/task-state-machine-spec.md +2177 -0
  226. package/src/services/task/state-machine/constants.ts +172 -0
  227. package/src/services/task/state-machine/guards.ts +445 -0
  228. package/src/services/task/state-machine/index.ts +28 -0
  229. package/src/services/task/state-machine/types.ts +243 -0
  230. package/src/services/task/state-machine/uiControlsComputer.ts +961 -0
  231. package/src/services/task/taskDataNormalizer.ts +137 -0
  232. package/src/services/task/types.ts +734 -71
  233. package/src/services/task/voice/Voice.ts +1270 -0
  234. package/src/services/task/voice/WebRTC.ts +187 -0
  235. package/src/types.ts +205 -2
  236. package/src/utils/AGENTS.md +278 -0
  237. package/src/utils/ai-docs/utils-spec.md +381 -0
  238. package/src/webex.js +2 -0
  239. package/test/unit/spec/cc.ts +503 -43
  240. package/test/unit/spec/logger-proxy.ts +70 -0
  241. package/test/unit/spec/services/ApiAiAssistant.ts +273 -0
  242. package/test/unit/spec/services/UserPreference.ts +401 -0
  243. package/test/unit/spec/services/WebCallingService.ts +7 -1
  244. package/test/unit/spec/services/config/index.ts +85 -29
  245. package/test/unit/spec/services/core/Utils.ts +481 -2
  246. package/test/unit/spec/services/core/websocket/WebSocketManager.ts +137 -41
  247. package/test/unit/spec/services/core/websocket/connection-service.ts +3 -1
  248. package/test/unit/spec/services/task/AutoWrapup.ts +63 -0
  249. package/test/unit/spec/services/task/Task.ts +477 -0
  250. package/test/unit/spec/services/task/TaskFactory.ts +62 -0
  251. package/test/unit/spec/services/task/TaskManager.ts +1001 -1003
  252. package/test/unit/spec/services/task/TaskUtils.ts +235 -0
  253. package/test/unit/spec/services/task/dialer.ts +372 -96
  254. package/test/unit/spec/services/task/digital/Digital.ts +105 -0
  255. package/test/unit/spec/services/task/state-machine/TaskStateMachine.ts +2651 -0
  256. package/test/unit/spec/services/task/state-machine/guards.ts +637 -0
  257. package/test/unit/spec/services/task/state-machine/types.ts +18 -0
  258. package/test/unit/spec/services/task/state-machine/uiControlsComputer.ts +2663 -0
  259. package/test/unit/spec/services/task/taskTestUtils.ts +87 -0
  260. package/test/unit/spec/services/task/voice/Voice.ts +649 -0
  261. package/test/unit/spec/services/task/voice/WebRTC.ts +235 -0
  262. package/umd/contact-center.min.js +2 -2
  263. package/umd/contact-center.min.js.map +1 -1
  264. package/dist/services/task/index.js +0 -1525
  265. package/dist/services/task/index.js.map +0 -1
  266. package/src/services/task/index.ts +0 -1801
  267. package/test/unit/spec/services/task/index.ts +0 -2184
@@ -0,0 +1,338 @@
1
+ # Metrics Module - Architecture
2
+
3
+ > **Legacy/reference-only.** Canonical SDD: [`metrics-spec.md`](metrics-spec.md). Use the package [manifest](../../../.sdd/manifest.json) and [`SPEC_INDEX.md`](../../../ai-docs/SPEC_INDEX.md) for routing; code and tests remain the behavioral referee.
4
+
5
+ > **Purpose**: Technical documentation for the metrics collection, batching, and submission system within the Contact Center SDK.
6
+
7
+ ---
8
+
9
+ ## Component Overview
10
+
11
+ | Component | File | Responsibility |
12
+ | ------------------------ | ----------------------- | ------------------------------------------------------------------------------ |
13
+ | `MetricsManager` | `MetricsManager.ts` | Singleton that manages event queuing, timing, payload preparation, and submission |
14
+ | `BehavioralEventTaxonomy`| `behavioral-events.ts` | Maps metric event names to structured taxonomy for behavioral analytics |
15
+ | `METRIC_EVENT_NAMES` | `constants.ts` | Canonical constant object of all tracked metric event names |
16
+
17
+ ---
18
+
19
+ ## File Structure
20
+
21
+ ```
22
+ src/metrics/
23
+ ├── MetricsManager.ts # Singleton metrics manager
24
+ ├── behavioral-events.ts # Behavioral event taxonomy mapping
25
+ ├── constants.ts # METRIC_EVENT_NAMES constants
26
+ └── ai-docs/
27
+ ├── AGENTS.md # Usage documentation (see PR #4762)
28
+ └── ARCHITECTURE.md # This file
29
+ ```
30
+
31
+ ---
32
+
33
+ ## Singleton Pattern
34
+
35
+ `MetricsManager` uses a private constructor with a static `getInstance` factory:
36
+
37
+ ```typescript
38
+ // MetricsManager.ts
39
+ export default class MetricsManager {
40
+ private static instance: MetricsManager;
41
+ private constructor() {}
42
+
43
+ public static getInstance(options?: {webex: WebexSDK}): MetricsManager {
44
+ if (!MetricsManager.instance) {
45
+ MetricsManager.instance = new MetricsManager();
46
+ }
47
+ if (!MetricsManager.instance.webex && options?.webex) {
48
+ MetricsManager.instance.setWebex(options.webex);
49
+ }
50
+ return MetricsManager.instance;
51
+ }
52
+
53
+ public static resetInstance() {
54
+ MetricsManager.instance = undefined;
55
+ }
56
+ }
57
+ ```
58
+
59
+ - The Webex SDK instance is set once via `setWebex()`, which listens for the `ready` event before flushing pending queues.
60
+ - `resetInstance()` sets the singleton to `undefined`, allowing a fresh instance to be created. Primarily used in tests.
61
+
62
+ ---
63
+
64
+ ## Data Flow
65
+
66
+ ### Event Submission Flow
67
+
68
+ ```mermaid
69
+ flowchart TD
70
+ A[cc.ts calls metricsManager.timeEvent] --> B[Store startTime + keys in runningEvents]
71
+ B --> C[Operation executes]
72
+ C --> D{Success or Failure?}
73
+ D -->|Success| E[cc.ts calls metricsManager.trackEvent with success name]
74
+ D -->|Failure| F[cc.ts calls metricsManager.trackEvent with failure name]
75
+ E --> G[addDurationIfTimed attaches duration_ms]
76
+ F --> G
77
+ G --> H[preparePayload cleans and enriches]
78
+ H --> I{Metric type?}
79
+ I -->|behavioral| J[Push to pendingBehavioralEvents]
80
+ I -->|operational| K[Push to pendingOperationalEvents]
81
+ I -->|business| L[Push to pendingBusinessEvents]
82
+ J --> M[submitPendingBehavioralEvents]
83
+ K --> N[submitPendingOperationalEvents]
84
+ L --> O[submitPendingBusinessEvents]
85
+ M --> P[webex.internal.newMetrics.submitBehavioralEvent]
86
+ N --> Q[webex.internal.newMetrics.submitOperationalEvent]
87
+ O --> R[webex.internal.newMetrics.submitBusinessEvent]
88
+ ```
89
+
90
+ ---
91
+
92
+ ## Sequence Diagrams
93
+
94
+ ### Track Event with Timing
95
+
96
+ ```mermaid
97
+ sequenceDiagram
98
+ participant CC as ContactCenter (cc.ts)
99
+ participant MM as MetricsManager
100
+ participant NM as webex.internal.newMetrics
101
+
102
+ CC->>MM: timeEvent([SUCCESS_KEY, FAILURE_KEY])
103
+ Note over MM: Store startTime + key set in runningEvents
104
+ CC->>CC: Execute operation (e.g., stationLogin)
105
+ Note over MM: trackEvent defaults to ['behavioral'] only if no metricServices specified
106
+ alt Success
107
+ CC->>MM: trackEvent(SUCCESS_KEY, payload, ['behavioral', 'operational', 'business'])
108
+ else Failure
109
+ CC->>MM: trackEvent(FAILURE_KEY, payload, ['behavioral', 'operational', 'business'])
110
+ end
111
+ MM->>MM: addDurationIfTimed → attach duration_ms
112
+ MM->>MM: preparePayload → clean empty fields, add tabHidden
113
+ loop For each metric type
114
+ MM->>MM: Push to pending queue
115
+ alt readyToSubmitEvents
116
+ MM->>NM: submit[Behavioral|Operational|Business]Event
117
+ else not ready
118
+ Note over MM: Events stay queued until SDK ready
119
+ end
120
+ end
121
+ ```
122
+
123
+ ### Initialization and Readiness
124
+
125
+ ```mermaid
126
+ sequenceDiagram
127
+ participant CC as ContactCenter
128
+ participant MM as MetricsManager
129
+ participant Webex as WebexSDK
130
+
131
+ CC->>MM: getInstance({webex})
132
+ MM->>MM: Create singleton (if needed)
133
+ MM->>MM: setWebex(webex)
134
+ opt webex.ready === true
135
+ MM->>MM: setReadyToSubmitEvents()
136
+ MM->>MM: submitPendingEvents()
137
+ end
138
+ MM->>Webex: webex.once('ready', callback)
139
+ Note over MM: 'ready' listener is always registered
140
+ Webex-->>MM: 'ready' event fires
141
+ MM->>MM: setReadyToSubmitEvents()
142
+ MM->>MM: submitPendingEvents()
143
+ ```
144
+
145
+ ---
146
+
147
+ ## Behavioral Event Taxonomy
148
+
149
+ Each metric event name maps to a `BehavioralEventTaxonomy` with four fields:
150
+
151
+ ```typescript
152
+ type BehavioralEventTaxonomy = {
153
+ product: MetricEventProduct; // Always PRODUCT_NAME ('wxcc_sdk')
154
+ agent: MetricEventAgent; // 'user' or 'service'
155
+ target: string; // e.g., 'station_login', 'task_accept'
156
+ verb: MetricEventVerb; // 'complete' for success, 'fail' for failure
157
+ };
158
+ ```
159
+
160
+ The final behavioral event name is constructed as: `{product}.{agent}.{target}.{verb}`
161
+
162
+ Example: `wxcc_sdk.user.station_login.complete`
163
+
164
+ The mapping is defined in `behavioral-events.ts` via `eventTaxonomyMap` and accessed through `getEventTaxonomy(name)`.
165
+
166
+ ---
167
+
168
+ ## Event Queuing and Submission
169
+
170
+ ### Three Parallel Queues
171
+
172
+ MetricsManager maintains three independent pending event queues:
173
+
174
+ | Queue | Type | Submitted Via | Name Transform | Extra Metadata |
175
+ | --------------------------- | ------------ | -------------------------------------------------- | ----------------------------------------------- | -------------------------------- |
176
+ | `pendingBehavioralEvents` | behavioral | `webex.internal.newMetrics.submitBehavioralEvent` | Taxonomy-based (`{product}.{agent}.{target}.{verb}`) | None |
177
+ | `pendingOperationalEvents` | operational | `webex.internal.newMetrics.submitOperationalEvent` | `WXCC_SDK_` prefix + uppercase (e.g. `WXCC_SDK_STATION_LOGIN_SUCCESS`) | None |
178
+ | `pendingBusinessEvents` | business | `webex.internal.newMetrics.submitBusinessEvent` | `WXCC_SDK_` prefix + uppercase (same as operational) | `metadata: {appType: 'wxcc_sdk'}` |
179
+
180
+ ### Submission Guards
181
+
182
+ - **readyToSubmitEvents**: Set to `true` only after `webex.once('ready')` fires. Events queue until then.
183
+ - **submittingEvents**: Lock flag to prevent concurrent `submitPendingEvents()` calls.
184
+ - **metricsDisabled**: When `true`, all `track*` methods return early and `clearPendingEvents()` empties all queues.
185
+
186
+ ---
187
+
188
+ ## Timing Pattern (`timeEvent` / `trackEvent`)
189
+
190
+ ```mermaid
191
+ flowchart LR
192
+ A[timeEvent keys] --> B[runningEvents stores startTime + key Set]
193
+ B --> C[trackEvent called with one of the keys]
194
+ C --> D[addDurationIfTimed matches key]
195
+ D --> E[Calculates duration_ms = now - startTime]
196
+ E --> F[Removes all keys for that operation]
197
+ F --> G[Attaches duration_ms to payload]
198
+ ```
199
+
200
+ Usage pattern from `cc.ts`:
201
+
202
+ ```typescript
203
+ // Before operation
204
+ this.metricsManager.timeEvent([
205
+ METRIC_EVENT_NAMES.STATION_LOGIN_SUCCESS,
206
+ METRIC_EVENT_NAMES.STATION_LOGIN_FAILED,
207
+ ]);
208
+
209
+ // On success
210
+ this.metricsManager.trackEvent(
211
+ METRIC_EVENT_NAMES.STATION_LOGIN_SUCCESS,
212
+ { ...MetricsManager.getCommonTrackingFieldForAQMResponse(resp) },
213
+ ['behavioral', 'operational', 'business']
214
+ );
215
+
216
+ // On failure
217
+ this.metricsManager.trackEvent(
218
+ METRIC_EVENT_NAMES.STATION_LOGIN_FAILED,
219
+ { ...MetricsManager.getCommonTrackingFieldForAQMResponseFailed(failure) },
220
+ ['behavioral', 'operational', 'business']
221
+ );
222
+ ```
223
+
224
+ ---
225
+
226
+ ## Payload Preparation
227
+
228
+ `preparePayload()` processes every event payload before submission:
229
+
230
+ 1. **Removes empty/null/undefined fields** — strips keys with `undefined`, `null`, `''`, any arrays, or empty objects
231
+ 2. **Converts spaces to underscores** — `spacesToUnderscore()` applied to all key names
232
+ 3. **Adds common metadata** — appends `tabHidden: document.hidden` in browser environments
233
+
234
+ ---
235
+
236
+ ## Error Handling Strategy
237
+
238
+ MetricsManager does not throw errors to callers. Instead:
239
+
240
+ - Invalid metric types are logged via `LoggerProxy.error`
241
+ - Empty `timeEvent` key arrays are logged and ignored
242
+ - Disabled state (`metricsDisabled`) silently drops events
243
+ - The `submittingEvents` lock prevents race conditions during concurrent submissions
244
+
245
+ ---
246
+
247
+ ## Common Tracking Field Extraction
248
+
249
+ Two static helpers extract standardized fields from AQM responses for metric payloads:
250
+
251
+ ### `getCommonTrackingFieldForAQMResponse(response)`
252
+
253
+ Extracts: `agentId`, `agentSessionId`, `teamId`, `siteId`, `orgId`, `eventType`, `trackingId`, `notifTrackingId`
254
+
255
+ ### `getCommonTrackingFieldForAQMResponseFailed(failureResponse)`
256
+
257
+ Extracts: `agentId`, `trackingId`, `notifTrackingId`, `orgId`, `failureType`, `failureReason`, `reasonCode`
258
+
259
+ ---
260
+
261
+ ## Metric Event Names
262
+
263
+ All event names are defined in `constants.ts` as `METRIC_EVENT_NAMES`. Events follow a `{Domain} {Action} {Success|Failed}` naming convention:
264
+
265
+ | Category | Success Event | Failure Event |
266
+ | ---------------------- | -------------------------------------- | -------------------------------------- |
267
+ | Station Login | `STATION_LOGIN_SUCCESS` | `STATION_LOGIN_FAILED` |
268
+ | Station Logout | `STATION_LOGOUT_SUCCESS` | `STATION_LOGOUT_FAILED` |
269
+ | Station Relogin | `STATION_RELOGIN_SUCCESS` | `STATION_RELOGIN_FAILED` |
270
+ | State Change | `AGENT_STATE_CHANGE_SUCCESS` | `AGENT_STATE_CHANGE_FAILED` |
271
+ | Buddy Agents | `FETCH_BUDDY_AGENTS_SUCCESS` | `FETCH_BUDDY_AGENTS_FAILED` |
272
+ | WebSocket Register | `WEBSOCKET_REGISTER_SUCCESS` | `WEBSOCKET_REGISTER_FAILED` |
273
+ | Task Accept | `TASK_ACCEPT_SUCCESS` | `TASK_ACCEPT_FAILED` |
274
+ | Task Decline | `TASK_DECLINE_SUCCESS` | `TASK_DECLINE_FAILED` |
275
+ | Task End | `TASK_END_SUCCESS` | `TASK_END_FAILED` |
276
+ | Task Wrapup | `TASK_WRAPUP_SUCCESS` | `TASK_WRAPUP_FAILED` |
277
+ | Task Hold | `TASK_HOLD_SUCCESS` | `TASK_HOLD_FAILED` |
278
+ | Task Resume | `TASK_RESUME_SUCCESS` | `TASK_RESUME_FAILED` |
279
+ | Task Consult Start | `TASK_CONSULT_START_SUCCESS` | `TASK_CONSULT_START_FAILED` |
280
+ | Task Consult End | `TASK_CONSULT_END_SUCCESS` | `TASK_CONSULT_END_FAILED` |
281
+ | Task Transfer | `TASK_TRANSFER_SUCCESS` | `TASK_TRANSFER_FAILED` |
282
+ | Task Resume Recording | `TASK_RESUME_RECORDING_SUCCESS` | `TASK_RESUME_RECORDING_FAILED` |
283
+ | Task Pause Recording | `TASK_PAUSE_RECORDING_SUCCESS` | `TASK_PAUSE_RECORDING_FAILED` |
284
+ | Task Accept Consult | `TASK_ACCEPT_CONSULT_SUCCESS` | `TASK_ACCEPT_CONSULT_FAILED` |
285
+ | Task Auto Answer | `TASK_AUTO_ANSWER_SUCCESS` | `TASK_AUTO_ANSWER_FAILED` |
286
+ | Conference Start | `TASK_CONFERENCE_START_SUCCESS` | `TASK_CONFERENCE_START_FAILED` |
287
+ | Conference End | `TASK_CONFERENCE_END_SUCCESS` | `TASK_CONFERENCE_END_FAILED` |
288
+ | Conference Transfer | `TASK_CONFERENCE_TRANSFER_SUCCESS` | `TASK_CONFERENCE_TRANSFER_FAILED` |
289
+ | Conference Exit | `TASK_CONFERENCE_EXIT_SUCCESS` | `TASK_CONFERENCE_EXIT_FAILED` |
290
+ | Switch Call | `TASK_SWITCH_CALL_SUCCESS` | `TASK_SWITCH_CALL_FAILED` |
291
+ | Outdial | `TASK_OUTDIAL_SUCCESS` | `TASK_OUTDIAL_FAILED` |
292
+ | Upload Logs | `UPLOAD_LOGS_SUCCESS` | `UPLOAD_LOGS_FAILED` |
293
+ | WebSocket Deregister | `WEBSOCKET_DEREGISTER_SUCCESS` | `WEBSOCKET_DEREGISTER_FAIL` |
294
+ | Device Type Update | `AGENT_DEVICE_TYPE_UPDATE_SUCCESS` | `AGENT_DEVICE_TYPE_UPDATE_FAILED` |
295
+ | EntryPoint | `ENTRYPOINT_FETCH_SUCCESS` | `ENTRYPOINT_FETCH_FAILED` |
296
+ | AddressBook | `ADDRESSBOOK_FETCH_SUCCESS` | `ADDRESSBOOK_FETCH_FAILED` |
297
+ | Queue | `QUEUE_FETCH_SUCCESS` | `QUEUE_FETCH_FAILED` |
298
+ | Outdial ANI Entries | `OUTDIAL_ANI_EP_FETCH_SUCCESS` | `OUTDIAL_ANI_EP_FETCH_FAILED` |
299
+
300
+ Special events (no success/failure pair):
301
+ - `AGENT_RONA` — has behavioral taxonomy (`service.agent_rona.set`)
302
+ - `AGENT_CONTACT_ASSIGN_FAILED` — has behavioral taxonomy (`service.agent_contact_assign.fail`)
303
+ - `AGENT_INVITE_FAILED` — has behavioral taxonomy (`service.agent_invite.fail`)
304
+ - `WEBSOCKET_EVENT_RECEIVED` — **no** behavioral taxonomy (not in `eventTaxonomyMap`)
305
+
306
+ Events **without** behavioral taxonomy (not in `eventTaxonomyMap`): `WEBSOCKET_DEREGISTER_SUCCESS`, `WEBSOCKET_DEREGISTER_FAIL`, `WEBSOCKET_EVENT_RECEIVED`
307
+
308
+ ---
309
+
310
+ ## Troubleshooting
311
+
312
+ ### Issue: Metrics not being submitted
313
+
314
+ **Cause**: Webex SDK not yet ready when `trackEvent` is called
315
+
316
+ **Solution**: Events are automatically queued in `pending*Events` arrays and flushed once `webex.once('ready')` fires. Verify the SDK is initializing correctly.
317
+
318
+ ### Issue: Duration not attached to metric
319
+
320
+ **Cause**: `timeEvent` was not called before `trackEvent`, or the event name does not match any key in `runningEvents`
321
+
322
+ **Solution**: Ensure `timeEvent([SUCCESS_KEY, FAILURE_KEY])` is called before the operation, and that the exact `METRIC_EVENT_NAMES` constant is used in both calls.
323
+
324
+ ### Issue: Metrics silently dropped
325
+
326
+ **Cause**: `metricsDisabled` is set to `true`
327
+
328
+ **Solution**: Check if `setMetricsDisabled(true)` was called. This clears all pending queues and causes all `track*` methods to return early.
329
+
330
+ ---
331
+
332
+ ## Related Files
333
+
334
+ - [MetricsManager.ts](../MetricsManager.ts) — Singleton metrics manager
335
+ - [behavioral-events.ts](../behavioral-events.ts) — Event taxonomy mapping
336
+ - [constants.ts](../constants.ts) — METRIC_EVENT_NAMES definitions
337
+ - [cc.ts](../../cc.ts) — Main plugin class (primary consumer)
338
+ - [constants.ts](../../constants.ts) — PRODUCT_NAME used in event prefixing