@webex/contact-center 3.12.0-next.9 → 3.12.0-task-refactor.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 (200) hide show
  1. package/AGENTS.md +438 -0
  2. package/ai-docs/README.md +131 -0
  3. package/ai-docs/RULES.md +455 -0
  4. package/ai-docs/patterns/event-driven-patterns.md +485 -0
  5. package/ai-docs/patterns/testing-patterns.md +480 -0
  6. package/ai-docs/patterns/typescript-patterns.md +365 -0
  7. package/ai-docs/templates/README.md +102 -0
  8. package/ai-docs/templates/documentation/create-agents-md.md +240 -0
  9. package/ai-docs/templates/documentation/create-architecture-md.md +295 -0
  10. package/ai-docs/templates/existing-service/bug-fix.md +254 -0
  11. package/ai-docs/templates/existing-service/feature-enhancement.md +450 -0
  12. package/ai-docs/templates/new-method/00-master.md +80 -0
  13. package/ai-docs/templates/new-method/01-requirements.md +232 -0
  14. package/ai-docs/templates/new-method/02-implementation.md +295 -0
  15. package/ai-docs/templates/new-method/03-tests.md +201 -0
  16. package/ai-docs/templates/new-method/04-validation.md +141 -0
  17. package/ai-docs/templates/new-service/00-master.md +109 -0
  18. package/ai-docs/templates/new-service/01-pre-questions.md +159 -0
  19. package/ai-docs/templates/new-service/02-code-generation.md +346 -0
  20. package/ai-docs/templates/new-service/03-integration.md +178 -0
  21. package/ai-docs/templates/new-service/04-test-generation.md +205 -0
  22. package/ai-docs/templates/new-service/05-validation.md +145 -0
  23. package/dist/cc.js +65 -123
  24. package/dist/cc.js.map +1 -1
  25. package/dist/constants.js +13 -2
  26. package/dist/constants.js.map +1 -1
  27. package/dist/index.js +13 -5
  28. package/dist/index.js.map +1 -1
  29. package/dist/metrics/behavioral-events.js +26 -13
  30. package/dist/metrics/behavioral-events.js.map +1 -1
  31. package/dist/metrics/constants.js +7 -6
  32. package/dist/metrics/constants.js.map +1 -1
  33. package/dist/services/ApiAiAssistant.js +0 -3
  34. package/dist/services/ApiAiAssistant.js.map +1 -1
  35. package/dist/services/config/Util.js +2 -3
  36. package/dist/services/config/Util.js.map +1 -1
  37. package/dist/services/config/types.js +16 -14
  38. package/dist/services/config/types.js.map +1 -1
  39. package/dist/services/constants.js +0 -1
  40. package/dist/services/constants.js.map +1 -1
  41. package/dist/services/core/Err.js.map +1 -1
  42. package/dist/services/core/Utils.js +79 -55
  43. package/dist/services/core/Utils.js.map +1 -1
  44. package/dist/services/core/aqm-reqs.js +17 -92
  45. package/dist/services/core/aqm-reqs.js.map +1 -1
  46. package/dist/services/core/websocket/WebSocketManager.js +5 -25
  47. package/dist/services/core/websocket/WebSocketManager.js.map +1 -1
  48. package/dist/services/core/websocket/types.js.map +1 -1
  49. package/dist/services/index.js +1 -2
  50. package/dist/services/index.js.map +1 -1
  51. package/dist/services/task/Task.js +644 -0
  52. package/dist/services/task/Task.js.map +1 -0
  53. package/dist/services/task/TaskFactory.js +45 -0
  54. package/dist/services/task/TaskFactory.js.map +1 -0
  55. package/dist/services/task/TaskManager.js +570 -535
  56. package/dist/services/task/TaskManager.js.map +1 -1
  57. package/dist/services/task/TaskUtils.js +132 -28
  58. package/dist/services/task/TaskUtils.js.map +1 -1
  59. package/dist/services/task/constants.js +7 -6
  60. package/dist/services/task/constants.js.map +1 -1
  61. package/dist/services/task/dialer.js +0 -51
  62. package/dist/services/task/dialer.js.map +1 -1
  63. package/dist/services/task/digital/Digital.js +77 -0
  64. package/dist/services/task/digital/Digital.js.map +1 -0
  65. package/dist/services/task/state-machine/TaskStateMachine.js +634 -0
  66. package/dist/services/task/state-machine/TaskStateMachine.js.map +1 -0
  67. package/dist/services/task/state-machine/actions.js +372 -0
  68. package/dist/services/task/state-machine/actions.js.map +1 -0
  69. package/dist/services/task/state-machine/constants.js +139 -0
  70. package/dist/services/task/state-machine/constants.js.map +1 -0
  71. package/dist/services/task/state-machine/guards.js +263 -0
  72. package/dist/services/task/state-machine/guards.js.map +1 -0
  73. package/dist/services/task/state-machine/index.js +53 -0
  74. package/dist/services/task/state-machine/index.js.map +1 -0
  75. package/dist/services/task/state-machine/types.js +54 -0
  76. package/dist/services/task/state-machine/types.js.map +1 -0
  77. package/dist/services/task/state-machine/uiControlsComputer.js +377 -0
  78. package/dist/services/task/state-machine/uiControlsComputer.js.map +1 -0
  79. package/dist/services/task/taskDataNormalizer.js +99 -0
  80. package/dist/services/task/taskDataNormalizer.js.map +1 -0
  81. package/dist/services/task/types.js +157 -18
  82. package/dist/services/task/types.js.map +1 -1
  83. package/dist/services/task/voice/Voice.js +1031 -0
  84. package/dist/services/task/voice/Voice.js.map +1 -0
  85. package/dist/services/task/voice/WebRTC.js +149 -0
  86. package/dist/services/task/voice/WebRTC.js.map +1 -0
  87. package/dist/types/cc.d.ts +4 -33
  88. package/dist/types/constants.d.ts +13 -2
  89. package/dist/types/index.d.ts +11 -5
  90. package/dist/types/metrics/constants.d.ts +5 -3
  91. package/dist/types/services/ApiAiAssistant.d.ts +1 -1
  92. package/dist/types/services/config/types.d.ts +97 -25
  93. package/dist/types/services/core/Err.d.ts +0 -2
  94. package/dist/types/services/core/Utils.d.ts +25 -23
  95. package/dist/types/services/core/aqm-reqs.d.ts +0 -49
  96. package/dist/types/services/core/websocket/WebSocketManager.d.ts +1 -1
  97. package/dist/types/services/core/websocket/connection-service.d.ts +0 -1
  98. package/dist/types/services/core/websocket/types.d.ts +1 -1
  99. package/dist/types/services/index.d.ts +1 -1
  100. package/dist/types/services/task/Task.d.ts +146 -0
  101. package/dist/types/services/task/TaskFactory.d.ts +12 -0
  102. package/dist/types/services/task/TaskUtils.d.ts +39 -8
  103. package/dist/types/services/task/constants.d.ts +5 -4
  104. package/dist/types/services/task/dialer.d.ts +0 -15
  105. package/dist/types/services/task/digital/Digital.d.ts +22 -0
  106. package/dist/types/services/task/state-machine/TaskStateMachine.d.ts +906 -0
  107. package/dist/types/services/task/state-machine/actions.d.ts +8 -0
  108. package/dist/types/services/task/state-machine/constants.d.ts +91 -0
  109. package/dist/types/services/task/state-machine/guards.d.ts +78 -0
  110. package/dist/types/services/task/state-machine/index.d.ts +13 -0
  111. package/dist/types/services/task/state-machine/types.d.ts +256 -0
  112. package/dist/types/services/task/state-machine/uiControlsComputer.d.ts +9 -0
  113. package/dist/types/services/task/taskDataNormalizer.d.ts +10 -0
  114. package/dist/types/services/task/types.d.ts +539 -88
  115. package/dist/types/services/task/voice/Voice.d.ts +183 -0
  116. package/dist/types/services/task/voice/WebRTC.d.ts +53 -0
  117. package/dist/types/types.d.ts +68 -0
  118. package/dist/types/webex.d.ts +1 -0
  119. package/dist/types.js +70 -0
  120. package/dist/types.js.map +1 -1
  121. package/dist/webex.js +14 -2
  122. package/dist/webex.js.map +1 -1
  123. package/package.json +14 -11
  124. package/src/cc.ts +91 -177
  125. package/src/constants.ts +13 -2
  126. package/src/index.ts +14 -5
  127. package/src/metrics/ai-docs/AGENTS.md +348 -0
  128. package/src/metrics/ai-docs/ARCHITECTURE.md +336 -0
  129. package/src/metrics/behavioral-events.ts +28 -14
  130. package/src/metrics/constants.ts +7 -8
  131. package/src/services/ApiAiAssistant.ts +2 -4
  132. package/src/services/agent/ai-docs/AGENTS.md +238 -0
  133. package/src/services/agent/ai-docs/ARCHITECTURE.md +302 -0
  134. package/src/services/ai-docs/AGENTS.md +384 -0
  135. package/src/services/config/Util.ts +2 -3
  136. package/src/services/config/ai-docs/AGENTS.md +253 -0
  137. package/src/services/config/ai-docs/ARCHITECTURE.md +424 -0
  138. package/src/services/config/types.ts +108 -20
  139. package/src/services/constants.ts +0 -1
  140. package/src/services/core/Err.ts +0 -1
  141. package/src/services/core/Utils.ts +90 -67
  142. package/src/services/core/ai-docs/AGENTS.md +379 -0
  143. package/src/services/core/ai-docs/ARCHITECTURE.md +696 -0
  144. package/src/services/core/aqm-reqs.ts +22 -100
  145. package/src/services/core/websocket/WebSocketManager.ts +4 -23
  146. package/src/services/core/websocket/types.ts +1 -1
  147. package/src/services/index.ts +1 -2
  148. package/src/services/task/Task.ts +785 -0
  149. package/src/services/task/TaskFactory.ts +55 -0
  150. package/src/services/task/TaskManager.ts +579 -633
  151. package/src/services/task/TaskUtils.ts +175 -31
  152. package/src/services/task/ai-docs/AGENTS.md +448 -0
  153. package/src/services/task/ai-docs/ARCHITECTURE.md +573 -0
  154. package/src/services/task/constants.ts +5 -4
  155. package/src/services/task/dialer.ts +1 -56
  156. package/src/services/task/digital/Digital.ts +95 -0
  157. package/src/services/task/state-machine/TaskStateMachine.ts +793 -0
  158. package/src/services/task/state-machine/actions.ts +422 -0
  159. package/src/services/task/state-machine/ai-docs/AGENTS.md +495 -0
  160. package/src/services/task/state-machine/ai-docs/ARCHITECTURE.md +1135 -0
  161. package/src/services/task/state-machine/constants.ts +150 -0
  162. package/src/services/task/state-machine/guards.ts +303 -0
  163. package/src/services/task/state-machine/index.ts +28 -0
  164. package/src/services/task/state-machine/types.ts +228 -0
  165. package/src/services/task/state-machine/uiControlsComputer.ts +542 -0
  166. package/src/services/task/taskDataNormalizer.ts +137 -0
  167. package/src/services/task/types.ts +641 -95
  168. package/src/services/task/voice/Voice.ts +1255 -0
  169. package/src/services/task/voice/WebRTC.ts +187 -0
  170. package/src/types.ts +88 -5
  171. package/src/utils/AGENTS.md +276 -0
  172. package/src/webex.js +2 -0
  173. package/test/unit/spec/cc.ts +59 -142
  174. package/test/unit/spec/logger-proxy.ts +70 -0
  175. package/test/unit/spec/services/ApiAiAssistant.ts +17 -0
  176. package/test/unit/spec/services/config/index.ts +26 -55
  177. package/test/unit/spec/services/core/Utils.ts +103 -52
  178. package/test/unit/spec/services/core/websocket/WebSocketManager.ts +48 -112
  179. package/test/unit/spec/services/core/websocket/connection-service.ts +5 -4
  180. package/test/unit/spec/services/task/AutoWrapup.ts +63 -0
  181. package/test/unit/spec/services/task/Task.ts +416 -0
  182. package/test/unit/spec/services/task/TaskFactory.ts +62 -0
  183. package/test/unit/spec/services/task/TaskManager.ts +781 -1735
  184. package/test/unit/spec/services/task/TaskUtils.ts +125 -0
  185. package/test/unit/spec/services/task/dialer.ts +112 -198
  186. package/test/unit/spec/services/task/digital/Digital.ts +105 -0
  187. package/test/unit/spec/services/task/state-machine/TaskStateMachine.ts +473 -0
  188. package/test/unit/spec/services/task/state-machine/guards.ts +288 -0
  189. package/test/unit/spec/services/task/state-machine/types.ts +18 -0
  190. package/test/unit/spec/services/task/state-machine/uiControlsComputer.ts +147 -0
  191. package/test/unit/spec/services/task/taskTestUtils.ts +87 -0
  192. package/test/unit/spec/services/task/voice/Voice.ts +587 -0
  193. package/test/unit/spec/services/task/voice/WebRTC.ts +242 -0
  194. package/umd/contact-center.min.js +2 -2
  195. package/umd/contact-center.min.js.map +1 -1
  196. package/dist/services/task/index.js +0 -1525
  197. package/dist/services/task/index.js.map +0 -1
  198. package/dist/types/services/task/index.d.ts +0 -650
  199. package/src/services/task/index.ts +0 -1801
  200. package/test/unit/spec/services/task/index.ts +0 -2184
