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