@absolutejs/voice 0.0.22-beta.285 → 0.0.22-beta.287
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
|
@@ -18,8 +18,8 @@ export { assertVoicePlatformCoverage, buildVoicePlatformCoverageSummary, createV
|
|
|
18
18
|
export type { VoicePlatformCoverageAssertionInput, VoicePlatformCoverageAssertionReport, VoicePlatformCoverageEvidence, VoicePlatformCoverageRoutesOptions, VoicePlatformCoverageStatus, VoicePlatformCoverageSummary, VoicePlatformCoverageSummaryInput, VoicePlatformCoverageSurface } from './platformCoverage';
|
|
19
19
|
export { assertVoiceProofTrendEvidence, buildEmptyVoiceProofTrendReport, buildVoiceProofTrendReport, createVoiceProofTrendRoutes, DEFAULT_VOICE_PROOF_TRENDS_MAX_AGE_MS, evaluateVoiceProofTrendEvidence, formatVoiceProofTrendAge, normalizeVoiceProofTrendReport, readVoiceProofTrendReportFile } from './proofTrends';
|
|
20
20
|
export type { VoiceProofTrendAssertionInput, VoiceProofTrendAssertionReport, VoiceProofTrendCycle, VoiceProofTrendReport, VoiceProofTrendReportInput, VoiceProofTrendRoutesOptions, VoiceProofTrendStatus, VoiceProofTrendSummary } from './proofTrends';
|
|
21
|
-
export { assertVoiceSloCalibration, buildVoiceSloCalibrationReport, createVoiceSloThresholdProfile, createVoiceSloCalibrationRoutes, renderVoiceSloCalibrationMarkdown } from './sloCalibration';
|
|
22
|
-
export type { VoiceSloCalibrationMetricKey, VoiceSloCalibrationOptions, VoiceSloCalibrationReport, VoiceSloCalibrationRoutesOptions, VoiceSloCalibrationSample, VoiceSloCalibrationStatus, VoiceSloCalibrationThreshold, VoiceSloCalibrationThresholds, VoiceSloThresholdProfile } from './sloCalibration';
|
|
21
|
+
export { assertVoiceSloCalibration, buildVoiceSloCalibrationReport, createVoiceSloReadinessThresholdOptions, createVoiceSloThresholdProfile, createVoiceSloCalibrationRoutes, renderVoiceSloCalibrationMarkdown } from './sloCalibration';
|
|
22
|
+
export type { VoiceSloCalibrationMetricKey, VoiceSloCalibrationOptions, VoiceSloCalibrationReport, VoiceSloCalibrationRoutesOptions, VoiceSloCalibrationSample, VoiceSloCalibrationStatus, VoiceSloCalibrationThreshold, VoiceSloCalibrationThresholds, VoiceSloReadinessThresholdOptions, VoiceSloThresholdProfile } from './sloCalibration';
|
|
23
23
|
export { assertVoiceLiveOpsControlEvidence, assertVoiceLiveOpsEvidence, buildVoiceLiveOpsControlState, createVoiceLiveOpsController, createVoiceLiveOpsRoutes, createVoiceMemoryLiveOpsControlStore, evaluateVoiceLiveOpsControlEvidence, evaluateVoiceLiveOpsEvidence, getVoiceLiveOpsControlStatus, VOICE_LIVE_OPS_ACTIONS } from './liveOps';
|
|
24
24
|
export type { VoiceLiveOpsAction, VoiceLiveOpsActionInput, VoiceLiveOpsActionResult, VoiceLiveOpsControllerOptions, VoiceLiveOpsControlState, VoiceLiveOpsControlStatus, VoiceLiveOpsControlStore, VoiceLiveOpsControlEvidenceInput, VoiceLiveOpsControlEvidenceReport, VoiceLiveOpsEvidenceInput, VoiceLiveOpsEvidenceReport, VoiceLiveOpsRoutesOptions } from './liveOps';
|
|
25
25
|
export { buildVoiceDeliveryRuntimeReport, createVoiceDeliveryRuntime, createVoiceDeliveryRuntimePresetConfig, createVoiceDeliveryRuntimeRoutes, renderVoiceDeliveryRuntimeHTML } from './deliveryRuntime';
|
package/dist/index.js
CHANGED
|
@@ -10798,6 +10798,18 @@ var findDuplicateTurnIds = (snapshots) => {
|
|
|
10798
10798
|
}
|
|
10799
10799
|
return [...duplicates].sort();
|
|
10800
10800
|
};
|
|
10801
|
+
var percentile = (values, rank) => {
|
|
10802
|
+
if (values.length === 0) {
|
|
10803
|
+
return;
|
|
10804
|
+
}
|
|
10805
|
+
const sorted = [...values].sort((left, right) => left - right);
|
|
10806
|
+
const index = Math.min(sorted.length - 1, Math.max(0, Math.ceil(rank / 100 * sorted.length) - 1));
|
|
10807
|
+
return sorted[index];
|
|
10808
|
+
};
|
|
10809
|
+
var getResumeLatencies = (snapshots) => snapshots.filter((snapshot) => snapshot.reconnect.status === "resumed" && typeof snapshot.reconnect.lastResumedAt === "number").map((snapshot) => {
|
|
10810
|
+
const previousReconnect = snapshots.filter((candidate) => candidate.at <= snapshot.at && candidate.reconnect.status === "reconnecting" && typeof candidate.reconnect.lastDisconnectAt === "number").at(-1);
|
|
10811
|
+
return previousReconnect?.reconnect.lastDisconnectAt === undefined ? undefined : snapshot.reconnect.lastResumedAt - previousReconnect.reconnect.lastDisconnectAt;
|
|
10812
|
+
}).filter((value) => typeof value === "number" && value >= 0);
|
|
10801
10813
|
var runVoiceReconnectContract = (options) => {
|
|
10802
10814
|
const snapshots = [...options.snapshots].sort((left, right) => left.at - right.at);
|
|
10803
10815
|
const issues = [];
|
|
@@ -10808,6 +10820,7 @@ var runVoiceReconnectContract = (options) => {
|
|
|
10808
10820
|
const resumed = statuses.includes("resumed");
|
|
10809
10821
|
const exhausted = statuses.includes("exhausted");
|
|
10810
10822
|
const duplicateTurnIds = findDuplicateTurnIds(snapshots);
|
|
10823
|
+
const resumeLatencyP95Ms = percentile(getResumeLatencies(snapshots), 95);
|
|
10811
10824
|
const requireReconnect = options.requireReconnect ?? true;
|
|
10812
10825
|
const requireResume = options.requireResume ?? true;
|
|
10813
10826
|
const requireReplayProtection = options.requireReplayProtection ?? true;
|
|
@@ -10861,6 +10874,7 @@ var runVoiceReconnectContract = (options) => {
|
|
|
10861
10874
|
checkedAt: Date.now(),
|
|
10862
10875
|
issues,
|
|
10863
10876
|
pass,
|
|
10877
|
+
resumeLatencyP95Ms,
|
|
10864
10878
|
snapshotCount: snapshots.length,
|
|
10865
10879
|
statuses,
|
|
10866
10880
|
summary: {
|
|
@@ -12628,7 +12642,7 @@ var DEFAULT_WARN_RATIO = 0.8;
|
|
|
12628
12642
|
var DEFAULT_MIN_PASSING_RUNS = 3;
|
|
12629
12643
|
var roundMs = (value) => Math.max(1, Math.ceil(value));
|
|
12630
12644
|
var finiteNumber = (value) => typeof value === "number" && Number.isFinite(value) && value >= 0;
|
|
12631
|
-
var
|
|
12645
|
+
var percentile2 = (values, rank) => {
|
|
12632
12646
|
if (values.length === 0) {
|
|
12633
12647
|
return;
|
|
12634
12648
|
}
|
|
@@ -12651,7 +12665,7 @@ var normalizeSample = (input) => {
|
|
|
12651
12665
|
return input;
|
|
12652
12666
|
};
|
|
12653
12667
|
var createThreshold = (metric, values, options) => {
|
|
12654
|
-
const baselineP95Ms =
|
|
12668
|
+
const baselineP95Ms = percentile2(values, 95);
|
|
12655
12669
|
const maxObservedMs = values.length > 0 ? Math.max(...values) : undefined;
|
|
12656
12670
|
const recommendedMs = baselineP95Ms === undefined ? undefined : roundMs(Math.max(options.minimumMs, baselineP95Ms * options.headroomMultiplier));
|
|
12657
12671
|
const warnAfterMs = recommendedMs === undefined ? undefined : roundMs(Math.max(options.minimumMs, recommendedMs * options.warnRatio));
|
|
@@ -12776,6 +12790,16 @@ var createVoiceSloThresholdProfile = (input, options = {}) => {
|
|
|
12776
12790
|
status: report.status
|
|
12777
12791
|
};
|
|
12778
12792
|
};
|
|
12793
|
+
var createVoiceSloReadinessThresholdOptions = (input, options = {}) => {
|
|
12794
|
+
const profile = "providerSlo" in input ? input : createVoiceSloThresholdProfile(input, options);
|
|
12795
|
+
return {
|
|
12796
|
+
liveLatencyFailAfterMs: profile.liveLatency.failAfterMs,
|
|
12797
|
+
liveLatencyWarnAfterMs: profile.liveLatency.warnAfterMs,
|
|
12798
|
+
monitoringNotifierDeliveryFailAfterMs: profile.monitoring.notifierDeliveryFailAfterMs,
|
|
12799
|
+
monitoringRunFailAfterMs: profile.monitoring.monitorRunFailAfterMs,
|
|
12800
|
+
reconnectResumeFailAfterMs: profile.reconnect.failAfterMs
|
|
12801
|
+
};
|
|
12802
|
+
};
|
|
12779
12803
|
var escapeMarkdown = (value) => value.replaceAll("|", "\\|");
|
|
12780
12804
|
var renderVoiceSloCalibrationMarkdown = (report, options = {}) => {
|
|
12781
12805
|
const rows = Object.values(report.thresholds).map((threshold) => `| ${escapeMarkdown(threshold.metric)} | ${threshold.status} | ${threshold.samples} | ${threshold.baselineP95Ms ?? "n/a"} | ${threshold.warnAfterMs ?? "n/a"} | ${threshold.failAfterMs ?? "n/a"} |`).join(`
|
|
@@ -17030,7 +17054,7 @@ var createVoiceTurnLatencyRoutes = (options) => {
|
|
|
17030
17054
|
// src/liveLatency.ts
|
|
17031
17055
|
import { Elysia as Elysia27 } from "elysia";
|
|
17032
17056
|
var escapeHtml26 = (value) => value.replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">").replaceAll('"', """).replaceAll("'", "'");
|
|
17033
|
-
var
|
|
17057
|
+
var percentile3 = (values, percentileValue) => {
|
|
17034
17058
|
if (values.length === 0) {
|
|
17035
17059
|
return;
|
|
17036
17060
|
}
|
|
@@ -17066,8 +17090,8 @@ var summarizeVoiceLiveLatency = async (options) => {
|
|
|
17066
17090
|
averageLatencyMs: latencies.length > 0 ? Math.round(latencies.reduce((total, value) => total + value, 0) / latencies.length) : undefined,
|
|
17067
17091
|
checkedAt: Date.now(),
|
|
17068
17092
|
failed,
|
|
17069
|
-
p50LatencyMs:
|
|
17070
|
-
p95LatencyMs:
|
|
17093
|
+
p50LatencyMs: percentile3(latencies, 50),
|
|
17094
|
+
p95LatencyMs: percentile3(latencies, 95),
|
|
17071
17095
|
recent,
|
|
17072
17096
|
status: latencies.length === 0 ? "empty" : failed > 0 ? "fail" : warnings > 0 ? "warn" : "pass",
|
|
17073
17097
|
total: latencies.length,
|
|
@@ -17143,7 +17167,7 @@ var TRACE_TYPES = [
|
|
|
17143
17167
|
];
|
|
17144
17168
|
var getNumber6 = (value) => typeof value === "number" && Number.isFinite(value) ? value : undefined;
|
|
17145
17169
|
var getString12 = (value) => typeof value === "string" && value.trim() ? value : undefined;
|
|
17146
|
-
var
|
|
17170
|
+
var percentile4 = (values, percentileValue) => {
|
|
17147
17171
|
if (values.length === 0) {
|
|
17148
17172
|
return;
|
|
17149
17173
|
}
|
|
@@ -17351,8 +17375,8 @@ var summarizeStage = (stage, measurements, options) => {
|
|
|
17351
17375
|
label: STAGE_LABELS[stage],
|
|
17352
17376
|
maxMs: latencies.length > 0 ? Math.max(...latencies) : undefined,
|
|
17353
17377
|
measurements: stageMeasurements,
|
|
17354
|
-
p50Ms:
|
|
17355
|
-
p95Ms:
|
|
17378
|
+
p50Ms: percentile4(latencies, 50),
|
|
17379
|
+
p95Ms: percentile4(latencies, 95),
|
|
17356
17380
|
stage,
|
|
17357
17381
|
status: stageMeasurements.length === 0 ? "empty" : failed > 0 ? "fail" : warnings > 0 ? "warn" : "pass",
|
|
17358
17382
|
total: stageMeasurements.length,
|
|
@@ -23790,7 +23814,7 @@ var rate3 = (count, total) => count / Math.max(1, total);
|
|
|
23790
23814
|
var uniqueSorted5 = (values) => [
|
|
23791
23815
|
...new Set(values.filter((value) => typeof value === "string"))
|
|
23792
23816
|
].sort();
|
|
23793
|
-
var
|
|
23817
|
+
var percentile5 = (values, rank) => {
|
|
23794
23818
|
if (values.length === 0) {
|
|
23795
23819
|
return 0;
|
|
23796
23820
|
}
|
|
@@ -23848,7 +23872,7 @@ var summarizeKind = (kind, events, thresholds, required) => {
|
|
|
23848
23872
|
unit: "rate"
|
|
23849
23873
|
}),
|
|
23850
23874
|
p95ElapsedMs: createMetric2({
|
|
23851
|
-
actual:
|
|
23875
|
+
actual: percentile5(latencies, 95),
|
|
23852
23876
|
label: "P95 latency",
|
|
23853
23877
|
threshold: thresholds.maxP95ElapsedMs,
|
|
23854
23878
|
unit: "ms"
|
|
@@ -28166,15 +28190,17 @@ var buildVoiceProductionReadinessReport = async (options, input = {}) => {
|
|
|
28166
28190
|
} : undefined;
|
|
28167
28191
|
const monitoringSummary = monitoring ? {
|
|
28168
28192
|
criticalOpen: monitoring.summary.criticalOpen,
|
|
28193
|
+
elapsedMs: monitoring.elapsedMs,
|
|
28169
28194
|
open: monitoring.summary.open,
|
|
28170
|
-
status: monitoring.status,
|
|
28195
|
+
status: options.monitoringRunFailAfterMs !== undefined && monitoring.elapsedMs > options.monitoringRunFailAfterMs ? "fail" : monitoring.status,
|
|
28171
28196
|
total: monitoring.summary.total
|
|
28172
28197
|
} : undefined;
|
|
28173
28198
|
const monitoringNotifierDeliverySummary = monitoringNotifierDelivery ? {
|
|
28199
|
+
elapsedMs: monitoringNotifierDelivery.elapsedMs,
|
|
28174
28200
|
failed: monitoringNotifierDelivery.summary.failed,
|
|
28175
28201
|
notifiers: monitoringNotifierDelivery.summary.notifiers,
|
|
28176
28202
|
sent: monitoringNotifierDelivery.summary.sent,
|
|
28177
|
-
status: monitoringNotifierDelivery.status,
|
|
28203
|
+
status: options.monitoringNotifierDeliveryFailAfterMs !== undefined && monitoringNotifierDelivery.elapsedMs > options.monitoringNotifierDeliveryFailAfterMs ? "fail" : monitoringNotifierDelivery.status,
|
|
28178
28204
|
total: monitoringNotifierDelivery.summary.total
|
|
28179
28205
|
} : undefined;
|
|
28180
28206
|
const telephonyWebhookSecuritySummary = telephonyWebhookSecurity ? {
|
|
@@ -28184,12 +28210,17 @@ var buildVoiceProductionReadinessReport = async (options, input = {}) => {
|
|
|
28184
28210
|
status: telephonyWebhookSecurity.status,
|
|
28185
28211
|
warned: telephonyWebhookSecurity.summary.warned
|
|
28186
28212
|
} : undefined;
|
|
28187
|
-
const reconnectContractSummary = reconnectContracts ? {
|
|
28188
|
-
|
|
28189
|
-
|
|
28190
|
-
|
|
28191
|
-
|
|
28192
|
-
|
|
28213
|
+
const reconnectContractSummary = reconnectContracts ? (() => {
|
|
28214
|
+
const failedReports = reconnectContracts.filter((report) => !report.pass || options.reconnectResumeFailAfterMs !== undefined && report.resumeLatencyP95Ms !== undefined && report.resumeLatencyP95Ms > options.reconnectResumeFailAfterMs);
|
|
28215
|
+
const resumeLatencies = reconnectContracts.map((report) => report.resumeLatencyP95Ms).filter((value) => typeof value === "number");
|
|
28216
|
+
return {
|
|
28217
|
+
failed: failedReports.length,
|
|
28218
|
+
passed: reconnectContracts.length - failedReports.length,
|
|
28219
|
+
resumeLatencyP95Ms: resumeLatencies.length > 0 ? Math.max(...resumeLatencies) : undefined,
|
|
28220
|
+
status: failedReports.length > 0 ? "fail" : reconnectContracts.length === 0 ? "warn" : "pass",
|
|
28221
|
+
total: reconnectContracts.length
|
|
28222
|
+
};
|
|
28223
|
+
})() : undefined;
|
|
28193
28224
|
const bargeInSummary = bargeInReports ? {
|
|
28194
28225
|
failed: bargeInReports.reduce((total, report) => total + report.failed, 0),
|
|
28195
28226
|
passed: bargeInReports.reduce((total, report) => total + report.passed, 0),
|
|
@@ -28406,7 +28437,7 @@ var buildVoiceProductionReadinessReport = async (options, input = {}) => {
|
|
|
28406
28437
|
}
|
|
28407
28438
|
if (reconnectContractSummary) {
|
|
28408
28439
|
checks.push({
|
|
28409
|
-
detail: reconnectContractSummary.status === "pass" ? `${reconnectContractSummary.passed} reconnect contract(s) are passing.` : reconnectContractSummary.total === 0 ? "No reconnect contracts are configured." : `${reconnectContractSummary.failed} reconnect contract(s) failed.`,
|
|
28440
|
+
detail: reconnectContractSummary.status === "pass" ? `${reconnectContractSummary.passed} reconnect contract(s) are passing.` : reconnectContractSummary.total === 0 ? "No reconnect contracts are configured." : options.reconnectResumeFailAfterMs !== undefined && reconnectContractSummary.resumeLatencyP95Ms !== undefined && reconnectContractSummary.resumeLatencyP95Ms > options.reconnectResumeFailAfterMs ? `Reconnect resume p95 ${reconnectContractSummary.resumeLatencyP95Ms}ms exceeded ${options.reconnectResumeFailAfterMs}ms.` : `${reconnectContractSummary.failed} reconnect contract(s) failed.`,
|
|
28410
28441
|
href: options.links?.reconnectContracts ?? options.links?.sessions ?? "/sessions",
|
|
28411
28442
|
label: "Reconnect recovery contracts",
|
|
28412
28443
|
proofSource: proofSource("reconnectContracts", "reconnect"),
|
|
@@ -28575,7 +28606,7 @@ var buildVoiceProductionReadinessReport = async (options, input = {}) => {
|
|
|
28575
28606
|
}
|
|
28576
28607
|
if (monitoring && monitoringSummary) {
|
|
28577
28608
|
checks.push({
|
|
28578
|
-
detail: monitoringSummary.status === "pass" ? `${monitoringSummary.total} monitor(s) are passing with no open issues.` : `${monitoringSummary.open} monitor issue(s) open, ${monitoringSummary.criticalOpen} critical.`,
|
|
28609
|
+
detail: monitoringSummary.status === "pass" ? `${monitoringSummary.total} monitor(s) are passing with no open issues.` : options.monitoringRunFailAfterMs !== undefined && monitoringSummary.elapsedMs !== undefined && monitoringSummary.elapsedMs > options.monitoringRunFailAfterMs ? `Monitor run took ${monitoringSummary.elapsedMs}ms, above ${options.monitoringRunFailAfterMs}ms.` : `${monitoringSummary.open} monitor issue(s) open, ${monitoringSummary.criticalOpen} critical.`,
|
|
28579
28610
|
href: options.links?.monitoring ?? "/voice/monitors",
|
|
28580
28611
|
label: "Monitoring issues",
|
|
28581
28612
|
status: monitoringSummary.status,
|
|
@@ -28591,7 +28622,7 @@ var buildVoiceProductionReadinessReport = async (options, input = {}) => {
|
|
|
28591
28622
|
}
|
|
28592
28623
|
if (monitoringNotifierDelivery && monitoringNotifierDeliverySummary) {
|
|
28593
28624
|
checks.push({
|
|
28594
|
-
detail: monitoringNotifierDeliverySummary.status === "pass" ? `${monitoringNotifierDeliverySummary.sent} monitor notification(s) delivered.` : `${monitoringNotifierDeliverySummary.failed} monitor notification delivery failure(s).`,
|
|
28625
|
+
detail: monitoringNotifierDeliverySummary.status === "pass" ? `${monitoringNotifierDeliverySummary.sent} monitor notification(s) delivered.` : options.monitoringNotifierDeliveryFailAfterMs !== undefined && monitoringNotifierDeliverySummary.elapsedMs !== undefined && monitoringNotifierDeliverySummary.elapsedMs > options.monitoringNotifierDeliveryFailAfterMs ? `Monitor notification delivery took ${monitoringNotifierDeliverySummary.elapsedMs}ms, above ${options.monitoringNotifierDeliveryFailAfterMs}ms.` : `${monitoringNotifierDeliverySummary.failed} monitor notification delivery failure(s).`,
|
|
28595
28626
|
href: options.links?.monitoringNotifierDelivery ?? "/api/voice/monitor-issues/notifications",
|
|
28596
28627
|
label: "Monitor notifier delivery",
|
|
28597
28628
|
status: monitoringNotifierDeliverySummary.status,
|
|
@@ -28823,7 +28854,8 @@ var createVoiceMemoryMonitorNotifierDeliveryReceiptStore = (initial = []) => {
|
|
|
28823
28854
|
};
|
|
28824
28855
|
};
|
|
28825
28856
|
var buildVoiceMonitorRunReport = async (options) => {
|
|
28826
|
-
const
|
|
28857
|
+
const startedAt = Date.now();
|
|
28858
|
+
const checkedAt = options.now ?? startedAt;
|
|
28827
28859
|
const runs = await Promise.all(options.monitors.map(async (monitor) => {
|
|
28828
28860
|
const evaluation = await monitor.evaluate({
|
|
28829
28861
|
evidence: options.evidence,
|
|
@@ -28863,6 +28895,7 @@ var buildVoiceMonitorRunReport = async (options) => {
|
|
|
28863
28895
|
const criticalOpen = openIssues.filter((issue) => issue.severity === "critical").length;
|
|
28864
28896
|
return {
|
|
28865
28897
|
checkedAt,
|
|
28898
|
+
elapsedMs: Math.max(0, Date.now() - startedAt),
|
|
28866
28899
|
issues,
|
|
28867
28900
|
runs,
|
|
28868
28901
|
status: criticalOpen > 0 ? "fail" : openIssues.length > 0 || rollupStatus4(runs) === "warn" ? "warn" : rollupStatus4(runs),
|
|
@@ -28923,7 +28956,8 @@ var createVoiceMonitorWebhookNotifier = (options) => ({
|
|
|
28923
28956
|
}
|
|
28924
28957
|
});
|
|
28925
28958
|
var deliverVoiceMonitorIssueNotifications = async (options) => {
|
|
28926
|
-
const
|
|
28959
|
+
const startedAt = Date.now();
|
|
28960
|
+
const checkedAt = options.now ?? startedAt;
|
|
28927
28961
|
const statuses = new Set(options.statuses ?? ["open"]);
|
|
28928
28962
|
const issues = (await options.issueStore.list()).filter((issue) => statuses.has(issue.status));
|
|
28929
28963
|
const receipts = [];
|
|
@@ -28949,6 +28983,7 @@ var deliverVoiceMonitorIssueNotifications = async (options) => {
|
|
|
28949
28983
|
const skipped = allReceipts.filter((receipt) => receipt.status === "skipped").length;
|
|
28950
28984
|
return {
|
|
28951
28985
|
checkedAt,
|
|
28986
|
+
elapsedMs: Math.max(0, Date.now() - startedAt),
|
|
28952
28987
|
receipts: allReceipts,
|
|
28953
28988
|
status: failed > 0 ? "fail" : allReceipts.length === 0 ? "warn" : "pass",
|
|
28954
28989
|
summary: {
|
|
@@ -32945,6 +32980,7 @@ export {
|
|
|
32945
32980
|
createVoiceTaskCreatedEvent,
|
|
32946
32981
|
createVoiceTTSProviderRouter,
|
|
32947
32982
|
createVoiceSloThresholdProfile,
|
|
32983
|
+
createVoiceSloReadinessThresholdOptions,
|
|
32948
32984
|
createVoiceSloCalibrationRoutes,
|
|
32949
32985
|
createVoiceSimulationSuiteRoutes,
|
|
32950
32986
|
createVoiceSessionsJSONHandler,
|
|
@@ -181,11 +181,13 @@ export type VoiceProductionReadinessReport = {
|
|
|
181
181
|
};
|
|
182
182
|
monitoring?: {
|
|
183
183
|
criticalOpen: number;
|
|
184
|
+
elapsedMs?: number;
|
|
184
185
|
open: number;
|
|
185
186
|
status: VoiceProductionReadinessStatus;
|
|
186
187
|
total: number;
|
|
187
188
|
};
|
|
188
189
|
monitoringNotifierDelivery?: {
|
|
190
|
+
elapsedMs?: number;
|
|
189
191
|
failed: number;
|
|
190
192
|
notifiers: number;
|
|
191
193
|
sent: number;
|
|
@@ -259,6 +261,7 @@ export type VoiceProductionReadinessReport = {
|
|
|
259
261
|
reconnectContracts?: {
|
|
260
262
|
failed: number;
|
|
261
263
|
passed: number;
|
|
264
|
+
resumeLatencyP95Ms?: number;
|
|
262
265
|
status: VoiceProductionReadinessStatus;
|
|
263
266
|
total: number;
|
|
264
267
|
};
|
|
@@ -482,6 +485,9 @@ export type VoiceProductionReadinessRoutesOptions = {
|
|
|
482
485
|
liveLatencyWarnAfterMs?: number;
|
|
483
486
|
liveLatencyFailAfterMs?: number;
|
|
484
487
|
liveLatencyMaxAgeMs?: number;
|
|
488
|
+
monitoringRunFailAfterMs?: number;
|
|
489
|
+
monitoringNotifierDeliveryFailAfterMs?: number;
|
|
490
|
+
reconnectResumeFailAfterMs?: number;
|
|
485
491
|
};
|
|
486
492
|
export declare const summarizeVoiceProductionReadinessGate: (report: VoiceProductionReadinessReport, options?: VoiceProductionReadinessGateOptions) => VoiceProductionReadinessGateReport;
|
|
487
493
|
export declare const evaluateVoiceProductionReadinessEvidence: (report: VoiceProductionReadinessReport, input?: VoiceProductionReadinessAssertionInput) => VoiceProductionReadinessAssertionReport;
|
package/dist/sloCalibration.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { Elysia } from 'elysia';
|
|
2
2
|
import type { VoiceProviderSloThresholdConfig } from './providerSlo';
|
|
3
|
+
import type { VoiceProductionReadinessRoutesOptions } from './productionReadiness';
|
|
3
4
|
import type { VoiceProofTrendReport } from './proofTrends';
|
|
4
5
|
export type VoiceSloCalibrationStatus = 'fail' | 'pass' | 'warn';
|
|
5
6
|
export type VoiceSloCalibrationMetricKey = 'interruption' | 'liveLatency' | 'monitorRun' | 'notifierDelivery' | 'provider' | 'reconnect' | 'turnLatency';
|
|
@@ -68,6 +69,7 @@ export type VoiceSloThresholdProfile = {
|
|
|
68
69
|
};
|
|
69
70
|
status: VoiceSloCalibrationStatus;
|
|
70
71
|
};
|
|
72
|
+
export type VoiceSloReadinessThresholdOptions = Pick<VoiceProductionReadinessRoutesOptions, 'liveLatencyFailAfterMs' | 'liveLatencyWarnAfterMs' | 'monitoringNotifierDeliveryFailAfterMs' | 'monitoringRunFailAfterMs' | 'reconnectResumeFailAfterMs'>;
|
|
71
73
|
export type VoiceSloCalibrationOptions = {
|
|
72
74
|
headroomMultiplier?: number;
|
|
73
75
|
liveLatencyMinimumMs?: number;
|
|
@@ -91,6 +93,7 @@ export type VoiceSloCalibrationRoutesOptions = VoiceSloCalibrationOptions & {
|
|
|
91
93
|
export declare const buildVoiceSloCalibrationReport: (input: Array<VoiceProofTrendReport | VoiceSloCalibrationSample>, options?: VoiceSloCalibrationOptions) => VoiceSloCalibrationReport;
|
|
92
94
|
export declare const assertVoiceSloCalibration: (input: Array<VoiceProofTrendReport | VoiceSloCalibrationSample>, options?: VoiceSloCalibrationOptions) => VoiceSloCalibrationReport;
|
|
93
95
|
export declare const createVoiceSloThresholdProfile: (input: VoiceSloCalibrationReport | Array<VoiceProofTrendReport | VoiceSloCalibrationSample>, options?: VoiceSloCalibrationOptions) => VoiceSloThresholdProfile;
|
|
96
|
+
export declare const createVoiceSloReadinessThresholdOptions: (input: VoiceSloCalibrationReport | VoiceSloThresholdProfile | Array<VoiceProofTrendReport | VoiceSloCalibrationSample>, options?: VoiceSloCalibrationOptions) => VoiceSloReadinessThresholdOptions;
|
|
94
97
|
export declare const renderVoiceSloCalibrationMarkdown: (report: VoiceSloCalibrationReport, options?: {
|
|
95
98
|
title?: string;
|
|
96
99
|
}) => string;
|
|
@@ -83,6 +83,7 @@ export type VoiceMonitorNotifierDeliveryReceiptStore = {
|
|
|
83
83
|
};
|
|
84
84
|
export type VoiceMonitorNotifierDeliveryReport = {
|
|
85
85
|
checkedAt: number;
|
|
86
|
+
elapsedMs: number;
|
|
86
87
|
receipts: VoiceMonitorNotifierDeliveryReceipt[];
|
|
87
88
|
status: VoiceMonitorStatus;
|
|
88
89
|
summary: {
|
|
@@ -95,6 +96,7 @@ export type VoiceMonitorNotifierDeliveryReport = {
|
|
|
95
96
|
};
|
|
96
97
|
export type VoiceMonitorRunReport = {
|
|
97
98
|
checkedAt: number;
|
|
99
|
+
elapsedMs: number;
|
|
98
100
|
issues: VoiceMonitorIssue[];
|
|
99
101
|
runs: VoiceMonitorRun[];
|
|
100
102
|
status: VoiceMonitorStatus;
|