@@ -352,6 +352,34 @@ const eventTaxonomyMap: Record<string, BehavioralEventTaxonomy> = {
352
352
  verb: 'fail',
353
353
  },
354
354
 
355
+ // Conference Exit
356
+ [METRIC_EVENT_NAMES.TASK_CONFERENCE_EXIT_SUCCESS]: {
357
+ product,
358
+ agent: 'user',
359
+ target: 'task_conference_exit',
360
+ verb: 'complete',
361
+ },
362
+ [METRIC_EVENT_NAMES.TASK_CONFERENCE_EXIT_FAILED]: {
363
+ product,
364
+ agent: 'user',
365
+ target: 'task_conference_exit',
366
+ verb: 'fail',
367
+ },
368
+
369
+ // Switch Call
370
+ [METRIC_EVENT_NAMES.TASK_SWITCH_CALL_SUCCESS]: {
371
+ product,
372
+ agent: 'user',
373
+ target: 'task_switch_call',
374
+ verb: 'complete',
375
+ },
376
+ [METRIC_EVENT_NAMES.TASK_SWITCH_CALL_FAILED]: {
377
+ product,
378
+ agent: 'user',
379
+ target: 'task_switch_call',
380
+ verb: 'fail',
381
+ },
382
+
355
383
  // upload logs
