@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 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;
@@ -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 = {}) => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@absolutejs/voice",
3
- "version": "0.0.22-beta.266",
3
+ "version": "0.0.22-beta.268",
4
4
  "description": "Voice primitives and Elysia plugin for AbsoluteJS",
5
5
  "repository": {
6
6
  "type": "git",