@webex/contact-center 3.12.0-next.9 → 3.12.0-next.91

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 (229) hide show
  1. package/.sdd/manifest.json +876 -0
  2. package/AGENTS.md +94 -0
  3. package/ai-docs/ARCHITECTURE.md +168 -0
  4. package/ai-docs/CONTRACTS.md +46 -0
  5. package/ai-docs/GETTING_STARTED.md +168 -0
  6. package/ai-docs/GLOSSARY.md +43 -0
  7. package/ai-docs/README.md +138 -0
  8. package/ai-docs/REVIEW_CHECKLIST.md +41 -0
  9. package/ai-docs/RULES.md +444 -0
  10. package/ai-docs/SECURITY.md +52 -0
  11. package/ai-docs/SERVICE_STATE.md +48 -0
  12. package/ai-docs/SPEC_INDEX.md +65 -0
  13. package/ai-docs/adr/0001-spec-source-policy.md +55 -0
  14. package/ai-docs/adr/README.md +8 -0
  15. package/ai-docs/adr/_adr-template.md +31 -0
  16. package/ai-docs/contact-center-spec.md +341 -0
  17. package/ai-docs/features/generated-spec-conformance-fidelity-remediation/spec/feature-spec.md +117 -0
  18. package/ai-docs/features/residual-warning-coverage-completion/spec/feature-spec.md +203 -0
  19. package/ai-docs/features/validator-code-fidelity-drift-fix/spec/feature-spec.md +315 -0
  20. package/ai-docs/patterns/event-driven-patterns.md +485 -0
  21. package/ai-docs/patterns/testing-patterns.md +480 -0
  22. package/ai-docs/patterns/typescript-patterns.md +365 -0
  23. package/ai-docs/templates/README.md +102 -0
  24. package/ai-docs/templates/documentation/create-agents-md.md +240 -0
  25. package/ai-docs/templates/documentation/create-architecture-md.md +295 -0
  26. package/ai-docs/templates/existing-service/bug-fix.md +254 -0
  27. package/ai-docs/templates/existing-service/feature-enhancement.md +450 -0
  28. package/ai-docs/templates/new-method/00-master.md +80 -0
  29. package/ai-docs/templates/new-method/01-requirements.md +232 -0
  30. package/ai-docs/templates/new-method/02-implementation.md +295 -0
  31. package/ai-docs/templates/new-method/03-tests.md +201 -0
  32. package/ai-docs/templates/new-method/04-validation.md +141 -0
  33. package/ai-docs/templates/new-service/00-master.md +109 -0
  34. package/ai-docs/templates/new-service/01-pre-questions.md +159 -0
  35. package/ai-docs/templates/new-service/02-code-generation.md +346 -0
  36. package/ai-docs/templates/new-service/03-integration.md +178 -0
  37. package/ai-docs/templates/new-service/04-test-generation.md +205 -0
  38. package/ai-docs/templates/new-service/05-validation.md +145 -0
  39. package/dist/cc.js +265 -29
  40. package/dist/cc.js.map +1 -1
  41. package/dist/config.js +6 -0
  42. package/dist/config.js.map +1 -1
  43. package/dist/constants.js +17 -1
  44. package/dist/constants.js.map +1 -1
  45. package/dist/index.js +20 -5
  46. package/dist/index.js.map +1 -1
  47. package/dist/metrics/behavioral-events.js +101 -0
  48. package/dist/metrics/behavioral-events.js.map +1 -1
  49. package/dist/metrics/constants.js +25 -4
  50. package/dist/metrics/constants.js.map +1 -1
  51. package/dist/services/ApiAiAssistant.js +153 -8
  52. package/dist/services/ApiAiAssistant.js.map +1 -1
  53. package/dist/services/UserPreference.js +427 -0
  54. package/dist/services/UserPreference.js.map +1 -0
  55. package/dist/services/config/Util.js +3 -3
  56. package/dist/services/config/Util.js.map +1 -1
  57. package/dist/services/config/constants.js +23 -2
  58. package/dist/services/config/constants.js.map +1 -1
  59. package/dist/services/config/types.js +49 -9
  60. package/dist/services/config/types.js.map +1 -1
  61. package/dist/services/core/Err.js.map +1 -1
  62. package/dist/services/core/Utils.js +107 -32
  63. package/dist/services/core/Utils.js.map +1 -1
  64. package/dist/services/core/websocket/WebSocketManager.js +2 -1
  65. package/dist/services/core/websocket/WebSocketManager.js.map +1 -1
  66. package/dist/services/core/websocket/types.js.map +1 -1
  67. package/dist/services/index.js +1 -1
  68. package/dist/services/index.js.map +1 -1
  69. package/dist/services/task/Task.js +688 -0
  70. package/dist/services/task/Task.js.map +1 -0
  71. package/dist/services/task/TaskFactory.js +45 -0
  72. package/dist/services/task/TaskFactory.js.map +1 -0
  73. package/dist/services/task/TaskManager.js +728 -527
  74. package/dist/services/task/TaskManager.js.map +1 -1
  75. package/dist/services/task/TaskUtils.js +162 -26
  76. package/dist/services/task/TaskUtils.js.map +1 -1
  77. package/dist/services/task/constants.js +9 -2
  78. package/dist/services/task/constants.js.map +1 -1
  79. package/dist/services/task/dialer.js +78 -0
  80. package/dist/services/task/dialer.js.map +1 -1
  81. package/dist/services/task/digital/Digital.js +77 -0
  82. package/dist/services/task/digital/Digital.js.map +1 -0
  83. package/dist/services/task/state-machine/TaskStateMachine.js +837 -0
  84. package/dist/services/task/state-machine/TaskStateMachine.js.map +1 -0
  85. package/dist/services/task/state-machine/actions.js +543 -0
  86. package/dist/services/task/state-machine/actions.js.map +1 -0
  87. package/dist/services/task/state-machine/constants.js +161 -0
  88. package/dist/services/task/state-machine/constants.js.map +1 -0
  89. package/dist/services/task/state-machine/guards.js +340 -0
  90. package/dist/services/task/state-machine/guards.js.map +1 -0
  91. package/dist/services/task/state-machine/index.js +53 -0
  92. package/dist/services/task/state-machine/index.js.map +1 -0
  93. package/dist/services/task/state-machine/types.js +54 -0
  94. package/dist/services/task/state-machine/types.js.map +1 -0
  95. package/dist/services/task/state-machine/uiControlsComputer.js +553 -0
  96. package/dist/services/task/state-machine/uiControlsComputer.js.map +1 -0
  97. package/dist/services/task/taskDataNormalizer.js +99 -0
  98. package/dist/services/task/taskDataNormalizer.js.map +1 -0
  99. package/dist/services/task/types.js +212 -4
  100. package/dist/services/task/types.js.map +1 -1
  101. package/dist/services/task/voice/Voice.js +1042 -0
  102. package/dist/services/task/voice/Voice.js.map +1 -0
  103. package/dist/services/task/voice/WebRTC.js +149 -0
  104. package/dist/services/task/voice/WebRTC.js.map +1 -0
  105. package/dist/types/cc.d.ts +94 -1
  106. package/dist/types/config.d.ts +6 -0
  107. package/dist/types/constants.d.ts +17 -1
  108. package/dist/types/index.d.ts +21 -6
  109. package/dist/types/metrics/constants.d.ts +21 -1
  110. package/dist/types/services/ApiAiAssistant.d.ts +22 -4
  111. package/dist/types/services/UserPreference.d.ts +118 -0
  112. package/dist/types/services/config/constants.d.ts +21 -0
  113. package/dist/types/services/config/types.d.ts +171 -10
  114. package/dist/types/services/core/Err.d.ts +4 -0
  115. package/dist/types/services/core/Utils.d.ts +33 -13
  116. package/dist/types/services/core/websocket/WebSocketManager.d.ts +1 -0
  117. package/dist/types/services/core/websocket/types.d.ts +1 -1
  118. package/dist/types/services/index.d.ts +1 -1
  119. package/dist/types/services/task/Task.d.ts +157 -0
  120. package/dist/types/services/task/TaskFactory.d.ts +12 -0
  121. package/dist/types/services/task/TaskUtils.d.ts +46 -2
  122. package/dist/types/services/task/constants.d.ts +7 -0
  123. package/dist/types/services/task/dialer.d.ts +30 -0
  124. package/dist/types/services/task/digital/Digital.d.ts +22 -0
  125. package/dist/types/services/task/state-machine/TaskStateMachine.d.ts +1144 -0
  126. package/dist/types/services/task/state-machine/actions.d.ts +10 -0
  127. package/dist/types/services/task/state-machine/constants.d.ts +107 -0
  128. package/dist/types/services/task/state-machine/guards.d.ts +90 -0
  129. package/dist/types/services/task/state-machine/index.d.ts +13 -0
  130. package/dist/types/services/task/state-machine/types.d.ts +267 -0
  131. package/dist/types/services/task/state-machine/uiControlsComputer.d.ts +9 -0
  132. package/dist/types/services/task/taskDataNormalizer.d.ts +10 -0
  133. package/dist/types/services/task/types.d.ts +603 -66
  134. package/dist/types/services/task/voice/Voice.d.ts +184 -0
  135. package/dist/types/services/task/voice/WebRTC.d.ts +53 -0
  136. package/dist/types/types.d.ts +135 -0
  137. package/dist/types/webex.d.ts +1 -0
  138. package/dist/types.js +118 -2
  139. package/dist/types.js.map +1 -1
  140. package/dist/webex.js +14 -2
  141. package/dist/webex.js.map +1 -1
  142. package/package.json +15 -12
  143. package/src/cc.ts +329 -30
  144. package/src/config.ts +6 -0
  145. package/src/constants.ts +17 -1
  146. package/src/index.ts +23 -5
  147. package/src/metrics/ai-docs/AGENTS.md +350 -0
  148. package/src/metrics/ai-docs/ARCHITECTURE.md +338 -0
  149. package/src/metrics/ai-docs/metrics-spec.md +854 -0
  150. package/src/metrics/behavioral-events.ts +106 -0
  151. package/src/metrics/constants.ts +27 -4
  152. package/src/services/ApiAiAssistant.ts +203 -8
  153. package/src/services/UserPreference.ts +509 -0
  154. package/src/services/agent/ai-docs/AGENTS.md +240 -0
  155. package/src/services/agent/ai-docs/ARCHITECTURE.md +304 -0
  156. package/src/services/agent/ai-docs/agent-spec.md +504 -0
  157. package/src/services/ai-docs/AGENTS.md +386 -0
  158. package/src/services/ai-docs/services-spec.md +492 -0
  159. package/src/services/config/Util.ts +3 -3
  160. package/src/services/config/ai-docs/AGENTS.md +255 -0
  161. package/src/services/config/ai-docs/ARCHITECTURE.md +426 -0
  162. package/src/services/config/ai-docs/config-spec.md +669 -0
  163. package/src/services/config/constants.ts +25 -1
  164. package/src/services/config/types.ts +174 -11
  165. package/src/services/core/Err.ts +2 -0
  166. package/src/services/core/Utils.ts +123 -37
  167. package/src/services/core/ai-docs/AGENTS.md +381 -0
  168. package/src/services/core/ai-docs/ARCHITECTURE.md +698 -0
  169. package/src/services/core/ai-docs/core-spec.md +783 -0
  170. package/src/services/core/websocket/WebSocketManager.ts +2 -0
  171. package/src/services/core/websocket/types.ts +1 -1
  172. package/src/services/index.ts +1 -1
  173. package/src/services/task/Task.ts +837 -0
  174. package/src/services/task/TaskFactory.ts +55 -0
  175. package/src/services/task/TaskManager.ts +739 -614
  176. package/src/services/task/TaskUtils.ts +205 -25
  177. package/src/services/task/ai-docs/AGENTS.md +457 -0
  178. package/src/services/task/ai-docs/ARCHITECTURE.md +594 -0
  179. package/src/services/task/ai-docs/task-spec.md +1319 -0
  180. package/src/services/task/constants.ts +7 -0
  181. package/src/services/task/dialer.ts +80 -0
  182. package/src/services/task/digital/Digital.ts +95 -0
  183. package/src/services/task/state-machine/TaskStateMachine.ts +1077 -0
  184. package/src/services/task/state-machine/actions.ts +685 -0
  185. package/src/services/task/state-machine/ai-docs/AGENTS.md +458 -0
  186. package/src/services/task/state-machine/ai-docs/ARCHITECTURE.md +1137 -0
  187. package/src/services/task/state-machine/ai-docs/task-state-machine-spec.md +2115 -0
  188. package/src/services/task/state-machine/constants.ts +172 -0
  189. package/src/services/task/state-machine/guards.ts +406 -0
  190. package/src/services/task/state-machine/index.ts +28 -0
  191. package/src/services/task/state-machine/types.ts +241 -0
  192. package/src/services/task/state-machine/uiControlsComputer.ts +867 -0
  193. package/src/services/task/taskDataNormalizer.ts +137 -0
  194. package/src/services/task/types.ts +710 -71
  195. package/src/services/task/voice/Voice.ts +1267 -0
  196. package/src/services/task/voice/WebRTC.ts +187 -0
  197. package/src/types.ts +166 -2
  198. package/src/utils/AGENTS.md +278 -0
  199. package/src/utils/ai-docs/utils-spec.md +381 -0
  200. package/src/webex.js +2 -0
  201. package/test/unit/spec/cc.ts +343 -23
  202. package/test/unit/spec/logger-proxy.ts +70 -0
  203. package/test/unit/spec/services/ApiAiAssistant.ts +178 -20
  204. package/test/unit/spec/services/UserPreference.ts +401 -0
  205. package/test/unit/spec/services/WebCallingService.ts +7 -1
  206. package/test/unit/spec/services/config/index.ts +30 -30
  207. package/test/unit/spec/services/core/Utils.ts +425 -8
  208. package/test/unit/spec/services/core/websocket/WebSocketManager.ts +66 -40
  209. package/test/unit/spec/services/task/AutoWrapup.ts +63 -0
  210. package/test/unit/spec/services/task/Task.ts +477 -0
  211. package/test/unit/spec/services/task/TaskFactory.ts +62 -0
  212. package/test/unit/spec/services/task/TaskManager.ts +834 -1704
  213. package/test/unit/spec/services/task/TaskUtils.ts +206 -0
  214. package/test/unit/spec/services/task/dialer.ts +190 -0
  215. package/test/unit/spec/services/task/digital/Digital.ts +105 -0
  216. package/test/unit/spec/services/task/state-machine/TaskStateMachine.ts +1825 -0
  217. package/test/unit/spec/services/task/state-machine/guards.ts +479 -0
  218. package/test/unit/spec/services/task/state-machine/types.ts +18 -0
  219. package/test/unit/spec/services/task/state-machine/uiControlsComputer.ts +2020 -0
  220. package/test/unit/spec/services/task/taskTestUtils.ts +87 -0
  221. package/test/unit/spec/services/task/voice/Voice.ts +631 -0
  222. package/test/unit/spec/services/task/voice/WebRTC.ts +235 -0
  223. package/umd/contact-center.min.js +2 -2
  224. package/umd/contact-center.min.js.map +1 -1
  225. package/dist/services/task/index.js +0 -1525
  226. package/dist/services/task/index.js.map +0 -1
  227. package/dist/types/services/task/index.d.ts +0 -650
  228. package/src/services/task/index.ts +0 -1801
  229. package/test/unit/spec/services/task/index.ts +0 -2184
