@webex/contact-center 3.12.0-next.84 → 3.12.0-next.85

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 (47) hide show
  1. package/.sdd/manifest.json +876 -0
  2. package/AGENTS.md +65 -409
  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 +25 -18
  8. package/ai-docs/REVIEW_CHECKLIST.md +41 -0
  9. package/ai-docs/RULES.md +187 -198
  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/templates/README.md +1 -1
  21. package/ai-docs/templates/new-method/04-validation.md +1 -1
  22. package/ai-docs/templates/new-service/05-validation.md +1 -1
  23. package/dist/webex.js +1 -1
  24. package/package.json +1 -1
  25. package/src/metrics/ai-docs/AGENTS.md +2 -0
  26. package/src/metrics/ai-docs/ARCHITECTURE.md +2 -0
  27. package/src/metrics/ai-docs/metrics-spec.md +854 -0
  28. package/src/services/agent/ai-docs/AGENTS.md +3 -1
  29. package/src/services/agent/ai-docs/ARCHITECTURE.md +2 -0
  30. package/src/services/agent/ai-docs/agent-spec.md +504 -0
  31. package/src/services/ai-docs/AGENTS.md +4 -2
  32. package/src/services/ai-docs/services-spec.md +492 -0
  33. package/src/services/config/ai-docs/AGENTS.md +3 -1
  34. package/src/services/config/ai-docs/ARCHITECTURE.md +2 -0
  35. package/src/services/config/ai-docs/config-spec.md +669 -0
  36. package/src/services/core/ai-docs/AGENTS.md +4 -2
  37. package/src/services/core/ai-docs/ARCHITECTURE.md +2 -0
  38. package/src/services/core/ai-docs/core-spec.md +783 -0
  39. package/src/services/task/ai-docs/AGENTS.md +2 -0
  40. package/src/services/task/ai-docs/ARCHITECTURE.md +11 -2
  41. package/src/services/task/ai-docs/task-spec.md +1319 -0
  42. package/src/services/task/state-machine/ai-docs/AGENTS.md +38 -75
  43. package/src/services/task/state-machine/ai-docs/ARCHITECTURE.md +6 -4
  44. package/src/services/task/state-machine/ai-docs/task-state-machine-spec.md +2115 -0
  45. package/src/utils/AGENTS.md +3 -1
  46. package/src/utils/ai-docs/utils-spec.md +381 -0
  47. package/umd/contact-center.min.js +2 -2
