@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.
- package/.sdd/manifest.json +882 -0
- package/AGENTS.md +94 -0
- package/ai-docs/ARCHITECTURE.md +168 -0
- package/ai-docs/CONTRACTS.md +46 -0
- package/ai-docs/GETTING_STARTED.md +168 -0
- package/ai-docs/GLOSSARY.md +43 -0
- package/ai-docs/README.md +138 -0
- package/ai-docs/REVIEW_CHECKLIST.md +41 -0
- package/ai-docs/RULES.md +444 -0
- package/ai-docs/SECURITY.md +52 -0
- package/ai-docs/SERVICE_STATE.md +48 -0
- package/ai-docs/SPEC_INDEX.md +65 -0
- package/ai-docs/adr/0001-spec-source-policy.md +55 -0
- package/ai-docs/adr/README.md +8 -0
- package/ai-docs/adr/_adr-template.md +31 -0
- package/ai-docs/contact-center-spec.md +341 -0
- package/ai-docs/features/generated-spec-conformance-fidelity-remediation/spec/feature-spec.md +117 -0
- package/ai-docs/features/residual-warning-coverage-completion/spec/feature-spec.md +203 -0
- package/ai-docs/features/validator-code-fidelity-drift-fix/spec/feature-spec.md +315 -0
- package/ai-docs/patterns/event-driven-patterns.md +485 -0
- package/ai-docs/patterns/testing-patterns.md +480 -0
- package/ai-docs/patterns/typescript-patterns.md +365 -0
- package/ai-docs/templates/README.md +102 -0
- package/ai-docs/templates/documentation/create-agents-md.md +240 -0
- package/ai-docs/templates/documentation/create-architecture-md.md +295 -0
- package/ai-docs/templates/existing-service/bug-fix.md +254 -0
- package/ai-docs/templates/existing-service/feature-enhancement.md +450 -0
- package/ai-docs/templates/new-method/00-master.md +80 -0
- package/ai-docs/templates/new-method/01-requirements.md +232 -0
- package/ai-docs/templates/new-method/02-implementation.md +295 -0
- package/ai-docs/templates/new-method/03-tests.md +201 -0
- package/ai-docs/templates/new-method/04-validation.md +141 -0
- package/ai-docs/templates/new-service/00-master.md +109 -0
- package/ai-docs/templates/new-service/01-pre-questions.md +159 -0
- package/ai-docs/templates/new-service/02-code-generation.md +346 -0
- package/ai-docs/templates/new-service/03-integration.md +178 -0
- package/ai-docs/templates/new-service/04-test-generation.md +205 -0
- package/ai-docs/templates/new-service/05-validation.md +145 -0
- package/dist/cc.js +379 -50
- package/dist/cc.js.map +1 -1
- package/dist/config.js +6 -0
- package/dist/config.js.map +1 -1
- package/dist/constants.js +22 -2
- package/dist/constants.js.map +1 -1
- package/dist/index.js +27 -5
- package/dist/index.js.map +1 -1
- package/dist/metrics/behavioral-events.js +114 -0
- package/dist/metrics/behavioral-events.js.map +1 -1
- package/dist/metrics/constants.js +32 -3
- package/dist/metrics/constants.js.map +1 -1
- package/dist/services/ApiAiAssistant.js +318 -0
- package/dist/services/ApiAiAssistant.js.map +1 -0
- package/dist/services/UserPreference.js +427 -0
- package/dist/services/UserPreference.js.map +1 -0
- package/dist/services/agent/types.js.map +1 -1
- package/dist/services/config/Util.js +8 -4
- package/dist/services/config/Util.js.map +1 -1
- package/dist/services/config/constants.js +35 -2
- package/dist/services/config/constants.js.map +1 -1
- package/dist/services/config/index.js +41 -2
- package/dist/services/config/index.js.map +1 -1
- package/dist/services/config/types.js +66 -8
- package/dist/services/config/types.js.map +1 -1
- package/dist/services/constants.js +27 -1
- package/dist/services/constants.js.map +1 -1
- package/dist/services/core/Err.js.map +1 -1
- package/dist/services/core/Utils.js +122 -25
- package/dist/services/core/Utils.js.map +1 -1
- package/dist/services/core/aqm-reqs.js +92 -17
- package/dist/services/core/aqm-reqs.js.map +1 -1
- package/dist/services/core/websocket/WebSocketManager.js +22 -6
- package/dist/services/core/websocket/WebSocketManager.js.map +1 -1
- package/dist/services/core/websocket/connection-service.js +3 -1
- package/dist/services/core/websocket/connection-service.js.map +1 -1
- package/dist/services/core/websocket/types.js.map +1 -1
- package/dist/services/index.js +6 -0
- package/dist/services/index.js.map +1 -1
- package/dist/services/task/Task.js +688 -0
- package/dist/services/task/Task.js.map +1 -0
- package/dist/services/task/TaskFactory.js +45 -0
- package/dist/services/task/TaskFactory.js.map +1 -0
- package/dist/services/task/TaskManager.js +751 -457
- package/dist/services/task/TaskManager.js.map +1 -1
- package/dist/services/task/TaskUtils.js +220 -23
- package/dist/services/task/TaskUtils.js.map +1 -1
- package/dist/services/task/constants.js +23 -2
- package/dist/services/task/constants.js.map +1 -1
- package/dist/services/task/dialer.js +129 -0
- package/dist/services/task/dialer.js.map +1 -1
- package/dist/services/task/digital/Digital.js +77 -0
- package/dist/services/task/digital/Digital.js.map +1 -0
- package/dist/services/task/state-machine/TaskStateMachine.js +873 -0
- package/dist/services/task/state-machine/TaskStateMachine.js.map +1 -0
- package/dist/services/task/state-machine/actions.js +567 -0
- package/dist/services/task/state-machine/actions.js.map +1 -0
- package/dist/services/task/state-machine/constants.js +161 -0
- package/dist/services/task/state-machine/constants.js.map +1 -0
- package/dist/services/task/state-machine/guards.js +382 -0
- package/dist/services/task/state-machine/guards.js.map +1 -0
- package/dist/services/task/state-machine/index.js +53 -0
- package/dist/services/task/state-machine/index.js.map +1 -0
- package/dist/services/task/state-machine/types.js +54 -0
- package/dist/services/task/state-machine/types.js.map +1 -0
- package/dist/services/task/state-machine/uiControlsComputer.js +603 -0
- package/dist/services/task/state-machine/uiControlsComputer.js.map +1 -0
- package/dist/services/task/taskDataNormalizer.js +99 -0
- package/dist/services/task/taskDataNormalizer.js.map +1 -0
- package/dist/services/task/types.js +227 -4
- package/dist/services/task/types.js.map +1 -1
- package/dist/services/task/voice/Voice.js +1044 -0
- package/dist/services/task/voice/Voice.js.map +1 -0
- package/dist/services/task/voice/WebRTC.js +149 -0
- package/dist/services/task/voice/WebRTC.js.map +1 -0
- package/dist/types/cc.d.ts +894 -0
- package/dist/types/config.d.ts +72 -0
- package/dist/types/constants.d.ts +66 -0
- package/dist/types/index.d.ts +199 -0
- package/dist/types/logger-proxy.d.ts +71 -0
- package/dist/types/metrics/MetricsManager.d.ts +223 -0
- package/dist/types/metrics/behavioral-events.d.ts +29 -0
- package/dist/types/metrics/constants.d.ts +181 -0
- package/dist/types/services/AddressBook.d.ts +74 -0
- package/dist/types/services/ApiAiAssistant.d.ts +49 -0
- package/dist/types/services/EntryPoint.d.ts +67 -0
- package/dist/types/services/Queue.d.ts +76 -0
- package/dist/types/services/UserPreference.d.ts +118 -0
- package/dist/types/services/WebCallingService.d.ts +1 -0
- package/dist/types/services/agent/index.d.ts +46 -0
- package/dist/types/services/agent/types.d.ts +413 -0
- package/dist/types/services/config/Util.d.ts +20 -0
- package/dist/types/services/config/constants.d.ts +270 -0
- package/dist/types/services/config/index.d.ts +177 -0
- package/dist/types/services/config/types.d.ts +1368 -0
- package/dist/types/services/constants.d.ts +110 -0
- package/dist/types/services/core/Err.d.ts +125 -0
- package/dist/types/services/core/GlobalTypes.d.ts +58 -0
- package/dist/types/services/core/Utils.d.ts +121 -0
- package/dist/types/services/core/WebexRequest.d.ts +22 -0
- package/dist/types/services/core/aqm-reqs.d.ts +65 -0
- package/dist/types/services/core/constants.d.ts +99 -0
- package/dist/types/services/core/types.d.ts +47 -0
- package/dist/types/services/core/websocket/WebSocketManager.d.ts +36 -0
- package/dist/types/services/core/websocket/connection-service.d.ts +27 -0
- package/dist/types/services/core/websocket/keepalive.worker.d.ts +2 -0
- package/dist/types/services/core/websocket/types.d.ts +37 -0
- package/dist/types/services/index.d.ts +54 -0
- package/dist/types/services/task/AutoWrapup.d.ts +40 -0
- package/dist/types/services/task/Task.d.ts +157 -0
- package/dist/types/services/task/TaskFactory.d.ts +12 -0
- package/dist/types/services/task/TaskManager.d.ts +1 -0
- package/dist/types/services/task/TaskUtils.d.ts +138 -0
- package/dist/types/services/task/constants.d.ts +91 -0
- package/dist/types/services/task/contact.d.ts +69 -0
- package/dist/types/services/task/dialer.d.ts +73 -0
- package/dist/types/services/task/digital/Digital.d.ts +22 -0
- package/dist/types/services/task/state-machine/TaskStateMachine.d.ts +1194 -0
- package/dist/types/services/task/state-machine/actions.d.ts +10 -0
- package/dist/types/services/task/state-machine/constants.d.ts +107 -0
- package/dist/types/services/task/state-machine/guards.d.ts +102 -0
- package/dist/types/services/task/state-machine/index.d.ts +13 -0
- package/dist/types/services/task/state-machine/types.d.ts +269 -0
- package/dist/types/services/task/state-machine/uiControlsComputer.d.ts +9 -0
- package/dist/types/services/task/taskDataNormalizer.d.ts +10 -0
- package/dist/types/services/task/types.d.ts +1856 -0
- package/dist/types/services/task/voice/Voice.d.ts +184 -0
- package/dist/types/services/task/voice/WebRTC.d.ts +53 -0
- package/dist/types/types.d.ts +778 -0
- package/dist/types/utils/PageCache.d.ts +173 -0
- package/dist/types/webex-config.d.ts +53 -0
- package/dist/types/webex.d.ts +8 -0
- package/dist/types.js +130 -1
- package/dist/types.js.map +1 -1
- package/dist/webex.js +14 -2
- package/dist/webex.js.map +1 -1
- package/package.json +16 -12
- package/src/cc.ts +477 -51
- package/src/config.ts +6 -0
- package/src/constants.ts +21 -1
- package/src/index.ts +24 -5
- package/src/metrics/ai-docs/AGENTS.md +350 -0
- package/src/metrics/ai-docs/ARCHITECTURE.md +338 -0
- package/src/metrics/ai-docs/metrics-spec.md +854 -0
- package/src/metrics/behavioral-events.ts +120 -0
- package/src/metrics/constants.ts +37 -3
- package/src/services/ApiAiAssistant.ts +412 -0
- package/src/services/UserPreference.ts +509 -0
- package/src/services/agent/ai-docs/AGENTS.md +240 -0
- package/src/services/agent/ai-docs/ARCHITECTURE.md +304 -0
- package/src/services/agent/ai-docs/agent-spec.md +504 -0
- package/src/services/agent/types.ts +1 -1
- package/src/services/ai-docs/AGENTS.md +386 -0
- package/src/services/ai-docs/services-spec.md +492 -0
- package/src/services/config/Util.ts +10 -2
- package/src/services/config/ai-docs/AGENTS.md +255 -0
- package/src/services/config/ai-docs/ARCHITECTURE.md +426 -0
- package/src/services/config/ai-docs/config-spec.md +669 -0
- package/src/services/config/constants.ts +37 -1
- package/src/services/config/index.ts +45 -1
- package/src/services/config/types.ts +241 -11
- package/src/services/constants.ts +29 -0
- package/src/services/core/Err.ts +3 -0
- package/src/services/core/Utils.ts +143 -30
- package/src/services/core/ai-docs/AGENTS.md +381 -0
- package/src/services/core/ai-docs/ARCHITECTURE.md +698 -0
- package/src/services/core/ai-docs/core-spec.md +783 -0
- package/src/services/core/aqm-reqs.ts +100 -22
- package/src/services/core/websocket/WebSocketManager.ts +23 -6
- package/src/services/core/websocket/connection-service.ts +5 -1
- package/src/services/core/websocket/types.ts +1 -1
- package/src/services/index.ts +4 -0
- package/src/services/task/Task.ts +837 -0
- package/src/services/task/TaskFactory.ts +55 -0
- package/src/services/task/TaskManager.ts +793 -521
- package/src/services/task/TaskUtils.ts +314 -24
- package/src/services/task/ai-docs/AGENTS.md +457 -0
- package/src/services/task/ai-docs/ARCHITECTURE.md +594 -0
- package/src/services/task/ai-docs/task-spec.md +1319 -0
- package/src/services/task/constants.ts +23 -0
- package/src/services/task/dialer.ts +136 -1
- package/src/services/task/digital/Digital.ts +95 -0
- package/src/services/task/state-machine/TaskStateMachine.ts +1166 -0
- package/src/services/task/state-machine/actions.ts +738 -0
- package/src/services/task/state-machine/ai-docs/AGENTS.md +458 -0
- package/src/services/task/state-machine/ai-docs/ARCHITECTURE.md +1137 -0
- package/src/services/task/state-machine/ai-docs/task-state-machine-spec.md +2177 -0
- package/src/services/task/state-machine/constants.ts +172 -0
- package/src/services/task/state-machine/guards.ts +445 -0
- package/src/services/task/state-machine/index.ts +28 -0
- package/src/services/task/state-machine/types.ts +243 -0
- package/src/services/task/state-machine/uiControlsComputer.ts +961 -0
- package/src/services/task/taskDataNormalizer.ts +137 -0
- package/src/services/task/types.ts +734 -71
- package/src/services/task/voice/Voice.ts +1270 -0
- package/src/services/task/voice/WebRTC.ts +187 -0
- package/src/types.ts +205 -2
- package/src/utils/AGENTS.md +278 -0
- package/src/utils/ai-docs/utils-spec.md +381 -0
- package/src/webex.js +2 -0
- package/test/unit/spec/cc.ts +503 -43
- package/test/unit/spec/logger-proxy.ts +70 -0
- package/test/unit/spec/services/ApiAiAssistant.ts +273 -0
- package/test/unit/spec/services/UserPreference.ts +401 -0
- package/test/unit/spec/services/WebCallingService.ts +7 -1
- package/test/unit/spec/services/config/index.ts +85 -29
- package/test/unit/spec/services/core/Utils.ts +481 -2
- package/test/unit/spec/services/core/websocket/WebSocketManager.ts +137 -41
- package/test/unit/spec/services/core/websocket/connection-service.ts +3 -1
- package/test/unit/spec/services/task/AutoWrapup.ts +63 -0
- package/test/unit/spec/services/task/Task.ts +477 -0
- package/test/unit/spec/services/task/TaskFactory.ts +62 -0
- package/test/unit/spec/services/task/TaskManager.ts +1001 -1003
- package/test/unit/spec/services/task/TaskUtils.ts +235 -0
- package/test/unit/spec/services/task/dialer.ts +372 -96
- package/test/unit/spec/services/task/digital/Digital.ts +105 -0
- package/test/unit/spec/services/task/state-machine/TaskStateMachine.ts +2651 -0
- package/test/unit/spec/services/task/state-machine/guards.ts +637 -0
- package/test/unit/spec/services/task/state-machine/types.ts +18 -0
- package/test/unit/spec/services/task/state-machine/uiControlsComputer.ts +2663 -0
- package/test/unit/spec/services/task/taskTestUtils.ts +87 -0
- package/test/unit/spec/services/task/voice/Voice.ts +649 -0
- package/test/unit/spec/services/task/voice/WebRTC.ts +235 -0
- package/umd/contact-center.min.js +2 -2
- package/umd/contact-center.min.js.map +1 -1
- package/dist/services/task/index.js +0 -1525
- package/dist/services/task/index.js.map +0 -1
- package/src/services/task/index.ts +0 -1801
- 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
|