@@ -0,0 +1,255 @@
1
+ # Config Service - AI Agent Guide
2
+
3
+ > **Legacy/reference-only.** Canonical SDD: [`config-spec.md`](config-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**: Fetch and aggregate agent configuration data from multiple API endpoints to build the AgentProfile.
6
+ >
7
+ > **Legacy scope:** See [Root AGENTS.md](../../../../AGENTS.md) for the orchestrator and cross-scope rules.
8
+
9
+ ---
10
+
11
+ ## Overview
12
+
13
+ The Config Service is an **internal service** that builds the comprehensive AgentProfile (`Profile` type) by:
14
+ 1. Fetching user data
15
+ 2. Fetching desktop profile
16
+ 3. Fetching teams
17
+ 4. Fetching aux codes (idle/wrapup codes)
18
+ 5. Fetching organization settings
19
+ 6. Aggregating all data into a single AgentProfile
20
+
21
+ The AgentProfile is the central configuration object required for an agent to operate within the contact center. It is built during the registration flow (`cc.register()`) and contains all the data an agent needs: identity, team assignments, dial plans, aux codes, login options, and feature flags. Once constructed, the AgentProfile is stored on the `ContactCenter` plugin instance as `this.agentConfig` and is used by other services (Agent, Task) throughout the session.
22
+
23
+
24
+ ---
25
+
26
+ ## File Structure
27
+
28
+ ```
29
+ services/config/
30
+ ├── index.ts # AgentConfigService class
31
+ ├── types.ts # Profile, CC_EVENTS, types
32
+ ├── constants.ts # API endpoints, defaults
33
+ ├── Util.ts # parseAgentConfigs helper
34
+ └── ai-docs/
35
+ ├── AGENTS.md # Usage documentation
36
+ └── ARCHITECTURE.md # This file
37
+ ```
38
+
39
+ ---
40
+
41
+ ## Quick Usage
42
+
43
+ ```typescript
44
+ // Config service is used internally during the registration flow.
45
+ // Inside cc.ts → connectWebsocket(), after WebSocket connection is established:
46
+ const agentId = data.agentId;
47
+ const orgId = this.$webex.credentials.getOrgId();
48
+ this.agentConfig = await this.services.config.getAgentConfig(orgId, agentId);
49
+
50
+ // The returned AgentProfile contains all agent configuration:
51
+ LoggerProxy.info(`Agent ID: ${this.agentConfig.agentId}`, {
52
+ module: 'cc',
53
+ method: 'connectWebsocket',
54
+ });
55
+ LoggerProxy.info(`Teams: ${this.agentConfig.teams}`, {
56
+ module: 'cc',
57
+ method: 'connectWebsocket',
58
+ });
59
+ ```
60
+
61
+ ---
62
+
63
+ ## Key Capabilities
64
+
65
+ - **AgentProfile Aggregation**: Combines data from 8+ API endpoints
66
+ - **Aux Codes Fetching**: Gets all idle and wrapup codes with pagination
67
+ - **Team Data**: Retrieves agent's team assignments
68
+ - **Dial Plan**: Fetches number transformation rules
69
+ - **Outdial ANI**: Retrieves outbound caller ID options (standalone, publicly exposed via `cc.ts`)
70
+ - **Multimedia Profile**: Fetches channel capacity and blending config (standalone, not yet publicly exposed)
71
+ - **Paginated Data Access**: `getListOfTeams` and `getListOfAuxCodes` support custom pagination independent of profile building
72
+
73
+ ---
74
+
75
+ ## AgentProfile Object (Key Fields)
76
+
77
+ The AgentProfile is defined as the [`Profile`](../types.ts) type. This is not an exhaustive list — see [`types.ts`](../types.ts) for the full 50+ field definition. Key fields:
78
+
79
+ | Field | Type | Description |
80
+ |-------|------|-------------|
81
+ | `agentId` | string | Unique agent identifier |
82
+ | `agentName` | string | Display name |
83
+ | `agentMailId` | string | Email address |
84
+ | `teams` | [`TeamList[]`](../types.ts) | Assigned teams (runtime data from `getAllTeams()` — `Profile` type declares `Team[]` but actual objects are `TeamList` with `id`, `name`, `teamType`, `siteId`, etc.) |
85
+ | `defaultDn` | string | Default dial number |
86
+ | `idleCodes` | [`Entity[]`](../types.ts) | Available idle codes |
87
+ | `wrapupCodes` | [`Entity[]`](../types.ts) | Available wrapup codes |
88
+ | `webRtcEnabled` | boolean | WebRTC calling enabled |
89
+ | `loginVoiceOptions` | [`LoginOption[]`](../types.ts) | Available login types |
90
+ | `dialPlan` | [`DialPlan`](../types.ts) | Number transformation rules |
91
+ | `isOutboundEnabledForAgent` | boolean | Outbound calling allowed |
92
+ | `outDialEp` | string | Outbound entry point ID |
93
+
94
+ ---
95
+
96
+ ## Data Aggregation Flow
97
+
98
+ The following diagram shows how `getAgentConfig` orchestrates multiple API calls and combines their results into the AgentProfile via `parseAgentConfigs()`:
99
+
100
+ ```
101
+ getUserUsingCI ────────────┐
102
+
103
+ getOrgInfo ────────────────┤
104
+
105
+ getOrganizationSetting ────┤
106
+
107
+ getTenantData ─────────────┤
108
+
109
+ getURLMapping ─────────────┼──► parseAgentConfigs() ──► AgentProfile
110
+
111
+ getAllAuxCodes ─────────────┤
112
+
113
+ getDesktopProfileById ─────┤
114
+
115
+ getSiteInfo ───────────────┤ (computes multimediaProfileId)
116
+
117
+ getAllTeams ────────────────┤
118
+
119
+ getDialPlanData ───────────┘
120
+ ```
121
+
122
+ ---
123
+
124
+ ## API Methods (Internal)
125
+
126
+ ### `getAgentConfig(orgId, agentId)`
127
+
128
+ Main method that aggregates all configuration data into the AgentProfile.
129
+
130
+ **Returns**: `Promise<Profile>`
131
+
132
+ **Flow**:
133
+ 1. Fetch user data (`getUserUsingCI`)
134
+ 2. Fetch org info (`getOrgInfo`), settings (`getOrganizationSetting`), tenant data (`getTenantData`) in parallel
135
+ 3. Fetch aux codes with pagination (`getAllAuxCodes`)
136
+ 4. Fetch desktop profile (`getDesktopProfileById`), site info (`getSiteInfo`)
137
+ 5. Fetch dial plan if enabled (`getDialPlanData`)
138
+ 6. Fetch teams (`getAllTeams`)
139
+ 7. Parse and combine all data (`parseAgentConfigs`)
140
+
141
+ ---
142
+
143
+ ## Standalone APIs (Not Part of AgentProfile Building)
144
+
145
+ These methods exist in `AgentConfigService` but are **not** part of the `getAgentConfig()` aggregation flow. They can be used independently by applications.
146
+
147
+ | Method | Status | Returns | Description |
148
+ |--------|--------|---------|-------------|
149
+ | `getOutdialAniEntries(orgId, params)` | **Publicly exposed** via `cc.getOutdialAniEntries()` | `OutdialAniEntriesResponse` | Fetch outbound ANI entries for caller ID selection. Supports pagination and search via [`OutdialAniParams`](../types.ts). |
150
+ | `getMultimediaProfileById(orgId, multimediaProfileId)` | **Not exposed, never called** | `MultimediaProfileResponse` | Fetch channel capacities (chat, email, telephony, social) and blending config. Available but unused anywhere. |
151
+ | `getListOfTeams(orgId, page, pageSize, filter)` | Used internally by `getAllTeams()` | `ListTeamsResponse` | Single-page team fetch with pagination metadata. Useful for custom pagination. |
152
+ | `getListOfAuxCodes(orgId, page, pageSize, filter, attributes)` | Used internally by `getAllAuxCodes()` | `ListAuxCodesResponse` | Single-page aux code fetch with pagination metadata. Useful for custom pagination. |
153
+
154
+ Additionally, the following endpoints are defined in `constants.ts` `endPointMap` but are consumed by separate service classes, not by `AgentConfigService`:
155
+
156
+ | Endpoint | Used By | Description |
157
+ |----------|---------|-------------|
158
+ | `queueList` | [`Queue.ts`](../../Queue.ts) | Fetch contact service queues |
159
+ | `entryPointList` | [`EntryPoint.ts`](../../EntryPoint.ts) | Fetch entry points |
160
+ | `addressBookEntries` | [`AddressBook.ts`](../../AddressBook.ts) | Fetch address book entries |
161
+
162
+ ---
163
+
164
+ ## Key Types
165
+
166
+ Types used by the config service, all defined in [`types.ts`](../types.ts):
167
+
168
+ | Type | Description |
169
+ |------|-------------|
170
+ | `Profile` | Final aggregated agent config returned by `getAgentConfig()` |
171
+ | `AgentResponse` | Raw response from `getUserUsingCI()` — agent metadata, teamIds, siteId, agentProfileId |
172
+ | `DesktopProfileResponse` | Desktop profile settings — layout, dial plan, login options |
173
+ | `TeamList` | Team record from API — `id`, `name`, `teamType`, `siteId`, `multiMediaProfileId` |
174
+ | `ListTeamsResponse` | Paginated wrapper around `TeamList[]` with `meta` for pagination |
175
+ | `OrgInfo` | Organization info — `tenantId`, timezone |
176
+ | `OrgSettings` | Org feature flags — `webRtcEnabled`, `sensitiveDataMaskingEnabled` |
177
+ | `TenantData` | Tenant-level config — inactivity timeout, `forceDefaultDn`, `outdialEnabled` |
178
+ | `SiteInfo` | Site config — `id`, `name`, `multimediaProfileId` |
179
+ | `URLMapping` | External URL mapping — `id`, `name`, `url` |
180
+ | `MultimediaProfileResponse` | Multimedia profile — channel capacities and settings |
181
+ | `AuxCode` | Auxiliary code record — `id`, `name`, `description`, `workTypeCode` |
182
+ | `ListAuxCodesResponse` | Paginated wrapper around `AuxCode[]` with `meta` |
183
+ | `DialPlanEntity` | Dial plan rule — regex pattern, prefix, strip digits |
184
+ | `Entity` | Basic entity info — `isSystem`, `name`, `id`, `description` |
185
+ | `WrapupData` | Wrap-up config — auto-wrapup settings, available wrapup codes |
186
+ | `OutdialAniParams` | Parameters for `getOutdialAniEntries()` — ANI ID, pagination, filtering |
187
+ | `Team` | Simplified team shape in `Profile` — `teamId`, `teamName`, `desktopLayoutId` |
188
+
189
+ ## Events (CC_EVENTS)
190
+
191
+ The config service defines event constants used throughout the SDK:
192
+
193
+ | Event Category | Examples |
194
+ |----------------|----------|
195
+ | Agent Events | WELCOME, AGENT_LOGOUT, AGENT_STATE_CHANGE |
196
+ | Task Events | AGENT_CONTACT, AGENT_OFFER_CONTACT, CONTACT_ENDED |
197
+ | Login Events | AGENT_STATION_LOGIN_SUCCESS, AGENT_STATION_LOGIN_FAILED |
198
+
199
+ See [`types.ts`](../types.ts) for complete list.
200
+
201
+ ---
202
+
203
+ ## Types Defined
204
+
205
+ Key types in `services/config/types.ts`:
206
+
207
+ | Type | Description |
208
+ |------|-------------|
209
+ | `Profile` | Complete AgentProfile |
210
+ | `CC_EVENTS` | All event constants |
211
+ | `CC_AGENT_EVENTS` | Agent-specific events |
212
+ | `CC_TASK_EVENTS` | Task-specific events |
213
+ | `AuxCode` | Idle/wrapup code definition |
214
+ | `Team` | Team configuration |
215
+ | `DesktopProfileResponse` | Desktop profile settings |
216
+ | `LoginOption` | Login types (BROWSER, EXTENSION, AGENT_DN) |
217
+
218
+ ---
219
+
220
+ ## Error Handling
221
+
222
+ All API methods within the config service throw errors on failure. Since `getAgentConfig` calls multiple sub-APIs (`getUserUsingCI`, `getOrgInfo`, `getOrganizationSetting`, `getTenantData`, `getAllAuxCodes`, `getDesktopProfileById`, `getAllTeams`, `getDialPlanData`, etc.) and awaits them via `Promise.all`, **a failure in any single sub-API will cause the entire AgentProfile fetch to fail**. There is no partial profile — either all data is successfully fetched and aggregated, or the operation throws.
223
+
224
+ ```typescript
225
+ try {
226
+ const profile = await this.services.config.getAgentConfig(orgId, agentId);
227
+ } catch (error) {
228
+ LoggerProxy.error(`Config fetch failed: ${error}`, {
229
+ module: 'ConfigService',
230
+ method: 'getAgentConfig',
231
+ });
232
+ throw error;
233
+ }
234
+ ```
235
+
236
+ ---
237
+
238
+ ## Usage in cc.ts
239
+
240
+ ```typescript
241
+ // In register() -> connectWebsocket()
242
+ const agentId = data.agentId;
243
+ const orgId = this.$webex.credentials.getOrgId();
244
+ this.agentConfig = await this.services.config.getAgentConfig(orgId, agentId);
245
+ ```
246
+
247
+ ---
248
+
249
+ ## Related
250
+
251
+ - [Root AGENTS.md](../../../../AGENTS.md) - Orchestrator and cross-scope rules
252
+ - [ARCHITECTURE.md](ARCHITECTURE.md) - Technical deep-dive
253
+ - [types.ts](../types.ts) - Type definitions
254
+ - [Util.ts](../Util.ts) - AgentProfile parsing utilities
255
+ - [constants.ts](../constants.ts) - API endpoints
@@ -0,0 +1,426 @@
1
+ # Config Service - Architecture
2
+
3
+ > **Legacy/reference-only.** Canonical SDD: [`config-spec.md`](config-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 agent configuration aggregation.
6
+
7
+ ---
8
+
9
+ ## Component Overview
10
+
11
+ | Component | File | Responsibility |
12
+ |-----------|------|----------------|
13
+ | `AgentConfigService` | `config/index.ts` | Main config service class |
14
+ | `parseAgentConfigs` | `config/Util.ts` | Profile parsing/aggregation |
15
+ | `endPointMap` | `config/constants.ts` | API endpoint definitions |
16
+ | `types` | `config/types.ts` | Types, events, interfaces |
17
+
18
+ ---
19
+
20
+ ## Data Flow
21
+
22
+ ```mermaid
23
+ sequenceDiagram
24
+ participant CC as ContactCenter
25
+ participant Cfg as AgentConfigService
26
+ participant WR as WebexRequest
27
+ participant API as Backend APIs
28
+
29
+ CC->>Cfg: getAgentConfig(orgId, agentId)
30
+
31
+ par Wave 1 — fire immediately
32
+ Cfg->>WR: getUserUsingCI
33
+ Cfg->>WR: getOrgInfo
34
+ Cfg->>WR: getOrganizationSetting
35
+ Cfg->>WR: getTenantData
36
+ Cfg->>WR: getURLMapping
37
+ Cfg->>WR: getAllAuxCodes
38
+ end
39
+
40
+ WR->>API: 6 parallel API calls
41
+ API-->>WR: Responses
42
+ Note over Cfg: await userConfigData (needed for wave 2)
43
+
44
+ par Wave 2 — depends on userConfigData
45
+ Cfg->>WR: getDesktopProfileById(agentProfileId)
46
+ Cfg->>WR: getSiteInfo(siteId)
47
+ Cfg->>WR: getAllTeams(teamIds)
48
+ end
49
+
50
+ Note over Cfg: getDialPlanData chained off agentProfile<br/>(fires only if dialPlanEnabled)
51
+
52
+ Note over Cfg: Single Promise.all() awaits all 9 promises<br/>(wave 1 + wave 2 + conditional dialPlan)
53
+
54
+ WR->>API: Remaining API calls
55
+ API-->>WR: Responses
56
+
57
+ Cfg->>Cfg: parseAgentConfigs(allData)
58
+ Cfg-->>CC: Profile
59
+ ```
60
+
61
+ ---
62
+
63
+ ## API Endpoints
64
+
65
+ The config service uses multiple API endpoints to fetch agent configuration data. These endpoints are defined in `constants.ts` and include:
66
+
67
+ - **Core user data**: User profile, agent settings, site information
68
+ - **Team & organization**: Team memberships, organization settings, tenant configuration
69
+ - **Auxiliary codes**: Idle codes and wrap-up codes with pagination
70
+ - **Communication settings**: Dial plans, URL mappings, multimedia profiles
71
+ - **Outbound features**: Queue lists, entry points, address books, outdial ANI entries
72
+
73
+ ### Endpoint Definitions
74
+
75
+ All endpoints are relative to the WCC API Gateway base URL. Query parameters like `agentView=true` filter responses to agent-relevant data.
76
+
77
+ **Example Usage:**
78
+ ```typescript
79
+ // Fetch user data
80
+ const resource = endPointMap.userByCI('org-123', 'agent-456');
81
+ // Result: "organization/org-123/user/by-ci-user-id/agent-456"
82
+
83
+ // Fetch teams with pagination and filtering
84
+ const resource = endPointMap.listTeams('org-123', 0, 100, ['team-1', 'team-2']);
85
+ // Result: "organization/org-123/v2/team?page=0&pageSize=100&filter=id=in=(team-1,team-2)"
86
+
87
+ // Fetch organization settings
88
+ const resource = endPointMap.orgSettings('org-123');
89
+ // Result: "organization/org-123/v2/organization-setting?agentView=true"
90
+ ```
91
+
92
+ **Full Endpoint Map:**
93
+ ```typescript
94
+ export const endPointMap = {
95
+ userByCI: (orgId: string, agentId: string) =>
96
+ `organization/${orgId}/user/by-ci-user-id/${agentId}`,
97
+
98
+ desktopProfile: (orgId: string, desktopProfileId: string) =>
99
+ `organization/${orgId}/agent-profile/${desktopProfileId}`,
100
+
101
+ multimediaProfile: (orgId: string, multimediaProfileId: string) =>
102
+ `organization/${orgId}/multimedia-profile/${multimediaProfileId}`,
103
+
104
+ listTeams: (orgId: string, page: number, pageSize: number, filter: string[]) =>
105
+ `organization/${orgId}/v2/team?page=${page}&pageSize=${pageSize}${
106
+ filter && filter.length > 0 ? `&filter=id=in=(${filter})` : ''
107
+ }`,
108
+
109
+ listAuxCodes: (orgId: string, page: number, pageSize: number, filter: string[], attributes: string[]) =>
110
+ `organization/${orgId}/v2/auxiliary-code?page=${page}&pageSize=${pageSize}${
111
+ filter && filter.length > 0 ? `&filter=id=in=(${filter})` : ''
112
+ }&attributes=${attributes}`,
113
+
114
+ orgInfo: (orgId: string) =>
115
+ `organization/${orgId}`,
116
+
117
+ orgSettings: (orgId: string) =>
118
+ `organization/${orgId}/v2/organization-setting?agentView=true`,
119
+
120
+ siteInfo: (orgId: string, siteId: string) =>
121
+ `organization/${orgId}/site/${siteId}`,
122
+
123
+ tenantData: (orgId: string) =>
124
+ `organization/${orgId}/v2/tenant-configuration?agentView=true`,
125
+
126
+ urlMapping: (orgId: string) =>
127
+ `organization/${orgId}/v2/org-url-mapping?sort=name,ASC`,
128
+
129
+ dialPlan: (orgId: string) =>
130
+ `organization/${orgId}/dial-plan?agentView=true`,
131
+
132
+ queueList: (orgId: string, queryParams: string) =>
133
+ `/organization/${orgId}/v2/contact-service-queue?${queryParams}`,
134
+
135
+ entryPointList: (orgId: string, queryParams: string) =>
136
+ `/organization/${orgId}/v2/entry-point?${queryParams}`,
137
+
138
+ addressBookEntries: (orgId: string, addressBookId: string, queryParams: string) =>
139
+ `/organization/${orgId}/v2/address-book/${addressBookId}/entry?${queryParams}`,
140
+
141
+ outdialAniEntries: (orgId: string, outdialANI: string, queryParams: string) =>
142
+ `organization/${orgId}/v2/outdial-ani/${outdialANI}/entry${
143
+ queryParams ? `?${queryParams}` : ''
144
+ }`,
145
+ };
146
+ ```
147
+
148
+ ---
149
+
150
+ ## Pagination Pattern
151
+
152
+ For endpoints with pagination (teams, aux codes):
153
+
154
+ ```typescript
155
+ import {DEFAULT_PAGE} from './constants'; // DEFAULT_PAGE = 0
156
+
157
+ public async getAllTeams(orgId, pageSize, filter): Promise<TeamList[]> {
158
+ let allTeams: TeamList[] = [];
159
+ let page = DEFAULT_PAGE;
160
+
161
+ // First request to get totalPages
162
+ const firstResponse = await this.getListOfTeams(orgId, page, pageSize, filter);
163
+ allTeams = allTeams.concat(firstResponse.data);
164
+ const totalPages = firstResponse.meta.totalPages;
165
+
166
+ // Parallel requests for remaining pages
167
+ const requests = [];
168
+ for (page = DEFAULT_PAGE + 1; page < totalPages; page += 1) {
169
+ requests.push(this.getListOfTeams(orgId, page, pageSize, filter));
170
+ }
171
+
172
+ const responses = await Promise.all(requests);
173
+ for (const response of responses) {
174
+ allTeams = allTeams.concat(response.data);
175
+ }
176
+
177
+ return allTeams;
178
+ }
179
+ ```
180
+
181
+ ---
182
+
183
+ ## Profile Parsing
184
+
185
+ `parseAgentConfigs` in Util.ts combines all data into a unified `Profile` object. See [types.ts](../types.ts) for full type definitions.
186
+
187
+ ### API Response Structures
188
+
189
+ The service fetches data from multiple APIs with these response structures:
190
+
191
+ | API Method | Response Type | Key Fields | Usage |
192
+ |------------|---------------|------------|-------|
193
+ | `getUserUsingCI` | `AgentResponse` | `ciUserId`, `id`, `firstName`, `lastName`, `email`, `teamIds`, `agentProfileId`, `siteId` | Primary agent identity and profile references |
194
+ | `getDesktopProfileById` | `DesktopProfileResponse` | `dialPlanEnabled`, `autoAnswer`, `accessWrapUpCode`, `wrapUpCodes`, `accessIdleCode`, `idleCodes`, `loginVoiceOptions` | Agent desktop settings and feature enablement |
195
+ | `getAllTeams` | `TeamList[]` | `id`, `name`, `type`, `channelMap` (+ 10 more fields) | Full team details with channel configurations |
196
+ | `getTenantData` | `TenantData` | `outdialEnabled`, `forceDefaultDn`, `privacyShieldVisible`, `timeoutDesktopInactivityEnabled` | Tenant-level feature flags |
197
+ | `getOrgInfo` | `OrgInfo` | `tenantId`, `timezone` | Organization metadata |
198
+ | `getAllAuxCodes` | `AuxCode[]` | `id`, `name`, `workTypeCode`, `active`, `isSystemCode`, `defaultCode` | Auxiliary codes for idle/wrap-up states |
199
+ | `getOrganizationSetting` | `OrgSettings` | `webRtcEnabled`, `maskSensitiveData`, `campaignManagerEnabled` | Organization-level feature flags |
200
+ | `getDialPlanData` | `DialPlanEntity[]` | `id`, `name`, `regularExpression`, `prefix`, `strippedChars` | Dial plan rules for outbound calling |
201
+ | `getURLMapping` | `URLMapping[]` | `name`, `url` | External service URL mappings |
202
+ | `getSiteInfo` | `SiteInfo` | Site-specific configuration | Site details |
203
+
204
+ These responses are parsed and aggregated into a single `Profile` object by the `parseAgentConfigs` function.
205
+
206
+ ### Profile Aggregation Function
207
+
208
+ ```typescript
209
+ // See full implementation in Util.ts
210
+ function parseAgentConfigs(profileData: {
211
+ userData: AgentResponse; // See types.ts:AgentResponse
212
+ teamData: Team[]; // NOTE: Declared as Team[] (teamId, teamName) but receives TeamList[] (id, name, + 12 more fields) at runtime
213
+ tenantData: TenantData; // See types.ts:TenantData
214
+ orgInfoData: OrgInfo; // See types.ts:OrgInfo
215
+ auxCodes: AuxCode[]; // See types.ts:AuxCode
216
+ orgSettingsData: OrgSettings; // See types.ts:OrgSettings
217
+ agentProfileData: DesktopProfileResponse; // See types.ts:DesktopProfileResponse
218
+ dialPlanData: DialPlanEntity[]; // See types.ts:DialPlanEntity
219
+ urlMapping: URLMapping[]; // See types.ts:URLMapping
220
+ multimediaProfileId: string;
221
+ }): Profile { // See types.ts:Profile
222
+ const { userData, teamData, tenantData, orgInfoData, auxCodes,
223
+ orgSettingsData, agentProfileData, dialPlanData, urlMapping } = profileData;
224
+
225
+ // Aux code filtering via getFilterAuxCodes():
226
+ // - checks auxCode.active
227
+ // - checks specificCodes access level (ALL → no filter, SPECIFIC → include list)
228
+ // - maps to Entity {id, name, isSystem, isDefault}
229
+ const wrapupCodes = getFilterAuxCodes(auxCodes, WRAP_UP_CODE,
230
+ agentProfileData.accessWrapUpCode === 'ALL' ? [] : agentProfileData.wrapUpCodes);
231
+ const idleCodes = getFilterAuxCodes(auxCodes, IDLE_CODE,
232
+ agentProfileData.accessIdleCode === 'ALL' ? [] : agentProfileData.idleCodes);
233
+
234
+ // Hardcoded "Available" state always appended to idle codes
235
+ idleCodes.push({ id: '0', name: 'Available', isSystem: false, isDefault: false });
236
+
237
+ return {
238
+ agentId: userData.ciUserId, // NOTE: uses ciUserId for agent identification
239
+ analyserUserId: userData.id, // NOTE: userData.id is used for analytics/reporting
240
+ agentName: `${userData.firstName} ${userData.lastName}`,
241
+ teams: teamData, // NOTE: Raw TeamList[] passed directly without mapping
242
+ idleCodes, // NOTE: Filtered via getFilterAuxCodes() + hardcoded "Available" state
243
+ wrapupCodes, // NOTE: Filtered via getFilterAuxCodes()
244
+ webRtcEnabled: orgSettingsData.webRtcEnabled,
245
+ loginVoiceOptions: agentProfileData.loginVoiceOptions ?? [],
246
+ enterpriseId: orgInfoData.tenantId,
247
+ tenantTimezone: orgInfoData.timezone,
248
+ multimediaProfileId: profileData.multimediaProfileId,
249
+ // ... 30+ more fields — see Util.ts:184-258 for full implementation
250
+ };
251
+ }
252
+ ```
253
+
254
+ ---
255
+
256
+ ## Error Handling
257
+
258
+ Each method follows consistent error handling:
259
+
260
+ ```typescript
261
+ public async getUserUsingCI(orgId: string, agentId: string): Promise<AgentResponse> {
262
+ LoggerProxy.info('Fetching user data using CI', {
263
+ module: CONFIG_FILE_NAME,
264
+ method: METHODS.GET_USER_USING_CI,
265
+ });
266
+
267
+ try {
268
+ const resource = endPointMap.userByCI(orgId, agentId);
269
+ const response = await this.webexReq.request({
270
+ service: WCC_API_GATEWAY,
271
+ resource,
272
+ method: HTTP_METHODS.GET,
273
+ });
274
+
275
+ if (response.statusCode !== 200) {
276
+ throw new Error(`API call failed with ${response.statusCode}`);
277
+ }
278
+
279
+ LoggerProxy.log('getUserUsingCI api success.', {
280
+ module: CONFIG_FILE_NAME,
281
+ method: METHODS.GET_USER_USING_CI,
282
+ });
283
+
284
+ return Promise.resolve(response.body);
285
+ } catch (error) {
286
+ LoggerProxy.error(`getUserUsingCI API call failed with ${error}`, {
287
+ module: CONFIG_FILE_NAME,
288
+ method: METHODS.GET_USER_USING_CI,
289
+ });
290
+ throw error;
291
+ }
292
+ }
293
+ ```
294
+
295
+ ---
296
+
297
+ ## Troubleshooting
298
+
299
+ ### Common Issues and Log Patterns
300
+
301
+ #### Issue: Profile incomplete or getAgentConfig fails
302
+
303
+ **Cause**: One of the parallel API calls failed (network error, 401/403/404/500 response)
304
+
305
+ **Log patterns to search for:**
306
+ ```typescript
307
+ // General config failure
308
+ "getAgentConfig call failed"
309
+ "module": "config/index.ts", "method": "getAgentConfig"
310
+
311
+ // Specific API method failures
312
+ "getUserUsingCI API call failed"
313
+ "getDesktopProfileById API call failed"
314
+ "getAllTeams API call failed"
315
+ "getAllAuxCodes API call failed"
316
+
317
+ // Look for HTTP error codes
318
+ "API call failed with 401" // Authentication
319
+ "API call failed with 403" // Authorization
320
+ "API call failed with 404" // Not found
321
+ "API call failed with 500" // Server error
322
+ ```
323
+
324
+ **Solution**:
325
+ 1. Check logs for specific API that failed
326
+ 2. Verify orgId and agentId are correct
327
+ 3. Ensure authentication tokens are valid
328
+ 4. Check network connectivity to WCC API Gateway
329
+
330
+ #### Issue: Empty teams or aux codes
331
+
332
+ **Cause**: Pagination not completing or filter parameters incorrect
333
+
334
+ **Log patterns:**
335
+ ```typescript
336
+ "getAllTeams API call failed"
337
+ "getAllAuxCodes API call failed"
338
+ "method": "getListOfTeams"
339
+ "method": "getListOfAuxCodes"
340
+ ```
341
+
342
+ **Solution**:
343
+ 1. Check `totalPages` in first response
344
+ 2. Verify filter array contains valid team/aux code IDs
345
+ 3. Check if pageSize is appropriate (default: 100)
346
+ 4. Ensure all pages are fetched in Promise.all()
347
+
348
+ #### Issue: WebRTC or other features not enabled
349
+
350
+ **Cause**: Organization or tenant settings have feature disabled
351
+
352
+ **Log patterns:**
353
+ ```typescript
354
+ "getOrganizationSetting api success"
355
+ "getTenantData api success"
356
+ ```
357
+
358
+ **Solution**:
359
+ 1. Check `orgSettingsData.webRtcEnabled` in response
360
+ 2. Check `tenantData.outdialEnabled` for outbound features
361
+ 3. Verify feature is enabled in admin portal settings
362
+ 4. Confirm agentProfileData has correct feature flags
363
+
364
+ #### Issue: Missing dial plan data
365
+
366
+ **Cause**: `dialPlanEnabled` is false in desktop profile
367
+
368
+ **Solution**:
369
+ 1. Check `agentProfileData.dialPlanEnabled` value
370
+ 2. Verify dial plans are assigned in agent profile configuration
371
+ 3. Note: dial plan fetch only happens if `dialPlanEnabled === true`
372
+
373
+ #### Issue: Incorrect auxiliary code filtering
374
+
375
+ **Cause**: Access level set to 'SPECIFIC' but missing code IDs
376
+
377
+ **Log patterns:**
378
+ ```typescript
379
+ "method": "getFilterAuxCodes"
380
+ ```
381
+
382
+ **Solution**:
383
+ 1. Check `agentProfileData.accessWrapUpCode` (should be 'ALL' or 'SPECIFIC')
384
+ 2. Check `agentProfileData.accessIdleCode`
385
+ 3. If 'SPECIFIC', verify `wrapUpCodes` and `idleCodes` arrays contain valid IDs
386
+ 4. Ensure aux codes have `active: true` status
387
+ 5. Note: "Available" state is always appended to idle codes
388
+
389
+ ---
390
+
391
+ ## Types and Events
392
+
393
+ The config service defines comprehensive TypeScript types for all data structures. See [types.ts](../types.ts) for complete definitions.
394
+
395
+ ### Core Types
396
+
397
+ **Configuration Types:**
398
+ - `Profile` - Unified agent profile after aggregation
399
+ - `AgentResponse` - User data from userByCI endpoint
400
+ - `DesktopProfileResponse` - Agent desktop settings
401
+ - `TeamList` - Team data with full details (id, name, type, channelMap, etc.)
402
+ - `Team` - Simplified team reference (teamId, teamName, desktopLayoutId)
403
+ - `AuxCode` - Auxiliary code definition
404
+ - `Entity` - Filtered code entity (used for idle/wrapup codes in Profile)
405
+
406
+ **Organization Types:**
407
+ - `OrgInfo` - Organization metadata
408
+ - `OrgSettings` - Organization-level feature flags
409
+ - `TenantData` - Tenant configuration and feature enablement
410
+ - `SiteInfo` - Site-specific configuration
411
+
412
+ **Communication Types:**
413
+ - `DialPlanEntity` - Dial plan rule definition
414
+ - `URLMapping` - External service URL mapping
415
+ - `MultimediaProfile` - Multimedia profile configuration
416
+
417
+ **Note:** The config service itself does not emit events. For agent and task events, see the Agent and Task services. Event constants are defined in [types.ts](../types.ts) under `CC_AGENT_EVENTS` and `CC_TASK_EVENTS`.
418
+
419
+ ---
420
+
421
+ ## Related Files
422
+
423
+ - [index.ts](../index.ts) - Service implementation with all API methods
424
+ - [types.ts](../types.ts) - Complete type definitions and event constants
425
+ - [Util.ts](../Util.ts) - Profile parsing utilities (parseAgentConfigs, getFilterAuxCodes, etc.)
426
+ - [constants.ts](../constants.ts) - API endpoints, default values, and method names