@webex/contact-center 3.12.0-next.8 → 3.12.0-next.81
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/AGENTS.md +438 -0
- package/ai-docs/README.md +131 -0
- package/ai-docs/RULES.md +455 -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 +265 -29
- package/dist/cc.js.map +1 -1
- package/dist/config.js +6 -0
- package/dist/config.js.map +1 -1
- package/dist/constants.js +16 -1
- package/dist/constants.js.map +1 -1
- package/dist/index.js +20 -5
- package/dist/index.js.map +1 -1
- package/dist/metrics/behavioral-events.js +101 -0
- package/dist/metrics/behavioral-events.js.map +1 -1
- package/dist/metrics/constants.js +23 -4
- package/dist/metrics/constants.js.map +1 -1
- package/dist/services/ApiAiAssistant.js +74 -3
- package/dist/services/ApiAiAssistant.js.map +1 -1
- package/dist/services/UserPreference.js +427 -0
- package/dist/services/UserPreference.js.map +1 -0
- package/dist/services/config/Util.js +3 -3
- package/dist/services/config/Util.js.map +1 -1
- package/dist/services/config/constants.js +23 -2
- package/dist/services/config/constants.js.map +1 -1
- package/dist/services/config/types.js +49 -9
- package/dist/services/config/types.js.map +1 -1
- package/dist/services/core/Err.js.map +1 -1
- package/dist/services/core/Utils.js +107 -32
- package/dist/services/core/Utils.js.map +1 -1
- package/dist/services/core/websocket/WebSocketManager.js +2 -1
- package/dist/services/core/websocket/WebSocketManager.js.map +1 -1
- package/dist/services/core/websocket/types.js.map +1 -1
- package/dist/services/index.js +1 -1
- 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 +725 -526
- package/dist/services/task/TaskManager.js.map +1 -1
- package/dist/services/task/TaskUtils.js +162 -26
- package/dist/services/task/TaskUtils.js.map +1 -1
- package/dist/services/task/constants.js +9 -2
- package/dist/services/task/constants.js.map +1 -1
- package/dist/services/task/dialer.js +78 -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 +837 -0
- package/dist/services/task/state-machine/TaskStateMachine.js.map +1 -0
- package/dist/services/task/state-machine/actions.js +543 -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 +340 -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 +553 -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 +212 -4
- package/dist/services/task/types.js.map +1 -1
- package/dist/services/task/voice/Voice.js +1042 -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 +94 -1
- package/dist/types/config.d.ts +6 -0
- package/dist/types/constants.d.ts +16 -1
- package/dist/types/index.d.ts +21 -6
- package/dist/types/metrics/constants.d.ts +19 -1
- package/dist/types/services/ApiAiAssistant.d.ts +11 -3
- package/dist/types/services/UserPreference.d.ts +118 -0
- package/dist/types/services/config/constants.d.ts +21 -0
- package/dist/types/services/config/types.d.ts +171 -10
- package/dist/types/services/core/Err.d.ts +4 -0
- package/dist/types/services/core/Utils.d.ts +33 -13
- package/dist/types/services/core/websocket/WebSocketManager.d.ts +1 -0
- package/dist/types/services/core/websocket/types.d.ts +1 -1
- package/dist/types/services/index.d.ts +1 -1
- 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/TaskUtils.d.ts +46 -2
- package/dist/types/services/task/constants.d.ts +7 -0
- package/dist/types/services/task/dialer.d.ts +30 -0
- package/dist/types/services/task/digital/Digital.d.ts +22 -0
- package/dist/types/services/task/state-machine/TaskStateMachine.d.ts +1144 -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 +90 -0
- package/dist/types/services/task/state-machine/index.d.ts +13 -0
- package/dist/types/services/task/state-machine/types.d.ts +267 -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 +603 -66
- 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 +94 -0
- package/dist/types/webex.d.ts +1 -0
- package/dist/types.js +85 -0
- package/dist/types.js.map +1 -1
- package/dist/webex.js +14 -2
- package/dist/webex.js.map +1 -1
- package/package.json +15 -12
- package/src/cc.ts +329 -30
- package/src/config.ts +6 -0
- package/src/constants.ts +16 -1
- package/src/index.ts +23 -5
- package/src/metrics/ai-docs/AGENTS.md +348 -0
- package/src/metrics/ai-docs/ARCHITECTURE.md +336 -0
- package/src/metrics/behavioral-events.ts +106 -0
- package/src/metrics/constants.ts +23 -4
- package/src/services/ApiAiAssistant.ts +104 -3
- package/src/services/UserPreference.ts +509 -0
- package/src/services/agent/ai-docs/AGENTS.md +238 -0
- package/src/services/agent/ai-docs/ARCHITECTURE.md +302 -0
- package/src/services/ai-docs/AGENTS.md +384 -0
- package/src/services/config/Util.ts +3 -3
- package/src/services/config/ai-docs/AGENTS.md +253 -0
- package/src/services/config/ai-docs/ARCHITECTURE.md +424 -0
- package/src/services/config/constants.ts +25 -1
- package/src/services/config/types.ts +174 -11
- package/src/services/core/Err.ts +2 -0
- package/src/services/core/Utils.ts +123 -37
- package/src/services/core/ai-docs/AGENTS.md +379 -0
- package/src/services/core/ai-docs/ARCHITECTURE.md +696 -0
- package/src/services/core/websocket/WebSocketManager.ts +2 -0
- package/src/services/core/websocket/types.ts +1 -1
- package/src/services/index.ts +1 -1
- package/src/services/task/Task.ts +837 -0
- package/src/services/task/TaskFactory.ts +55 -0
- package/src/services/task/TaskManager.ts +738 -613
- package/src/services/task/TaskUtils.ts +205 -25
- package/src/services/task/ai-docs/AGENTS.md +455 -0
- package/src/services/task/ai-docs/ARCHITECTURE.md +585 -0
- package/src/services/task/constants.ts +7 -0
- package/src/services/task/dialer.ts +80 -0
- package/src/services/task/digital/Digital.ts +95 -0
- package/src/services/task/state-machine/TaskStateMachine.ts +1077 -0
- package/src/services/task/state-machine/actions.ts +685 -0
- package/src/services/task/state-machine/ai-docs/AGENTS.md +495 -0
- package/src/services/task/state-machine/ai-docs/ARCHITECTURE.md +1135 -0
- package/src/services/task/state-machine/constants.ts +172 -0
- package/src/services/task/state-machine/guards.ts +406 -0
- package/src/services/task/state-machine/index.ts +28 -0
- package/src/services/task/state-machine/types.ts +241 -0
- package/src/services/task/state-machine/uiControlsComputer.ts +867 -0
- package/src/services/task/taskDataNormalizer.ts +137 -0
- package/src/services/task/types.ts +710 -71
- package/src/services/task/voice/Voice.ts +1267 -0
- package/src/services/task/voice/WebRTC.ts +187 -0
- package/src/types.ts +122 -2
- package/src/utils/AGENTS.md +276 -0
- package/src/webex.js +2 -0
- package/test/unit/spec/cc.ts +343 -23
- package/test/unit/spec/logger-proxy.ts +70 -0
- package/test/unit/spec/services/ApiAiAssistant.ts +122 -17
- 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 +30 -30
- package/test/unit/spec/services/core/Utils.ts +425 -8
- package/test/unit/spec/services/core/websocket/WebSocketManager.ts +66 -40
- 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 +832 -1702
- package/test/unit/spec/services/task/TaskUtils.ts +206 -0
- package/test/unit/spec/services/task/dialer.ts +190 -0
- package/test/unit/spec/services/task/digital/Digital.ts +105 -0
- package/test/unit/spec/services/task/state-machine/TaskStateMachine.ts +1825 -0
- package/test/unit/spec/services/task/state-machine/guards.ts +479 -0
- package/test/unit/spec/services/task/state-machine/types.ts +18 -0
- package/test/unit/spec/services/task/state-machine/uiControlsComputer.ts +2020 -0
- package/test/unit/spec/services/task/taskTestUtils.ts +87 -0
- package/test/unit/spec/services/task/voice/Voice.ts +631 -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/dist/types/services/task/index.d.ts +0 -650
- package/src/services/task/index.ts +0 -1801
- package/test/unit/spec/services/task/index.ts +0 -2184
|
@@ -0,0 +1,238 @@
|
|
|
1
|
+
# Agent Service - AI Agent Guide
|
|
2
|
+
|
|
3
|
+
> **Purpose**: Manage agent lifecycle including login, logout, state changes, and buddy agent queries.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## Quick Start
|
|
8
|
+
|
|
9
|
+
```typescript
|
|
10
|
+
const cc = webex.cc;
|
|
11
|
+
|
|
12
|
+
// Register and login
|
|
13
|
+
const profile = await cc.register();
|
|
14
|
+
await cc.stationLogin({
|
|
15
|
+
teamId: profile.teams[0].teamId,
|
|
16
|
+
loginOption: 'BROWSER',
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
// Set state to Available
|
|
20
|
+
await cc.setAgentState({
|
|
21
|
+
state: 'Available',
|
|
22
|
+
auxCodeId: '0',
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
// Get available agents for transfer
|
|
26
|
+
const buddies = await cc.getBuddyAgents({
|
|
27
|
+
state: 'Available',
|
|
28
|
+
mediaType: 'telephony',
|
|
29
|
+
});
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
---
|
|
33
|
+
|
|
34
|
+
## Key Capabilities
|
|
35
|
+
|
|
36
|
+
- **Station Login**: Login with browser (WebRTC), extension, or dial number
|
|
37
|
+
- **Station Logout**: Logout from current station with reason
|
|
38
|
+
- **State Management**: Toggle between Available/Idle states with aux codes
|
|
39
|
+
- **Buddy Agents**: Query available agents for consult/transfer
|
|
40
|
+
- **Silent Relogin**: Automatic re-authentication on reconnection
|
|
41
|
+
|
|
42
|
+
---
|
|
43
|
+
|
|
44
|
+
## API Reference
|
|
45
|
+
|
|
46
|
+
### Login Options
|
|
47
|
+
|
|
48
|
+
| Option | Description | Requires dialNumber |
|
|
49
|
+
|--------|-------------|---------------------|
|
|
50
|
+
| `BROWSER` | WebRTC softphone in browser | No |
|
|
51
|
+
| `EXTENSION` | Desk phone extension | Yes |
|
|
52
|
+
| `AGENT_DN` | Direct dial number | Yes |
|
|
53
|
+
|
|
54
|
+
### Methods
|
|
55
|
+
|
|
56
|
+
#### `cc.stationLogin(params)`
|
|
57
|
+
|
|
58
|
+
Login agent to a station.
|
|
59
|
+
|
|
60
|
+
**Parameters**:
|
|
61
|
+
- `teamId` (string): Team to login to
|
|
62
|
+
- `loginOption` ('BROWSER' | 'EXTENSION' | 'AGENT_DN'): Device type
|
|
63
|
+
- `dialNumber` (string, optional): Required for EXTENSION/AGENT_DN
|
|
64
|
+
|
|
65
|
+
**Returns**: `Promise<StationLoginResponse>`
|
|
66
|
+
|
|
67
|
+
**Example**:
|
|
68
|
+
```typescript
|
|
69
|
+
// Browser login
|
|
70
|
+
const response = await cc.stationLogin({
|
|
71
|
+
teamId: 'team-123',
|
|
72
|
+
loginOption: 'BROWSER',
|
|
73
|
+
});
|
|
74
|
+
|
|
75
|
+
// Extension login
|
|
76
|
+
const response = await cc.stationLogin({
|
|
77
|
+
teamId: 'team-123',
|
|
78
|
+
loginOption: 'EXTENSION',
|
|
79
|
+
dialNumber: '1234',
|
|
80
|
+
});
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
---
|
|
84
|
+
|
|
85
|
+
#### `cc.stationLogout(params)`
|
|
86
|
+
|
|
87
|
+
Logout agent from station.
|
|
88
|
+
|
|
89
|
+
**Parameters**:
|
|
90
|
+
- `logoutReason` (string, optional): 'User requested logout' | 'Inactivity Logout' | 'User requested agent profile update'
|
|
91
|
+
|
|
92
|
+
**Returns**: `Promise<StationLogoutResponse>`
|
|
93
|
+
|
|
94
|
+
**Example**:
|
|
95
|
+
```typescript
|
|
96
|
+
await cc.stationLogout({
|
|
97
|
+
logoutReason: 'User requested logout',
|
|
98
|
+
});
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
---
|
|
102
|
+
|
|
103
|
+
#### `cc.setAgentState(params)`
|
|
104
|
+
|
|
105
|
+
Change agent state (Available/Idle).
|
|
106
|
+
|
|
107
|
+
**Parameters**:
|
|
108
|
+
- `state` ('Available' | 'Idle'): New state
|
|
109
|
+
- `auxCodeId` (string): Auxiliary code ID
|
|
110
|
+
- `lastStateChangeReason` (string, optional): Reason for change
|
|
111
|
+
- `agentId` (string, optional): Agent ID (defaults to current agent)
|
|
112
|
+
|
|
113
|
+
**Returns**: `Promise<SetStateResponse>`
|
|
114
|
+
|
|
115
|
+
**Example**:
|
|
116
|
+
```typescript
|
|
117
|
+
// Go Available
|
|
118
|
+
await cc.setAgentState({
|
|
119
|
+
state: 'Available',
|
|
120
|
+
auxCodeId: '0',
|
|
121
|
+
});
|
|
122
|
+
|
|
123
|
+
// Go to Idle with specific code
|
|
124
|
+
await cc.setAgentState({
|
|
125
|
+
state: 'Idle',
|
|
126
|
+
auxCodeId: 'break-code-123',
|
|
127
|
+
lastStateChangeReason: 'Coffee break',
|
|
128
|
+
});
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
---
|
|
132
|
+
|
|
133
|
+
#### `cc.getBuddyAgents(params)`
|
|
134
|
+
|
|
135
|
+
Get list of agents for consult/transfer.
|
|
136
|
+
|
|
137
|
+
**Parameters**:
|
|
138
|
+
- `state` (string, optional): Filter by state ('Available', 'Idle')
|
|
139
|
+
- `mediaType` (string): Media type filter ('telephony', 'chat', 'social', 'email')
|
|
140
|
+
**Returns**: `Promise<BuddyAgentsResponse>`
|
|
141
|
+
|
|
142
|
+
**Example**:
|
|
143
|
+
```typescript
|
|
144
|
+
const response = await cc.getBuddyAgents({
|
|
145
|
+
state: 'Available',
|
|
146
|
+
mediaType: 'telephony',
|
|
147
|
+
});
|
|
148
|
+
|
|
149
|
+
response.data.agentList.forEach(agent => {
|
|
150
|
+
console.log(`${agent.agentName} (${agent.state})`);
|
|
151
|
+
});
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
---
|
|
155
|
+
|
|
156
|
+
## Events
|
|
157
|
+
|
|
158
|
+
| Event | Type | Description |
|
|
159
|
+
|-------|------|-------------|
|
|
160
|
+
| `agent:stationLoginSuccess` | `StationLoginSuccessResponse` | Login succeeded |
|
|
161
|
+
| `agent:stationLoginFailed` | Error | Login failed |
|
|
162
|
+
| `agent:logoutSuccess` | `LogoutSuccess` | Logout succeeded |
|
|
163
|
+
| `agent:logoutFailed` | Error | Logout failed |
|
|
164
|
+
| `agent:stateChange` | `StateChangeSuccess` | State changed (any source) |
|
|
165
|
+
| `agent:stateChangeSuccess` | `StateChangeSuccess` | State change succeeded |
|
|
166
|
+
| `agent:stateChangeFailed` | Error | State change failed |
|
|
167
|
+
| `agent:multiLogin` | Object | Multi-login detected |
|
|
168
|
+
| `agent:reloginSuccess` | `ReloginSuccess` | Silent relogin succeeded |
|
|
169
|
+
| `agent:dnRegistered` | Object | DN registration complete |
|
|
170
|
+
|
|
171
|
+
### Event Usage
|
|
172
|
+
|
|
173
|
+
```typescript
|
|
174
|
+
cc.on('agent:stateChange', (event) => {
|
|
175
|
+
console.log(`State: ${event.subStatus}, AuxCode: ${event.auxCodeId}`);
|
|
176
|
+
});
|
|
177
|
+
|
|
178
|
+
cc.on('agent:multiLogin', (event) => {
|
|
179
|
+
console.warn('Another session detected');
|
|
180
|
+
});
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
---
|
|
184
|
+
|
|
185
|
+
## Agent States
|
|
186
|
+
|
|
187
|
+
The `AgentState` type (`'Available' | 'Idle' | 'RONA' | string`) is extensible -- the `string` union member allows backend-defined states beyond the known values listed below.
|
|
188
|
+
|
|
189
|
+
| State | SubStatus | Description |
|
|
190
|
+
|-------|-----------|-------------|
|
|
191
|
+
| LoggedIn | Available | Ready to receive tasks |
|
|
192
|
+
| LoggedIn | Idle | On break or not ready (uses aux code for sub-reason) |
|
|
193
|
+
| RONA | - | Rang but no answer; agent failed to accept offered task |
|
|
194
|
+
| LoggedOut | - | Not logged in |
|
|
195
|
+
| LoggedIn | *(custom)* | Additional org-specific states defined via aux codes |
|
|
196
|
+
|
|
197
|
+
> **Note**: `AgentState` is a union with `string`, so consumers should handle unknown state values gracefully rather than exhaustively matching only the known literals.
|
|
198
|
+
|
|
199
|
+
---
|
|
200
|
+
|
|
201
|
+
## Error Handling
|
|
202
|
+
|
|
203
|
+
```typescript
|
|
204
|
+
try {
|
|
205
|
+
await cc.stationLogin(params);
|
|
206
|
+
} catch (error) {
|
|
207
|
+
console.error('Login failed:', error.message);
|
|
208
|
+
// Access error details
|
|
209
|
+
if (error.data) {
|
|
210
|
+
console.error('Field:', error.data.fieldName);
|
|
211
|
+
console.error('Message:', error.data.message);
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
```
|
|
215
|
+
|
|
216
|
+
### Common Error Reasons
|
|
217
|
+
|
|
218
|
+
| Reason | Description |
|
|
219
|
+
|--------|-------------|
|
|
220
|
+
| `DUPLICATE_LOCATION` | Extension/DN already in use |
|
|
221
|
+
| `INVALID_DIAL_NUMBER` | Invalid phone number format |
|
|
222
|
+
| `AGENT_NOT_FOUND` | Agent doesn't exist (silent relogin) |
|
|
223
|
+
|
|
224
|
+
---
|
|
225
|
+
|
|
226
|
+
## Dependencies
|
|
227
|
+
|
|
228
|
+
- Requires `cc.register()` to be called first
|
|
229
|
+
- Agent profile must be fetched before login
|
|
230
|
+
- WebRTC (BROWSER option) requires mercury connection
|
|
231
|
+
|
|
232
|
+
---
|
|
233
|
+
|
|
234
|
+
## Related
|
|
235
|
+
|
|
236
|
+
- [ARCHITECTURE.md](ARCHITECTURE.md) - Technical deep-dive
|
|
237
|
+
- [`cc.ts`](../../../cc.ts) - Main plugin implementation
|
|
238
|
+
- [`types.ts`](../types.ts) - Type definitions
|
|
@@ -0,0 +1,302 @@
|
|
|
1
|
+
# Agent Service - Architecture
|
|
2
|
+
|
|
3
|
+
> **Purpose**: Technical documentation for agent lifecycle operations.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## Component Overview
|
|
8
|
+
|
|
9
|
+
| Component | File | Responsibility |
|
|
10
|
+
| --------------- | --------------------------- | --------------------------------------------------------------- |
|
|
11
|
+
| `ContactCenter` | `src/cc.ts` | Plugin class exposing agent methods |
|
|
12
|
+
| `routingAgent` | `services/agent/index.ts` | AQM request definitions |
|
|
13
|
+
| `Services` | `services/index.ts` | Service singleton with agent service |
|
|
14
|
+
| `AqmReqs` | `services/core/aqm-reqs.ts` | HTTP requests to backend; responses via WebSocket notifications |
|
|
15
|
+
|
|
16
|
+
---
|
|
17
|
+
|
|
18
|
+
## File Structure
|
|
19
|
+
|
|
20
|
+
```
|
|
21
|
+
services/agent/
|
|
22
|
+
├── index.ts # Agent service factory
|
|
23
|
+
├── types.ts # Agent types and events
|
|
24
|
+
└── ai-docs/
|
|
25
|
+
├── AGENTS.md # Usage documentation
|
|
26
|
+
└── ARCHITECTURE.md # This file
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
---
|
|
30
|
+
|
|
31
|
+
## Service Factory Pattern
|
|
32
|
+
|
|
33
|
+
The agent service uses a factory pattern:
|
|
34
|
+
|
|
35
|
+
```typescript
|
|
36
|
+
// services/agent/index.ts
|
|
37
|
+
export default function routingAgent(routing: AqmReqs) {
|
|
38
|
+
return {
|
|
39
|
+
stationLogin: routing.req((p: {data: UserStationLogin}) => ({
|
|
40
|
+
url: '/v1/agents/login',
|
|
41
|
+
host: WCC_API_GATEWAY,
|
|
42
|
+
data: p.data,
|
|
43
|
+
notifSuccess: {
|
|
44
|
+
bind: {type: CC_EVENTS.AGENT_STATION_LOGIN, ...},
|
|
45
|
+
msg: {} as StationLoginSuccess,
|
|
46
|
+
},
|
|
47
|
+
notifFail: {...},
|
|
48
|
+
})),
|
|
49
|
+
logout: routing.req((p: {data: Logout}) => ({...})),
|
|
50
|
+
stateChange: routing.req((p: {data: StateChange}) => ({...})),
|
|
51
|
+
buddyAgents: routing.req((p: {data: BuddyAgents}) => ({...})),
|
|
52
|
+
reload: routing.reqEmpty(() => ({...})),
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
---
|
|
58
|
+
|
|
59
|
+
## Data Flow
|
|
60
|
+
|
|
61
|
+
### Station Login Flow
|
|
62
|
+
|
|
63
|
+
```mermaid
|
|
64
|
+
flowchart TD
|
|
65
|
+
A[cc.stationLogin] --> B[Validate input]
|
|
66
|
+
B --> C[services.agent.stationLogin]
|
|
67
|
+
C --> D[AqmReqs.req]
|
|
68
|
+
D --> E[HTTP REST request to backend]
|
|
69
|
+
E --> F[Backend processes]
|
|
70
|
+
F --> G{Success?}
|
|
71
|
+
G -->|Yes| H[StationLoginSuccess event]
|
|
72
|
+
G -->|No| I[StationLoginFailed event]
|
|
73
|
+
H --> J[Register WebCalling if BROWSER]
|
|
74
|
+
J --> K[Track metrics]
|
|
75
|
+
K --> L[Return response]
|
|
76
|
+
I --> M[getErrorDetails]
|
|
77
|
+
M --> N[Throw error]
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
---
|
|
81
|
+
|
|
82
|
+
## Sequence Diagrams
|
|
83
|
+
|
|
84
|
+
### Station Login
|
|
85
|
+
|
|
86
|
+
```mermaid
|
|
87
|
+
sequenceDiagram
|
|
88
|
+
participant App
|
|
89
|
+
participant CC as ContactCenter
|
|
90
|
+
participant Svc as Services.agent
|
|
91
|
+
participant AQM as AqmReqs
|
|
92
|
+
participant WS as WebSocket
|
|
93
|
+
participant BE as Backend
|
|
94
|
+
App->>CC: stationLogin(params)
|
|
95
|
+
CC->>CC: Validate dial number
|
|
96
|
+
CC->>CC: timeEvent(LOGIN_SUCCESS, LOGIN_FAILED)
|
|
97
|
+
CC->>Svc: stationLogin({data})
|
|
98
|
+
Svc->>AQM: req(config)
|
|
99
|
+
AQM->>BE: HTTP POST /v1/agents/login
|
|
100
|
+
BE-->>WS: AgentStationLoginSuccess
|
|
101
|
+
WS-->>AQM: Resolve with response
|
|
102
|
+
AQM-->>Svc: Return response
|
|
103
|
+
Svc-->>CC: Login response
|
|
104
|
+
CC->>CC: Register WebCalling (if BROWSER)
|
|
105
|
+
CC->>CC: trackEvent(LOGIN_SUCCESS)
|
|
106
|
+
CC-->>App: StationLoginResponse
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
### State Change
|
|
110
|
+
|
|
111
|
+
```mermaid
|
|
112
|
+
sequenceDiagram
|
|
113
|
+
participant App
|
|
114
|
+
participant CC as ContactCenter
|
|
115
|
+
participant Svc as Services.agent
|
|
116
|
+
participant WS as WebSocket
|
|
117
|
+
participant BE as Backend
|
|
118
|
+
|
|
119
|
+
App->>CC: setAgentState(params)
|
|
120
|
+
CC->>CC: timeEvent(STATE_SUCCESS, STATE_FAILED)
|
|
121
|
+
CC->>Svc: stateChange({data})
|
|
122
|
+
Svc->>BE: HTTP PUT /v1/agents/session/state
|
|
123
|
+
BE-->>WS: AgentStateChangeSuccess
|
|
124
|
+
WS-->>CC: Emit via handleWebsocketMessage
|
|
125
|
+
CC->>CC: emit(agent:stateChange)
|
|
126
|
+
CC->>CC: trackEvent(STATE_SUCCESS)
|
|
127
|
+
CC-->>App: SetStateResponse
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
---
|
|
131
|
+
|
|
132
|
+
## Request Configuration
|
|
133
|
+
|
|
134
|
+
Each agent method defines:
|
|
135
|
+
|
|
136
|
+
```typescript
|
|
137
|
+
{
|
|
138
|
+
url: '/v1/agents/...', // API endpoint
|
|
139
|
+
host: WCC_API_GATEWAY, // Base URL
|
|
140
|
+
data: p.data, // Request payload
|
|
141
|
+
method: HTTP_METHODS.POST, // HTTP method (POST if data present, GET otherwise)
|
|
142
|
+
err: errorHandler, // Error transformer
|
|
143
|
+
notifSuccess: {
|
|
144
|
+
bind: {
|
|
145
|
+
type: CC_EVENTS.SUCCESS_TYPE,
|
|
146
|
+
data: {type: CC_EVENTS.SUCCESS_TYPE},
|
|
147
|
+
},
|
|
148
|
+
msg: {} as SuccessType, // Response type hint
|
|
149
|
+
},
|
|
150
|
+
notifFail: {
|
|
151
|
+
bind: {
|
|
152
|
+
type: CC_EVENTS.FAIL_TYPE,
|
|
153
|
+
data: {type: CC_EVENTS.FAIL_TYPE},
|
|
154
|
+
},
|
|
155
|
+
errId: 'Service.aqm.agent.method',
|
|
156
|
+
},
|
|
157
|
+
}
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
---
|
|
161
|
+
|
|
162
|
+
## Event Flow
|
|
163
|
+
|
|
164
|
+
### WebSocket to Application
|
|
165
|
+
|
|
166
|
+
```mermaid
|
|
167
|
+
flowchart LR
|
|
168
|
+
A[WebSocket Message] --> B[WebSocketManager]
|
|
169
|
+
B --> C[cc.handleWebsocketMessage]
|
|
170
|
+
C --> D{Event Type?}
|
|
171
|
+
D -->|AGENT_STATE_CHANGE| E[emit agent:stateChange]
|
|
172
|
+
D -->|data.type check| F{Nested Type?}
|
|
173
|
+
F -->|STATION_LOGIN_SUCCESS| G[Transform channelsMap]
|
|
174
|
+
G --> H[emit agent:stationLoginSuccess]
|
|
175
|
+
F -->|LOGOUT_SUCCESS| I[emit agent:logoutSuccess]
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
### ChannelsMap Transformation
|
|
179
|
+
|
|
180
|
+
The login success event transforms `channelsMap` to `mmProfile`:
|
|
181
|
+
|
|
182
|
+
```typescript
|
|
183
|
+
// Incoming
|
|
184
|
+
channelsMap: {
|
|
185
|
+
chat: ['channel-1', 'channel-2'],
|
|
186
|
+
email: ['channel-3'],
|
|
187
|
+
telephony: ['channel-4'],
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
// Transformed
|
|
191
|
+
mmProfile: {
|
|
192
|
+
chat: 2, // Length of arrays
|
|
193
|
+
email: 1,
|
|
194
|
+
social: 0,
|
|
195
|
+
telephony: 1,
|
|
196
|
+
}
|
|
197
|
+
```
|
|
198
|
+
|
|
199
|
+
---
|
|
200
|
+
|
|
201
|
+
## Silent Relogin
|
|
202
|
+
|
|
203
|
+
Automatic relogin on WebSocket reconnection:
|
|
204
|
+
|
|
205
|
+
```mermaid
|
|
206
|
+
flowchart TD
|
|
207
|
+
A[WebSocket Reconnected] --> B[handleConnectionLost]
|
|
208
|
+
B --> C{allowAutomatedRelogin?}
|
|
209
|
+
C -->|Yes| D[silentRelogin]
|
|
210
|
+
D --> E[services.agent.reload]
|
|
211
|
+
E --> F{Success?}
|
|
212
|
+
F -->|Yes| G[Update agentConfig]
|
|
213
|
+
G --> H{lastStateChangeReason?}
|
|
214
|
+
H -->|agent-wss-disconnect| I[setAgentState Available]
|
|
215
|
+
H -->|Other| J[Keep current state]
|
|
216
|
+
F -->|No, AGENT_NOT_FOUND| K[Handle silently]
|
|
217
|
+
F -->|No, Other| L[Throw error]
|
|
218
|
+
```
|
|
219
|
+
|
|
220
|
+
---
|
|
221
|
+
|
|
222
|
+
## Error Handling
|
|
223
|
+
|
|
224
|
+
### Login Error Details
|
|
225
|
+
|
|
226
|
+
For `stationLogin`, special error handling extracts field-specific messages:
|
|
227
|
+
|
|
228
|
+
```typescript
|
|
229
|
+
// Utils.ts - getStationLoginErrorData
|
|
230
|
+
const errorCodeMessageMap = {
|
|
231
|
+
DUPLICATE_LOCATION: {
|
|
232
|
+
message: 'This extension is already in use',
|
|
233
|
+
fieldName: loginOption,
|
|
234
|
+
},
|
|
235
|
+
INVALID_DIAL_NUMBER: {
|
|
236
|
+
message: 'Enter a valid US dial number...',
|
|
237
|
+
fieldName: loginOption,
|
|
238
|
+
},
|
|
239
|
+
};
|
|
240
|
+
```
|
|
241
|
+
|
|
242
|
+
---
|
|
243
|
+
|
|
244
|
+
## Metrics Tracking
|
|
245
|
+
|
|
246
|
+
| Metric | Type | When Tracked |
|
|
247
|
+
| ---------------------------- | --------------------------------- | ------------------------ |
|
|
248
|
+
| `STATION_LOGIN_SUCCESS` | behavioral, business, operational | Login succeeds |
|
|
249
|
+
| `STATION_LOGIN_FAILED` | behavioral, business, operational | Login fails |
|
|
250
|
+
| `STATION_LOGOUT_SUCCESS` | behavioral, business, operational | Logout succeeds |
|
|
251
|
+
| `STATION_LOGOUT_FAILED` | behavioral, business, operational | Logout fails |
|
|
252
|
+
| `AGENT_STATE_CHANGE_SUCCESS` | behavioral, business, operational | State change succeeds |
|
|
253
|
+
| `AGENT_STATE_CHANGE_FAILED` | behavioral, business, operational | State change fails |
|
|
254
|
+
| `FETCH_BUDDY_AGENTS_SUCCESS` | operational | Buddy agents fetched |
|
|
255
|
+
| `FETCH_BUDDY_AGENTS_FAILED` | operational | Buddy agents fetch fails |
|
|
256
|
+
|
|
257
|
+
---
|
|
258
|
+
|
|
259
|
+
## Troubleshooting
|
|
260
|
+
|
|
261
|
+
### Issue: Login fails with DUPLICATE_LOCATION
|
|
262
|
+
|
|
263
|
+
**Cause**: Extension/DN already in use by another session
|
|
264
|
+
|
|
265
|
+
**Solution**:
|
|
266
|
+
|
|
267
|
+
1. Logout from other session
|
|
268
|
+
2. Use different extension
|
|
269
|
+
3. Contact admin if stuck
|
|
270
|
+
|
|
271
|
+
### Issue: State change fails
|
|
272
|
+
|
|
273
|
+
**Cause**: Agent may be in a call or transitioning state
|
|
274
|
+
|
|
275
|
+
**Solution**:
|
|
276
|
+
1. Complete current interaction
|
|
277
|
+
2. Wait for state to stabilize
|
|
278
|
+
3. Retry state change
|
|
279
|
+
|
|
280
|
+
### Issue: Silent relogin not working
|
|
281
|
+
|
|
282
|
+
**Cause**: `allowAutomatedRelogin` config not set
|
|
283
|
+
|
|
284
|
+
**Solution**:
|
|
285
|
+
```typescript
|
|
286
|
+
const webex = Webex.init({
|
|
287
|
+
config: {
|
|
288
|
+
cc: {
|
|
289
|
+
allowAutomatedRelogin: true,
|
|
290
|
+
},
|
|
291
|
+
},
|
|
292
|
+
});
|
|
293
|
+
```
|
|
294
|
+
|
|
295
|
+
---
|
|
296
|
+
|
|
297
|
+
## Related Files
|
|
298
|
+
|
|
299
|
+
- [cc.ts](../../../cc.ts) - Main plugin
|
|
300
|
+
- [agent/index.ts](../index.ts) - Service implementation
|
|
301
|
+
- [agent/types.ts](../types.ts) - Type definitions
|
|
302
|
+
- [cc.ts test](../../../../test/unit/spec/cc.ts) - Test file
|