356
384
  [METRIC_EVENT_NAMES.UPLOAD_LOGS_SUCCESS]: {
357
385
  product,
@@ -435,20 +463,6 @@ const eventTaxonomyMap: Record<string, BehavioralEventTaxonomy> = {
435
463
  target: 'outdial_ani_ep_fetch',
436
464
  verb: 'fail',
437
465
  },
438
-
439
- // Campaign Preview API Events
440
- [METRIC_EVENT_NAMES.CAMPAIGN_PREVIEW_ACCEPT_SUCCESS]: {
441
- product,
442
- agent: 'user',
443
- target: 'campaign_preview_accept',
444
- verb: 'complete',
445
- },
446
- [METRIC_EVENT_NAMES.CAMPAIGN_PREVIEW_ACCEPT_FAILED]: {
447
- product,
448
- agent: 'user',
449
- target: 'campaign_preview_accept',
450
- verb: 'fail',
451
- },
452
466
  };
453
467
 
454
468
  /**
@@ -129,6 +129,10 @@ export const METRIC_EVENT_NAMES = {
129
129
  TASK_CONFERENCE_END_FAILED: 'Task Conference End Failed',
130
130
  TASK_CONFERENCE_TRANSFER_SUCCESS: 'Task Conference Transfer Success',
131
131
  TASK_CONFERENCE_TRANSFER_FAILED: 'Task Conference Transfer Failed',
132
+ TASK_CONFERENCE_EXIT_SUCCESS: 'Task Conference Exit Success',
133
+ TASK_CONFERENCE_EXIT_FAILED: 'Task Conference Exit Failed',
134
+ TASK_SWITCH_CALL_SUCCESS: 'Task Switch Call Success',
135
+ TASK_SWITCH_CALL_FAILED: 'Task Switch Call Failed',
132
136
 
133
137
  TASK_OUTDIAL_SUCCESS: 'Task Outdial Success',
134
138
  TASK_OUTDIAL_FAILED: 'Task Outdial Failed',
@@ -138,11 +142,10 @@ export const METRIC_EVENT_NAMES = {
138
142
  WEBSOCKET_DEREGISTER_SUCCESS: 'Websocket Deregister Success',
139
143
  WEBSOCKET_DEREGISTER_FAIL: 'Websocket Deregister Failed',
140
144
 
141
- // WebSocket message events
142
- WEBSOCKET_EVENT_RECEIVED: 'Websocket Event Received',
143
-
144
145
  AGENT_DEVICE_TYPE_UPDATE_SUCCESS: 'Agent Device Type Update Success',
145
146
  AGENT_DEVICE_TYPE_UPDATE_FAILED: 'Agent Device Type Update Failed',
147
+ // WebSocket message events
148
+ WEBSOCKET_EVENT_RECEIVED: 'Websocket Event Received',
146
149
 
147
150
  // EntryPoint API Events
148
151
  ENTRYPOINT_FETCH_SUCCESS: 'Entrypoint Fetch Success',
@@ -160,11 +163,7 @@ export const METRIC_EVENT_NAMES = {
160
163
  OUTDIAL_ANI_EP_FETCH_SUCCESS: 'Outdial ANI Entries Fetch Success',
161
164
  OUTDIAL_ANI_EP_FETCH_FAILED: 'Outdial ANI Entries Fetch Failed',
162
165
 
163
- // Campaign Preview API Events
164
- CAMPAIGN_PREVIEW_ACCEPT_SUCCESS: 'Campaign Preview Accept Success',
165
- CAMPAIGN_PREVIEW_ACCEPT_FAILED: 'Campaign Preview Accept Failed',
166
-
167
- // AI Assistant transcript events
166
+ // AI Assistant events
168
167
  AI_ASSISTANT_SEND_EVENT_SUCCESS: 'AI Assistant Send Event Success',
169
168
  AI_ASSISTANT_SEND_EVENT_FAILED: 'AI Assistant Send Event Failed',
170
169
  AI_ASSISTANT_FETCH_HISTORIC_TRANSCRIPTS_SUCCESS:
@@ -27,7 +27,7 @@ import {AIFeatureFlags} from './config/types';
27
27
  export class ApiAIAssistant {
28
28
  private webex: WebexSDK;
29
29
  private metricsManager: MetricsManager;
30
- public aiFeature: AIFeatureFlags;
30
+ private aiFeature: AIFeatureFlags;
31
31
 
32
32
  constructor(webex: WebexSDK) {
33
33
  this.webex = webex;
@@ -201,9 +201,7 @@ export class ApiAIAssistant {
201
201
  },
202
202
  ['operational']
203
203
  );
204
- if (error instanceof Error) {
205
- throw error;
206
- }
204
+
207
205
  const {error: detailedError} = getErrorDetails(
208
206
  error,
209
207
  METHODS.FETCH_HISTORIC_TRANSCRIPTS,
@@ -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