@webex/contact-center 3.12.0-next.16 → 3.12.0-next.161
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.sdd/manifest.json +887 -0
- package/AGENTS.md +94 -0
- package/ai-docs/ARCHITECTURE.md +168 -0
- package/ai-docs/CONTRACTS.md +62 -0
- package/ai-docs/GETTING_STARTED.md +168 -0
- package/ai-docs/GLOSSARY.md +43 -0
- package/ai-docs/README.md +138 -0
- package/ai-docs/REVIEW_CHECKLIST.md +41 -0
- package/ai-docs/RULES.md +444 -0
- package/ai-docs/SECURITY.md +52 -0
- package/ai-docs/SERVICE_STATE.md +52 -0
- package/ai-docs/SPEC_INDEX.md +65 -0
- package/ai-docs/adr/0001-spec-source-policy.md +55 -0
- package/ai-docs/adr/README.md +8 -0
- package/ai-docs/adr/_adr-template.md +31 -0
- package/ai-docs/contact-center-spec.md +385 -0
- package/ai-docs/features/consult-transfer-list-policy/spec/feature-spec.md +362 -0
- package/ai-docs/features/contact-owner-change-refactor.md +78 -0
- package/ai-docs/features/generated-spec-conformance-fidelity-remediation/spec/feature-spec.md +117 -0
- package/ai-docs/features/residual-warning-coverage-completion/spec/feature-spec.md +203 -0
- package/ai-docs/features/validator-code-fidelity-drift-fix/spec/feature-spec.md +315 -0
- package/ai-docs/patterns/event-driven-patterns.md +485 -0
- package/ai-docs/patterns/testing-patterns.md +480 -0
- package/ai-docs/patterns/typescript-patterns.md +365 -0
- package/ai-docs/templates/README.md +102 -0
- package/ai-docs/templates/documentation/create-agents-md.md +240 -0
- package/ai-docs/templates/documentation/create-architecture-md.md +295 -0
- package/ai-docs/templates/existing-service/bug-fix.md +254 -0
- package/ai-docs/templates/existing-service/feature-enhancement.md +450 -0
- package/ai-docs/templates/new-method/00-master.md +80 -0
- package/ai-docs/templates/new-method/01-requirements.md +232 -0
- package/ai-docs/templates/new-method/02-implementation.md +295 -0
- package/ai-docs/templates/new-method/03-tests.md +201 -0
- package/ai-docs/templates/new-method/04-validation.md +141 -0
- package/ai-docs/templates/new-service/00-master.md +109 -0
- package/ai-docs/templates/new-service/01-pre-questions.md +159 -0
- package/ai-docs/templates/new-service/02-code-generation.md +346 -0
- package/ai-docs/templates/new-service/03-integration.md +178 -0
- package/ai-docs/templates/new-service/04-test-generation.md +205 -0
- package/ai-docs/templates/new-service/05-validation.md +145 -0
- package/dist/cc.js +888 -49
- package/dist/cc.js.map +1 -1
- package/dist/config.js +13 -0
- package/dist/config.js.map +1 -1
- package/dist/constants.js +38 -3
- package/dist/constants.js.map +1 -1
- package/dist/index.js +54 -17
- package/dist/index.js.map +1 -1
- package/dist/metrics/MetricsManager.js +16 -0
- package/dist/metrics/MetricsManager.js.map +1 -1
- package/dist/metrics/behavioral-events.js +185 -0
- package/dist/metrics/behavioral-events.js.map +1 -1
- package/dist/metrics/constants.js +54 -4
- package/dist/metrics/constants.js.map +1 -1
- package/dist/services/AddressBook.js +18 -15
- package/dist/services/AddressBook.js.map +1 -1
- package/dist/services/AnswerCallOnWebexService.js +202 -0
- package/dist/services/AnswerCallOnWebexService.js.map +1 -0
- package/dist/services/ApiAiAssistant.js +369 -14
- package/dist/services/ApiAiAssistant.js.map +1 -1
- package/dist/services/EntryPoint.js +46 -68
- package/dist/services/EntryPoint.js.map +1 -1
- package/dist/services/Queue.js +27 -22
- package/dist/services/Queue.js.map +1 -1
- package/dist/services/UserPreference.js +427 -0
- package/dist/services/UserPreference.js.map +1 -0
- package/dist/services/WebCallingService.js +10 -2
- package/dist/services/WebCallingService.js.map +1 -1
- package/dist/services/WebexCrossClientService.js +225 -0
- package/dist/services/WebexCrossClientService.js.map +1 -0
- package/dist/services/WxAppTelephonyMercurySync.js +111 -0
- package/dist/services/WxAppTelephonyMercurySync.js.map +1 -0
- package/dist/services/config/Util.js +48 -48
- package/dist/services/config/Util.js.map +1 -1
- package/dist/services/config/constants.js +56 -78
- package/dist/services/config/constants.js.map +1 -1
- package/dist/services/config/index.js +100 -226
- package/dist/services/config/index.js.map +1 -1
- package/dist/services/config/types.js +93 -24
- package/dist/services/config/types.js.map +1 -1
- package/dist/services/constants.js +11 -1
- package/dist/services/constants.js.map +1 -1
- package/dist/services/core/Err.js.map +1 -1
- package/dist/services/core/Utils.js +131 -32
- package/dist/services/core/Utils.js.map +1 -1
- package/dist/services/core/WebexRequest.js +6 -2
- package/dist/services/core/WebexRequest.js.map +1 -1
- package/dist/services/core/aqm-reqs.js +17 -11
- package/dist/services/core/aqm-reqs.js.map +1 -1
- package/dist/services/core/constants.js +9 -1
- package/dist/services/core/constants.js.map +1 -1
- package/dist/services/core/types.js.map +1 -1
- package/dist/services/core/websocket/WebSocketManager.js +19 -2
- package/dist/services/core/websocket/WebSocketManager.js.map +1 -1
- package/dist/services/core/websocket/types.js.map +1 -1
- package/dist/services/index.js +1 -1
- package/dist/services/index.js.map +1 -1
- package/dist/services/task/Task.js +955 -0
- package/dist/services/task/Task.js.map +1 -0
- package/dist/services/task/TaskFactory.js +50 -0
- package/dist/services/task/TaskFactory.js.map +1 -0
- package/dist/services/task/TaskManager.js +1272 -605
- package/dist/services/task/TaskManager.js.map +1 -1
- package/dist/services/task/TaskUtils.js +221 -27
- package/dist/services/task/TaskUtils.js.map +1 -1
- package/dist/services/task/WebexCallingUtils.js +70 -0
- package/dist/services/task/WebexCallingUtils.js.map +1 -0
- package/dist/services/task/constants.js +19 -2
- package/dist/services/task/constants.js.map +1 -1
- package/dist/services/task/contact.js +29 -0
- package/dist/services/task/contact.js.map +1 -1
- package/dist/services/task/digital/Digital.js +78 -0
- package/dist/services/task/digital/Digital.js.map +1 -0
- package/dist/services/task/state-machine/TaskStateMachine.js +982 -0
- package/dist/services/task/state-machine/TaskStateMachine.js.map +1 -0
- package/dist/services/task/state-machine/actions.js +572 -0
- package/dist/services/task/state-machine/actions.js.map +1 -0
- package/dist/services/task/state-machine/constants.js +161 -0
- package/dist/services/task/state-machine/constants.js.map +1 -0
- package/dist/services/task/state-machine/guards.js +379 -0
- package/dist/services/task/state-machine/guards.js.map +1 -0
- package/dist/services/task/state-machine/index.js +53 -0
- package/dist/services/task/state-machine/index.js.map +1 -0
- package/dist/services/task/state-machine/types.js +54 -0
- package/dist/services/task/state-machine/types.js.map +1 -0
- package/dist/services/task/state-machine/uiControlsComputer.js +703 -0
- package/dist/services/task/state-machine/uiControlsComputer.js.map +1 -0
- package/dist/services/task/taskDataNormalizer.js +99 -0
- package/dist/services/task/taskDataNormalizer.js.map +1 -0
- package/dist/services/task/types.js +215 -5
- package/dist/services/task/types.js.map +1 -1
- package/dist/services/task/voice/Voice.js +1504 -0
- package/dist/services/task/voice/Voice.js.map +1 -0
- package/dist/services/task/voice/WebRTC.js +152 -0
- package/dist/services/task/voice/WebRTC.js.map +1 -0
- package/dist/services/task/voice/wxAppOfferObservability.js +145 -0
- package/dist/services/task/voice/wxAppOfferObservability.js.map +1 -0
- package/dist/services/task/voice/wxAppVoiceMethods.js +395 -0
- package/dist/services/task/voice/wxAppVoiceMethods.js.map +1 -0
- package/dist/services/wxAppDiagnosticLogging.js +159 -0
- package/dist/services/wxAppDiagnosticLogging.js.map +1 -0
- package/dist/services/wxAppTelephonyUtils.js +19 -0
- package/dist/services/wxAppTelephonyUtils.js.map +1 -0
- package/dist/types/cc.d.ts +152 -9
- package/dist/types/config.d.ts +13 -0
- package/dist/types/constants.d.ts +36 -1
- package/dist/types/index.d.ts +54 -20
- package/dist/types/metrics/MetricsManager.d.ts +6 -0
- package/dist/types/metrics/constants.d.ts +48 -1
- package/dist/types/services/AddressBook.d.ts +2 -1
- package/dist/types/services/AnswerCallOnWebexService.d.ts +38 -0
- package/dist/types/services/ApiAiAssistant.d.ts +67 -5
- package/dist/types/services/EntryPoint.d.ts +7 -5
- package/dist/types/services/Queue.d.ts +5 -3
- package/dist/types/services/UserPreference.d.ts +118 -0
- package/dist/types/services/WebexCrossClientService.d.ts +32 -0
- package/dist/types/services/WxAppTelephonyMercurySync.d.ts +28 -0
- package/dist/types/services/config/Util.d.ts +4 -8
- package/dist/types/services/config/constants.d.ts +49 -76
- package/dist/types/services/config/index.d.ts +16 -64
- package/dist/types/services/config/types.d.ts +240 -114
- package/dist/types/services/constants.d.ts +9 -0
- package/dist/types/services/core/Err.d.ts +2 -0
- package/dist/types/services/core/Utils.d.ts +43 -13
- package/dist/types/services/core/WebexRequest.d.ts +1 -0
- package/dist/types/services/core/constants.d.ts +7 -0
- package/dist/types/services/core/types.d.ts +2 -0
- package/dist/types/services/core/websocket/WebSocketManager.d.ts +1 -0
- package/dist/types/services/core/websocket/types.d.ts +1 -1
- package/dist/types/services/index.d.ts +1 -1
- package/dist/types/services/task/Task.d.ts +186 -0
- package/dist/types/services/task/TaskFactory.d.ts +14 -0
- package/dist/types/services/task/TaskUtils.d.ts +54 -2
- package/dist/types/services/task/WebexCallingUtils.d.ts +11 -0
- package/dist/types/services/task/constants.d.ts +17 -0
- package/dist/types/services/task/contact.d.ts +4 -0
- package/dist/types/services/task/digital/Digital.d.ts +23 -0
- package/dist/types/services/task/state-machine/TaskStateMachine.d.ts +1442 -0
- package/dist/types/services/task/state-machine/actions.d.ts +10 -0
- package/dist/types/services/task/state-machine/constants.d.ts +107 -0
- package/dist/types/services/task/state-machine/guards.d.ts +103 -0
- package/dist/types/services/task/state-machine/index.d.ts +13 -0
- package/dist/types/services/task/state-machine/types.d.ts +277 -0
- package/dist/types/services/task/state-machine/uiControlsComputer.d.ts +9 -0
- package/dist/types/services/task/taskDataNormalizer.d.ts +10 -0
- package/dist/types/services/task/types.d.ts +738 -66
- package/dist/types/services/task/voice/Voice.d.ts +241 -0
- package/dist/types/services/task/voice/WebRTC.d.ts +54 -0
- package/dist/types/services/task/voice/wxAppOfferObservability.d.ts +39 -0
- package/dist/types/services/task/voice/wxAppVoiceMethods.d.ts +68 -0
- package/dist/types/services/wxAppDiagnosticLogging.d.ts +63 -0
- package/dist/types/services/wxAppTelephonyUtils.d.ts +5 -0
- package/dist/types/types.d.ts +213 -11
- package/dist/types/utils/PageCache.d.ts +20 -3
- package/dist/types/webex.d.ts +1 -0
- package/dist/types.js +168 -6
- package/dist/types.js.map +1 -1
- package/dist/utils/PageCache.js +19 -5
- package/dist/utils/PageCache.js.map +1 -1
- package/dist/webex.js +22 -2
- package/dist/webex.js.map +1 -1
- package/package.json +16 -12
- package/src/cc.ts +1137 -67
- package/src/config.ts +13 -0
- package/src/constants.ts +39 -1
- package/src/index.ts +62 -15
- package/src/metrics/MetricsManager.ts +16 -0
- package/src/metrics/ai-docs/AGENTS.md +350 -0
- package/src/metrics/ai-docs/ARCHITECTURE.md +338 -0
- package/src/metrics/ai-docs/metrics-spec.md +971 -0
- package/src/metrics/behavioral-events.ts +190 -0
- package/src/metrics/constants.ts +59 -4
- package/src/services/AddressBook.ts +17 -6
- package/src/services/AnswerCallOnWebexService.ts +239 -0
- package/src/services/ApiAiAssistant.ts +494 -15
- package/src/services/EntryPoint.ts +59 -60
- package/src/services/Queue.ts +29 -12
- package/src/services/UserPreference.ts +509 -0
- package/src/services/WebCallingService.ts +16 -2
- package/src/services/WebexCrossClientService.ts +298 -0
- package/src/services/WxAppTelephonyMercurySync.ts +142 -0
- package/src/services/agent/ai-docs/AGENTS.md +240 -0
- package/src/services/agent/ai-docs/ARCHITECTURE.md +304 -0
- package/src/services/agent/ai-docs/agent-spec.md +505 -0
- package/src/services/ai-docs/AGENTS.md +386 -0
- package/src/services/ai-docs/services-spec.md +512 -0
- package/src/services/config/Util.ts +54 -84
- package/src/services/config/ai-docs/AGENTS.md +250 -0
- package/src/services/config/ai-docs/ARCHITECTURE.md +413 -0
- package/src/services/config/ai-docs/config-spec.md +669 -0
- package/src/services/config/constants.ts +63 -85
- package/src/services/config/index.ts +116 -277
- package/src/services/config/types.ts +229 -125
- package/src/services/constants.ts +10 -0
- package/src/services/core/Err.ts +1 -0
- package/src/services/core/Utils.ts +151 -37
- package/src/services/core/WebexRequest.ts +3 -1
- package/src/services/core/ai-docs/AGENTS.md +381 -0
- package/src/services/core/ai-docs/ARCHITECTURE.md +698 -0
- package/src/services/core/ai-docs/core-spec.md +797 -0
- package/src/services/core/aqm-reqs.ts +18 -12
- package/src/services/core/constants.ts +8 -0
- package/src/services/core/types.ts +33 -1
- package/src/services/core/websocket/WebSocketManager.ts +28 -2
- package/src/services/core/websocket/types.ts +1 -1
- package/src/services/index.ts +1 -1
- package/src/services/task/Task.ts +1211 -0
- package/src/services/task/TaskFactory.ts +82 -0
- package/src/services/task/TaskManager.ts +1585 -724
- package/src/services/task/TaskUtils.ts +316 -25
- package/src/services/task/WebexCallingUtils.ts +136 -0
- package/src/services/task/ai-docs/AGENTS.md +457 -0
- package/src/services/task/ai-docs/ARCHITECTURE.md +595 -0
- package/src/services/task/ai-docs/task-spec.md +1501 -0
- package/src/services/task/constants.ts +18 -0
- package/src/services/task/contact.ts +30 -0
- package/src/services/task/digital/Digital.ts +102 -0
- package/src/services/task/state-machine/TaskStateMachine.ts +1320 -0
- package/src/services/task/state-machine/actions.ts +741 -0
- package/src/services/task/state-machine/ai-docs/AGENTS.md +460 -0
- package/src/services/task/state-machine/ai-docs/ARCHITECTURE.md +1156 -0
- package/src/services/task/state-machine/ai-docs/task-state-machine-spec.md +2247 -0
- package/src/services/task/state-machine/constants.ts +172 -0
- package/src/services/task/state-machine/guards.ts +442 -0
- package/src/services/task/state-machine/index.ts +28 -0
- package/src/services/task/state-machine/types.ts +258 -0
- package/src/services/task/state-machine/uiControlsComputer.ts +1135 -0
- package/src/services/task/taskDataNormalizer.ts +137 -0
- package/src/services/task/types.ts +918 -70
- package/src/services/task/voice/Voice.ts +1878 -0
- package/src/services/task/voice/WebRTC.ts +194 -0
- package/src/services/task/voice/wxAppOfferObservability.ts +204 -0
- package/src/services/task/voice/wxAppVoiceMethods.ts +575 -0
- package/src/services/wxAppDiagnosticLogging.ts +286 -0
- package/src/services/wxAppTelephonyUtils.ts +14 -0
- package/src/types.ts +272 -13
- package/src/utils/AGENTS.md +289 -0
- package/src/utils/PageCache.ts +38 -5
- package/src/utils/ai-docs/utils-spec.md +391 -0
- package/src/webex.js +10 -0
- package/test/unit/fixtures/aiSummaryTestUtils.ts +40 -0
- package/test/unit/spec/cc.ts +3553 -107
- package/test/unit/spec/index.ts +885 -0
- package/test/unit/spec/logger-proxy.ts +70 -0
- package/test/unit/spec/metrics/MetricsManager.ts +25 -0
- package/test/unit/spec/metrics/behavioral-events.ts +60 -0
- package/test/unit/spec/services/AddressBook.ts +37 -6
- package/test/unit/spec/services/AnswerCallOnWebexService.ts +264 -0
- package/test/unit/spec/services/ApiAiAssistant.ts +442 -23
- package/test/unit/spec/services/EntryPoint.ts +87 -40
- package/test/unit/spec/services/Queue.ts +123 -12
- package/test/unit/spec/services/UserPreference.ts +401 -0
- package/test/unit/spec/services/WebCallingService.ts +45 -1
- package/test/unit/spec/services/WebexCrossClientService.ts +509 -0
- package/test/unit/spec/services/WxAppTelephonyMercurySync.ts +136 -0
- package/test/unit/spec/services/config/Util.ts +501 -0
- package/test/unit/spec/services/config/index.ts +317 -547
- package/test/unit/spec/services/core/Utils.ts +447 -8
- package/test/unit/spec/services/core/WebexRequest.ts +8 -7
- package/test/unit/spec/services/core/aqm-reqs.ts +142 -1
- package/test/unit/spec/services/core/websocket/WebSocketManager.ts +129 -53
- package/test/unit/spec/services/task/AutoWrapup.ts +63 -0
- package/test/unit/spec/services/task/Task.ts +2723 -0
- package/test/unit/spec/services/task/TaskFactory.ts +116 -0
- package/test/unit/spec/services/task/TaskManager.ts +4734 -1769
- package/test/unit/spec/services/task/TaskUtils.ts +307 -0
- package/test/unit/spec/services/task/WebexCallingUtils.ts +153 -0
- package/test/unit/spec/services/task/contact.ts +33 -0
- package/test/unit/spec/services/task/digital/Digital.ts +105 -0
- package/test/unit/spec/services/task/state-machine/TaskStateMachine.ts +4060 -0
- package/test/unit/spec/services/task/state-machine/guards.ts +839 -0
- package/test/unit/spec/services/task/state-machine/types.ts +18 -0
- package/test/unit/spec/services/task/state-machine/uiControlsComputer.ts +3101 -0
- package/test/unit/spec/services/task/taskTestUtils.ts +87 -0
- package/test/unit/spec/services/task/voice/Voice.ts +2355 -0
- package/test/unit/spec/services/task/voice/WebRTC.ts +235 -0
- package/test/unit/spec/services/task/voice/wxAppOfferObservability.ts +361 -0
- package/test/unit/spec/services/task/voice/wxAppVoiceMethods.ts +719 -0
- package/test/unit/spec/services/wxAppDiagnosticLogging.ts +179 -0
- package/test/unit/spec/wellnessSampleUtils.ts +288 -0
- package/typedoc.md +1 -1
- package/umd/contact-center.min.js +2 -2
- package/umd/contact-center.min.js.map +1 -1
- package/dist/services/task/index.js +0 -1530
- package/dist/services/task/index.js.map +0 -1
- package/dist/types/services/task/index.d.ts +0 -650
- package/src/services/task/index.ts +0 -1806
- package/test/unit/spec/services/task/index.ts +0 -2205
|
@@ -1,17 +1,24 @@
|
|
|
1
|
+
import {v4 as uuidv4} from 'uuid';
|
|
1
2
|
import LoggerProxy from '../logger-proxy';
|
|
2
3
|
import MetricsManager from '../metrics/MetricsManager';
|
|
3
4
|
import {METRIC_EVENT_NAMES} from '../metrics/constants';
|
|
4
|
-
import {CC_FILE, METHODS} from '../constants';
|
|
5
|
+
import {AI_SUMMARY_ERROR_CODES, CC_FILE, METHODS} from '../constants';
|
|
5
6
|
import {
|
|
6
7
|
HTTP_METHODS,
|
|
7
8
|
WebexSDK,
|
|
8
9
|
IHttpResponse,
|
|
9
|
-
TranscriptAction,
|
|
10
10
|
AIAssistantEventType,
|
|
11
11
|
AIAssistantEventName,
|
|
12
12
|
HistoricTranscriptsResponse,
|
|
13
|
+
RealTimeAssistanceParams,
|
|
14
|
+
RealTimeAssistanceUserActionParams,
|
|
15
|
+
RespondToWellnessBreakParams,
|
|
16
|
+
WellnessBreakUserAction,
|
|
17
|
+
WELLNESS_BREAK_USER_ACTIONS,
|
|
18
|
+
GenericError,
|
|
13
19
|
} from '../types';
|
|
14
20
|
import {getErrorDetails} from './core/Utils';
|
|
21
|
+
import type {PendingRtdRequest, RtdRequestOptions} from './core/types';
|
|
15
22
|
import {
|
|
16
23
|
AI_ASSISTANT_BASE_URL_TEMPLATE,
|
|
17
24
|
AI_ASSISTANT_ENV_MAP,
|
|
@@ -20,6 +27,12 @@ import {
|
|
|
20
27
|
} from './constants';
|
|
21
28
|
import {AIFeatureFlags} from './config/types';
|
|
22
29
|
|
|
30
|
+
type WellnessBreakContextProvider = () => {
|
|
31
|
+
isWellnessBreakEnabled: boolean;
|
|
32
|
+
agentId?: string;
|
|
33
|
+
agentSessionId?: string;
|
|
34
|
+
};
|
|
35
|
+
|
|
23
36
|
/**
|
|
24
37
|
* ApiAIAssistant provides AI Assistant APIs for transcript controls.
|
|
25
38
|
* @public
|
|
@@ -27,10 +40,26 @@ import {AIFeatureFlags} from './config/types';
|
|
|
27
40
|
export class ApiAIAssistant {
|
|
28
41
|
private webex: WebexSDK;
|
|
29
42
|
private metricsManager: MetricsManager;
|
|
43
|
+
/** @internal Current AI flags from the agent configuration. */
|
|
30
44
|
public aiFeature: AIFeatureFlags;
|
|
45
|
+
private pendingRtdRequests = new Map<string, PendingRtdRequest<unknown>>();
|
|
46
|
+
private readonly wellnessContextProvider?: WellnessBreakContextProvider;
|
|
47
|
+
|
|
48
|
+
private createWellnessError(reason: string): GenericError {
|
|
49
|
+
const error = new Error(reason) as GenericError;
|
|
50
|
+
error.details = {
|
|
51
|
+
type: 'SDK_VALIDATION_ERROR',
|
|
52
|
+
orgId: this.webex.credentials.getOrgId(),
|
|
53
|
+
trackingId: '',
|
|
54
|
+
data: {reason},
|
|
55
|
+
};
|
|
56
|
+
|
|
57
|
+
return error;
|
|
58
|
+
}
|
|
31
59
|
|
|
32
|
-
constructor(webex: WebexSDK) {
|
|
60
|
+
constructor(webex: WebexSDK, wellnessContextProvider?: WellnessBreakContextProvider) {
|
|
33
61
|
this.webex = webex;
|
|
62
|
+
this.wellnessContextProvider = wellnessContextProvider;
|
|
34
63
|
this.metricsManager = MetricsManager.getInstance({webex});
|
|
35
64
|
}
|
|
36
65
|
|
|
@@ -38,12 +67,152 @@ export class ApiAIAssistant {
|
|
|
38
67
|
this.aiFeature = aiFeature;
|
|
39
68
|
}
|
|
40
69
|
|
|
70
|
+
/**
|
|
71
|
+
* Validates a caller-supplied identifier (agentId/interactionId) before it is used to
|
|
72
|
+
* construct a request. Accepts a non-empty alphanumeric identifier that may contain
|
|
73
|
+
* hyphens or underscores.
|
|
74
|
+
* @param value - the identifier to validate
|
|
75
|
+
* @returns {boolean} true when the identifier is a non-empty, well-formed string
|
|
76
|
+
* @private
|
|
77
|
+
*/
|
|
78
|
+
private isValidTranscriptIdentifier(value: unknown): boolean {
|
|
79
|
+
return typeof value === 'string' && /^[A-Za-z0-9_-]{1,128}$/.test(value);
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
private async sendWellnessBreakAction(
|
|
83
|
+
action: WellnessBreakUserAction,
|
|
84
|
+
method: string
|
|
85
|
+
): Promise<void> {
|
|
86
|
+
this.metricsManager.timeEvent([
|
|
87
|
+
METRIC_EVENT_NAMES.AI_ASSISTANT_WELLNESS_ACTION_ACCEPTED,
|
|
88
|
+
METRIC_EVENT_NAMES.AI_ASSISTANT_WELLNESS_ACTION_FAILED,
|
|
89
|
+
]);
|
|
90
|
+
|
|
91
|
+
try {
|
|
92
|
+
const context = this.wellnessContextProvider?.();
|
|
93
|
+
const agentId = context?.agentId?.trim();
|
|
94
|
+
const agentSessionId = context?.agentSessionId?.trim();
|
|
95
|
+
const orgId = this.webex.credentials.getOrgId()?.trim();
|
|
96
|
+
|
|
97
|
+
if (context?.isWellnessBreakEnabled !== true) {
|
|
98
|
+
throw this.createWellnessError('WELLNESS_BREAK_NOT_ENABLED');
|
|
99
|
+
}
|
|
100
|
+
if (!orgId) {
|
|
101
|
+
throw this.createWellnessError('WELLNESS_BREAK_ORG_ID_REQUIRED');
|
|
102
|
+
}
|
|
103
|
+
if (!agentId) {
|
|
104
|
+
throw this.createWellnessError('WELLNESS_BREAK_AGENT_ID_REQUIRED');
|
|
105
|
+
}
|
|
106
|
+
if (!agentSessionId) {
|
|
107
|
+
throw this.createWellnessError('WELLNESS_BREAK_AGENT_SESSION_REQUIRED');
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
const baseUrl = this.getBaseUrl();
|
|
111
|
+
const response = (await this.webex.request({
|
|
112
|
+
uri: `${baseUrl}${AI_ASSISTANT_API_URLS.EVENT}`,
|
|
113
|
+
method: HTTP_METHODS.POST,
|
|
114
|
+
addAuthHeader: true,
|
|
115
|
+
body: {
|
|
116
|
+
agentId,
|
|
117
|
+
orgId,
|
|
118
|
+
eventType: AIAssistantEventType.CUSTOM_EVENT,
|
|
119
|
+
eventName: AIAssistantEventName.WELLNESS_BREAK_ACTION,
|
|
120
|
+
eventDetails: {
|
|
121
|
+
data: {
|
|
122
|
+
action,
|
|
123
|
+
agentSessionId,
|
|
124
|
+
actionTimeStamp: Date.now(),
|
|
125
|
+
},
|
|
126
|
+
},
|
|
127
|
+
},
|
|
128
|
+
})) as IHttpResponse;
|
|
129
|
+
|
|
130
|
+
if (response.statusCode !== 202) {
|
|
131
|
+
throw this.createWellnessError(
|
|
132
|
+
`WELLNESS_BREAK_ACTION_UNEXPECTED_STATUS_${response.statusCode}`
|
|
133
|
+
);
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
this.metricsManager.trackEvent(
|
|
137
|
+
METRIC_EVENT_NAMES.AI_ASSISTANT_WELLNESS_ACTION_ACCEPTED,
|
|
138
|
+
{action},
|
|
139
|
+
['operational']
|
|
140
|
+
);
|
|
141
|
+
LoggerProxy.log('Wellness action accepted by AI Assistant', {
|
|
142
|
+
module: CC_FILE,
|
|
143
|
+
method,
|
|
144
|
+
data: {action},
|
|
145
|
+
});
|
|
146
|
+
} catch (error) {
|
|
147
|
+
this.metricsManager.trackEvent(
|
|
148
|
+
METRIC_EVENT_NAMES.AI_ASSISTANT_WELLNESS_ACTION_FAILED,
|
|
149
|
+
{
|
|
150
|
+
action,
|
|
151
|
+
error: error instanceof Error ? error.message : String(error),
|
|
152
|
+
},
|
|
153
|
+
['operational']
|
|
154
|
+
);
|
|
155
|
+
const {error: detailedError} = getErrorDetails(error, method, CC_FILE);
|
|
156
|
+
throw detailedError;
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
/**
|
|
161
|
+
* Requests an Agent Wellness Break.
|
|
162
|
+
* The promise resolves when the HTTP request is accepted with status 202; the later
|
|
163
|
+
* approval or denial is delivered independently through a wellness notification.
|
|
164
|
+
* @returns A promise that resolves with no value after HTTP acceptance
|
|
165
|
+
* @throws Structured Contact Center error when disabled, stale, invalid, or delivery fails
|
|
166
|
+
* @example
|
|
167
|
+
* await webex.cc.apiAIAssistant.requestWellnessBreak();
|
|
168
|
+
* @public
|
|
169
|
+
*/
|
|
170
|
+
public async requestWellnessBreak(): Promise<void> {
|
|
171
|
+
return this.sendWellnessBreakAction(
|
|
172
|
+
WELLNESS_BREAK_USER_ACTIONS.REQUESTED,
|
|
173
|
+
METHODS.REQUEST_WELLNESS_BREAK
|
|
174
|
+
);
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
/**
|
|
178
|
+
* Responds to a backend-provided Agent Wellness Break offer.
|
|
179
|
+
* The promise resolves when the HTTP request is accepted with status 202 and does not
|
|
180
|
+
* wait for a WebSocket completion event.
|
|
181
|
+
* @param params - ACCEPTED, REJECTED, or NO_RESPONSE
|
|
182
|
+
* @returns A promise that resolves with no value after HTTP acceptance
|
|
183
|
+
* @throws Structured Contact Center error when disabled, stale, invalid, or delivery fails
|
|
184
|
+
* @example
|
|
185
|
+
* await webex.cc.apiAIAssistant.respondToWellnessBreak({
|
|
186
|
+
* action: WELLNESS_BREAK_USER_ACTIONS.ACCEPTED,
|
|
187
|
+
* });
|
|
188
|
+
* @public
|
|
189
|
+
*/
|
|
190
|
+
public async respondToWellnessBreak(params: RespondToWellnessBreakParams): Promise<void> {
|
|
191
|
+
const {action} = params;
|
|
192
|
+
if (
|
|
193
|
+
![
|
|
194
|
+
WELLNESS_BREAK_USER_ACTIONS.ACCEPTED,
|
|
195
|
+
WELLNESS_BREAK_USER_ACTIONS.REJECTED,
|
|
196
|
+
WELLNESS_BREAK_USER_ACTIONS.NO_RESPONSE,
|
|
197
|
+
].includes(action)
|
|
198
|
+
) {
|
|
199
|
+
const {error} = getErrorDetails(
|
|
200
|
+
this.createWellnessError('WELLNESS_BREAK_ACTION_INVALID'),
|
|
201
|
+
METHODS.RESPOND_TO_WELLNESS_BREAK,
|
|
202
|
+
CC_FILE
|
|
203
|
+
);
|
|
204
|
+
throw error;
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
return this.sendWellnessBreakAction(action, METHODS.RESPOND_TO_WELLNESS_BREAK);
|
|
208
|
+
}
|
|
209
|
+
|
|
41
210
|
private getBaseUrl(): string {
|
|
42
211
|
const wccApiGatewayUrl = this.webex.internal.services.get(WCC_API_GATEWAY) || '';
|
|
43
212
|
|
|
44
213
|
if (!wccApiGatewayUrl) {
|
|
45
214
|
const {error: detailedError} = getErrorDetails(
|
|
46
|
-
new Error(
|
|
215
|
+
new Error(AI_SUMMARY_ERROR_CODES.AI_ASSISTANT_BASE_URL_NOT_AVAILABLE),
|
|
47
216
|
METHODS.GET_BASE_URL,
|
|
48
217
|
CC_FILE
|
|
49
218
|
);
|
|
@@ -58,9 +227,10 @@ export class ApiAIAssistant {
|
|
|
58
227
|
}
|
|
59
228
|
|
|
60
229
|
const resolvedEnv = AI_ASSISTANT_ENV_MAP[hostname];
|
|
230
|
+
|
|
61
231
|
if (!resolvedEnv) {
|
|
62
232
|
const {error: detailedError} = getErrorDetails(
|
|
63
|
-
new Error(
|
|
233
|
+
new Error(AI_SUMMARY_ERROR_CODES.AI_ASSISTANT_BASE_URL_NOT_AVAILABLE),
|
|
64
234
|
METHODS.GET_BASE_URL,
|
|
65
235
|
CC_FILE
|
|
66
236
|
);
|
|
@@ -70,26 +240,131 @@ export class ApiAIAssistant {
|
|
|
70
240
|
return AI_ASSISTANT_BASE_URL_TEMPLATE.replace('%s', resolvedEnv);
|
|
71
241
|
}
|
|
72
242
|
|
|
243
|
+
private static getRtdRequestKey(rtdEventType: string, correlationId: string): string {
|
|
244
|
+
return JSON.stringify([rtdEventType, correlationId]);
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
private removeRtdRequest<T>(
|
|
248
|
+
rtdEventType: string,
|
|
249
|
+
correlationId: string,
|
|
250
|
+
settle?: (request: PendingRtdRequest<T>) => void
|
|
251
|
+
): PendingRtdRequest<T> | undefined {
|
|
252
|
+
const key = ApiAIAssistant.getRtdRequestKey(rtdEventType, correlationId);
|
|
253
|
+
const request = this.pendingRtdRequests.get(key) as PendingRtdRequest<T> | undefined;
|
|
254
|
+
|
|
255
|
+
if (!request) {
|
|
256
|
+
return undefined;
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
if (request.timeoutId) {
|
|
260
|
+
clearTimeout(request.timeoutId);
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
settle?.(request);
|
|
264
|
+
this.pendingRtdRequests.delete(key);
|
|
265
|
+
|
|
266
|
+
return request;
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
/** Sends an AI event and waits for its matching RTD response. @internal */
|
|
270
|
+
public async requestAndWaitForRtd<T>(options: RtdRequestOptions): Promise<T> {
|
|
271
|
+
const key = ApiAIAssistant.getRtdRequestKey(options.rtdEventType, options.correlationId);
|
|
272
|
+
let resolveResult: (payload: T) => void = () => undefined;
|
|
273
|
+
let rejectResult: (error: Error) => void = () => undefined;
|
|
274
|
+
const result = new Promise<T>((resolve, reject) => {
|
|
275
|
+
resolveResult = resolve;
|
|
276
|
+
rejectResult = reject;
|
|
277
|
+
});
|
|
278
|
+
const previousRequest = this.pendingRtdRequests.get(key);
|
|
279
|
+
if (previousRequest?.timeoutId) {
|
|
280
|
+
clearTimeout(previousRequest.timeoutId);
|
|
281
|
+
}
|
|
282
|
+
const request: PendingRtdRequest<T> = {
|
|
283
|
+
correlationId: options.correlationId,
|
|
284
|
+
rtdEventType: options.rtdEventType,
|
|
285
|
+
resolve: resolveResult,
|
|
286
|
+
reject: rejectResult,
|
|
287
|
+
};
|
|
288
|
+
|
|
289
|
+
request.timeoutId = setTimeout(() => {
|
|
290
|
+
this.removeRtdRequest<T>(options.rtdEventType, options.correlationId, (currentRequest) => {
|
|
291
|
+
currentRequest.reject(options.createTimeoutError());
|
|
292
|
+
});
|
|
293
|
+
}, options.timeoutMs);
|
|
294
|
+
this.pendingRtdRequests.set(key, request as PendingRtdRequest<unknown>);
|
|
295
|
+
const publishTimestamp = options.publishTimestamp ?? Date.now();
|
|
296
|
+
const acknowledgement = Promise.resolve()
|
|
297
|
+
.then(() =>
|
|
298
|
+
this.sendEvent(
|
|
299
|
+
options.agentId,
|
|
300
|
+
options.interactionId,
|
|
301
|
+
options.eventType,
|
|
302
|
+
options.eventName,
|
|
303
|
+
options.eventMetaData,
|
|
304
|
+
undefined,
|
|
305
|
+
undefined,
|
|
306
|
+
publishTimestamp,
|
|
307
|
+
options.timeout
|
|
308
|
+
)
|
|
309
|
+
)
|
|
310
|
+
.catch((error) => {
|
|
311
|
+
this.removeRtdRequest(options.rtdEventType, options.correlationId);
|
|
312
|
+
throw error;
|
|
313
|
+
});
|
|
314
|
+
|
|
315
|
+
const [payload] = await Promise.all([result, acknowledgement]);
|
|
316
|
+
|
|
317
|
+
return payload;
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
/** Resolves a pending request from a parsed RTD event. @internal */
|
|
321
|
+
public resolveFromRtdEvent<T>(
|
|
322
|
+
rtdEventType: string,
|
|
323
|
+
correlationId: string,
|
|
324
|
+
payload: T
|
|
325
|
+
): 'resolved' | 'not-found' {
|
|
326
|
+
const request = this.removeRtdRequest<T>(rtdEventType, correlationId, (currentRequest) => {
|
|
327
|
+
currentRequest.resolve(payload);
|
|
328
|
+
});
|
|
329
|
+
|
|
330
|
+
return request ? 'resolved' : 'not-found';
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
/** Clears pending RTD requests when the RTD lifecycle ends. @internal */
|
|
334
|
+
public clearAllRtdRequests(): void {
|
|
335
|
+
Array.from(this.pendingRtdRequests.values()).forEach((request) => {
|
|
336
|
+
this.removeRtdRequest(request.rtdEventType, request.correlationId, (currentRequest) => {
|
|
337
|
+
currentRequest.reject(new Error('RTD request cleared'));
|
|
338
|
+
});
|
|
339
|
+
});
|
|
340
|
+
}
|
|
341
|
+
|
|
73
342
|
/**
|
|
74
343
|
* Sends an event to the AI Assistant service.
|
|
75
344
|
* @param agentId - agent identifier
|
|
76
345
|
* @param interactionId - interaction/conversation identifier
|
|
77
346
|
* @param eventType - the type of event (e.g. 'CUSTOM_EVENT')
|
|
78
347
|
* @param eventName - the name of the event (e.g. 'GET_TRANSCRIPTS')
|
|
79
|
-
* @param
|
|
348
|
+
* @param eventMetaData - event-specific fields to include in eventDetails.data
|
|
349
|
+
* @param languageCode - language code within eventDetails.data
|
|
350
|
+
* @param trackingId - tracking identifier within eventDetails.data
|
|
80
351
|
*/
|
|
81
352
|
public async sendEvent(
|
|
82
353
|
agentId: string,
|
|
83
354
|
interactionId: string,
|
|
84
355
|
eventType: AIAssistantEventType,
|
|
85
356
|
eventName: AIAssistantEventName,
|
|
86
|
-
|
|
357
|
+
eventMetaData?: Record<string, unknown>,
|
|
358
|
+
languageCode?: string,
|
|
359
|
+
trackingId?: string,
|
|
360
|
+
publishTimestamp?: number,
|
|
361
|
+
timeout?: number
|
|
87
362
|
): Promise<Record<string, unknown>> {
|
|
88
363
|
LoggerProxy.info('Sending event', {
|
|
89
364
|
module: CC_FILE,
|
|
90
365
|
method: METHODS.SEND_EVENT,
|
|
91
366
|
interactionId,
|
|
92
|
-
data: {eventType, eventName,
|
|
367
|
+
data: {eventType, eventName, eventMetaData},
|
|
93
368
|
});
|
|
94
369
|
this.metricsManager.timeEvent([
|
|
95
370
|
METRIC_EVENT_NAMES.AI_ASSISTANT_SEND_EVENT_SUCCESS,
|
|
@@ -99,28 +374,33 @@ export class ApiAIAssistant {
|
|
|
99
374
|
try {
|
|
100
375
|
const baseUrl = this.getBaseUrl();
|
|
101
376
|
const orgId = this.webex.credentials.getOrgId();
|
|
377
|
+
const data = {
|
|
378
|
+
...eventMetaData,
|
|
379
|
+
interactionId,
|
|
380
|
+
actionTimeStamp: String(Date.now()),
|
|
381
|
+
languageCode,
|
|
382
|
+
trackingId,
|
|
383
|
+
};
|
|
102
384
|
const response = (await this.webex.request({
|
|
103
385
|
uri: `${baseUrl}${AI_ASSISTANT_API_URLS.EVENT}`,
|
|
104
386
|
method: HTTP_METHODS.POST,
|
|
105
387
|
addAuthHeader: true,
|
|
388
|
+
...(timeout !== undefined ? {timeout} : {}),
|
|
106
389
|
body: {
|
|
107
390
|
agentId,
|
|
108
391
|
orgId,
|
|
109
392
|
eventType,
|
|
110
393
|
eventName,
|
|
394
|
+
...(publishTimestamp !== undefined ? {publishTimestamp} : {}),
|
|
111
395
|
eventDetails: {
|
|
112
|
-
data
|
|
113
|
-
interactionId,
|
|
114
|
-
action,
|
|
115
|
-
actionTimeStamp: String(Date.now()),
|
|
116
|
-
},
|
|
396
|
+
data,
|
|
117
397
|
},
|
|
118
398
|
},
|
|
119
399
|
})) as IHttpResponse;
|
|
120
400
|
|
|
121
401
|
this.metricsManager.trackEvent(
|
|
122
402
|
METRIC_EVENT_NAMES.AI_ASSISTANT_SEND_EVENT_SUCCESS,
|
|
123
|
-
{agentId, orgId, interactionId, eventType, eventName
|
|
403
|
+
{agentId, orgId, interactionId, eventType, eventName},
|
|
124
404
|
['operational']
|
|
125
405
|
);
|
|
126
406
|
|
|
@@ -132,7 +412,6 @@ export class ApiAIAssistant {
|
|
|
132
412
|
interactionId,
|
|
133
413
|
eventType,
|
|
134
414
|
eventName,
|
|
135
|
-
action,
|
|
136
415
|
error: error instanceof Error ? error.message : String(error),
|
|
137
416
|
},
|
|
138
417
|
['operational']
|
|
@@ -143,6 +422,193 @@ export class ApiAIAssistant {
|
|
|
143
422
|
}
|
|
144
423
|
}
|
|
145
424
|
|
|
425
|
+
/**
|
|
426
|
+
* Requests real-time assistance for an interaction.
|
|
427
|
+
*
|
|
428
|
+
* @param params - Real-time assistance request parameters
|
|
429
|
+
* @returns HTTP response body from the AI Assistant event API
|
|
430
|
+
* @public
|
|
431
|
+
*/
|
|
432
|
+
public async getRealTimeAssistance(params: RealTimeAssistanceParams) {
|
|
433
|
+
const {agentId, interactionId, context} = params;
|
|
434
|
+
const trimmedContext = context?.trim();
|
|
435
|
+
const languageCode = params.languageCode ?? 'en';
|
|
436
|
+
const trackingId = `WX_CC_SDK_${uuidv4()}`;
|
|
437
|
+
const eventName = trimmedContext
|
|
438
|
+
? AIAssistantEventName.ADD_SUGGESTIONS_EXTRA_CONTEXT
|
|
439
|
+
: AIAssistantEventName.GET_SUGGESTIONS;
|
|
440
|
+
|
|
441
|
+
const loggerContext = {
|
|
442
|
+
module: CC_FILE,
|
|
443
|
+
method: METHODS.GET_REAL_TIME_ASSISTANCE,
|
|
444
|
+
interactionId,
|
|
445
|
+
trackingId,
|
|
446
|
+
data: {eventName},
|
|
447
|
+
};
|
|
448
|
+
|
|
449
|
+
LoggerProxy.info('Requesting real-time assistance', loggerContext);
|
|
450
|
+
|
|
451
|
+
this.metricsManager.timeEvent([
|
|
452
|
+
METRIC_EVENT_NAMES.AI_ASSISTANT_GET_REAL_TIME_ASSISTANCE_SUCCESS,
|
|
453
|
+
METRIC_EVENT_NAMES.AI_ASSISTANT_GET_REAL_TIME_ASSISTANCE_FAILED,
|
|
454
|
+
]);
|
|
455
|
+
|
|
456
|
+
try {
|
|
457
|
+
if (!this.aiFeature?.suggestedResponses?.enable) {
|
|
458
|
+
const {error: detailedError} = getErrorDetails(
|
|
459
|
+
new Error('SUGGESTED_RESPONSES_NOT_ENABLED'),
|
|
460
|
+
METHODS.GET_REAL_TIME_ASSISTANCE,
|
|
461
|
+
CC_FILE
|
|
462
|
+
);
|
|
463
|
+
throw detailedError;
|
|
464
|
+
}
|
|
465
|
+
|
|
466
|
+
const orgId = this.webex.credentials.getOrgId();
|
|
467
|
+
|
|
468
|
+
const response = await this.sendEvent(
|
|
469
|
+
agentId,
|
|
470
|
+
interactionId,
|
|
471
|
+
AIAssistantEventType.CUSTOM_EVENT,
|
|
472
|
+
eventName,
|
|
473
|
+
trimmedContext !== undefined ? {context: trimmedContext} : undefined,
|
|
474
|
+
languageCode,
|
|
475
|
+
trackingId
|
|
476
|
+
);
|
|
477
|
+
|
|
478
|
+
this.metricsManager.trackEvent(
|
|
479
|
+
METRIC_EVENT_NAMES.AI_ASSISTANT_GET_REAL_TIME_ASSISTANCE_SUCCESS,
|
|
480
|
+
{
|
|
481
|
+
agentId,
|
|
482
|
+
orgId,
|
|
483
|
+
interactionId,
|
|
484
|
+
eventName,
|
|
485
|
+
trackingId,
|
|
486
|
+
context,
|
|
487
|
+
},
|
|
488
|
+
['operational']
|
|
489
|
+
);
|
|
490
|
+
LoggerProxy.log('Real-time assistance request succeeded', loggerContext);
|
|
491
|
+
|
|
492
|
+
return response;
|
|
493
|
+
} catch (error) {
|
|
494
|
+
LoggerProxy.error('Real-time assistance request failed', {...loggerContext, error});
|
|
495
|
+
this.metricsManager.trackEvent(
|
|
496
|
+
METRIC_EVENT_NAMES.AI_ASSISTANT_GET_REAL_TIME_ASSISTANCE_FAILED,
|
|
497
|
+
{
|
|
498
|
+
agentId,
|
|
499
|
+
interactionId,
|
|
500
|
+
trackingId,
|
|
501
|
+
eventName,
|
|
502
|
+
error: error instanceof Error ? error.message : String(error),
|
|
503
|
+
},
|
|
504
|
+
['operational']
|
|
505
|
+
);
|
|
506
|
+
|
|
507
|
+
const {error: detailedError} = getErrorDetails(
|
|
508
|
+
error,
|
|
509
|
+
METHODS.GET_REAL_TIME_ASSISTANCE,
|
|
510
|
+
CC_FILE
|
|
511
|
+
);
|
|
512
|
+
throw detailedError;
|
|
513
|
+
}
|
|
514
|
+
}
|
|
515
|
+
|
|
516
|
+
/**
|
|
517
|
+
* Sends user action feedback for a real-time assistance adaptive card.
|
|
518
|
+
*
|
|
519
|
+
* @param params - Real-time assistance user action parameters
|
|
520
|
+
* @returns HTTP response body from the AI Assistant event API
|
|
521
|
+
* @public
|
|
522
|
+
*/
|
|
523
|
+
public async sendRealTimeAssistanceUserAction(
|
|
524
|
+
params: RealTimeAssistanceUserActionParams
|
|
525
|
+
): Promise<Record<string, unknown>> {
|
|
526
|
+
const {agentId, interactionId, adaptiveCardId, actionId} = params;
|
|
527
|
+
const actionType = 'Action.Submit';
|
|
528
|
+
const languageCode = params.languageCode ?? 'en';
|
|
529
|
+
const trackingId = `WX_CC_SDK_${uuidv4()}`;
|
|
530
|
+
|
|
531
|
+
const loggerContext = {
|
|
532
|
+
module: CC_FILE,
|
|
533
|
+
method: METHODS.SEND_REAL_TIME_ASSISTANCE_USER_ACTION,
|
|
534
|
+
interactionId,
|
|
535
|
+
trackingId,
|
|
536
|
+
data: {actionId, adaptiveCardId},
|
|
537
|
+
};
|
|
538
|
+
|
|
539
|
+
LoggerProxy.info('Sending real-time assistance user action', loggerContext);
|
|
540
|
+
|
|
541
|
+
this.metricsManager.timeEvent([
|
|
542
|
+
METRIC_EVENT_NAMES.AI_ASSISTANT_SEND_REAL_TIME_ASSISTANCE_USER_ACTION_SUCCESS,
|
|
543
|
+
METRIC_EVENT_NAMES.AI_ASSISTANT_SEND_REAL_TIME_ASSISTANCE_USER_ACTION_FAILED,
|
|
544
|
+
]);
|
|
545
|
+
|
|
546
|
+
try {
|
|
547
|
+
if (!this.aiFeature?.suggestedResponses?.enable) {
|
|
548
|
+
const {error: detailedError} = getErrorDetails(
|
|
549
|
+
new Error('SUGGESTED_RESPONSES_NOT_ENABLED'),
|
|
550
|
+
METHODS.SEND_REAL_TIME_ASSISTANCE_USER_ACTION,
|
|
551
|
+
CC_FILE
|
|
552
|
+
);
|
|
553
|
+
throw detailedError;
|
|
554
|
+
}
|
|
555
|
+
|
|
556
|
+
const orgId = this.webex.credentials.getOrgId();
|
|
557
|
+
const response = await this.sendEvent(
|
|
558
|
+
agentId,
|
|
559
|
+
interactionId,
|
|
560
|
+
AIAssistantEventType.CUSTOM_EVENT,
|
|
561
|
+
AIAssistantEventName.SUGGESTED_RESPONSES_USER_ACTION,
|
|
562
|
+
{
|
|
563
|
+
adaptiveCardId,
|
|
564
|
+
userAction: {
|
|
565
|
+
actionType,
|
|
566
|
+
actionId,
|
|
567
|
+
},
|
|
568
|
+
},
|
|
569
|
+
languageCode,
|
|
570
|
+
trackingId
|
|
571
|
+
);
|
|
572
|
+
|
|
573
|
+
this.metricsManager.trackEvent(
|
|
574
|
+
METRIC_EVENT_NAMES.AI_ASSISTANT_SEND_REAL_TIME_ASSISTANCE_USER_ACTION_SUCCESS,
|
|
575
|
+
{
|
|
576
|
+
agentId,
|
|
577
|
+
orgId,
|
|
578
|
+
interactionId,
|
|
579
|
+
adaptiveCardId,
|
|
580
|
+
actionId,
|
|
581
|
+
trackingId,
|
|
582
|
+
},
|
|
583
|
+
['operational']
|
|
584
|
+
);
|
|
585
|
+
LoggerProxy.log('Real-time assistance user action sent', loggerContext);
|
|
586
|
+
|
|
587
|
+
return response;
|
|
588
|
+
} catch (error) {
|
|
589
|
+
LoggerProxy.error('Real-time assistance user action failed', {...loggerContext, error});
|
|
590
|
+
this.metricsManager.trackEvent(
|
|
591
|
+
METRIC_EVENT_NAMES.AI_ASSISTANT_SEND_REAL_TIME_ASSISTANCE_USER_ACTION_FAILED,
|
|
592
|
+
{
|
|
593
|
+
agentId,
|
|
594
|
+
interactionId,
|
|
595
|
+
adaptiveCardId,
|
|
596
|
+
actionId,
|
|
597
|
+
trackingId,
|
|
598
|
+
error: error instanceof Error ? error.message : String(error),
|
|
599
|
+
},
|
|
600
|
+
['operational']
|
|
601
|
+
);
|
|
602
|
+
|
|
603
|
+
const {error: detailedError} = getErrorDetails(
|
|
604
|
+
error,
|
|
605
|
+
METHODS.SEND_REAL_TIME_ASSISTANCE_USER_ACTION,
|
|
606
|
+
CC_FILE
|
|
607
|
+
);
|
|
608
|
+
throw detailedError;
|
|
609
|
+
}
|
|
610
|
+
}
|
|
611
|
+
|
|
146
612
|
/**
|
|
147
613
|
* Fetches historic transcripts for an interaction.
|
|
148
614
|
* This API is allowed only when real-time transcription feature is enabled.
|
|
@@ -171,6 +637,18 @@ export class ApiAIAssistant {
|
|
|
171
637
|
throw detailedError;
|
|
172
638
|
}
|
|
173
639
|
|
|
640
|
+
if (
|
|
641
|
+
!this.isValidTranscriptIdentifier(agentId) ||
|
|
642
|
+
!this.isValidTranscriptIdentifier(interactionId)
|
|
643
|
+
) {
|
|
644
|
+
const {error: detailedError} = getErrorDetails(
|
|
645
|
+
new Error('INVALID_AGENT_ID_OR_INTERACTION_ID'),
|
|
646
|
+
METHODS.FETCH_HISTORIC_TRANSCRIPTS,
|
|
647
|
+
CC_FILE
|
|
648
|
+
);
|
|
649
|
+
throw detailedError;
|
|
650
|
+
}
|
|
651
|
+
|
|
174
652
|
try {
|
|
175
653
|
const baseUrl = this.getBaseUrl();
|
|
176
654
|
const orgId = this.webex.credentials.getOrgId();
|
|
@@ -201,6 +679,7 @@ export class ApiAIAssistant {
|
|
|
201
679
|
},
|
|
202
680
|
['operational']
|
|
203
681
|
);
|
|
682
|
+
|
|
204
683
|
if (error instanceof Error) {
|
|
205
684
|
throw error;
|
|
206
685
|
}
|