@@ -0,0 +1,492 @@
1
+ # Services — SPEC
2
+
3
+ > Start here → root [`AGENTS.md`](../../../AGENTS.md) · router [`SPEC_INDEX.md`](../../../ai-docs/SPEC_INDEX.md) · system [`ARCHITECTURE.md`](../../../ai-docs/ARCHITECTURE.md). This is the module's canonical specification.
4
+
5
+ ## Metadata
6
+
7
+ | Field | Value |
8
+ |---|---|
9
+ | Module id | `services` |
10
+ | Source path(s) | `src/services` |
11
+ | Doc kind | Module spec |
12
+ | Coverage score | Partial (manifest-authoritative); 15/15 required document fields present |
13
+ | Generated from | `module-spec` @ SDLC template library `0.2.1` |
14
+ | generated_by / approved_by / updated_at | Codex generator / developer-approved follow-up review remediation / 2026-07-21 |
15
+ | Validation status | Follow-up validation passed (independent Claude fallback, 2026-07-21); coverage remains Partial |
16
+
17
+ ## Evidence Rules
18
+ Every requirement cites stable source and test file paths. Code/tests are the behavioral referee; routed source text supplies explicit intent and rationale. Missing or contradictory evidence blocks promotion.
19
+
20
+ ## Source Material Register
21
+ | Source material | Scope | Decision | Detail location or disposition |
22
+ |---|---|---|---|
23
+ | Reviewed prior module guides and architecture material | overview / architecture / API / tests | used and code-checked | Content is placed by meaning throughout this specification; exact routing remains in the manifest. |
24
+
25
+ ## Overview
26
+ Services is one of nine confirmed Contact Center SDK modules. Own composition and bootstrap order for backend request, realtime, data, and WebRTC service collaborators. Existing reviewed documentation is migrated by meaning and code/tests remain the behavioral referee.
27
+
28
+ The `src/services/` directory is the service layer of the `@webex/contact-center` SDK. It sits between the public plugin class (`cc.ts`) and the backend APIs/WebSocket. Every backend interaction — HTTP requests, WebSocket messages, agent operations, task lifecycle, configuration fetching — flows through this layer.
29
+
30
+ - Understanding service composition and which service owns which responsibility
31
+
32
+ - Determining the correct instantiation/bootstrap order for services
33
+
34
+ - Tracing request flow from `cc.ts` through services to the backend
35
+
36
+ - Choosing between AqmReqs and direct REST patterns for a new method
37
+
38
+ - Adding a new paginated data service (AddressBook/Queue/EntryPoint pattern) or a direct REST service such as UserPreference
39
+
40
+ - Adding a new AqmReqs method to agent, task, or dialer factories
41
+
42
+ - Routing to the correct service-level docs for task/agent/config/core changes
43
+
44
+ - Clarifying what the Services singleton creates vs what `cc.ts` creates
45
+
46
+ | Capability | Owner | Description |
47
+ |---|---|---|
48
+ | **Service Singleton** | [`index.ts`](../index.ts) | Central `Services` class that instantiates and provides access to all service modules via `Services.getInstance()` |
49
+ | **Agent Operations** | [`agent/`](../agent/index.ts) | Station login/logout, state changes, buddy agents — uses AqmReqs factory pattern |
50
+ | **Task Management** | [`task/`](../task/TaskManager.ts) | Task lifecycle (accept, hold, transfer, conference, wrapup), Task state machine, contact operations, outbound dialing |
51
+ | **Configuration** | [`config/`](../config/index.ts) | Agent profile aggregation from 8+ API endpoints, org settings, teams, aux codes, dial plans |
52
+ | **Core Infrastructure** | [`core/`](../core/WebexRequest.ts) | HTTP requests (`WebexRequest`), WebSocket management (`WebSocketManager`), connection lifecycle (`ConnectionService`), AQM request/response correlation (`AqmReqs`), error handling (`Utils`, `Err`) |
53
+ | **Data Services** | [`AddressBook.ts`](../AddressBook.ts), [`Queue.ts`](../Queue.ts), [`EntryPoint.ts`](../EntryPoint.ts) | Standalone REST-based data services with pagination and caching for address books, queues, and entry points |
54
+ | **User Preferences** | [`UserPreference.ts`](../UserPreference.ts) | Direct REST CRUD service exposed as `cc.userPreference`; it resolves the default user from agent configuration and does not use PageCache |
55
+ | **Utilities** | [`src/utils/PageCache.ts`](../../utils/PageCache.ts) | Shared `PageCache<T>` generic class for pagination caching, plus `BaseSearchParams`, `PaginatedResponse`, and `PaginationMeta` types used by all data services |
56
+ | **WebRTC Calling** | [`WebCallingService.ts`](../WebCallingService.ts) | Browser-based voice calling via `@webex/calling`, line registration, call answer/mute/decline |
57
+
58
+ Each service folder contains its own `ai-docs/` with detailed documentation. **Always load the relevant service docs before making changes.**
59
+
60
+ | Service | Scope / Keywords | AGENTS.md | ARCHITECTURE.md |
61
+ |---|---|---|---|
62
+ | **Agent** | login, logout, state change, buddy agents, station, RONA | [`agent/ai-docs/agent-spec.md`](../agent/ai-docs/agent-spec.md) | [`agent/ai-docs/agent-spec.md`](../agent/ai-docs/agent-spec.md) |
63
+ | **Task** | task, hold, transfer, conference, wrapup, outdial, consult, accept, decline, state machine, XState, task states, guards, actions | [`task/ai-docs/task-spec.md`](../task/ai-docs/task-spec.md) | [`task/ai-docs/task-spec.md`](../task/ai-docs/task-spec.md) |
64
+ | **Config** | profile, register, teams, aux codes, desktop profile, org settings, dial plan | [`config/ai-docs/config-spec.md`](../config/ai-docs/config-spec.md) | [`config/ai-docs/config-spec.md`](../config/ai-docs/config-spec.md) |
65
+ | **Core** | websocket, HTTP, connection, reconnect, aqm, utils, errors, keepalive | [`core/ai-docs/core-spec.md`](../core/ai-docs/core-spec.md) | [`core/ai-docs/core-spec.md`](../core/ai-docs/core-spec.md) |
66
+
67
+ > **Note**: The task state machine (`task/state-machine/`) is part of the Task service, not a separate service. Its dedicated docs live at [`task/state-machine/ai-docs/task-state-machine-spec.md`](../task/state-machine/ai-docs/task-state-machine-spec.md) and [`ARCHITECTURE.md`](../task/state-machine/ai-docs/task-state-machine-spec.md). Load these when working on state transitions, guards, or actions.
68
+
69
+ **Paginated data services** (AddressBook, Queue, EntryPoint) do not have dedicated ai-docs. Read their source files directly — they follow shared REST/pagination/caching patterns documented in [`ai-docs/patterns/typescript-patterns.md`](../../../ai-docs/patterns/typescript-patterns.md). `UserPreference` is also a direct REST service, but it has CRUD semantics and does not use their PageCache pattern.
70
+
71
+ **WebCallingService** also has no dedicated ai-docs, but it follows a different pattern: EventEmitter-based call lifecycle orchestration around `@webex/calling` (`createClient`, line registration/deregistration, `ICall` events), `callTaskMap` tracking, and async registration flows with timeout handling. Read [`WebCallingService.ts`](../WebCallingService.ts) directly when changing browser calling behavior.
72
+
73
+ The `ContactCenter` plugin class (`cc.ts`) is the **only public entry point**. It delegates all backend work to the services layer:
74
+
75
+ ```text
76
+ ContactCenter (cc.ts) — public API surface
77
+
78
+ ├── WebexRequest.getInstance({webex}) ← initialized FIRST (singleton)
79
+ ├── Services.getInstance({webex, connectionConfig}) ← initialized SECOND (singleton)
80
+ │ │
81
+ │ ├── webSocketManager ← primary Contact Center WebSocket transport
82
+ │ ├── rtdWebSocketManager ← separate RTD/transcription WebSocket transport
83
+ │ ├── AqmReqs ← HTTP request + WebSocket notification correlation
84
+ │ ├── ConnectionService ← WebSocket lifecycle, reconnection, keepalive
85
+ │ ├── AgentConfigService (config) ← profile aggregation via REST APIs
86
+ │ ├── routingAgent (agent) ← agent operations via AqmReqs factory
87
+ │ ├── routingContact (contact) ← task/contact operations via AqmReqs factory
88
+ │ └── aqmDialer (dialer) ← outbound dialing via AqmReqs factory
89
+
90
+ ├── TaskManager ← task lifecycle, created in the Webex READY callback
91
+ ├── WebCallingService ← WebRTC calling, created in READY (line registration remains conditional)
92
+ ├── ApiAIAssistant ← AI transcript/suggestion API, created in READY
93
+ ├── AddressBook ← REST data service, created in READY
94
+ ├── EntryPoint ← REST data service, created in READY
95
+ ├── Queue ← REST data service, created in READY
96
+ ├── UserPreference ← REST user-preference CRUD service, created in READY
97
+ └── MetricsManager.getInstance({webex}) ← telemetry singleton
98
+ ```
99
+
100
+ ## Purpose / Responsibility
101
+ Own composition and bootstrap order for backend request, realtime, data, and WebRTC service collaborators.
102
+
103
+ ## Stack
104
+ TypeScript 5.4, singleton composition, REST/WebSocket/AQM integrations, @webex/calling, Jest 27.
105
+
106
+ ## Folder / Package Structure
107
+ ```text
108
+ src/services/
109
+ ├── AddressBook.ts
110
+ ├── ApiAiAssistant.ts
111
+ ├── EntryPoint.ts
112
+ ├── Queue.ts
113
+ ├── UserPreference.ts
114
+ ├── WebCallingService.ts
115
+ ├── agent/
116
+ ├── config/
117
+ ├── constants.ts
118
+ ├── core/
119
+ ├── index.ts
120
+ ├── task/
121
+ ```
122
+
123
+ ```text
124
+ src/services/
125
+ ├── index.ts # Services singleton — composes all services
126
+ ├── constants.ts # Shared constants (gateway id, API paths, WebRTC domains/prefixes, timeout, method-name constants)
127
+ ├── ai-docs/
128
+ │ └── AGENTS.md # Preserved legacy migration source (non-canonical)
129
+
130
+ ├── agent/ # Agent operations service
131
+ │ ├── index.ts # routingAgent factory — stationLogin, stateChange, logout, buddyAgents
132
+ │ ├── types.ts # Agent types: StateChange, Logout, AGENT_EVENTS, LoginOption
133
+ │ └── ai-docs/ # Agent-specific documentation
134
+ │ ├── AGENTS.md
135
+ │ └── ARCHITECTURE.md
136
+
137
+ ├── task/ # Task management service
138
+ │ ├── TaskManager.ts # Task lifecycle manager — creates/destroys Task instances
139
+ │ ├── Task.ts # Individual task — hold, transfer, conference, wrapup
140
+ │ ├── TaskFactory.ts # Creates Task with config flags
141
+ │ ├── contact.ts # routingContact factory — task operations via AqmReqs
142
+ │ ├── dialer.ts # aqmDialer factory — outbound dialing
143
+ │ ├── AutoWrapup.ts # Auto wrapup timer handler
144
+ │ ├── TaskUtils.ts # Task utility functions
145
+ │ ├── taskDataNormalizer.ts # Normalizes task data from events
146
+ │ ├── types.ts # Task types: ITask, TASK_EVENTS, TaskResponse
147
+ │ ├── constants.ts # Task constants
148
+ │ ├── voice/ # Voice-specific task handling
149
+ │ │ ├── Voice.ts # Voice task operations
150
+ │ │ └── WebRTC.ts # WebRTC-specific voice operations
151
+ │ ├── digital/ # Digital channel task handling
152
+ │ │ └── Digital.ts # Digital task operations
153
+ │ ├── state-machine/ # XState-based task state machine
154
+ │ │ ├── TaskStateMachine.ts # State machine definition
155
+ │ │ ├── index.ts # Barrel export for state machine public API
156
+ │ │ ├── constants.ts # TaskState, TaskEvent enums
157
+ │ │ ├── types.ts # TaskContext type
158
+ │ │ ├── guards.ts # State transition guards
159
+ │ │ ├── actions.ts # State transition actions
160
+ │ │ ├── uiControlsComputer.ts # Computes UI controls from state
161
+ │ │ └── ai-docs/ # State machine documentation
162
+ │ │ ├── AGENTS.md
163
+ │ │ └── ARCHITECTURE.md
164
+ │ └── ai-docs/ # Task-specific documentation
165
+ │ ├── AGENTS.md
166
+ │ └── ARCHITECTURE.md
167
+
168
+ ├── config/ # Configuration service
169
+ │ ├── index.ts # AgentConfigService — getAgentConfig(), profile aggregation
170
+ │ ├── Util.ts # parseAgentConfigs, getFilterAuxCodes, helper functions
171
+ │ ├── types.ts # CC_EVENTS, Profile, CC_AGENT_EVENTS, CC_TASK_EVENTS
172
+ │ ├── constants.ts # endPointMap (API URL builders), pagination defaults
173
+ │ └── ai-docs/ # Config-specific documentation
174
+ │ ├── AGENTS.md
175
+ │ └── ARCHITECTURE.md
176
+
177
+ ├── core/ # Core infrastructure
178
+ │ ├── WebexRequest.ts # HTTP client singleton — request(), uploadLogs()
179
+ │ ├── aqm-reqs.ts # AqmReqs — HTTP request + WebSocket notification correlation
180
+ │ ├── Utils.ts # getErrorDetails, generateTaskErrorObject, isValidDialNumber
181
+ │ ├── Err.ts # Err.Details error class with structured metadata
182
+ │ ├── GlobalTypes.ts # Msg<T>, Failure, AugmentedError, TaskError
183
+ │ ├── types.ts # Req, Conf, Res types for AqmReqs
184
+ │ ├── constants.ts # Core constants
185
+ │ ├── websocket/
186
+ │ │ ├── WebSocketManager.ts # WebSocket connection handler
187
+ │ │ ├── connection-service.ts # Connection lifecycle, reconnection, keepalive
188
+ │ │ └── types.ts # WebSocket types
189
+ │ └── ai-docs/ # Core-specific documentation
190
+ │ ├── AGENTS.md
191
+ │ └── ARCHITECTURE.md
192
+
193
+ ├── AddressBook.ts # Address book entries — getEntries() with pagination/cache
194
+ ├── EntryPoint.ts # Entry points — getEntryPoints() with pagination/cache
195
+ ├── Queue.ts # Queues — getQueues() with pagination/cache
196
+ └── WebCallingService.ts # WebRTC calling — register/deregister line, answer/mute/decline
197
+ ```
198
+
199
+ Note: The `src/utils/` folder (sibling to `src/services/`) contains shared utilities like [`PageCache.ts`](../../utils/PageCache.ts) which provides generic pagination caching with `BaseSearchParams`, `PaginatedResponse`, and `PaginationMeta` types used by all data services.
200
+
201
+ Use [`constants.ts`](../constants.ts) as the canonical source for service-level naming and routing constants:
202
+
203
+ - `WCC_API_GATEWAY` — service identifier used by `WebexRequest` calls
204
+
205
+ - `SUBSCRIBE_API`, `LOGIN_API`, `STATE_CHANGE_API` — common API path constants
206
+
207
+ - `WEB_RTC_PREFIX` — path prefix for WebRTC-related endpoints
208
+
209
+ - `WEBSOCKET_EVENT_TIMEOUT` — defined as `20000` ms in `src/services/constants.ts` but not used by AqmReqs; active AQM correlation defaults to Core's `TIMEOUT_REQ = 20000`
210
+
211
+ - `DEFAULT_RTMS_DOMAIN`, `WCC_CALLING_RTMS_DOMAIN` — RTMS/WebRTC domain constants
212
+
213
+ - `METHODS` — method name constants used by `WebCallingService`
214
+
215
+ ## Key Files (source of truth)
216
+ | File | Holds |
217
+ |---|---|
218
+ | `src/services/index.ts` | Authoritative Services implementation or contract source. |
219
+ | `src/services/constants.ts` | Authoritative Services implementation or contract source. |
220
+ | `src/services/AddressBook.ts` | Authoritative Services implementation or contract source. |
221
+ | `src/services/EntryPoint.ts` | Authoritative Services implementation or contract source. |
222
+ | `src/services/Queue.ts` | Authoritative Services implementation or contract source. |
223
+ | `src/services/UserPreference.ts` | Direct REST user-preference CRUD exposed through `cc.userPreference`. |
224
+ | `src/services/WebCallingService.ts` | Authoritative Services implementation or contract source. |
225
+
226
+ ## Public Surface
227
+ | Contract ID | Type | Surface | Purpose | Compatibility / deprecation | Schema / detail link | Root index |
228
+ |---|---|---|---|---|---|---|
229
+ | `services.surface` | SDK / event / internal API | Internal `Services.getInstance()` composition root plus data-service and calling collaborators consumed by `ContactCenter`. | Stable module consumption boundary. | Additive changes by default; breaking package exports require a major-version transition. | `src/services/index.ts` | `../../../ai-docs/CONTRACTS.md` |
230
+ | `services.user-preference` | SDK data API | `UserPreference` and `cc.userPreference`. | Direct REST CRUD for user preferences; separate from PageCache-based pagination services. | Additive semver-public API; removals or signature changes are breaking. | `src/services/UserPreference.ts`, `src/services/config/types.ts` | `../../../ai-docs/CONTRACTS.md` |
231
+
232
+ Compatibility notes:
233
+ - Do not remove or reinterpret exported symbols/events without a documented consumer migration.
234
+
235
+ ## Requires (dependencies)
236
+ - Host Webex SDK READY lifecycle and authenticated request facilities.
237
+ - `WebexRequest` initialized by ContactCenter before `Services.getInstance()`.
238
+ - WCC REST endpoints plus primary Contact Center and RTD WebSocket transports.
239
+ - `ApiAIAssistant`, `WebCallingService`, `MetricsManager`, TaskManager, and PageCache-consuming data services constructed by ContactCenter.
240
+ - `@webex/calling` for browser calling.
241
+
242
+ ```text
243
+ ContactCenter READY callback
244
+ ├── WebexRequest.getInstance(webex)
245
+ ├── Services.getInstance(webex, connectionConfig)
246
+ │ ├── webSocketManager + rtdWebSocketManager
247
+ │ ├── AqmReqs(primary WebSocket)
248
+ │ ├── config + agent + contact + dialer
249
+ │ └── ConnectionService(primary WebSocket)
250
+ ├── WebCallingService + ApiAIAssistant + MetricsManager
251
+ ├── TaskManager(ApiAIAssistant, contact, calling, primary WS, RTD WS)
252
+ └── AddressBook + EntryPoint + Queue + UserPreference
253
+ ```
254
+
255
+ ## Requirements
256
+ | ID | WHAT | WHY | Source Evidence | Test / Example Evidence | Assumptions / Gaps | Confidence |
257
+ |---|---|---|---|---|---|---|
258
+ | SERVICES-R-001 | Build the Services singleton with agent/config/contact/dialer, two WebSocket managers, AqmReqs, and ConnectionService after WebexRequest is initialized. | Every AQM and transport collaborator depends on one shared authenticated host and primary message stream. | `src/services/index.ts` | `test/unit/spec/cc.ts` | None; source and test evidence rechecked during the 2026-07-09 remediation; independent document revalidation pending. | PRESENT |
259
+ | SERVICES-R-002 | Keep direct REST services, including UserPreference, separate from AQM request factories. | Direct data/config/user-preference calls complete from HTTP while AQM operations require correlated WebSocket completion. | `src/services/index.ts`, `src/services/UserPreference.ts` | `test/unit/spec/services/AddressBook.ts`, `test/unit/spec/services/UserPreference.ts` | None; UserPreference's direct-REST/no-PageCache behavior was independently validated by claude-code on 2026-07-15. | PRESENT |
260
+ | SERVICES-R-003 | Construct TaskManager, UserPreference, and other non-Services collaborators in ContactCenter's READY callback, not in `register()`. | Registration is a connection boundary; changing construction timing can duplicate listeners or access uninitialized host services. | `src/cc.ts` | `test/unit/spec/cc.ts`, `test/unit/spec/services/UserPreference.ts` | None; READY-time UserPreference ownership was independently validated by claude-code on 2026-07-15. | PRESENT |
261
+ | SERVICES-R-004 | Pass ApiAIAssistant, contact routing, WebCallingService, primary WebSocket, and RTD WebSocket into TaskManager. | Voice, task, transcript, and suggestion behavior depend on the complete collaborator set. | `src/cc.ts` | `test/unit/spec/services/task/TaskManager.ts` | None; source and test evidence rechecked during the 2026-07-09 remediation; independent document revalidation pending. | PRESENT |
262
+ | SERVICES-R-005 | Inherit authenticated request identity from the host Webex SDK through Core/WebexRequest; Services must not store, parse, or refresh credentials. | One host-owned authentication boundary avoids duplicate token handling and credential leakage across composed services. | `src/services/index.ts`, `src/services/core/WebexRequest.ts` | `test/unit/spec/services/core/WebexRequest.ts` | None; authentication ownership is explicit. | PRESENT |
263
+ | SERVICES-R-006 | Treat Services composition as unconditionally created by the ContactCenter READY callback; Services owns no rollout or feature-flag decision. | Capability flags belong to the consuming config/task/calling collaborators, so the composition root must not silently gate construction. | `src/services/index.ts`, `src/cc.ts` | `test/unit/spec/cc.ts` | None; rollout applicability is explicitly N/A for Services. | PRESENT |
264
+
265
+ ## Design Overview
266
+ `Services` is a singleton composition root for transport-facing capabilities only. It constructs two `WebSocketManager` instances (primary Contact Center and RTD), creates `AqmReqs` on the primary manager, then creates config, agent, contact, dialer, and ConnectionService collaborators.
267
+
268
+ ContactCenter owns the broader READY-time graph: WebCallingService, ApiAIAssistant, MetricsManager, TaskManager, EntryPoint, AddressBook, Queue, and UserPreference. TaskManager receives ApiAIAssistant, contact routing, calling, and both WebSocket managers. None of these collaborators is created by `register()`; registration attaches runtime listeners and connects the primary socket after READY initialization.
269
+
270
+ AQM factories return functions whose HTTP request is initiation and whose promise settles on correlated primary-WebSocket notifications. Direct config/data services return authenticated REST responses.
271
+
272
+ ## Data Flow
273
+ ```mermaid
274
+ flowchart TD
275
+ Ready[Host READY] --> WR[WebexRequest singleton]
276
+ WR --> S[Services singleton]
277
+ S --> PWS[Primary WebSocketManager]
278
+ S --> RTD[RTD WebSocketManager]
279
+ PWS --> AQM[AqmReqs]
280
+ AQM --> Agent[routingAgent]
281
+ AQM --> Contact[routingContact]
282
+ AQM --> Dialer[aqmDialer]
283
+ S --> Config[AgentConfigService]
284
+ PWS --> CS[ConnectionService]
285
+ Ready --> AI[ApiAIAssistant]
286
+ Ready --> Calling[WebCallingService]
287
+ Ready --> TM[TaskManager]
288
+ Ready --> UP[UserPreference]
289
+ AI --> TM
290
+ Contact --> TM
291
+ Calling --> TM
292
+ PWS --> TM
293
+ RTD --> TM
294
+ ```
295
+
296
+ Direct REST: caller → AgentConfigService/AddressBook/EntryPoint/Queue/UserPreference → WebexRequest → response.
297
+
298
+ AQM: caller → routing factory → AqmReqs → WebexRequest HTTP acknowledgement → matching primary-WebSocket success/failure → promise settlement.
299
+
300
+ Realtime task/AI: primary or RTD WebSocket → TaskManager → Task/state machine → typed application event.
301
+
302
+ ## Sequence Diagram(s)
303
+ Sequence coverage:
304
+
305
+ | Operation group | Diagram | Failure / recovery coverage |
306
+ |---|---|---|
307
+ | READY-time composition | READY composition | Invalid initialization prevents use of the incomplete graph. |
308
+ | Direct REST | Direct REST request | HTTP/service rejection is returned directly to the caller. |
309
+ | AQM | Correlated AQM operation | HTTP rejection, matching failure notification, and timeout reject the operation. |
310
+
311
+ ### READY composition
312
+
313
+ ```mermaid
314
+ sequenceDiagram
315
+ participant Host
316
+ participant CC as ContactCenter
317
+ participant S as Services
318
+ participant TM as TaskManager
319
+ Host-->>CC: READY
320
+ CC->>CC: initialize WebexRequest
321
+ CC->>S: getInstance(webex, connectionConfig)
322
+ S->>S: primary WS + RTD WS + AqmReqs + config/agent/contact/dialer + ConnectionService
323
+ CC->>CC: create calling + AI assistant + metrics + data services + UserPreference
324
+ CC->>TM: getTaskManager(AI, contact, calling, primary WS, RTD WS)
325
+ ```
326
+
327
+ ### Direct REST request
328
+
329
+ ```mermaid
330
+ sequenceDiagram
331
+ participant Caller
332
+ participant Service as Config/data service
333
+ participant WR as WebexRequest
334
+ participant Host as Authenticated Webex request
335
+ Caller->>Service: typed REST operation
336
+ Service->>WR: request(service + resource + method)
337
+ WR->>Host: resolve service and send request
338
+ alt HTTP success
339
+ Host-->>WR: response
340
+ WR-->>Service: typed response
341
+ Service-->>Caller: result
342
+ else service/HTTP rejection
343
+ Host-->>WR: error
344
+ WR-->>Service: same rejection
345
+ Service-->>Caller: reject
346
+ end
347
+ ```
348
+
349
+ ### Correlated AQM operation
350
+
351
+ ```mermaid
352
+ sequenceDiagram
353
+ participant Caller
354
+ participant Factory as agent/contact/dialer
355
+ participant AQM as AqmReqs
356
+ participant HTTP as WebexRequest
357
+ participant WS as Primary WebSocket
358
+ Caller->>Factory: typed operation
359
+ Factory->>AQM: generated request function(payload)
360
+ AQM->>HTTP: authenticated request(config)
361
+ HTTP-->>AQM: acknowledgement
362
+ alt matching success notification
363
+ WS-->>AQM: notifSuccess.bind match
364
+ AQM-->>Caller: typed response
365
+ else matching failure or timeout
366
+ WS-->>AQM: notifFail.bind match
367
+ AQM-->>Caller: structured rejection
368
+ end
369
+ ```
370
+
371
+ ## Class / Component Relationships
372
+ ```mermaid
373
+ classDiagram
374
+ class ContactCenter
375
+ class Services
376
+ class WebSocketManager
377
+ class AqmReqs
378
+ class ConnectionService
379
+ class AgentConfigService
380
+ class TaskManager
381
+ class ApiAIAssistant
382
+ ContactCenter --> Services
383
+ Services --> WebSocketManager : primary + RTD
384
+ Services --> AqmReqs : primary WS correlation
385
+ Services --> ConnectionService
386
+ Services --> AgentConfigService
387
+ ContactCenter --> ApiAIAssistant
388
+ ContactCenter --> TaskManager
389
+ ContactCenter --> UserPreference
390
+ TaskManager --> ApiAIAssistant
391
+ TaskManager --> WebSocketManager : primary + RTD
392
+ ```
393
+
394
+ ## Use Cases
395
+ - **UC-1 Compose services:** create the transport/factory singleton once per SDK host. Evidence: `src/services/index.ts`, `test/unit/spec/cc.ts`.
396
+ - **UC-2 Direct REST:** configuration, data, and user-preference services return authenticated HTTP results directly. Evidence: `src/services/config/index.ts`, `src/services/UserPreference.ts`, `test/unit/spec/services/config/index.ts`, `test/unit/spec/services/UserPreference.ts`.
397
+ - **UC-3 AQM operation:** initiate HTTP and settle only on matching WebSocket notification or timeout. Evidence: `src/services/core/aqm-reqs.ts`, `test/unit/spec/services/core/aqm-reqs.ts`.
398
+ - **UC-4 Task/AI realtime:** TaskManager consumes primary and RTD streams with ApiAIAssistant/calling collaborators. Evidence: `src/services/task/TaskManager.ts`, `test/unit/spec/services/task/TaskManager.ts`.
399
+
400
+ ## State Model
401
+ `Services` is a process-local singleton. Its first `getInstance({webex, connectionConfig})` call synchronously constructs the two WebSocket managers, AqmReqs-backed factories, config service, and ConnectionService; later calls return that same composed graph. Socket lifecycle and domain records are owned by the corresponding collaborators, not by a Services state machine.
402
+
403
+ ## Business Rules & Invariants
404
+ - The first singleton construction fixes the host SDK and connection configuration for that Services instance.
405
+ - The primary WebSocket manager is used for AQM correlation and Contact Center events; the RTD manager remains a distinct TaskManager dependency.
406
+ - ApiAIAssistant, TaskManager, and UserPreference are READY-time ContactCenter collaborators, not fields constructed by Services.
407
+ - Authentication is inherited from the host SDK through Core/WebexRequest; Services owns no credential lifecycle.
408
+ - Rollout applicability is N/A for the Services composition root: it is created at READY and does not evaluate a feature flag.
409
+
410
+ ## Concurrency & Reactive Flow
411
+ - `getInstance` composition is synchronous in the JavaScript execution turn. Direct REST promises can proceed independently, while each AQM promise remains pending until its matching primary-WebSocket notification, HTTP failure, or timeout.
412
+
413
+ These three services share an identical pattern. Use any one as a reference when creating similar services:
414
+
415
+ | Aspect | Pattern |
416
+ |---|---|
417
+ | **Class structure** | Standalone class with `WebexRequest`, `WebexSDK`, `MetricsManager`, `PageCache` |
418
+ | **Constructor** | `constructor(webex: WebexSDK)` — gets singletons via `.getInstance()` |
419
+ | **HTTP calls** | `this.webexRequest.request({service: WCC_API_GATEWAY, resource, method: HTTP_METHODS.GET})` |
420
+ | **Endpoints** | Uses `endPointMap` functions from `config/constants.ts` to build URL paths |
421
+ | **Pagination** | Query params with `page`, `pageSize`; uses `PageCache` for caching |
422
+ | **Caching** | `PageCache<T>` — caches pages for simple pagination, bypasses cache for search/filter |
423
+ | **Metrics** | `timeEvent` on API call start, `trackEvent` on success/failure |
424
+ | **Logging** | `LoggerProxy` with `{module: 'ClassName', method: 'methodName'}` context |
425
+ | **Error handling** | try/catch with `LoggerProxy.error` + `metricsManager.trackEvent` for failures, then re-throw so callers receive the error |
426
+
427
+ Reference files:
428
+
429
+ - [`AddressBook.ts`](../AddressBook.ts) — includes `addressBookId` parameter
430
+
431
+ - [`Queue.ts`](../Queue.ts) — includes additional query params (sortBy, sortOrder, etc.)
432
+
433
+ - [`EntryPoint.ts`](../EntryPoint.ts) — simplest example
434
+
435
+ `UserPreference.ts` is a separate direct REST CRUD pattern. It resolves a default user id from `agentConfig`, supports explicit user ids where applicable, and intentionally does not share PageCache behavior with the three paginated services.
436
+
437
+ ## State Machine
438
+ ```mermaid
439
+ stateDiagram-v2
440
+ [*] --> NotCreated
441
+ NotCreated --> Composed: first getInstance(options)
442
+ Composed --> Composed: later getInstance returns singleton
443
+ ```
444
+
445
+ ## Protocol / Wire Format
446
+ - Request, response, and event payload ownership is anchored in `src/services/index.ts`. HTTP initiates backend work where applicable; WebSocket messages provide realtime events and, for AQM flows, correlated completion.
447
+
448
+ ## Error Handling & Failure Modes
449
+ | Condition | Signal (error/code/result) | Caller recovery |
450
+ |---|---|---|
451
+ | Dependency rejection | Typed/rethrown error or failure event | Inspect structured details, preserve tracking id, and retry only when the operation is safe. |
452
+ | Timeout or missing async completion | Timeout/recovery state | Follow the module-specific recovery path; never synthesize success. |
453
+
454
+ ## Pitfalls
455
+ - Direct REST services complete from HTTP, while agent/contact/dialer AQM factories complete from correlated WebSocket notifications; treating them as the same transport model returns too early.
456
+ - The singleton must share one primary WebSocket with AqmReqs and a distinct RTD WebSocket with TaskManager; swapping or omitting either stream loses task or AI events.
457
+ - TaskManager and calling/AI/data/UserPreference collaborators are created by ContactCenter after READY, not by the Services constructor or `register()`.
458
+
459
+ ## Module Do's / Don'ts
460
+ - DO initialize `WebexRequest` before obtaining the Services singleton.
461
+ - DO preserve separate primary and RTD WebSocket ownership when changing composition.
462
+ - DON'T wrap direct REST services in AqmReqs or treat HTTP acknowledgement as AQM completion.
463
+ - DON'T add feature-flag decisions to the Services composition root.
464
+
465
+ ## Key Design Trade-off
466
+ - Two backend interaction patterns coexist: direct REST for immediate responses and AQM HTTP-plus-WebSocket correlation for asynchronous completion.
467
+
468
+ ## Test-Case Strategy (module)
469
+ Unit tests mirror module paths under `test/unit/spec/services`. Preserve positive and negative paths, event ordering, timeout/recovery behavior, and the package's 85% global branch/function/line/statement threshold.
470
+
471
+ | Behavior / Requirement | Existing test evidence | Gap |
472
+ |---|---|---|
473
+ | `SERVICES-R-001` | `test/unit/spec/cc.ts` | Add a focused Services singleton composition test if constructor wiring changes. |
474
+ | `SERVICES-R-002` | `test/unit/spec/services/config/index.ts`, `test/unit/spec/services/UserPreference.ts`, `test/unit/spec/services/core/aqm-reqs.ts` | Coverage is split across direct and AQM owners. |
475
+ | `SERVICES-R-003` | `test/unit/spec/cc.ts`, `test/unit/spec/services/UserPreference.ts` | None. |
476
+ | `SERVICES-R-004` | `test/unit/spec/services/task/TaskManager.ts`, `test/unit/spec/cc.ts` | None. |
477
+ | `SERVICES-R-005` | `test/unit/spec/services/core/WebexRequest.ts` | None. |
478
+ | `SERVICES-R-006` | `test/unit/spec/cc.ts` | None. |
479
+
480
+ ## Traceability
481
+ - Repo architecture: `../../../ai-docs/ARCHITECTURE.md` · Registry: `../../../ai-docs/SPEC_INDEX.md`
482
+ - Coverage state and contracts baseline: `../../../.sdd/manifest.json`
483
+
484
+ - [Root orchestrator AGENTS.md](../../../AGENTS.md) — repository rules; use [`SPEC_INDEX.md`](../../../ai-docs/SPEC_INDEX.md) for canonical module routing
485
+
486
+ - [ai-docs/RULES.md](../../../ai-docs/RULES.md) — coding standards
487
+
488
+ - [ai-docs/patterns/](../../../ai-docs/patterns/) — TypeScript, testing, and event patterns
489
+
490
+ - [types.ts](../../types.ts) — public type definitions
491
+
492
+ - [cc.ts](../../cc.ts) — main plugin class (public API surface)
@@ -1,8 +1,10 @@
1
1
  # Config Service - AI Agent Guide
2
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
+ >
3
5
  > **Purpose**: Fetch and aggregate agent configuration data from multiple API endpoints to build the AgentProfile.
4
6
  >
5
- > **Scope Authority**: This is the authoritative documentation for the **Config** service scope. See [Root AGENTS.md](../../../../AGENTS.md) for the orchestrator and cross-scope rules.
7
+ > **Legacy scope:** See [Root AGENTS.md](../../../../AGENTS.md) for the orchestrator and cross-scope rules.
6
8
 
7
9
  ---
8
10
 
@@ -1,5 +1,7 @@
1
1
  # Config Service - Architecture
2
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
+
3
5
  > **Purpose**: Technical documentation for agent configuration aggregation.
4
6
 
5
7
  ---