@absolutejs/voice 0.0.22-beta.266 → 0.0.22-beta.268
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/dist/index.d.ts +1 -1
- package/dist/index.js +25 -1
- package/dist/telephonyOutcome.d.ts +20 -0
- package/dist/testing/index.js +25 -1
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -115,7 +115,7 @@ export type { VoiceLiveLatencyOptions, VoiceLiveLatencyReport, VoiceLiveLatencyR
|
|
|
115
115
|
export type { VoiceLatencySLOBudget, VoiceLatencySLOGateError, VoiceLatencySLOGateOptions, VoiceLatencySLOGateReport, VoiceLatencySLOMeasurement, VoiceLatencySLOStage, VoiceLatencySLOStageSummary, VoiceLatencySLOStatus } from './latencySlo';
|
|
116
116
|
export type { VoiceTurnQualityHTMLHandlerOptions, VoiceTurnQualityItem, VoiceTurnQualityOptions, VoiceTurnQualityReport, VoiceTurnQualityRoutesOptions, VoiceTurnQualityStatus } from './turnQuality';
|
|
117
117
|
export type { VoiceOutcomeContractAssertionInput, VoiceOutcomeContractAssertionReport, VoiceOutcomeContractDefinition, VoiceOutcomeContractHTMLHandlerOptions, VoiceOutcomeContractIssue, VoiceOutcomeContractOptions, VoiceOutcomeContractReport, VoiceOutcomeContractRoutesOptions, VoiceOutcomeContractStatus, VoiceOutcomeContractSuiteReport } from './outcomeContract';
|
|
118
|
-
export type { VoiceTelephonyOutcomeAction, VoiceTelephonyOutcomeDecision, VoiceTelephonyOutcomePolicy, VoiceTelephonyOutcomeProviderEvent, VoiceTelephonyOutcomeRouteResult, VoiceTelephonyOutcomeStatusDecision, VoiceTelephonyWebhookDecision, VoiceTelephonyWebhookHandlerOptions, VoiceTelephonyWebhookIdempotencyStore, VoiceTelephonyWebhookNormalizationEvidenceDecision, VoiceTelephonyWebhookNormalizationEvidenceInput, VoiceTelephonyWebhookNormalizationEvidenceReport, VoiceTelephonyWebhookParseInput, VoiceTelephonyWebhookProvider, VoiceTelephonyWebhookRoutesOptions, VoiceTelephonyWebhookVerificationResult, StoredVoiceTelephonyWebhookDecision } from './telephonyOutcome';
|
|
118
|
+
export type { VoiceTelephonyOutcomeAction, VoiceTelephonyOutcomeDecision, VoiceTelephonyOutcomePolicy, VoiceTelephonyOutcomeProviderEvent, VoiceTelephonyOutcomeRouteResult, VoiceTelephonyOutcomeStatusDecision, VoiceTelephonyWebhookDecision, VoiceTelephonyWebhookHandlerOptions, VoiceTelephonyWebhookIdempotencyStore, VoiceTelephonyWebhookNormalizationEvidenceDecision, VoiceTelephonyWebhookNormalizationEvidenceInput, VoiceTelephonyWebhookNormalizationEvidenceReport, VoiceTelephonyWebhookParseInput, VoiceTelephonyWebhookProvider, VoiceTelephonyWebhookRoutesOptions, VoiceTelephonyWebhookVerificationEvidenceAttempt, VoiceTelephonyWebhookVerificationResult, StoredVoiceTelephonyWebhookDecision } from './telephonyOutcome';
|
|
119
119
|
export type { VoicePhoneAgentCarrier, VoicePhoneAgentCarrierSummary, VoicePhoneAssistantEvidenceInput, VoicePhoneAssistantEvidenceReport, VoicePhoneCallControlEvidenceInput, VoicePhoneCallControlEvidenceReport, VoicePhoneAgentLifecycleStage, VoicePhoneAgentPlivoCarrier, VoicePhoneAgentRoutes, VoicePhoneAgentRoutesOptions, VoicePhoneAgentSetupReport, VoicePhoneAgentTelnyxCarrier, VoicePhoneAgentTwilioCarrier } from './phoneAgent';
|
|
120
120
|
export type { VoicePhoneAgentProductionSmokeIssue, VoicePhoneAgentProductionSmokeHandlerOptions, VoicePhoneAgentProductionSmokeHTMLHandlerOptions, VoicePhoneAgentProductionSmokeOptions, VoicePhoneAgentProductionSmokeReport, VoicePhoneAgentProductionSmokeRoutesOptions, VoicePhoneAgentProductionSmokeRequirement } from './phoneAgentProductionSmoke';
|
|
121
121
|
export type { VoiceOpsConsoleLink, VoiceOpsConsoleReport, VoiceOpsConsoleRoutesOptions } from './opsConsoleRoutes';
|
package/dist/index.js
CHANGED
|
@@ -17396,6 +17396,7 @@ var isCallDisposition = (value) => value === "completed" || value === "escalated
|
|
|
17396
17396
|
var evaluateVoiceTelephonyWebhookNormalizationEvidence = (input = {}) => {
|
|
17397
17397
|
const issues = [];
|
|
17398
17398
|
const decisions = input.decisions ?? [];
|
|
17399
|
+
const verificationAttempts = input.verificationAttempts ?? [];
|
|
17399
17400
|
const actions = uniqueSorted3(decisions.map((decision) => decision.decision?.action ?? decision.action).filter(isTelephonyOutcomeAction));
|
|
17400
17401
|
const dispositions = uniqueSorted3(decisions.map((decision) => decision.decision?.disposition ?? decision.disposition).filter(isCallDisposition));
|
|
17401
17402
|
const providers = uniqueSorted3(decisions.map((decision) => decision.provider ?? decision.event?.provider).filter(isTelephonyWebhookProvider));
|
|
@@ -17404,8 +17405,13 @@ var evaluateVoiceTelephonyWebhookNormalizationEvidence = (input = {}) => {
|
|
|
17404
17405
|
const duplicateDecisions = decisions.filter((decision) => decision.duplicate === true);
|
|
17405
17406
|
const duplicateProviders = uniqueSorted3(duplicateDecisions.map((decision) => decision.provider ?? decision.event?.provider).filter(isTelephonyWebhookProvider));
|
|
17406
17407
|
const duplicateIdempotencyKeys = new Set(duplicateDecisions.map((decision) => decision.idempotencyKey).filter((key) => typeof key === "string" && key.length > 0)).size;
|
|
17408
|
+
const duplicateCampaignOutcomesApplied = duplicateDecisions.filter((decision) => isRecord(decision.campaignOutcome) && decision.campaignOutcome.applied === true).length;
|
|
17409
|
+
const duplicateOutcomeReasons = uniqueSorted3(duplicateDecisions.map((decision) => isRecord(decision.campaignOutcome) ? decision.campaignOutcome.reason : undefined).filter((reason) => typeof reason === "string"));
|
|
17407
17410
|
const routeResults = decisions.filter((decision) => isRecord(decision.routeResult)).length;
|
|
17408
17411
|
const missingSessionIds = decisions.filter((decision) => !decision.sessionId).length;
|
|
17412
|
+
const rejectedVerificationAttempts = verificationAttempts.filter((attempt) => attempt.rejected === true || attempt.status === 401 || attempt.verification?.ok === false && attempt.verification.reason === "invalid-signature");
|
|
17413
|
+
const rejectedVerificationProviders = uniqueSorted3(rejectedVerificationAttempts.map((attempt) => attempt.provider).filter(isTelephonyWebhookProvider));
|
|
17414
|
+
const rejectedVerificationSideEffects = rejectedVerificationAttempts.reduce((total, attempt) => total + Math.max(0, attempt.sideEffects ?? 0), 0);
|
|
17409
17415
|
if (input.minDecisions !== undefined && decisions.length < input.minDecisions) {
|
|
17410
17416
|
issues.push(`Expected at least ${String(input.minDecisions)} telephony webhook decision(s), found ${String(decisions.length)}.`);
|
|
17411
17417
|
}
|
|
@@ -17418,6 +17424,15 @@ var evaluateVoiceTelephonyWebhookNormalizationEvidence = (input = {}) => {
|
|
|
17418
17424
|
if (input.minDuplicateIdempotencyKeys !== undefined && duplicateIdempotencyKeys < input.minDuplicateIdempotencyKeys) {
|
|
17419
17425
|
issues.push(`Expected at least ${String(input.minDuplicateIdempotencyKeys)} duplicate telephony webhook idempotency key(s), found ${String(duplicateIdempotencyKeys)}.`);
|
|
17420
17426
|
}
|
|
17427
|
+
if (input.maxDuplicateCampaignOutcomesApplied !== undefined && duplicateCampaignOutcomesApplied > input.maxDuplicateCampaignOutcomesApplied) {
|
|
17428
|
+
issues.push(`Expected at most ${String(input.maxDuplicateCampaignOutcomesApplied)} duplicate telephony webhook campaign outcome application(s), found ${String(duplicateCampaignOutcomesApplied)}.`);
|
|
17429
|
+
}
|
|
17430
|
+
if (input.minRejectedVerificationAttempts !== undefined && rejectedVerificationAttempts.length < input.minRejectedVerificationAttempts) {
|
|
17431
|
+
issues.push(`Expected at least ${String(input.minRejectedVerificationAttempts)} rejected telephony webhook verification attempt(s), found ${String(rejectedVerificationAttempts.length)}.`);
|
|
17432
|
+
}
|
|
17433
|
+
if (input.maxRejectedVerificationSideEffects !== undefined && rejectedVerificationSideEffects > input.maxRejectedVerificationSideEffects) {
|
|
17434
|
+
issues.push(`Expected at most ${String(input.maxRejectedVerificationSideEffects)} rejected telephony webhook side effect(s), found ${String(rejectedVerificationSideEffects)}.`);
|
|
17435
|
+
}
|
|
17421
17436
|
if (input.maxMissingSessionIds !== undefined && missingSessionIds > input.maxMissingSessionIds) {
|
|
17422
17437
|
issues.push(`Expected at most ${String(input.maxMissingSessionIds)} telephony webhook decision(s) without sessionId, found ${String(missingSessionIds)}.`);
|
|
17423
17438
|
}
|
|
@@ -17430,6 +17445,9 @@ var evaluateVoiceTelephonyWebhookNormalizationEvidence = (input = {}) => {
|
|
|
17430
17445
|
for (const provider of findMissing3(duplicateProviders, input.requiredDuplicateProviders)) {
|
|
17431
17446
|
issues.push(`Missing duplicate telephony webhook provider: ${provider}.`);
|
|
17432
17447
|
}
|
|
17448
|
+
for (const provider of findMissing3(rejectedVerificationProviders, input.requiredRejectedVerificationProviders)) {
|
|
17449
|
+
issues.push(`Missing rejected telephony webhook verification provider: ${provider}.`);
|
|
17450
|
+
}
|
|
17433
17451
|
for (const action of findMissing3(actions, input.requiredActions)) {
|
|
17434
17452
|
issues.push(`Missing telephony webhook action: ${action}.`);
|
|
17435
17453
|
}
|
|
@@ -17441,15 +17459,21 @@ var evaluateVoiceTelephonyWebhookNormalizationEvidence = (input = {}) => {
|
|
|
17441
17459
|
applied,
|
|
17442
17460
|
decisions: decisions.length,
|
|
17443
17461
|
dispositions,
|
|
17462
|
+
duplicateCampaignOutcomesApplied,
|
|
17444
17463
|
duplicateIdempotencyKeys,
|
|
17464
|
+
duplicateOutcomeReasons,
|
|
17445
17465
|
duplicateProviders,
|
|
17446
17466
|
duplicates: duplicateDecisions.length,
|
|
17447
17467
|
issues,
|
|
17448
17468
|
missingSessionIds,
|
|
17449
17469
|
ok: issues.length === 0,
|
|
17450
17470
|
providers,
|
|
17471
|
+
rejectedVerificationAttempts: rejectedVerificationAttempts.length,
|
|
17472
|
+
rejectedVerificationProviders,
|
|
17473
|
+
rejectedVerificationSideEffects,
|
|
17451
17474
|
routeResults,
|
|
17452
|
-
sources
|
|
17475
|
+
sources,
|
|
17476
|
+
verificationAttempts: verificationAttempts.length
|
|
17453
17477
|
};
|
|
17454
17478
|
};
|
|
17455
17479
|
var assertVoiceTelephonyWebhookNormalizationEvidence = (input = {}) => {
|
|
@@ -75,6 +75,7 @@ export type VoiceTelephonyWebhookNormalizationEvidenceDecision = {
|
|
|
75
75
|
};
|
|
76
76
|
disposition?: VoiceCallDisposition | string;
|
|
77
77
|
duplicate?: boolean;
|
|
78
|
+
campaignOutcome?: unknown;
|
|
78
79
|
event?: VoiceTelephonyOutcomeProviderEvent;
|
|
79
80
|
idempotencyKey?: string;
|
|
80
81
|
provider?: VoiceTelephonyWebhookProvider | string;
|
|
@@ -82,6 +83,14 @@ export type VoiceTelephonyWebhookNormalizationEvidenceDecision = {
|
|
|
82
83
|
sessionId?: string;
|
|
83
84
|
source?: VoiceTelephonyOutcomeDecision['source'] | string;
|
|
84
85
|
};
|
|
86
|
+
export type VoiceTelephonyWebhookVerificationEvidenceAttempt = {
|
|
87
|
+
decisions?: number;
|
|
88
|
+
provider?: VoiceTelephonyWebhookProvider | string;
|
|
89
|
+
rejected?: boolean;
|
|
90
|
+
sideEffects?: number;
|
|
91
|
+
status?: number;
|
|
92
|
+
verification?: VoiceTelephonyWebhookVerificationResult;
|
|
93
|
+
};
|
|
85
94
|
export type VoiceTelephonyWebhookNormalizationEvidenceInput = {
|
|
86
95
|
decisions?: VoiceTelephonyWebhookNormalizationEvidenceDecision[];
|
|
87
96
|
maxMissingSessionIds?: number;
|
|
@@ -89,26 +98,37 @@ export type VoiceTelephonyWebhookNormalizationEvidenceInput = {
|
|
|
89
98
|
minDecisions?: number;
|
|
90
99
|
minDuplicateIdempotencyKeys?: number;
|
|
91
100
|
minDuplicates?: number;
|
|
101
|
+
maxDuplicateCampaignOutcomesApplied?: number;
|
|
102
|
+
maxRejectedVerificationSideEffects?: number;
|
|
103
|
+
minRejectedVerificationAttempts?: number;
|
|
92
104
|
requiredActions?: VoiceTelephonyOutcomeAction[];
|
|
93
105
|
requiredDispositions?: VoiceCallDisposition[];
|
|
94
106
|
requiredDuplicateProviders?: VoiceTelephonyWebhookProvider[];
|
|
95
107
|
requiredProviders?: VoiceTelephonyWebhookProvider[];
|
|
108
|
+
requiredRejectedVerificationProviders?: VoiceTelephonyWebhookProvider[];
|
|
96
109
|
requireRouteResults?: boolean;
|
|
110
|
+
verificationAttempts?: VoiceTelephonyWebhookVerificationEvidenceAttempt[];
|
|
97
111
|
};
|
|
98
112
|
export type VoiceTelephonyWebhookNormalizationEvidenceReport = {
|
|
99
113
|
actions: VoiceTelephonyOutcomeAction[];
|
|
100
114
|
applied: number;
|
|
101
115
|
decisions: number;
|
|
102
116
|
dispositions: VoiceCallDisposition[];
|
|
117
|
+
duplicateCampaignOutcomesApplied: number;
|
|
103
118
|
duplicateIdempotencyKeys: number;
|
|
119
|
+
duplicateOutcomeReasons: string[];
|
|
104
120
|
duplicateProviders: VoiceTelephonyWebhookProvider[];
|
|
105
121
|
duplicates: number;
|
|
106
122
|
issues: string[];
|
|
107
123
|
missingSessionIds: number;
|
|
108
124
|
ok: boolean;
|
|
109
125
|
providers: VoiceTelephonyWebhookProvider[];
|
|
126
|
+
rejectedVerificationAttempts: number;
|
|
127
|
+
rejectedVerificationProviders: VoiceTelephonyWebhookProvider[];
|
|
128
|
+
rejectedVerificationSideEffects: number;
|
|
110
129
|
routeResults: number;
|
|
111
130
|
sources: string[];
|
|
131
|
+
verificationAttempts: number;
|
|
112
132
|
};
|
|
113
133
|
export type VoiceTelephonyWebhookIdempotencyStore<TResult = unknown> = {
|
|
114
134
|
get: (key: string) => Promise<StoredVoiceTelephonyWebhookDecision<TResult> | undefined> | StoredVoiceTelephonyWebhookDecision<TResult> | undefined;
|
package/dist/testing/index.js
CHANGED
|
@@ -8251,6 +8251,7 @@ var isCallDisposition = (value) => value === "completed" || value === "escalated
|
|
|
8251
8251
|
var evaluateVoiceTelephonyWebhookNormalizationEvidence = (input = {}) => {
|
|
8252
8252
|
const issues = [];
|
|
8253
8253
|
const decisions = input.decisions ?? [];
|
|
8254
|
+
const verificationAttempts = input.verificationAttempts ?? [];
|
|
8254
8255
|
const actions = uniqueSorted(decisions.map((decision) => decision.decision?.action ?? decision.action).filter(isTelephonyOutcomeAction));
|
|
8255
8256
|
const dispositions = uniqueSorted(decisions.map((decision) => decision.decision?.disposition ?? decision.disposition).filter(isCallDisposition));
|
|
8256
8257
|
const providers = uniqueSorted(decisions.map((decision) => decision.provider ?? decision.event?.provider).filter(isTelephonyWebhookProvider));
|
|
@@ -8259,8 +8260,13 @@ var evaluateVoiceTelephonyWebhookNormalizationEvidence = (input = {}) => {
|
|
|
8259
8260
|
const duplicateDecisions = decisions.filter((decision) => decision.duplicate === true);
|
|
8260
8261
|
const duplicateProviders = uniqueSorted(duplicateDecisions.map((decision) => decision.provider ?? decision.event?.provider).filter(isTelephonyWebhookProvider));
|
|
8261
8262
|
const duplicateIdempotencyKeys = new Set(duplicateDecisions.map((decision) => decision.idempotencyKey).filter((key) => typeof key === "string" && key.length > 0)).size;
|
|
8263
|
+
const duplicateCampaignOutcomesApplied = duplicateDecisions.filter((decision) => isRecord(decision.campaignOutcome) && decision.campaignOutcome.applied === true).length;
|
|
8264
|
+
const duplicateOutcomeReasons = uniqueSorted(duplicateDecisions.map((decision) => isRecord(decision.campaignOutcome) ? decision.campaignOutcome.reason : undefined).filter((reason) => typeof reason === "string"));
|
|
8262
8265
|
const routeResults = decisions.filter((decision) => isRecord(decision.routeResult)).length;
|
|
8263
8266
|
const missingSessionIds = decisions.filter((decision) => !decision.sessionId).length;
|
|
8267
|
+
const rejectedVerificationAttempts = verificationAttempts.filter((attempt) => attempt.rejected === true || attempt.status === 401 || attempt.verification?.ok === false && attempt.verification.reason === "invalid-signature");
|
|
8268
|
+
const rejectedVerificationProviders = uniqueSorted(rejectedVerificationAttempts.map((attempt) => attempt.provider).filter(isTelephonyWebhookProvider));
|
|
8269
|
+
const rejectedVerificationSideEffects = rejectedVerificationAttempts.reduce((total, attempt) => total + Math.max(0, attempt.sideEffects ?? 0), 0);
|
|
8264
8270
|
if (input.minDecisions !== undefined && decisions.length < input.minDecisions) {
|
|
8265
8271
|
issues.push(`Expected at least ${String(input.minDecisions)} telephony webhook decision(s), found ${String(decisions.length)}.`);
|
|
8266
8272
|
}
|
|
@@ -8273,6 +8279,15 @@ var evaluateVoiceTelephonyWebhookNormalizationEvidence = (input = {}) => {
|
|
|
8273
8279
|
if (input.minDuplicateIdempotencyKeys !== undefined && duplicateIdempotencyKeys < input.minDuplicateIdempotencyKeys) {
|
|
8274
8280
|
issues.push(`Expected at least ${String(input.minDuplicateIdempotencyKeys)} duplicate telephony webhook idempotency key(s), found ${String(duplicateIdempotencyKeys)}.`);
|
|
8275
8281
|
}
|
|
8282
|
+
if (input.maxDuplicateCampaignOutcomesApplied !== undefined && duplicateCampaignOutcomesApplied > input.maxDuplicateCampaignOutcomesApplied) {
|
|
8283
|
+
issues.push(`Expected at most ${String(input.maxDuplicateCampaignOutcomesApplied)} duplicate telephony webhook campaign outcome application(s), found ${String(duplicateCampaignOutcomesApplied)}.`);
|
|
8284
|
+
}
|
|
8285
|
+
if (input.minRejectedVerificationAttempts !== undefined && rejectedVerificationAttempts.length < input.minRejectedVerificationAttempts) {
|
|
8286
|
+
issues.push(`Expected at least ${String(input.minRejectedVerificationAttempts)} rejected telephony webhook verification attempt(s), found ${String(rejectedVerificationAttempts.length)}.`);
|
|
8287
|
+
}
|
|
8288
|
+
if (input.maxRejectedVerificationSideEffects !== undefined && rejectedVerificationSideEffects > input.maxRejectedVerificationSideEffects) {
|
|
8289
|
+
issues.push(`Expected at most ${String(input.maxRejectedVerificationSideEffects)} rejected telephony webhook side effect(s), found ${String(rejectedVerificationSideEffects)}.`);
|
|
8290
|
+
}
|
|
8276
8291
|
if (input.maxMissingSessionIds !== undefined && missingSessionIds > input.maxMissingSessionIds) {
|
|
8277
8292
|
issues.push(`Expected at most ${String(input.maxMissingSessionIds)} telephony webhook decision(s) without sessionId, found ${String(missingSessionIds)}.`);
|
|
8278
8293
|
}
|
|
@@ -8285,6 +8300,9 @@ var evaluateVoiceTelephonyWebhookNormalizationEvidence = (input = {}) => {
|
|
|
8285
8300
|
for (const provider of findMissing(duplicateProviders, input.requiredDuplicateProviders)) {
|
|
8286
8301
|
issues.push(`Missing duplicate telephony webhook provider: ${provider}.`);
|
|
8287
8302
|
}
|
|
8303
|
+
for (const provider of findMissing(rejectedVerificationProviders, input.requiredRejectedVerificationProviders)) {
|
|
8304
|
+
issues.push(`Missing rejected telephony webhook verification provider: ${provider}.`);
|
|
8305
|
+
}
|
|
8288
8306
|
for (const action of findMissing(actions, input.requiredActions)) {
|
|
8289
8307
|
issues.push(`Missing telephony webhook action: ${action}.`);
|
|
8290
8308
|
}
|
|
@@ -8296,15 +8314,21 @@ var evaluateVoiceTelephonyWebhookNormalizationEvidence = (input = {}) => {
|
|
|
8296
8314
|
applied,
|
|
8297
8315
|
decisions: decisions.length,
|
|
8298
8316
|
dispositions,
|
|
8317
|
+
duplicateCampaignOutcomesApplied,
|
|
8299
8318
|
duplicateIdempotencyKeys,
|
|
8319
|
+
duplicateOutcomeReasons,
|
|
8300
8320
|
duplicateProviders,
|
|
8301
8321
|
duplicates: duplicateDecisions.length,
|
|
8302
8322
|
issues,
|
|
8303
8323
|
missingSessionIds,
|
|
8304
8324
|
ok: issues.length === 0,
|
|
8305
8325
|
providers,
|
|
8326
|
+
rejectedVerificationAttempts: rejectedVerificationAttempts.length,
|
|
8327
|
+
rejectedVerificationProviders,
|
|
8328
|
+
rejectedVerificationSideEffects,
|
|
8306
8329
|
routeResults,
|
|
8307
|
-
sources
|
|
8330
|
+
sources,
|
|
8331
|
+
verificationAttempts: verificationAttempts.length
|
|
8308
8332
|
};
|
|
8309
8333
|
};
|
|
8310
8334
|
var assertVoiceTelephonyWebhookNormalizationEvidence = (input = {}) => {
|