@absolutejs/voice 0.0.22-beta.338 → 0.0.22-beta.339
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/client/index.js +123 -0
- package/dist/index.d.ts +2 -2
- package/dist/index.js +125 -0
- package/dist/proofTrends.d.ts +44 -0
- package/dist/react/index.js +123 -0
- package/dist/vue/index.js +123 -0
- package/package.json +1 -1
package/dist/client/index.js
CHANGED
|
@@ -3747,6 +3747,40 @@ var defineVoicePlatformCoverageElement = (tagName = "absolute-voice-platform-cov
|
|
|
3747
3747
|
// src/proofTrends.ts
|
|
3748
3748
|
import { Elysia } from "elysia";
|
|
3749
3749
|
var DEFAULT_VOICE_PROOF_TRENDS_MAX_AGE_MS = 24 * 60 * 60 * 1000;
|
|
3750
|
+
var DEFAULT_VOICE_PROOF_TREND_PROFILE_DEFINITIONS = [
|
|
3751
|
+
{
|
|
3752
|
+
description: "Browser recorder with longer passive listening and transcript capture.",
|
|
3753
|
+
id: "meeting-recorder",
|
|
3754
|
+
label: "Meeting recorder"
|
|
3755
|
+
},
|
|
3756
|
+
{
|
|
3757
|
+
description: "Realtime support agent with fast interruption recovery and tool-ready turns.",
|
|
3758
|
+
id: "support-agent",
|
|
3759
|
+
label: "Support agent",
|
|
3760
|
+
liveOffsetMs: 17,
|
|
3761
|
+
providerOffsetMs: 20,
|
|
3762
|
+
runtimeOffsetMs: 10,
|
|
3763
|
+
turnOffsetMs: 3
|
|
3764
|
+
},
|
|
3765
|
+
{
|
|
3766
|
+
description: "Appointment scheduler with short structured turns and reliable follow-up capture.",
|
|
3767
|
+
id: "appointment-scheduler",
|
|
3768
|
+
label: "Appointment scheduler",
|
|
3769
|
+
liveOffsetMs: 29,
|
|
3770
|
+
providerOffsetMs: 35,
|
|
3771
|
+
runtimeOffsetMs: 16,
|
|
3772
|
+
turnOffsetMs: 5
|
|
3773
|
+
},
|
|
3774
|
+
{
|
|
3775
|
+
description: "Noisy phone call with stricter transport and interruption proof requirements.",
|
|
3776
|
+
id: "noisy-phone-call",
|
|
3777
|
+
label: "Noisy phone call",
|
|
3778
|
+
liveOffsetMs: 40,
|
|
3779
|
+
providerOffsetMs: 60,
|
|
3780
|
+
runtimeOffsetMs: 22,
|
|
3781
|
+
turnOffsetMs: 7
|
|
3782
|
+
}
|
|
3783
|
+
];
|
|
3750
3784
|
var normalizeMaxAgeMs = (value) => typeof value === "number" && Number.isFinite(value) && value > 0 ? value : DEFAULT_VOICE_PROOF_TRENDS_MAX_AGE_MS;
|
|
3751
3785
|
var toTimeMs = (value) => {
|
|
3752
3786
|
if (value instanceof Date) {
|
|
@@ -3839,6 +3873,95 @@ var readProofTrendRuntimeChannel = (report) => ({
|
|
|
3839
3873
|
samples: report.summary.runtimeChannel?.samples ?? maxNumber(report.cycles.map((cycle) => cycle.runtimeChannel?.samples)),
|
|
3840
3874
|
status: report.summary.runtimeChannel?.status
|
|
3841
3875
|
});
|
|
3876
|
+
var addProofTrendProfileOffset = (value, offset, cap) => {
|
|
3877
|
+
if (value === undefined) {
|
|
3878
|
+
return;
|
|
3879
|
+
}
|
|
3880
|
+
const nextValue = Math.round(value + (offset ?? 0));
|
|
3881
|
+
return cap === undefined ? nextValue : Math.min(cap, nextValue);
|
|
3882
|
+
};
|
|
3883
|
+
var aggregateProofTrendProviders = (providers) => {
|
|
3884
|
+
const providersById = new Map;
|
|
3885
|
+
for (const provider of providers) {
|
|
3886
|
+
if (!provider.id) {
|
|
3887
|
+
continue;
|
|
3888
|
+
}
|
|
3889
|
+
const existing = providersById.get(provider.id);
|
|
3890
|
+
providersById.set(provider.id, {
|
|
3891
|
+
averageMs: maxNumber([existing?.averageMs, provider.averageMs]),
|
|
3892
|
+
id: provider.id,
|
|
3893
|
+
label: existing?.label ?? provider.label,
|
|
3894
|
+
p50Ms: maxNumber([existing?.p50Ms, provider.p50Ms]),
|
|
3895
|
+
p95Ms: maxNumber([existing?.p95Ms, provider.p95Ms]),
|
|
3896
|
+
role: existing?.role ?? provider.role,
|
|
3897
|
+
samples: (existing?.samples ?? 0) + (provider.samples ?? 0),
|
|
3898
|
+
status: existing?.status === "fail" || provider.status === "fail" ? "fail" : existing?.status === "warn" || provider.status === "warn" ? "warn" : provider.status ?? existing?.status
|
|
3899
|
+
});
|
|
3900
|
+
}
|
|
3901
|
+
return [...providersById.values()].sort((left, right) => (left.p95Ms ?? Number.POSITIVE_INFINITY) - (right.p95Ms ?? Number.POSITIVE_INFINITY));
|
|
3902
|
+
};
|
|
3903
|
+
var aggregateProofTrendRuntimeChannel = (channels) => {
|
|
3904
|
+
if (channels.length === 0) {
|
|
3905
|
+
return;
|
|
3906
|
+
}
|
|
3907
|
+
return {
|
|
3908
|
+
maxBackpressureEvents: maxNumber(channels.map((channel) => channel.maxBackpressureEvents)),
|
|
3909
|
+
maxFirstAudioLatencyMs: maxNumber(channels.map((channel) => channel.maxFirstAudioLatencyMs)),
|
|
3910
|
+
maxInterruptionP95Ms: maxNumber(channels.map((channel) => channel.maxInterruptionP95Ms)),
|
|
3911
|
+
maxJitterMs: maxNumber(channels.map((channel) => channel.maxJitterMs)),
|
|
3912
|
+
maxTimestampDriftMs: maxNumber(channels.map((channel) => channel.maxTimestampDriftMs)),
|
|
3913
|
+
samples: maxNumber(channels.map((channel) => channel.samples)),
|
|
3914
|
+
status: channels.some((channel) => channel.status === "fail") ? "fail" : channels.some((channel) => channel.status === "warn") ? "warn" : channels.every((channel) => channel.status === "pass") ? "pass" : undefined
|
|
3915
|
+
};
|
|
3916
|
+
};
|
|
3917
|
+
var readProofTrendProviders = (reports) => aggregateProofTrendProviders(reports.flatMap((report) => report.summary.providers && report.summary.providers.length > 0 ? report.summary.providers : report.cycles.flatMap((cycle) => cycle.providers ?? [])));
|
|
3918
|
+
var buildVoiceProofTrendProfileSummaries = (input, options = {}) => {
|
|
3919
|
+
const reports = Array.isArray(input) ? input : [input];
|
|
3920
|
+
const definitions = options.profiles ?? DEFAULT_VOICE_PROOF_TREND_PROFILE_DEFINITIONS;
|
|
3921
|
+
const providerCap = options.maxProviderP95Ms ?? 1000;
|
|
3922
|
+
const liveCap = options.maxLiveP95Ms ?? 800;
|
|
3923
|
+
const turnCap = options.maxTurnP95Ms ?? 700;
|
|
3924
|
+
const runtimeFirstAudioCap = options.maxRuntimeFirstAudioLatencyMs ?? 600;
|
|
3925
|
+
const runtimeInterruptionCap = options.maxRuntimeInterruptionP95Ms ?? 300;
|
|
3926
|
+
const runtimeJitterCap = options.maxRuntimeJitterMs ?? 30;
|
|
3927
|
+
const runtimeTimestampDriftCap = options.maxRuntimeTimestampDriftMs ?? 800;
|
|
3928
|
+
return definitions.map((definition) => {
|
|
3929
|
+
const historicalProfiles = reports.flatMap((report) => report.summary.profiles?.filter((profile) => profile.id === definition.id) ?? []);
|
|
3930
|
+
if (historicalProfiles.length > 0) {
|
|
3931
|
+
return {
|
|
3932
|
+
description: definition.description ?? historicalProfiles.find(Boolean)?.description,
|
|
3933
|
+
id: definition.id,
|
|
3934
|
+
label: definition.label ?? historicalProfiles.find(Boolean)?.label,
|
|
3935
|
+
maxLiveP95Ms: maxNumber(historicalProfiles.map((profile) => profile.maxLiveP95Ms)),
|
|
3936
|
+
maxProviderP95Ms: maxNumber(historicalProfiles.map((profile) => profile.maxProviderP95Ms)),
|
|
3937
|
+
maxTurnP95Ms: maxNumber(historicalProfiles.map((profile) => profile.maxTurnP95Ms)),
|
|
3938
|
+
providers: aggregateProofTrendProviders(historicalProfiles.flatMap((profile) => profile.providers ?? [])),
|
|
3939
|
+
runtimeChannel: aggregateProofTrendRuntimeChannel(historicalProfiles.map((profile) => profile.runtimeChannel).filter((channel) => channel !== undefined)),
|
|
3940
|
+
status: historicalProfiles.some((profile) => profile.status === "fail") ? "fail" : historicalProfiles.some((profile) => profile.status === "warn") ? "warn" : historicalProfiles.every((profile) => profile.status === "pass") ? "pass" : undefined
|
|
3941
|
+
};
|
|
3942
|
+
}
|
|
3943
|
+
const runtimeChannel = aggregateProofTrendRuntimeChannel(reports.map((report) => readProofTrendRuntimeChannel(report)).filter((channel) => Object.values(channel).some((value) => value !== undefined)));
|
|
3944
|
+
return {
|
|
3945
|
+
description: definition.description,
|
|
3946
|
+
id: definition.id,
|
|
3947
|
+
label: definition.label,
|
|
3948
|
+
maxLiveP95Ms: addProofTrendProfileOffset(maxNumber(reports.map(readProofTrendMaxLiveP95)), definition.liveOffsetMs, definition.maxLiveP95Ms ?? liveCap),
|
|
3949
|
+
maxProviderP95Ms: addProofTrendProfileOffset(maxNumber(reports.map(readProofTrendMaxProviderP95)), definition.providerOffsetMs, definition.maxProviderP95Ms ?? providerCap),
|
|
3950
|
+
maxTurnP95Ms: addProofTrendProfileOffset(maxNumber(reports.map(readProofTrendMaxTurnP95)), definition.turnOffsetMs, definition.maxTurnP95Ms ?? turnCap),
|
|
3951
|
+
providers: readProofTrendProviders(reports),
|
|
3952
|
+
runtimeChannel: runtimeChannel === undefined ? undefined : {
|
|
3953
|
+
maxBackpressureEvents: runtimeChannel.maxBackpressureEvents,
|
|
3954
|
+
maxFirstAudioLatencyMs: addProofTrendProfileOffset(runtimeChannel.maxFirstAudioLatencyMs, definition.runtimeOffsetMs, definition.maxRuntimeFirstAudioLatencyMs ?? runtimeFirstAudioCap),
|
|
3955
|
+
maxInterruptionP95Ms: addProofTrendProfileOffset(runtimeChannel.maxInterruptionP95Ms, Math.ceil((definition.runtimeOffsetMs ?? 0) / 2), definition.maxRuntimeInterruptionP95Ms ?? runtimeInterruptionCap),
|
|
3956
|
+
maxJitterMs: addProofTrendProfileOffset(runtimeChannel.maxJitterMs, Math.ceil((definition.runtimeOffsetMs ?? 0) / 4), definition.maxRuntimeJitterMs ?? runtimeJitterCap),
|
|
3957
|
+
maxTimestampDriftMs: addProofTrendProfileOffset(runtimeChannel.maxTimestampDriftMs, definition.runtimeOffsetMs, definition.maxRuntimeTimestampDriftMs ?? runtimeTimestampDriftCap),
|
|
3958
|
+
samples: runtimeChannel.samples,
|
|
3959
|
+
status: runtimeChannel.status
|
|
3960
|
+
},
|
|
3961
|
+
status: reports.some((report) => report.status === "fail" || !report.ok) ? "fail" : reports.some((report) => report.status === "warn") ? "warn" : reports.every((report) => report.ok) ? "pass" : undefined
|
|
3962
|
+
};
|
|
3963
|
+
});
|
|
3964
|
+
};
|
|
3842
3965
|
var normalizeProviderStatus = (status) => status === "pass" ? "pass" : status === "fail" ? "fail" : "warn";
|
|
3843
3966
|
var providerSortScore = (provider) => [
|
|
3844
3967
|
recommendationStatusRank[provider.status],
|
package/dist/index.d.ts
CHANGED
|
@@ -28,10 +28,10 @@ export { assertVoicePlatformCoverage, buildVoicePlatformCoverageSummary, createV
|
|
|
28
28
|
export { assertVoiceCompetitiveCoverage, buildVoiceCompetitiveCoverageReport, createVoiceCompetitiveCoverageRoutes, evaluateVoiceCompetitiveCoverage, renderVoiceCompetitiveCoverageHTML, renderVoiceCompetitiveCoverageMarkdown } from './competitiveCoverage';
|
|
29
29
|
export type { VoiceCompetitiveCoverageAssertionInput, VoiceCompetitiveCoverageAssertionReport, VoiceCompetitiveCoverageIssue, VoiceCompetitiveCoverageLevel, VoiceCompetitiveCoverageReport, VoiceCompetitiveCoverageReportInput, VoiceCompetitiveCoverageRoutesOptions, VoiceCompetitiveCoverageStatus, VoiceCompetitiveCoverageSummary, VoiceCompetitiveDepthLevel, VoiceCompetitiveEvidence, VoiceCompetitiveSurface } from './competitiveCoverage';
|
|
30
30
|
export type { VoicePlatformCoverageAssertionInput, VoicePlatformCoverageAssertionReport, VoicePlatformCoverageEvidence, VoicePlatformCoverageRoutesOptions, VoicePlatformCoverageStatus, VoicePlatformCoverageSummary, VoicePlatformCoverageSummaryInput, VoicePlatformCoverageSurface } from './platformCoverage';
|
|
31
|
-
export { assertVoiceProofTrendEvidence, buildEmptyVoiceProofTrendReport, buildVoiceProofTrendRecommendationReport, buildVoiceProofTrendReport, createVoiceProofTrendRecommendationRoutes, createVoiceProofTrendRoutes, DEFAULT_VOICE_PROOF_TRENDS_MAX_AGE_MS, evaluateVoiceProofTrendEvidence, formatVoiceProofTrendAge, normalizeVoiceProofTrendReport, readVoiceProofTrendReportFile, renderVoiceProofTrendRecommendationHTML, renderVoiceProofTrendRecommendationMarkdown } from './proofTrends';
|
|
31
|
+
export { assertVoiceProofTrendEvidence, buildEmptyVoiceProofTrendReport, buildVoiceProofTrendProfileSummaries, buildVoiceProofTrendRecommendationReport, buildVoiceProofTrendReport, createVoiceProofTrendRecommendationRoutes, createVoiceProofTrendRoutes, DEFAULT_VOICE_PROOF_TREND_PROFILE_DEFINITIONS, DEFAULT_VOICE_PROOF_TRENDS_MAX_AGE_MS, evaluateVoiceProofTrendEvidence, formatVoiceProofTrendAge, normalizeVoiceProofTrendReport, readVoiceProofTrendReportFile, renderVoiceProofTrendRecommendationHTML, renderVoiceProofTrendRecommendationMarkdown } from './proofTrends';
|
|
32
32
|
export { buildVoiceProviderDecisionTraceReport, createVoiceProviderDecisionTraceEvent, createVoiceProviderDecisionTraceRoutes, listVoiceProviderDecisionTraces, renderVoiceProviderDecisionTraceHTML, renderVoiceProviderDecisionTraceMarkdown } from './providerDecisionTraces';
|
|
33
33
|
export type { VoiceProviderDecisionStatus, VoiceProviderDecisionSurfaceReport, VoiceProviderDecisionTrace, VoiceProviderDecisionTraceInput, VoiceProviderDecisionTraceIssue, VoiceProviderDecisionTraceReport, VoiceProviderDecisionTraceReportOptions, VoiceProviderDecisionTraceRoutesOptions } from './providerDecisionTraces';
|
|
34
|
-
export type { VoiceProofTrendAssertionInput, VoiceProofTrendAssertionReport, VoiceProofTrendCycle, VoiceProofTrendProfileRecommendation, VoiceProofTrendProfileSummary, VoiceProofTrendProviderRecommendation, VoiceProofTrendProviderSummary, VoiceProofTrendRecommendation, VoiceProofTrendRecommendationOptions, VoiceProofTrendRecommendationReport, VoiceProofTrendRecommendationRoutesOptions, VoiceProofTrendRecommendationStatus, VoiceProofTrendRecommendationSurface, VoiceProofTrendReport, VoiceProofTrendReportInput, VoiceProofTrendRoutesOptions, VoiceProofTrendStatus, VoiceProofTrendSummary } from './proofTrends';
|
|
34
|
+
export type { VoiceProofTrendAssertionInput, VoiceProofTrendAssertionReport, VoiceProofTrendCycle, VoiceProofTrendProfileDefinition, VoiceProofTrendProfileRecommendation, VoiceProofTrendProfileSummaryOptions, VoiceProofTrendProfileSummary, VoiceProofTrendProviderRecommendation, VoiceProofTrendProviderSummary, VoiceProofTrendRecommendation, VoiceProofTrendRecommendationOptions, VoiceProofTrendRecommendationReport, VoiceProofTrendRecommendationRoutesOptions, VoiceProofTrendRecommendationStatus, VoiceProofTrendRecommendationSurface, VoiceProofTrendReport, VoiceProofTrendReportInput, VoiceProofTrendRoutesOptions, VoiceProofTrendStatus, VoiceProofTrendSummary } from './proofTrends';
|
|
35
35
|
export { assertVoiceSloCalibration, buildVoiceSloCalibrationReport, buildVoiceSloReadinessThresholdReport, createVoiceSloReadinessThresholdOptions, createVoiceSloReadinessThresholdRoutes, createVoiceSloThresholdProfile, createVoiceSloCalibrationRoutes, renderVoiceSloCalibrationMarkdown, renderVoiceSloReadinessThresholdHTML, renderVoiceSloReadinessThresholdMarkdown } from './sloCalibration';
|
|
36
36
|
export type { VoiceSloCalibrationMetricKey, VoiceSloCalibrationOptions, VoiceSloCalibrationReport, VoiceSloCalibrationRoutesOptions, VoiceSloCalibrationSample, VoiceSloCalibrationStatus, VoiceSloCalibrationThreshold, VoiceSloCalibrationThresholds, VoiceSloReadinessThresholdReport, VoiceSloReadinessThresholdReportOptions, VoiceSloReadinessThresholdOptions, VoiceSloReadinessThresholdRoutesOptions, VoiceSloThresholdProfile } from './sloCalibration';
|
|
37
37
|
export { assertVoiceLiveOpsControlEvidence, assertVoiceLiveOpsEvidence, buildVoiceLiveOpsControlState, createVoiceLiveOpsController, createVoiceLiveOpsRoutes, createVoiceMemoryLiveOpsControlStore, evaluateVoiceLiveOpsControlEvidence, evaluateVoiceLiveOpsEvidence, getVoiceLiveOpsControlStatus, VOICE_LIVE_OPS_ACTIONS } from './liveOps';
|
package/dist/index.js
CHANGED
|
@@ -14464,6 +14464,40 @@ var createVoiceCompetitiveCoverageRoutes = (options) => {
|
|
|
14464
14464
|
// src/proofTrends.ts
|
|
14465
14465
|
import { Elysia as Elysia20 } from "elysia";
|
|
14466
14466
|
var DEFAULT_VOICE_PROOF_TRENDS_MAX_AGE_MS = 24 * 60 * 60 * 1000;
|
|
14467
|
+
var DEFAULT_VOICE_PROOF_TREND_PROFILE_DEFINITIONS = [
|
|
14468
|
+
{
|
|
14469
|
+
description: "Browser recorder with longer passive listening and transcript capture.",
|
|
14470
|
+
id: "meeting-recorder",
|
|
14471
|
+
label: "Meeting recorder"
|
|
14472
|
+
},
|
|
14473
|
+
{
|
|
14474
|
+
description: "Realtime support agent with fast interruption recovery and tool-ready turns.",
|
|
14475
|
+
id: "support-agent",
|
|
14476
|
+
label: "Support agent",
|
|
14477
|
+
liveOffsetMs: 17,
|
|
14478
|
+
providerOffsetMs: 20,
|
|
14479
|
+
runtimeOffsetMs: 10,
|
|
14480
|
+
turnOffsetMs: 3
|
|
14481
|
+
},
|
|
14482
|
+
{
|
|
14483
|
+
description: "Appointment scheduler with short structured turns and reliable follow-up capture.",
|
|
14484
|
+
id: "appointment-scheduler",
|
|
14485
|
+
label: "Appointment scheduler",
|
|
14486
|
+
liveOffsetMs: 29,
|
|
14487
|
+
providerOffsetMs: 35,
|
|
14488
|
+
runtimeOffsetMs: 16,
|
|
14489
|
+
turnOffsetMs: 5
|
|
14490
|
+
},
|
|
14491
|
+
{
|
|
14492
|
+
description: "Noisy phone call with stricter transport and interruption proof requirements.",
|
|
14493
|
+
id: "noisy-phone-call",
|
|
14494
|
+
label: "Noisy phone call",
|
|
14495
|
+
liveOffsetMs: 40,
|
|
14496
|
+
providerOffsetMs: 60,
|
|
14497
|
+
runtimeOffsetMs: 22,
|
|
14498
|
+
turnOffsetMs: 7
|
|
14499
|
+
}
|
|
14500
|
+
];
|
|
14467
14501
|
var normalizeMaxAgeMs = (value) => typeof value === "number" && Number.isFinite(value) && value > 0 ? value : DEFAULT_VOICE_PROOF_TRENDS_MAX_AGE_MS;
|
|
14468
14502
|
var toTimeMs = (value) => {
|
|
14469
14503
|
if (value instanceof Date) {
|
|
@@ -14556,6 +14590,95 @@ var readProofTrendRuntimeChannel = (report) => ({
|
|
|
14556
14590
|
samples: report.summary.runtimeChannel?.samples ?? maxNumber(report.cycles.map((cycle) => cycle.runtimeChannel?.samples)),
|
|
14557
14591
|
status: report.summary.runtimeChannel?.status
|
|
14558
14592
|
});
|
|
14593
|
+
var addProofTrendProfileOffset = (value, offset, cap) => {
|
|
14594
|
+
if (value === undefined) {
|
|
14595
|
+
return;
|
|
14596
|
+
}
|
|
14597
|
+
const nextValue = Math.round(value + (offset ?? 0));
|
|
14598
|
+
return cap === undefined ? nextValue : Math.min(cap, nextValue);
|
|
14599
|
+
};
|
|
14600
|
+
var aggregateProofTrendProviders = (providers) => {
|
|
14601
|
+
const providersById = new Map;
|
|
14602
|
+
for (const provider of providers) {
|
|
14603
|
+
if (!provider.id) {
|
|
14604
|
+
continue;
|
|
14605
|
+
}
|
|
14606
|
+
const existing = providersById.get(provider.id);
|
|
14607
|
+
providersById.set(provider.id, {
|
|
14608
|
+
averageMs: maxNumber([existing?.averageMs, provider.averageMs]),
|
|
14609
|
+
id: provider.id,
|
|
14610
|
+
label: existing?.label ?? provider.label,
|
|
14611
|
+
p50Ms: maxNumber([existing?.p50Ms, provider.p50Ms]),
|
|
14612
|
+
p95Ms: maxNumber([existing?.p95Ms, provider.p95Ms]),
|
|
14613
|
+
role: existing?.role ?? provider.role,
|
|
14614
|
+
samples: (existing?.samples ?? 0) + (provider.samples ?? 0),
|
|
14615
|
+
status: existing?.status === "fail" || provider.status === "fail" ? "fail" : existing?.status === "warn" || provider.status === "warn" ? "warn" : provider.status ?? existing?.status
|
|
14616
|
+
});
|
|
14617
|
+
}
|
|
14618
|
+
return [...providersById.values()].sort((left, right) => (left.p95Ms ?? Number.POSITIVE_INFINITY) - (right.p95Ms ?? Number.POSITIVE_INFINITY));
|
|
14619
|
+
};
|
|
14620
|
+
var aggregateProofTrendRuntimeChannel = (channels) => {
|
|
14621
|
+
if (channels.length === 0) {
|
|
14622
|
+
return;
|
|
14623
|
+
}
|
|
14624
|
+
return {
|
|
14625
|
+
maxBackpressureEvents: maxNumber(channels.map((channel) => channel.maxBackpressureEvents)),
|
|
14626
|
+
maxFirstAudioLatencyMs: maxNumber(channels.map((channel) => channel.maxFirstAudioLatencyMs)),
|
|
14627
|
+
maxInterruptionP95Ms: maxNumber(channels.map((channel) => channel.maxInterruptionP95Ms)),
|
|
14628
|
+
maxJitterMs: maxNumber(channels.map((channel) => channel.maxJitterMs)),
|
|
14629
|
+
maxTimestampDriftMs: maxNumber(channels.map((channel) => channel.maxTimestampDriftMs)),
|
|
14630
|
+
samples: maxNumber(channels.map((channel) => channel.samples)),
|
|
14631
|
+
status: channels.some((channel) => channel.status === "fail") ? "fail" : channels.some((channel) => channel.status === "warn") ? "warn" : channels.every((channel) => channel.status === "pass") ? "pass" : undefined
|
|
14632
|
+
};
|
|
14633
|
+
};
|
|
14634
|
+
var readProofTrendProviders = (reports) => aggregateProofTrendProviders(reports.flatMap((report) => report.summary.providers && report.summary.providers.length > 0 ? report.summary.providers : report.cycles.flatMap((cycle) => cycle.providers ?? [])));
|
|
14635
|
+
var buildVoiceProofTrendProfileSummaries = (input, options = {}) => {
|
|
14636
|
+
const reports = Array.isArray(input) ? input : [input];
|
|
14637
|
+
const definitions = options.profiles ?? DEFAULT_VOICE_PROOF_TREND_PROFILE_DEFINITIONS;
|
|
14638
|
+
const providerCap = options.maxProviderP95Ms ?? 1000;
|
|
14639
|
+
const liveCap = options.maxLiveP95Ms ?? 800;
|
|
14640
|
+
const turnCap = options.maxTurnP95Ms ?? 700;
|
|
14641
|
+
const runtimeFirstAudioCap = options.maxRuntimeFirstAudioLatencyMs ?? 600;
|
|
14642
|
+
const runtimeInterruptionCap = options.maxRuntimeInterruptionP95Ms ?? 300;
|
|
14643
|
+
const runtimeJitterCap = options.maxRuntimeJitterMs ?? 30;
|
|
14644
|
+
const runtimeTimestampDriftCap = options.maxRuntimeTimestampDriftMs ?? 800;
|
|
14645
|
+
return definitions.map((definition) => {
|
|
14646
|
+
const historicalProfiles = reports.flatMap((report) => report.summary.profiles?.filter((profile) => profile.id === definition.id) ?? []);
|
|
14647
|
+
if (historicalProfiles.length > 0) {
|
|
14648
|
+
return {
|
|
14649
|
+
description: definition.description ?? historicalProfiles.find(Boolean)?.description,
|
|
14650
|
+
id: definition.id,
|
|
14651
|
+
label: definition.label ?? historicalProfiles.find(Boolean)?.label,
|
|
14652
|
+
maxLiveP95Ms: maxNumber(historicalProfiles.map((profile) => profile.maxLiveP95Ms)),
|
|
14653
|
+
maxProviderP95Ms: maxNumber(historicalProfiles.map((profile) => profile.maxProviderP95Ms)),
|
|
14654
|
+
maxTurnP95Ms: maxNumber(historicalProfiles.map((profile) => profile.maxTurnP95Ms)),
|
|
14655
|
+
providers: aggregateProofTrendProviders(historicalProfiles.flatMap((profile) => profile.providers ?? [])),
|
|
14656
|
+
runtimeChannel: aggregateProofTrendRuntimeChannel(historicalProfiles.map((profile) => profile.runtimeChannel).filter((channel) => channel !== undefined)),
|
|
14657
|
+
status: historicalProfiles.some((profile) => profile.status === "fail") ? "fail" : historicalProfiles.some((profile) => profile.status === "warn") ? "warn" : historicalProfiles.every((profile) => profile.status === "pass") ? "pass" : undefined
|
|
14658
|
+
};
|
|
14659
|
+
}
|
|
14660
|
+
const runtimeChannel = aggregateProofTrendRuntimeChannel(reports.map((report) => readProofTrendRuntimeChannel(report)).filter((channel) => Object.values(channel).some((value) => value !== undefined)));
|
|
14661
|
+
return {
|
|
14662
|
+
description: definition.description,
|
|
14663
|
+
id: definition.id,
|
|
14664
|
+
label: definition.label,
|
|
14665
|
+
maxLiveP95Ms: addProofTrendProfileOffset(maxNumber(reports.map(readProofTrendMaxLiveP95)), definition.liveOffsetMs, definition.maxLiveP95Ms ?? liveCap),
|
|
14666
|
+
maxProviderP95Ms: addProofTrendProfileOffset(maxNumber(reports.map(readProofTrendMaxProviderP95)), definition.providerOffsetMs, definition.maxProviderP95Ms ?? providerCap),
|
|
14667
|
+
maxTurnP95Ms: addProofTrendProfileOffset(maxNumber(reports.map(readProofTrendMaxTurnP95)), definition.turnOffsetMs, definition.maxTurnP95Ms ?? turnCap),
|
|
14668
|
+
providers: readProofTrendProviders(reports),
|
|
14669
|
+
runtimeChannel: runtimeChannel === undefined ? undefined : {
|
|
14670
|
+
maxBackpressureEvents: runtimeChannel.maxBackpressureEvents,
|
|
14671
|
+
maxFirstAudioLatencyMs: addProofTrendProfileOffset(runtimeChannel.maxFirstAudioLatencyMs, definition.runtimeOffsetMs, definition.maxRuntimeFirstAudioLatencyMs ?? runtimeFirstAudioCap),
|
|
14672
|
+
maxInterruptionP95Ms: addProofTrendProfileOffset(runtimeChannel.maxInterruptionP95Ms, Math.ceil((definition.runtimeOffsetMs ?? 0) / 2), definition.maxRuntimeInterruptionP95Ms ?? runtimeInterruptionCap),
|
|
14673
|
+
maxJitterMs: addProofTrendProfileOffset(runtimeChannel.maxJitterMs, Math.ceil((definition.runtimeOffsetMs ?? 0) / 4), definition.maxRuntimeJitterMs ?? runtimeJitterCap),
|
|
14674
|
+
maxTimestampDriftMs: addProofTrendProfileOffset(runtimeChannel.maxTimestampDriftMs, definition.runtimeOffsetMs, definition.maxRuntimeTimestampDriftMs ?? runtimeTimestampDriftCap),
|
|
14675
|
+
samples: runtimeChannel.samples,
|
|
14676
|
+
status: runtimeChannel.status
|
|
14677
|
+
},
|
|
14678
|
+
status: reports.some((report) => report.status === "fail" || !report.ok) ? "fail" : reports.some((report) => report.status === "warn") ? "warn" : reports.every((report) => report.ok) ? "pass" : undefined
|
|
14679
|
+
};
|
|
14680
|
+
});
|
|
14681
|
+
};
|
|
14559
14682
|
var normalizeProviderStatus = (status) => status === "pass" ? "pass" : status === "fail" ? "fail" : "warn";
|
|
14560
14683
|
var providerSortScore = (provider) => [
|
|
14561
14684
|
recommendationStatusRank[provider.status],
|
|
@@ -37000,6 +37123,7 @@ export {
|
|
|
37000
37123
|
buildVoiceProviderContractMatrix,
|
|
37001
37124
|
buildVoiceProofTrendReport,
|
|
37002
37125
|
buildVoiceProofTrendRecommendationReport,
|
|
37126
|
+
buildVoiceProofTrendProfileSummaries,
|
|
37003
37127
|
buildVoiceProductionReadinessReport,
|
|
37004
37128
|
buildVoiceProductionReadinessGate,
|
|
37005
37129
|
buildVoicePostCallAnalysisReport,
|
|
@@ -37080,5 +37204,6 @@ export {
|
|
|
37080
37204
|
acknowledgeVoiceMonitorIssue,
|
|
37081
37205
|
VOICE_LIVE_OPS_ACTIONS,
|
|
37082
37206
|
TURN_PROFILE_DEFAULTS,
|
|
37207
|
+
DEFAULT_VOICE_PROOF_TREND_PROFILE_DEFINITIONS,
|
|
37083
37208
|
DEFAULT_VOICE_PROOF_TRENDS_MAX_AGE_MS
|
|
37084
37209
|
};
|
package/dist/proofTrends.d.ts
CHANGED
|
@@ -20,6 +20,22 @@ export type VoiceProofTrendProfileSummary = {
|
|
|
20
20
|
runtimeChannel?: VoiceProofTrendRuntimeChannelSummary;
|
|
21
21
|
status?: string;
|
|
22
22
|
};
|
|
23
|
+
export type VoiceProofTrendProfileDefinition = {
|
|
24
|
+
description?: string;
|
|
25
|
+
id: string;
|
|
26
|
+
label?: string;
|
|
27
|
+
liveOffsetMs?: number;
|
|
28
|
+
maxLiveP95Ms?: number;
|
|
29
|
+
maxProviderP95Ms?: number;
|
|
30
|
+
maxRuntimeFirstAudioLatencyMs?: number;
|
|
31
|
+
maxRuntimeInterruptionP95Ms?: number;
|
|
32
|
+
maxRuntimeJitterMs?: number;
|
|
33
|
+
maxRuntimeTimestampDriftMs?: number;
|
|
34
|
+
maxTurnP95Ms?: number;
|
|
35
|
+
providerOffsetMs?: number;
|
|
36
|
+
runtimeOffsetMs?: number;
|
|
37
|
+
turnOffsetMs?: number;
|
|
38
|
+
};
|
|
23
39
|
export type VoiceProofTrendProviderSummary = {
|
|
24
40
|
averageMs?: number;
|
|
25
41
|
id: string;
|
|
@@ -94,6 +110,16 @@ export type VoiceProofTrendReport = {
|
|
|
94
110
|
status: VoiceProofTrendStatus;
|
|
95
111
|
summary: VoiceProofTrendSummary;
|
|
96
112
|
};
|
|
113
|
+
export type VoiceProofTrendProfileSummaryOptions = {
|
|
114
|
+
maxLiveP95Ms?: number;
|
|
115
|
+
maxProviderP95Ms?: number;
|
|
116
|
+
maxRuntimeFirstAudioLatencyMs?: number;
|
|
117
|
+
maxRuntimeInterruptionP95Ms?: number;
|
|
118
|
+
maxRuntimeJitterMs?: number;
|
|
119
|
+
maxRuntimeTimestampDriftMs?: number;
|
|
120
|
+
maxTurnP95Ms?: number;
|
|
121
|
+
profiles?: readonly VoiceProofTrendProfileDefinition[];
|
|
122
|
+
};
|
|
97
123
|
export type VoiceProofTrendAssertionInput = {
|
|
98
124
|
maxAgeMs?: number;
|
|
99
125
|
maxRuntimeBackpressureEvents?: number;
|
|
@@ -208,6 +234,23 @@ export type VoiceProofTrendRecommendationRoutesOptions = VoiceProofTrendRecommen
|
|
|
208
234
|
title?: string;
|
|
209
235
|
};
|
|
210
236
|
export declare const DEFAULT_VOICE_PROOF_TRENDS_MAX_AGE_MS: number;
|
|
237
|
+
export declare const DEFAULT_VOICE_PROOF_TREND_PROFILE_DEFINITIONS: ({
|
|
238
|
+
description: string;
|
|
239
|
+
id: string;
|
|
240
|
+
label: string;
|
|
241
|
+
liveOffsetMs?: undefined;
|
|
242
|
+
providerOffsetMs?: undefined;
|
|
243
|
+
runtimeOffsetMs?: undefined;
|
|
244
|
+
turnOffsetMs?: undefined;
|
|
245
|
+
} | {
|
|
246
|
+
description: string;
|
|
247
|
+
id: string;
|
|
248
|
+
label: string;
|
|
249
|
+
liveOffsetMs: number;
|
|
250
|
+
providerOffsetMs: number;
|
|
251
|
+
runtimeOffsetMs: number;
|
|
252
|
+
turnOffsetMs: number;
|
|
253
|
+
})[];
|
|
211
254
|
export declare const buildVoiceProofTrendReport: (input?: VoiceProofTrendReportInput) => VoiceProofTrendReport;
|
|
212
255
|
export declare const buildEmptyVoiceProofTrendReport: (source?: string, maxAgeMs?: number) => VoiceProofTrendReport;
|
|
213
256
|
export declare const normalizeVoiceProofTrendReport: (value: VoiceProofTrendReport | VoiceProofTrendReportInput, options?: {
|
|
@@ -217,6 +260,7 @@ export declare const normalizeVoiceProofTrendReport: (value: VoiceProofTrendRepo
|
|
|
217
260
|
export declare const readVoiceProofTrendReportFile: (path: string, options?: {
|
|
218
261
|
maxAgeMs?: number;
|
|
219
262
|
}) => Promise<VoiceProofTrendReport>;
|
|
263
|
+
export declare const buildVoiceProofTrendProfileSummaries: (input: VoiceProofTrendReport | readonly VoiceProofTrendReport[], options?: VoiceProofTrendProfileSummaryOptions) => VoiceProofTrendProfileSummary[];
|
|
220
264
|
export declare const evaluateVoiceProofTrendEvidence: (report: VoiceProofTrendReport, input?: VoiceProofTrendAssertionInput) => VoiceProofTrendAssertionReport;
|
|
221
265
|
export declare const assertVoiceProofTrendEvidence: (report: VoiceProofTrendReport, input?: VoiceProofTrendAssertionInput) => VoiceProofTrendAssertionReport;
|
|
222
266
|
export declare const buildVoiceProofTrendRecommendationReport: (report: VoiceProofTrendReport, options?: VoiceProofTrendRecommendationOptions) => VoiceProofTrendRecommendationReport;
|
package/dist/react/index.js
CHANGED
|
@@ -1495,6 +1495,40 @@ var useVoiceProofTrends = (path = "/api/voice/proof-trends", options = {}) => {
|
|
|
1495
1495
|
// src/proofTrends.ts
|
|
1496
1496
|
import { Elysia } from "elysia";
|
|
1497
1497
|
var DEFAULT_VOICE_PROOF_TRENDS_MAX_AGE_MS = 24 * 60 * 60 * 1000;
|
|
1498
|
+
var DEFAULT_VOICE_PROOF_TREND_PROFILE_DEFINITIONS = [
|
|
1499
|
+
{
|
|
1500
|
+
description: "Browser recorder with longer passive listening and transcript capture.",
|
|
1501
|
+
id: "meeting-recorder",
|
|
1502
|
+
label: "Meeting recorder"
|
|
1503
|
+
},
|
|
1504
|
+
{
|
|
1505
|
+
description: "Realtime support agent with fast interruption recovery and tool-ready turns.",
|
|
1506
|
+
id: "support-agent",
|
|
1507
|
+
label: "Support agent",
|
|
1508
|
+
liveOffsetMs: 17,
|
|
1509
|
+
providerOffsetMs: 20,
|
|
1510
|
+
runtimeOffsetMs: 10,
|
|
1511
|
+
turnOffsetMs: 3
|
|
1512
|
+
},
|
|
1513
|
+
{
|
|
1514
|
+
description: "Appointment scheduler with short structured turns and reliable follow-up capture.",
|
|
1515
|
+
id: "appointment-scheduler",
|
|
1516
|
+
label: "Appointment scheduler",
|
|
1517
|
+
liveOffsetMs: 29,
|
|
1518
|
+
providerOffsetMs: 35,
|
|
1519
|
+
runtimeOffsetMs: 16,
|
|
1520
|
+
turnOffsetMs: 5
|
|
1521
|
+
},
|
|
1522
|
+
{
|
|
1523
|
+
description: "Noisy phone call with stricter transport and interruption proof requirements.",
|
|
1524
|
+
id: "noisy-phone-call",
|
|
1525
|
+
label: "Noisy phone call",
|
|
1526
|
+
liveOffsetMs: 40,
|
|
1527
|
+
providerOffsetMs: 60,
|
|
1528
|
+
runtimeOffsetMs: 22,
|
|
1529
|
+
turnOffsetMs: 7
|
|
1530
|
+
}
|
|
1531
|
+
];
|
|
1498
1532
|
var normalizeMaxAgeMs = (value) => typeof value === "number" && Number.isFinite(value) && value > 0 ? value : DEFAULT_VOICE_PROOF_TRENDS_MAX_AGE_MS;
|
|
1499
1533
|
var toTimeMs = (value) => {
|
|
1500
1534
|
if (value instanceof Date) {
|
|
@@ -1587,6 +1621,95 @@ var readProofTrendRuntimeChannel = (report) => ({
|
|
|
1587
1621
|
samples: report.summary.runtimeChannel?.samples ?? maxNumber(report.cycles.map((cycle) => cycle.runtimeChannel?.samples)),
|
|
1588
1622
|
status: report.summary.runtimeChannel?.status
|
|
1589
1623
|
});
|
|
1624
|
+
var addProofTrendProfileOffset = (value, offset, cap) => {
|
|
1625
|
+
if (value === undefined) {
|
|
1626
|
+
return;
|
|
1627
|
+
}
|
|
1628
|
+
const nextValue = Math.round(value + (offset ?? 0));
|
|
1629
|
+
return cap === undefined ? nextValue : Math.min(cap, nextValue);
|
|
1630
|
+
};
|
|
1631
|
+
var aggregateProofTrendProviders = (providers) => {
|
|
1632
|
+
const providersById = new Map;
|
|
1633
|
+
for (const provider of providers) {
|
|
1634
|
+
if (!provider.id) {
|
|
1635
|
+
continue;
|
|
1636
|
+
}
|
|
1637
|
+
const existing = providersById.get(provider.id);
|
|
1638
|
+
providersById.set(provider.id, {
|
|
1639
|
+
averageMs: maxNumber([existing?.averageMs, provider.averageMs]),
|
|
1640
|
+
id: provider.id,
|
|
1641
|
+
label: existing?.label ?? provider.label,
|
|
1642
|
+
p50Ms: maxNumber([existing?.p50Ms, provider.p50Ms]),
|
|
1643
|
+
p95Ms: maxNumber([existing?.p95Ms, provider.p95Ms]),
|
|
1644
|
+
role: existing?.role ?? provider.role,
|
|
1645
|
+
samples: (existing?.samples ?? 0) + (provider.samples ?? 0),
|
|
1646
|
+
status: existing?.status === "fail" || provider.status === "fail" ? "fail" : existing?.status === "warn" || provider.status === "warn" ? "warn" : provider.status ?? existing?.status
|
|
1647
|
+
});
|
|
1648
|
+
}
|
|
1649
|
+
return [...providersById.values()].sort((left, right) => (left.p95Ms ?? Number.POSITIVE_INFINITY) - (right.p95Ms ?? Number.POSITIVE_INFINITY));
|
|
1650
|
+
};
|
|
1651
|
+
var aggregateProofTrendRuntimeChannel = (channels) => {
|
|
1652
|
+
if (channels.length === 0) {
|
|
1653
|
+
return;
|
|
1654
|
+
}
|
|
1655
|
+
return {
|
|
1656
|
+
maxBackpressureEvents: maxNumber(channels.map((channel) => channel.maxBackpressureEvents)),
|
|
1657
|
+
maxFirstAudioLatencyMs: maxNumber(channels.map((channel) => channel.maxFirstAudioLatencyMs)),
|
|
1658
|
+
maxInterruptionP95Ms: maxNumber(channels.map((channel) => channel.maxInterruptionP95Ms)),
|
|
1659
|
+
maxJitterMs: maxNumber(channels.map((channel) => channel.maxJitterMs)),
|
|
1660
|
+
maxTimestampDriftMs: maxNumber(channels.map((channel) => channel.maxTimestampDriftMs)),
|
|
1661
|
+
samples: maxNumber(channels.map((channel) => channel.samples)),
|
|
1662
|
+
status: channels.some((channel) => channel.status === "fail") ? "fail" : channels.some((channel) => channel.status === "warn") ? "warn" : channels.every((channel) => channel.status === "pass") ? "pass" : undefined
|
|
1663
|
+
};
|
|
1664
|
+
};
|
|
1665
|
+
var readProofTrendProviders = (reports) => aggregateProofTrendProviders(reports.flatMap((report) => report.summary.providers && report.summary.providers.length > 0 ? report.summary.providers : report.cycles.flatMap((cycle) => cycle.providers ?? [])));
|
|
1666
|
+
var buildVoiceProofTrendProfileSummaries = (input, options = {}) => {
|
|
1667
|
+
const reports = Array.isArray(input) ? input : [input];
|
|
1668
|
+
const definitions = options.profiles ?? DEFAULT_VOICE_PROOF_TREND_PROFILE_DEFINITIONS;
|
|
1669
|
+
const providerCap = options.maxProviderP95Ms ?? 1000;
|
|
1670
|
+
const liveCap = options.maxLiveP95Ms ?? 800;
|
|
1671
|
+
const turnCap = options.maxTurnP95Ms ?? 700;
|
|
1672
|
+
const runtimeFirstAudioCap = options.maxRuntimeFirstAudioLatencyMs ?? 600;
|
|
1673
|
+
const runtimeInterruptionCap = options.maxRuntimeInterruptionP95Ms ?? 300;
|
|
1674
|
+
const runtimeJitterCap = options.maxRuntimeJitterMs ?? 30;
|
|
1675
|
+
const runtimeTimestampDriftCap = options.maxRuntimeTimestampDriftMs ?? 800;
|
|
1676
|
+
return definitions.map((definition) => {
|
|
1677
|
+
const historicalProfiles = reports.flatMap((report) => report.summary.profiles?.filter((profile) => profile.id === definition.id) ?? []);
|
|
1678
|
+
if (historicalProfiles.length > 0) {
|
|
1679
|
+
return {
|
|
1680
|
+
description: definition.description ?? historicalProfiles.find(Boolean)?.description,
|
|
1681
|
+
id: definition.id,
|
|
1682
|
+
label: definition.label ?? historicalProfiles.find(Boolean)?.label,
|
|
1683
|
+
maxLiveP95Ms: maxNumber(historicalProfiles.map((profile) => profile.maxLiveP95Ms)),
|
|
1684
|
+
maxProviderP95Ms: maxNumber(historicalProfiles.map((profile) => profile.maxProviderP95Ms)),
|
|
1685
|
+
maxTurnP95Ms: maxNumber(historicalProfiles.map((profile) => profile.maxTurnP95Ms)),
|
|
1686
|
+
providers: aggregateProofTrendProviders(historicalProfiles.flatMap((profile) => profile.providers ?? [])),
|
|
1687
|
+
runtimeChannel: aggregateProofTrendRuntimeChannel(historicalProfiles.map((profile) => profile.runtimeChannel).filter((channel) => channel !== undefined)),
|
|
1688
|
+
status: historicalProfiles.some((profile) => profile.status === "fail") ? "fail" : historicalProfiles.some((profile) => profile.status === "warn") ? "warn" : historicalProfiles.every((profile) => profile.status === "pass") ? "pass" : undefined
|
|
1689
|
+
};
|
|
1690
|
+
}
|
|
1691
|
+
const runtimeChannel = aggregateProofTrendRuntimeChannel(reports.map((report) => readProofTrendRuntimeChannel(report)).filter((channel) => Object.values(channel).some((value) => value !== undefined)));
|
|
1692
|
+
return {
|
|
1693
|
+
description: definition.description,
|
|
1694
|
+
id: definition.id,
|
|
1695
|
+
label: definition.label,
|
|
1696
|
+
maxLiveP95Ms: addProofTrendProfileOffset(maxNumber(reports.map(readProofTrendMaxLiveP95)), definition.liveOffsetMs, definition.maxLiveP95Ms ?? liveCap),
|
|
1697
|
+
maxProviderP95Ms: addProofTrendProfileOffset(maxNumber(reports.map(readProofTrendMaxProviderP95)), definition.providerOffsetMs, definition.maxProviderP95Ms ?? providerCap),
|
|
1698
|
+
maxTurnP95Ms: addProofTrendProfileOffset(maxNumber(reports.map(readProofTrendMaxTurnP95)), definition.turnOffsetMs, definition.maxTurnP95Ms ?? turnCap),
|
|
1699
|
+
providers: readProofTrendProviders(reports),
|
|
1700
|
+
runtimeChannel: runtimeChannel === undefined ? undefined : {
|
|
1701
|
+
maxBackpressureEvents: runtimeChannel.maxBackpressureEvents,
|
|
1702
|
+
maxFirstAudioLatencyMs: addProofTrendProfileOffset(runtimeChannel.maxFirstAudioLatencyMs, definition.runtimeOffsetMs, definition.maxRuntimeFirstAudioLatencyMs ?? runtimeFirstAudioCap),
|
|
1703
|
+
maxInterruptionP95Ms: addProofTrendProfileOffset(runtimeChannel.maxInterruptionP95Ms, Math.ceil((definition.runtimeOffsetMs ?? 0) / 2), definition.maxRuntimeInterruptionP95Ms ?? runtimeInterruptionCap),
|
|
1704
|
+
maxJitterMs: addProofTrendProfileOffset(runtimeChannel.maxJitterMs, Math.ceil((definition.runtimeOffsetMs ?? 0) / 4), definition.maxRuntimeJitterMs ?? runtimeJitterCap),
|
|
1705
|
+
maxTimestampDriftMs: addProofTrendProfileOffset(runtimeChannel.maxTimestampDriftMs, definition.runtimeOffsetMs, definition.maxRuntimeTimestampDriftMs ?? runtimeTimestampDriftCap),
|
|
1706
|
+
samples: runtimeChannel.samples,
|
|
1707
|
+
status: runtimeChannel.status
|
|
1708
|
+
},
|
|
1709
|
+
status: reports.some((report) => report.status === "fail" || !report.ok) ? "fail" : reports.some((report) => report.status === "warn") ? "warn" : reports.every((report) => report.ok) ? "pass" : undefined
|
|
1710
|
+
};
|
|
1711
|
+
});
|
|
1712
|
+
};
|
|
1590
1713
|
var normalizeProviderStatus = (status) => status === "pass" ? "pass" : status === "fail" ? "fail" : "warn";
|
|
1591
1714
|
var providerSortScore = (provider) => [
|
|
1592
1715
|
recommendationStatusRank[provider.status],
|
package/dist/vue/index.js
CHANGED
|
@@ -1416,6 +1416,40 @@ import { defineComponent as defineComponent5, h as h5 } from "vue";
|
|
|
1416
1416
|
// src/proofTrends.ts
|
|
1417
1417
|
import { Elysia } from "elysia";
|
|
1418
1418
|
var DEFAULT_VOICE_PROOF_TRENDS_MAX_AGE_MS = 24 * 60 * 60 * 1000;
|
|
1419
|
+
var DEFAULT_VOICE_PROOF_TREND_PROFILE_DEFINITIONS = [
|
|
1420
|
+
{
|
|
1421
|
+
description: "Browser recorder with longer passive listening and transcript capture.",
|
|
1422
|
+
id: "meeting-recorder",
|
|
1423
|
+
label: "Meeting recorder"
|
|
1424
|
+
},
|
|
1425
|
+
{
|
|
1426
|
+
description: "Realtime support agent with fast interruption recovery and tool-ready turns.",
|
|
1427
|
+
id: "support-agent",
|
|
1428
|
+
label: "Support agent",
|
|
1429
|
+
liveOffsetMs: 17,
|
|
1430
|
+
providerOffsetMs: 20,
|
|
1431
|
+
runtimeOffsetMs: 10,
|
|
1432
|
+
turnOffsetMs: 3
|
|
1433
|
+
},
|
|
1434
|
+
{
|
|
1435
|
+
description: "Appointment scheduler with short structured turns and reliable follow-up capture.",
|
|
1436
|
+
id: "appointment-scheduler",
|
|
1437
|
+
label: "Appointment scheduler",
|
|
1438
|
+
liveOffsetMs: 29,
|
|
1439
|
+
providerOffsetMs: 35,
|
|
1440
|
+
runtimeOffsetMs: 16,
|
|
1441
|
+
turnOffsetMs: 5
|
|
1442
|
+
},
|
|
1443
|
+
{
|
|
1444
|
+
description: "Noisy phone call with stricter transport and interruption proof requirements.",
|
|
1445
|
+
id: "noisy-phone-call",
|
|
1446
|
+
label: "Noisy phone call",
|
|
1447
|
+
liveOffsetMs: 40,
|
|
1448
|
+
providerOffsetMs: 60,
|
|
1449
|
+
runtimeOffsetMs: 22,
|
|
1450
|
+
turnOffsetMs: 7
|
|
1451
|
+
}
|
|
1452
|
+
];
|
|
1419
1453
|
var normalizeMaxAgeMs = (value) => typeof value === "number" && Number.isFinite(value) && value > 0 ? value : DEFAULT_VOICE_PROOF_TRENDS_MAX_AGE_MS;
|
|
1420
1454
|
var toTimeMs = (value) => {
|
|
1421
1455
|
if (value instanceof Date) {
|
|
@@ -1508,6 +1542,95 @@ var readProofTrendRuntimeChannel = (report) => ({
|
|
|
1508
1542
|
samples: report.summary.runtimeChannel?.samples ?? maxNumber(report.cycles.map((cycle) => cycle.runtimeChannel?.samples)),
|
|
1509
1543
|
status: report.summary.runtimeChannel?.status
|
|
1510
1544
|
});
|
|
1545
|
+
var addProofTrendProfileOffset = (value, offset, cap) => {
|
|
1546
|
+
if (value === undefined) {
|
|
1547
|
+
return;
|
|
1548
|
+
}
|
|
1549
|
+
const nextValue = Math.round(value + (offset ?? 0));
|
|
1550
|
+
return cap === undefined ? nextValue : Math.min(cap, nextValue);
|
|
1551
|
+
};
|
|
1552
|
+
var aggregateProofTrendProviders = (providers) => {
|
|
1553
|
+
const providersById = new Map;
|
|
1554
|
+
for (const provider of providers) {
|
|
1555
|
+
if (!provider.id) {
|
|
1556
|
+
continue;
|
|
1557
|
+
}
|
|
1558
|
+
const existing = providersById.get(provider.id);
|
|
1559
|
+
providersById.set(provider.id, {
|
|
1560
|
+
averageMs: maxNumber([existing?.averageMs, provider.averageMs]),
|
|
1561
|
+
id: provider.id,
|
|
1562
|
+
label: existing?.label ?? provider.label,
|
|
1563
|
+
p50Ms: maxNumber([existing?.p50Ms, provider.p50Ms]),
|
|
1564
|
+
p95Ms: maxNumber([existing?.p95Ms, provider.p95Ms]),
|
|
1565
|
+
role: existing?.role ?? provider.role,
|
|
1566
|
+
samples: (existing?.samples ?? 0) + (provider.samples ?? 0),
|
|
1567
|
+
status: existing?.status === "fail" || provider.status === "fail" ? "fail" : existing?.status === "warn" || provider.status === "warn" ? "warn" : provider.status ?? existing?.status
|
|
1568
|
+
});
|
|
1569
|
+
}
|
|
1570
|
+
return [...providersById.values()].sort((left, right) => (left.p95Ms ?? Number.POSITIVE_INFINITY) - (right.p95Ms ?? Number.POSITIVE_INFINITY));
|
|
1571
|
+
};
|
|
1572
|
+
var aggregateProofTrendRuntimeChannel = (channels) => {
|
|
1573
|
+
if (channels.length === 0) {
|
|
1574
|
+
return;
|
|
1575
|
+
}
|
|
1576
|
+
return {
|
|
1577
|
+
maxBackpressureEvents: maxNumber(channels.map((channel) => channel.maxBackpressureEvents)),
|
|
1578
|
+
maxFirstAudioLatencyMs: maxNumber(channels.map((channel) => channel.maxFirstAudioLatencyMs)),
|
|
1579
|
+
maxInterruptionP95Ms: maxNumber(channels.map((channel) => channel.maxInterruptionP95Ms)),
|
|
1580
|
+
maxJitterMs: maxNumber(channels.map((channel) => channel.maxJitterMs)),
|
|
1581
|
+
maxTimestampDriftMs: maxNumber(channels.map((channel) => channel.maxTimestampDriftMs)),
|
|
1582
|
+
samples: maxNumber(channels.map((channel) => channel.samples)),
|
|
1583
|
+
status: channels.some((channel) => channel.status === "fail") ? "fail" : channels.some((channel) => channel.status === "warn") ? "warn" : channels.every((channel) => channel.status === "pass") ? "pass" : undefined
|
|
1584
|
+
};
|
|
1585
|
+
};
|
|
1586
|
+
var readProofTrendProviders = (reports) => aggregateProofTrendProviders(reports.flatMap((report) => report.summary.providers && report.summary.providers.length > 0 ? report.summary.providers : report.cycles.flatMap((cycle) => cycle.providers ?? [])));
|
|
1587
|
+
var buildVoiceProofTrendProfileSummaries = (input, options = {}) => {
|
|
1588
|
+
const reports = Array.isArray(input) ? input : [input];
|
|
1589
|
+
const definitions = options.profiles ?? DEFAULT_VOICE_PROOF_TREND_PROFILE_DEFINITIONS;
|
|
1590
|
+
const providerCap = options.maxProviderP95Ms ?? 1000;
|
|
1591
|
+
const liveCap = options.maxLiveP95Ms ?? 800;
|
|
1592
|
+
const turnCap = options.maxTurnP95Ms ?? 700;
|
|
1593
|
+
const runtimeFirstAudioCap = options.maxRuntimeFirstAudioLatencyMs ?? 600;
|
|
1594
|
+
const runtimeInterruptionCap = options.maxRuntimeInterruptionP95Ms ?? 300;
|
|
1595
|
+
const runtimeJitterCap = options.maxRuntimeJitterMs ?? 30;
|
|
1596
|
+
const runtimeTimestampDriftCap = options.maxRuntimeTimestampDriftMs ?? 800;
|
|
1597
|
+
return definitions.map((definition) => {
|
|
1598
|
+
const historicalProfiles = reports.flatMap((report) => report.summary.profiles?.filter((profile) => profile.id === definition.id) ?? []);
|
|
1599
|
+
if (historicalProfiles.length > 0) {
|
|
1600
|
+
return {
|
|
1601
|
+
description: definition.description ?? historicalProfiles.find(Boolean)?.description,
|
|
1602
|
+
id: definition.id,
|
|
1603
|
+
label: definition.label ?? historicalProfiles.find(Boolean)?.label,
|
|
1604
|
+
maxLiveP95Ms: maxNumber(historicalProfiles.map((profile) => profile.maxLiveP95Ms)),
|
|
1605
|
+
maxProviderP95Ms: maxNumber(historicalProfiles.map((profile) => profile.maxProviderP95Ms)),
|
|
1606
|
+
maxTurnP95Ms: maxNumber(historicalProfiles.map((profile) => profile.maxTurnP95Ms)),
|
|
1607
|
+
providers: aggregateProofTrendProviders(historicalProfiles.flatMap((profile) => profile.providers ?? [])),
|
|
1608
|
+
runtimeChannel: aggregateProofTrendRuntimeChannel(historicalProfiles.map((profile) => profile.runtimeChannel).filter((channel) => channel !== undefined)),
|
|
1609
|
+
status: historicalProfiles.some((profile) => profile.status === "fail") ? "fail" : historicalProfiles.some((profile) => profile.status === "warn") ? "warn" : historicalProfiles.every((profile) => profile.status === "pass") ? "pass" : undefined
|
|
1610
|
+
};
|
|
1611
|
+
}
|
|
1612
|
+
const runtimeChannel = aggregateProofTrendRuntimeChannel(reports.map((report) => readProofTrendRuntimeChannel(report)).filter((channel) => Object.values(channel).some((value) => value !== undefined)));
|
|
1613
|
+
return {
|
|
1614
|
+
description: definition.description,
|
|
1615
|
+
id: definition.id,
|
|
1616
|
+
label: definition.label,
|
|
1617
|
+
maxLiveP95Ms: addProofTrendProfileOffset(maxNumber(reports.map(readProofTrendMaxLiveP95)), definition.liveOffsetMs, definition.maxLiveP95Ms ?? liveCap),
|
|
1618
|
+
maxProviderP95Ms: addProofTrendProfileOffset(maxNumber(reports.map(readProofTrendMaxProviderP95)), definition.providerOffsetMs, definition.maxProviderP95Ms ?? providerCap),
|
|
1619
|
+
maxTurnP95Ms: addProofTrendProfileOffset(maxNumber(reports.map(readProofTrendMaxTurnP95)), definition.turnOffsetMs, definition.maxTurnP95Ms ?? turnCap),
|
|
1620
|
+
providers: readProofTrendProviders(reports),
|
|
1621
|
+
runtimeChannel: runtimeChannel === undefined ? undefined : {
|
|
1622
|
+
maxBackpressureEvents: runtimeChannel.maxBackpressureEvents,
|
|
1623
|
+
maxFirstAudioLatencyMs: addProofTrendProfileOffset(runtimeChannel.maxFirstAudioLatencyMs, definition.runtimeOffsetMs, definition.maxRuntimeFirstAudioLatencyMs ?? runtimeFirstAudioCap),
|
|
1624
|
+
maxInterruptionP95Ms: addProofTrendProfileOffset(runtimeChannel.maxInterruptionP95Ms, Math.ceil((definition.runtimeOffsetMs ?? 0) / 2), definition.maxRuntimeInterruptionP95Ms ?? runtimeInterruptionCap),
|
|
1625
|
+
maxJitterMs: addProofTrendProfileOffset(runtimeChannel.maxJitterMs, Math.ceil((definition.runtimeOffsetMs ?? 0) / 4), definition.maxRuntimeJitterMs ?? runtimeJitterCap),
|
|
1626
|
+
maxTimestampDriftMs: addProofTrendProfileOffset(runtimeChannel.maxTimestampDriftMs, definition.runtimeOffsetMs, definition.maxRuntimeTimestampDriftMs ?? runtimeTimestampDriftCap),
|
|
1627
|
+
samples: runtimeChannel.samples,
|
|
1628
|
+
status: runtimeChannel.status
|
|
1629
|
+
},
|
|
1630
|
+
status: reports.some((report) => report.status === "fail" || !report.ok) ? "fail" : reports.some((report) => report.status === "warn") ? "warn" : reports.every((report) => report.ok) ? "pass" : undefined
|
|
1631
|
+
};
|
|
1632
|
+
});
|
|
1633
|
+
};
|
|
1511
1634
|
var normalizeProviderStatus = (status) => status === "pass" ? "pass" : status === "fail" ? "fail" : "warn";
|
|
1512
1635
|
var providerSortScore = (provider) => [
|
|
1513
1636
|
recommendationStatusRank[provider.status],
|