@absolutejs/voice 0.0.22-beta.335 → 0.0.22-beta.336
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 +26 -10
- package/dist/index.js +26 -10
- package/dist/proofTrends.d.ts +1 -0
- package/dist/react/index.js +26 -10
- package/dist/vue/index.js +26 -10
- package/package.json +1 -1
package/dist/client/index.js
CHANGED
|
@@ -3924,6 +3924,18 @@ var shouldSwitchProvider = (current, best, options) => {
|
|
|
3924
3924
|
const improvementRatio = current.p95Ms > 0 ? improvementMs / current.p95Ms : 0;
|
|
3925
3925
|
return improvementMs >= minImprovementMs || improvementRatio >= minImprovementRatio;
|
|
3926
3926
|
};
|
|
3927
|
+
var bestProviderByRole = (providers) => {
|
|
3928
|
+
const best = new Map;
|
|
3929
|
+
for (const provider of providers) {
|
|
3930
|
+
const role = provider.role ?? provider.id;
|
|
3931
|
+
const existing = best.get(role);
|
|
3932
|
+
if (!existing || compareProviders(provider, existing) < 0) {
|
|
3933
|
+
best.set(role, provider);
|
|
3934
|
+
}
|
|
3935
|
+
}
|
|
3936
|
+
return [...best.values()].sort((left, right) => String(left.role ?? left.id).localeCompare(String(right.role ?? right.id)));
|
|
3937
|
+
};
|
|
3938
|
+
var formatProviderMix = (providers) => providers.length === 0 ? "n/a" : providers.map((provider) => provider.role ? `${provider.role.toUpperCase()} ${provider.label ?? provider.id}` : provider.label ?? provider.id).join(", ");
|
|
3927
3939
|
var evaluateVoiceProofTrendEvidence = (report, input = {}) => {
|
|
3928
3940
|
const issues = [];
|
|
3929
3941
|
const requiredStatus = input.requireStatus ?? "pass";
|
|
@@ -4040,8 +4052,10 @@ var buildVoiceProofTrendRecommendationReport = (report, options = {}) => {
|
|
|
4040
4052
|
const runtimeChannel = readProofTrendRuntimeChannel(report);
|
|
4041
4053
|
const providers = summarizeProofTrendProviders(report, budgets.maxProviderP95Ms);
|
|
4042
4054
|
const bestProvider = providers.find((provider) => provider.status === "pass") ?? providers[0];
|
|
4055
|
+
const bestProviders = bestProviderByRole(providers).filter((provider) => provider.status === "pass");
|
|
4043
4056
|
const currentProvider = options.currentProviderId ? providers.find((provider) => provider.id === options.currentProviderId) : undefined;
|
|
4044
|
-
const
|
|
4057
|
+
const bestComparableProvider = currentProvider?.role ? bestProviders.find((provider) => provider.role === currentProvider.role) : bestProvider;
|
|
4058
|
+
const providerSwitchRecommended = shouldSwitchProvider(currentProvider, bestComparableProvider, options);
|
|
4045
4059
|
const recommendations = [];
|
|
4046
4060
|
const issues = [];
|
|
4047
4061
|
if (report.ok !== true) {
|
|
@@ -4049,19 +4063,20 @@ var buildVoiceProofTrendRecommendationReport = (report, options = {}) => {
|
|
|
4049
4063
|
}
|
|
4050
4064
|
recommendations.push({
|
|
4051
4065
|
evidence: {
|
|
4052
|
-
bestProviderId: bestProvider?.id,
|
|
4053
|
-
|
|
4066
|
+
bestProviderId: bestComparableProvider?.id ?? bestProvider?.id,
|
|
4067
|
+
bestProviderMix: formatProviderMix(bestProviders),
|
|
4068
|
+
bestProviderP95Ms: bestComparableProvider?.p95Ms ?? bestProvider?.p95Ms,
|
|
4054
4069
|
budgetMs: budgets.maxProviderP95Ms,
|
|
4055
4070
|
currentProviderId: currentProvider?.id ?? options.currentProviderId,
|
|
4056
4071
|
currentProviderP95Ms: currentProvider?.p95Ms,
|
|
4057
4072
|
providerComparisonCount: providers.length,
|
|
4058
4073
|
providerP95Ms: maxProviderP95Ms
|
|
4059
4074
|
},
|
|
4060
|
-
nextMove: providers.length > 0 ? providerSwitchRecommended ? `Route latency-sensitive
|
|
4061
|
-
providerId:
|
|
4062
|
-
recommendation: providers.length > 0 ? providerSwitchRecommended ? `Switch latency-sensitive routing to ${
|
|
4063
|
-
role:
|
|
4064
|
-
status: providers.length > 0 ? providerSwitchRecommended ? "warn" : bestProvider?.status ?? "fail" : withinBudget(maxProviderP95Ms, budgets.maxProviderP95Ms) ? "pass" : maxProviderP95Ms === undefined ? "fail" : "warn",
|
|
4075
|
+
nextMove: providers.length > 0 ? providerSwitchRecommended ? `Route latency-sensitive ${currentProvider?.role ?? "provider"} traffic to ${bestComparableProvider?.label ?? bestComparableProvider?.id} for this call profile and keep the current path as fallback.` : bestProviders.length > 0 ? `Use the fastest proven provider mix for this call profile: ${formatProviderMix(bestProviders)}.` : "Collect provider-specific sustained samples before making provider-specific routing decisions." : withinBudget(maxProviderP95Ms, budgets.maxProviderP95Ms) ? "Keep the current provider route for latency-sensitive turns and keep collecting sustained proof." : "Route latency-sensitive turns to a faster provider profile or tighten fallback/circuit-breaker budgets before promotion.",
|
|
4076
|
+
providerId: providerSwitchRecommended ? bestComparableProvider?.id : bestProviders.length === 1 ? bestProviders[0]?.id : undefined,
|
|
4077
|
+
recommendation: providers.length > 0 ? providerSwitchRecommended ? `Switch latency-sensitive ${currentProvider?.role ?? "provider"} routing to ${bestComparableProvider?.label ?? bestComparableProvider?.id}` : bestProviders.length > 0 ? "Prefer the fastest proven provider mix for this call profile" : "Collect provider-specific latency samples" : withinBudget(maxProviderP95Ms, budgets.maxProviderP95Ms) ? "Keep current provider path" : "Change provider routing for latency-sensitive traffic",
|
|
4078
|
+
role: bestComparableProvider?.role,
|
|
4079
|
+
status: providers.length > 0 ? providerSwitchRecommended ? "warn" : bestProviders.length > 0 ? "pass" : bestProvider?.status ?? "fail" : withinBudget(maxProviderP95Ms, budgets.maxProviderP95Ms) ? "pass" : maxProviderP95Ms === undefined ? "fail" : "warn",
|
|
4065
4080
|
surface: "provider-path"
|
|
4066
4081
|
});
|
|
4067
4082
|
const runtimePass = withinBudget(runtimeChannel.maxFirstAudioLatencyMs, budgets.maxRuntimeFirstAudioLatencyMs) && withinBudget(runtimeChannel.maxInterruptionP95Ms, budgets.maxRuntimeInterruptionP95Ms) && withinBudget(runtimeChannel.maxJitterMs, budgets.maxRuntimeJitterMs) && withinBudget(runtimeChannel.maxTimestampDriftMs, budgets.maxRuntimeTimestampDriftMs) && withinBudget(runtimeChannel.maxBackpressureEvents, budgets.maxRuntimeBackpressureEvents);
|
|
@@ -4105,6 +4120,7 @@ var buildVoiceProofTrendRecommendationReport = (report, options = {}) => {
|
|
|
4105
4120
|
const status = issues.length > 0 ? "fail" : worstRecommendationStatus(recommendations);
|
|
4106
4121
|
return {
|
|
4107
4122
|
bestProvider,
|
|
4123
|
+
bestProviders,
|
|
4108
4124
|
generatedAt: new Date().toISOString(),
|
|
4109
4125
|
issues,
|
|
4110
4126
|
ok: status !== "fail",
|
|
@@ -4128,7 +4144,7 @@ var renderVoiceProofTrendRecommendationMarkdown = (report, title = "Voice Provid
|
|
|
4128
4144
|
"",
|
|
4129
4145
|
`- Status: ${report.status}`,
|
|
4130
4146
|
`- Source: ${report.source}`,
|
|
4131
|
-
`- Best provider: ${report.
|
|
4147
|
+
`- Best provider mix: ${formatProviderMix(report.bestProviders)}`,
|
|
4132
4148
|
`- Provider comparisons: ${String(report.summary.providerComparisonCount)}`,
|
|
4133
4149
|
`- Recommended actions: ${String(report.summary.recommendedActions)}`,
|
|
4134
4150
|
"",
|
|
@@ -4151,7 +4167,7 @@ var renderVoiceProofTrendRecommendationHTML = (report, title = "Voice Provider R
|
|
|
4151
4167
|
const cards = report.recommendations.map((recommendation) => `<article class="${escapeHtml3(recommendation.status)}"><p class="eyebrow">${escapeHtml3(recommendation.surface)} \xB7 ${escapeHtml3(recommendation.status)}</p><h2>${escapeHtml3(recommendation.recommendation)}</h2><p>${escapeHtml3(recommendation.nextMove)}</p><pre>${escapeHtml3(JSON.stringify(recommendation.evidence, null, 2))}</pre></article>`).join("");
|
|
4152
4168
|
const issues = report.issues.length === 0 ? "<li>None</li>" : report.issues.map((issue) => `<li>${escapeHtml3(issue)}</li>`).join("");
|
|
4153
4169
|
const providerRows = report.providers.length === 0 ? "<li>No provider-specific samples were present.</li>" : report.providers.map((provider) => `<li><strong>#${String(provider.rank)} ${escapeHtml3(provider.label ?? provider.id)}</strong><span>${escapeHtml3(provider.role ?? "provider")} \xB7 ${escapeHtml3(provider.status)} \xB7 p95 ${escapeHtml3(provider.p95Ms ?? "n/a")}ms \xB7 ${escapeHtml3(provider.samples ?? "n/a")} sample(s)</span><small>${escapeHtml3(provider.nextMove)}</small></li>`).join("");
|
|
4154
|
-
return `<!doctype html><html lang="en"><head><meta charset="utf-8" /><meta name="viewport" content="width=device-width,initial-scale=1" /><title>${escapeHtml3(title)}</title><style>body{background:#101418;color:#f7f3e8;font-family:ui-sans-serif,system-ui,sans-serif;margin:0}main{margin:auto;max-width:1120px;padding:32px}.hero,article{background:#17201d;border:1px solid #2e3d36;border-radius:24px;margin-bottom:16px;padding:22px}.hero{background:linear-gradient(135deg,rgba(20,184,166,.18),rgba(245,158,11,.12))}.eyebrow{color:#5eead4;font-weight:900;letter-spacing:.1em;text-transform:uppercase}h1{font-size:clamp(2.2rem,6vw,4.7rem);letter-spacing:-.06em;line-height:.92;margin:.2rem 0 1rem}.summary{display:flex;flex-wrap:wrap;gap:10px}.pill{border:1px solid #42534a;border-radius:999px;padding:8px 12px}.pass{border-color:rgba(34,197,94,.55)}.warn{border-color:rgba(245,158,11,.7)}.fail{border-color:rgba(239,68,68,.75)}pre{background:#0b1110;border-radius:14px;overflow:auto;padding:12px}a{color:#5eead4}li{margin:.45rem 0}li span,li small{display:block;color:#c9d3ca}</style></head><body><main><section class="hero"><p class="eyebrow">Sustained proof recommendations</p><h1>${escapeHtml3(title)}</h1><p>Generated ${escapeHtml3(report.generatedAt)} from ${escapeHtml3(report.source)}.</p><div class="summary"><span class="pill">Status ${escapeHtml3(report.status)}</span><span class="pill">Provider ${report.summary.keepCurrentProviderPath ? "keep" : "change"}</span><span class="pill">Best ${escapeHtml3(report.
|
|
4170
|
+
return `<!doctype html><html lang="en"><head><meta charset="utf-8" /><meta name="viewport" content="width=device-width,initial-scale=1" /><title>${escapeHtml3(title)}</title><style>body{background:#101418;color:#f7f3e8;font-family:ui-sans-serif,system-ui,sans-serif;margin:0}main{margin:auto;max-width:1120px;padding:32px}.hero,article{background:#17201d;border:1px solid #2e3d36;border-radius:24px;margin-bottom:16px;padding:22px}.hero{background:linear-gradient(135deg,rgba(20,184,166,.18),rgba(245,158,11,.12))}.eyebrow{color:#5eead4;font-weight:900;letter-spacing:.1em;text-transform:uppercase}h1{font-size:clamp(2.2rem,6vw,4.7rem);letter-spacing:-.06em;line-height:.92;margin:.2rem 0 1rem}.summary{display:flex;flex-wrap:wrap;gap:10px}.pill{border:1px solid #42534a;border-radius:999px;padding:8px 12px}.pass{border-color:rgba(34,197,94,.55)}.warn{border-color:rgba(245,158,11,.7)}.fail{border-color:rgba(239,68,68,.75)}pre{background:#0b1110;border-radius:14px;overflow:auto;padding:12px}a{color:#5eead4}li{margin:.45rem 0}li span,li small{display:block;color:#c9d3ca}</style></head><body><main><section class="hero"><p class="eyebrow">Sustained proof recommendations</p><h1>${escapeHtml3(title)}</h1><p>Generated ${escapeHtml3(report.generatedAt)} from ${escapeHtml3(report.source)}.</p><div class="summary"><span class="pill">Status ${escapeHtml3(report.status)}</span><span class="pill">Provider ${report.summary.keepCurrentProviderPath ? "keep" : "change"}</span><span class="pill">Best mix ${escapeHtml3(formatProviderMix(report.bestProviders))}</span><span class="pill">Runtime ${report.summary.keepCurrentRuntimeChannel ? "keep" : "tune"}</span><span class="pill">${String(report.summary.recommendedActions)} action(s)</span></div></section>${cards}<section class="hero"><h2>Provider Comparison</h2><ul>${providerRows}</ul></section><section class="hero"><h2>Issues</h2><ul>${issues}</ul></section></main></body></html>`;
|
|
4155
4171
|
};
|
|
4156
4172
|
var createVoiceProofTrendRecommendationRoutes = (options) => {
|
|
4157
4173
|
const path = options.path ?? "/api/voice/proof-trend-recommendations";
|
package/dist/index.js
CHANGED
|
@@ -14641,6 +14641,18 @@ var shouldSwitchProvider = (current, best, options) => {
|
|
|
14641
14641
|
const improvementRatio = current.p95Ms > 0 ? improvementMs / current.p95Ms : 0;
|
|
14642
14642
|
return improvementMs >= minImprovementMs || improvementRatio >= minImprovementRatio;
|
|
14643
14643
|
};
|
|
14644
|
+
var bestProviderByRole = (providers) => {
|
|
14645
|
+
const best = new Map;
|
|
14646
|
+
for (const provider of providers) {
|
|
14647
|
+
const role = provider.role ?? provider.id;
|
|
14648
|
+
const existing = best.get(role);
|
|
14649
|
+
if (!existing || compareProviders(provider, existing) < 0) {
|
|
14650
|
+
best.set(role, provider);
|
|
14651
|
+
}
|
|
14652
|
+
}
|
|
14653
|
+
return [...best.values()].sort((left, right) => String(left.role ?? left.id).localeCompare(String(right.role ?? right.id)));
|
|
14654
|
+
};
|
|
14655
|
+
var formatProviderMix = (providers) => providers.length === 0 ? "n/a" : providers.map((provider) => provider.role ? `${provider.role.toUpperCase()} ${provider.label ?? provider.id}` : provider.label ?? provider.id).join(", ");
|
|
14644
14656
|
var evaluateVoiceProofTrendEvidence = (report, input = {}) => {
|
|
14645
14657
|
const issues = [];
|
|
14646
14658
|
const requiredStatus = input.requireStatus ?? "pass";
|
|
@@ -14757,8 +14769,10 @@ var buildVoiceProofTrendRecommendationReport = (report, options = {}) => {
|
|
|
14757
14769
|
const runtimeChannel = readProofTrendRuntimeChannel(report);
|
|
14758
14770
|
const providers = summarizeProofTrendProviders(report, budgets.maxProviderP95Ms);
|
|
14759
14771
|
const bestProvider = providers.find((provider) => provider.status === "pass") ?? providers[0];
|
|
14772
|
+
const bestProviders = bestProviderByRole(providers).filter((provider) => provider.status === "pass");
|
|
14760
14773
|
const currentProvider = options.currentProviderId ? providers.find((provider) => provider.id === options.currentProviderId) : undefined;
|
|
14761
|
-
const
|
|
14774
|
+
const bestComparableProvider = currentProvider?.role ? bestProviders.find((provider) => provider.role === currentProvider.role) : bestProvider;
|
|
14775
|
+
const providerSwitchRecommended = shouldSwitchProvider(currentProvider, bestComparableProvider, options);
|
|
14762
14776
|
const recommendations = [];
|
|
14763
14777
|
const issues = [];
|
|
14764
14778
|
if (report.ok !== true) {
|
|
@@ -14766,19 +14780,20 @@ var buildVoiceProofTrendRecommendationReport = (report, options = {}) => {
|
|
|
14766
14780
|
}
|
|
14767
14781
|
recommendations.push({
|
|
14768
14782
|
evidence: {
|
|
14769
|
-
bestProviderId: bestProvider?.id,
|
|
14770
|
-
|
|
14783
|
+
bestProviderId: bestComparableProvider?.id ?? bestProvider?.id,
|
|
14784
|
+
bestProviderMix: formatProviderMix(bestProviders),
|
|
14785
|
+
bestProviderP95Ms: bestComparableProvider?.p95Ms ?? bestProvider?.p95Ms,
|
|
14771
14786
|
budgetMs: budgets.maxProviderP95Ms,
|
|
14772
14787
|
currentProviderId: currentProvider?.id ?? options.currentProviderId,
|
|
14773
14788
|
currentProviderP95Ms: currentProvider?.p95Ms,
|
|
14774
14789
|
providerComparisonCount: providers.length,
|
|
14775
14790
|
providerP95Ms: maxProviderP95Ms
|
|
14776
14791
|
},
|
|
14777
|
-
nextMove: providers.length > 0 ? providerSwitchRecommended ? `Route latency-sensitive
|
|
14778
|
-
providerId:
|
|
14779
|
-
recommendation: providers.length > 0 ? providerSwitchRecommended ? `Switch latency-sensitive routing to ${
|
|
14780
|
-
role:
|
|
14781
|
-
status: providers.length > 0 ? providerSwitchRecommended ? "warn" : bestProvider?.status ?? "fail" : withinBudget(maxProviderP95Ms, budgets.maxProviderP95Ms) ? "pass" : maxProviderP95Ms === undefined ? "fail" : "warn",
|
|
14792
|
+
nextMove: providers.length > 0 ? providerSwitchRecommended ? `Route latency-sensitive ${currentProvider?.role ?? "provider"} traffic to ${bestComparableProvider?.label ?? bestComparableProvider?.id} for this call profile and keep the current path as fallback.` : bestProviders.length > 0 ? `Use the fastest proven provider mix for this call profile: ${formatProviderMix(bestProviders)}.` : "Collect provider-specific sustained samples before making provider-specific routing decisions." : withinBudget(maxProviderP95Ms, budgets.maxProviderP95Ms) ? "Keep the current provider route for latency-sensitive turns and keep collecting sustained proof." : "Route latency-sensitive turns to a faster provider profile or tighten fallback/circuit-breaker budgets before promotion.",
|
|
14793
|
+
providerId: providerSwitchRecommended ? bestComparableProvider?.id : bestProviders.length === 1 ? bestProviders[0]?.id : undefined,
|
|
14794
|
+
recommendation: providers.length > 0 ? providerSwitchRecommended ? `Switch latency-sensitive ${currentProvider?.role ?? "provider"} routing to ${bestComparableProvider?.label ?? bestComparableProvider?.id}` : bestProviders.length > 0 ? "Prefer the fastest proven provider mix for this call profile" : "Collect provider-specific latency samples" : withinBudget(maxProviderP95Ms, budgets.maxProviderP95Ms) ? "Keep current provider path" : "Change provider routing for latency-sensitive traffic",
|
|
14795
|
+
role: bestComparableProvider?.role,
|
|
14796
|
+
status: providers.length > 0 ? providerSwitchRecommended ? "warn" : bestProviders.length > 0 ? "pass" : bestProvider?.status ?? "fail" : withinBudget(maxProviderP95Ms, budgets.maxProviderP95Ms) ? "pass" : maxProviderP95Ms === undefined ? "fail" : "warn",
|
|
14782
14797
|
surface: "provider-path"
|
|
14783
14798
|
});
|
|
14784
14799
|
const runtimePass = withinBudget(runtimeChannel.maxFirstAudioLatencyMs, budgets.maxRuntimeFirstAudioLatencyMs) && withinBudget(runtimeChannel.maxInterruptionP95Ms, budgets.maxRuntimeInterruptionP95Ms) && withinBudget(runtimeChannel.maxJitterMs, budgets.maxRuntimeJitterMs) && withinBudget(runtimeChannel.maxTimestampDriftMs, budgets.maxRuntimeTimestampDriftMs) && withinBudget(runtimeChannel.maxBackpressureEvents, budgets.maxRuntimeBackpressureEvents);
|
|
@@ -14822,6 +14837,7 @@ var buildVoiceProofTrendRecommendationReport = (report, options = {}) => {
|
|
|
14822
14837
|
const status = issues.length > 0 ? "fail" : worstRecommendationStatus(recommendations);
|
|
14823
14838
|
return {
|
|
14824
14839
|
bestProvider,
|
|
14840
|
+
bestProviders,
|
|
14825
14841
|
generatedAt: new Date().toISOString(),
|
|
14826
14842
|
issues,
|
|
14827
14843
|
ok: status !== "fail",
|
|
@@ -14845,7 +14861,7 @@ var renderVoiceProofTrendRecommendationMarkdown = (report, title = "Voice Provid
|
|
|
14845
14861
|
"",
|
|
14846
14862
|
`- Status: ${report.status}`,
|
|
14847
14863
|
`- Source: ${report.source}`,
|
|
14848
|
-
`- Best provider: ${report.
|
|
14864
|
+
`- Best provider mix: ${formatProviderMix(report.bestProviders)}`,
|
|
14849
14865
|
`- Provider comparisons: ${String(report.summary.providerComparisonCount)}`,
|
|
14850
14866
|
`- Recommended actions: ${String(report.summary.recommendedActions)}`,
|
|
14851
14867
|
"",
|
|
@@ -14868,7 +14884,7 @@ var renderVoiceProofTrendRecommendationHTML = (report, title = "Voice Provider R
|
|
|
14868
14884
|
const cards = report.recommendations.map((recommendation) => `<article class="${escapeHtml22(recommendation.status)}"><p class="eyebrow">${escapeHtml22(recommendation.surface)} \xB7 ${escapeHtml22(recommendation.status)}</p><h2>${escapeHtml22(recommendation.recommendation)}</h2><p>${escapeHtml22(recommendation.nextMove)}</p><pre>${escapeHtml22(JSON.stringify(recommendation.evidence, null, 2))}</pre></article>`).join("");
|
|
14869
14885
|
const issues = report.issues.length === 0 ? "<li>None</li>" : report.issues.map((issue) => `<li>${escapeHtml22(issue)}</li>`).join("");
|
|
14870
14886
|
const providerRows = report.providers.length === 0 ? "<li>No provider-specific samples were present.</li>" : report.providers.map((provider) => `<li><strong>#${String(provider.rank)} ${escapeHtml22(provider.label ?? provider.id)}</strong><span>${escapeHtml22(provider.role ?? "provider")} \xB7 ${escapeHtml22(provider.status)} \xB7 p95 ${escapeHtml22(provider.p95Ms ?? "n/a")}ms \xB7 ${escapeHtml22(provider.samples ?? "n/a")} sample(s)</span><small>${escapeHtml22(provider.nextMove)}</small></li>`).join("");
|
|
14871
|
-
return `<!doctype html><html lang="en"><head><meta charset="utf-8" /><meta name="viewport" content="width=device-width,initial-scale=1" /><title>${escapeHtml22(title)}</title><style>body{background:#101418;color:#f7f3e8;font-family:ui-sans-serif,system-ui,sans-serif;margin:0}main{margin:auto;max-width:1120px;padding:32px}.hero,article{background:#17201d;border:1px solid #2e3d36;border-radius:24px;margin-bottom:16px;padding:22px}.hero{background:linear-gradient(135deg,rgba(20,184,166,.18),rgba(245,158,11,.12))}.eyebrow{color:#5eead4;font-weight:900;letter-spacing:.1em;text-transform:uppercase}h1{font-size:clamp(2.2rem,6vw,4.7rem);letter-spacing:-.06em;line-height:.92;margin:.2rem 0 1rem}.summary{display:flex;flex-wrap:wrap;gap:10px}.pill{border:1px solid #42534a;border-radius:999px;padding:8px 12px}.pass{border-color:rgba(34,197,94,.55)}.warn{border-color:rgba(245,158,11,.7)}.fail{border-color:rgba(239,68,68,.75)}pre{background:#0b1110;border-radius:14px;overflow:auto;padding:12px}a{color:#5eead4}li{margin:.45rem 0}li span,li small{display:block;color:#c9d3ca}</style></head><body><main><section class="hero"><p class="eyebrow">Sustained proof recommendations</p><h1>${escapeHtml22(title)}</h1><p>Generated ${escapeHtml22(report.generatedAt)} from ${escapeHtml22(report.source)}.</p><div class="summary"><span class="pill">Status ${escapeHtml22(report.status)}</span><span class="pill">Provider ${report.summary.keepCurrentProviderPath ? "keep" : "change"}</span><span class="pill">Best ${escapeHtml22(report.
|
|
14887
|
+
return `<!doctype html><html lang="en"><head><meta charset="utf-8" /><meta name="viewport" content="width=device-width,initial-scale=1" /><title>${escapeHtml22(title)}</title><style>body{background:#101418;color:#f7f3e8;font-family:ui-sans-serif,system-ui,sans-serif;margin:0}main{margin:auto;max-width:1120px;padding:32px}.hero,article{background:#17201d;border:1px solid #2e3d36;border-radius:24px;margin-bottom:16px;padding:22px}.hero{background:linear-gradient(135deg,rgba(20,184,166,.18),rgba(245,158,11,.12))}.eyebrow{color:#5eead4;font-weight:900;letter-spacing:.1em;text-transform:uppercase}h1{font-size:clamp(2.2rem,6vw,4.7rem);letter-spacing:-.06em;line-height:.92;margin:.2rem 0 1rem}.summary{display:flex;flex-wrap:wrap;gap:10px}.pill{border:1px solid #42534a;border-radius:999px;padding:8px 12px}.pass{border-color:rgba(34,197,94,.55)}.warn{border-color:rgba(245,158,11,.7)}.fail{border-color:rgba(239,68,68,.75)}pre{background:#0b1110;border-radius:14px;overflow:auto;padding:12px}a{color:#5eead4}li{margin:.45rem 0}li span,li small{display:block;color:#c9d3ca}</style></head><body><main><section class="hero"><p class="eyebrow">Sustained proof recommendations</p><h1>${escapeHtml22(title)}</h1><p>Generated ${escapeHtml22(report.generatedAt)} from ${escapeHtml22(report.source)}.</p><div class="summary"><span class="pill">Status ${escapeHtml22(report.status)}</span><span class="pill">Provider ${report.summary.keepCurrentProviderPath ? "keep" : "change"}</span><span class="pill">Best mix ${escapeHtml22(formatProviderMix(report.bestProviders))}</span><span class="pill">Runtime ${report.summary.keepCurrentRuntimeChannel ? "keep" : "tune"}</span><span class="pill">${String(report.summary.recommendedActions)} action(s)</span></div></section>${cards}<section class="hero"><h2>Provider Comparison</h2><ul>${providerRows}</ul></section><section class="hero"><h2>Issues</h2><ul>${issues}</ul></section></main></body></html>`;
|
|
14872
14888
|
};
|
|
14873
14889
|
var createVoiceProofTrendRecommendationRoutes = (options) => {
|
|
14874
14890
|
const path = options.path ?? "/api/voice/proof-trend-recommendations";
|
package/dist/proofTrends.d.ts
CHANGED
|
@@ -145,6 +145,7 @@ export type VoiceProofTrendProviderRecommendation = {
|
|
|
145
145
|
};
|
|
146
146
|
export type VoiceProofTrendRecommendationReport = {
|
|
147
147
|
bestProvider?: VoiceProofTrendProviderRecommendation;
|
|
148
|
+
bestProviders: VoiceProofTrendProviderRecommendation[];
|
|
148
149
|
generatedAt: string;
|
|
149
150
|
issues: string[];
|
|
150
151
|
ok: boolean;
|
package/dist/react/index.js
CHANGED
|
@@ -1672,6 +1672,18 @@ var shouldSwitchProvider = (current, best, options) => {
|
|
|
1672
1672
|
const improvementRatio = current.p95Ms > 0 ? improvementMs / current.p95Ms : 0;
|
|
1673
1673
|
return improvementMs >= minImprovementMs || improvementRatio >= minImprovementRatio;
|
|
1674
1674
|
};
|
|
1675
|
+
var bestProviderByRole = (providers) => {
|
|
1676
|
+
const best = new Map;
|
|
1677
|
+
for (const provider of providers) {
|
|
1678
|
+
const role = provider.role ?? provider.id;
|
|
1679
|
+
const existing = best.get(role);
|
|
1680
|
+
if (!existing || compareProviders(provider, existing) < 0) {
|
|
1681
|
+
best.set(role, provider);
|
|
1682
|
+
}
|
|
1683
|
+
}
|
|
1684
|
+
return [...best.values()].sort((left, right) => String(left.role ?? left.id).localeCompare(String(right.role ?? right.id)));
|
|
1685
|
+
};
|
|
1686
|
+
var formatProviderMix = (providers) => providers.length === 0 ? "n/a" : providers.map((provider) => provider.role ? `${provider.role.toUpperCase()} ${provider.label ?? provider.id}` : provider.label ?? provider.id).join(", ");
|
|
1675
1687
|
var evaluateVoiceProofTrendEvidence = (report, input = {}) => {
|
|
1676
1688
|
const issues = [];
|
|
1677
1689
|
const requiredStatus = input.requireStatus ?? "pass";
|
|
@@ -1788,8 +1800,10 @@ var buildVoiceProofTrendRecommendationReport = (report, options = {}) => {
|
|
|
1788
1800
|
const runtimeChannel = readProofTrendRuntimeChannel(report);
|
|
1789
1801
|
const providers = summarizeProofTrendProviders(report, budgets.maxProviderP95Ms);
|
|
1790
1802
|
const bestProvider = providers.find((provider) => provider.status === "pass") ?? providers[0];
|
|
1803
|
+
const bestProviders = bestProviderByRole(providers).filter((provider) => provider.status === "pass");
|
|
1791
1804
|
const currentProvider = options.currentProviderId ? providers.find((provider) => provider.id === options.currentProviderId) : undefined;
|
|
1792
|
-
const
|
|
1805
|
+
const bestComparableProvider = currentProvider?.role ? bestProviders.find((provider) => provider.role === currentProvider.role) : bestProvider;
|
|
1806
|
+
const providerSwitchRecommended = shouldSwitchProvider(currentProvider, bestComparableProvider, options);
|
|
1793
1807
|
const recommendations = [];
|
|
1794
1808
|
const issues = [];
|
|
1795
1809
|
if (report.ok !== true) {
|
|
@@ -1797,19 +1811,20 @@ var buildVoiceProofTrendRecommendationReport = (report, options = {}) => {
|
|
|
1797
1811
|
}
|
|
1798
1812
|
recommendations.push({
|
|
1799
1813
|
evidence: {
|
|
1800
|
-
bestProviderId: bestProvider?.id,
|
|
1801
|
-
|
|
1814
|
+
bestProviderId: bestComparableProvider?.id ?? bestProvider?.id,
|
|
1815
|
+
bestProviderMix: formatProviderMix(bestProviders),
|
|
1816
|
+
bestProviderP95Ms: bestComparableProvider?.p95Ms ?? bestProvider?.p95Ms,
|
|
1802
1817
|
budgetMs: budgets.maxProviderP95Ms,
|
|
1803
1818
|
currentProviderId: currentProvider?.id ?? options.currentProviderId,
|
|
1804
1819
|
currentProviderP95Ms: currentProvider?.p95Ms,
|
|
1805
1820
|
providerComparisonCount: providers.length,
|
|
1806
1821
|
providerP95Ms: maxProviderP95Ms
|
|
1807
1822
|
},
|
|
1808
|
-
nextMove: providers.length > 0 ? providerSwitchRecommended ? `Route latency-sensitive
|
|
1809
|
-
providerId:
|
|
1810
|
-
recommendation: providers.length > 0 ? providerSwitchRecommended ? `Switch latency-sensitive routing to ${
|
|
1811
|
-
role:
|
|
1812
|
-
status: providers.length > 0 ? providerSwitchRecommended ? "warn" : bestProvider?.status ?? "fail" : withinBudget(maxProviderP95Ms, budgets.maxProviderP95Ms) ? "pass" : maxProviderP95Ms === undefined ? "fail" : "warn",
|
|
1823
|
+
nextMove: providers.length > 0 ? providerSwitchRecommended ? `Route latency-sensitive ${currentProvider?.role ?? "provider"} traffic to ${bestComparableProvider?.label ?? bestComparableProvider?.id} for this call profile and keep the current path as fallback.` : bestProviders.length > 0 ? `Use the fastest proven provider mix for this call profile: ${formatProviderMix(bestProviders)}.` : "Collect provider-specific sustained samples before making provider-specific routing decisions." : withinBudget(maxProviderP95Ms, budgets.maxProviderP95Ms) ? "Keep the current provider route for latency-sensitive turns and keep collecting sustained proof." : "Route latency-sensitive turns to a faster provider profile or tighten fallback/circuit-breaker budgets before promotion.",
|
|
1824
|
+
providerId: providerSwitchRecommended ? bestComparableProvider?.id : bestProviders.length === 1 ? bestProviders[0]?.id : undefined,
|
|
1825
|
+
recommendation: providers.length > 0 ? providerSwitchRecommended ? `Switch latency-sensitive ${currentProvider?.role ?? "provider"} routing to ${bestComparableProvider?.label ?? bestComparableProvider?.id}` : bestProviders.length > 0 ? "Prefer the fastest proven provider mix for this call profile" : "Collect provider-specific latency samples" : withinBudget(maxProviderP95Ms, budgets.maxProviderP95Ms) ? "Keep current provider path" : "Change provider routing for latency-sensitive traffic",
|
|
1826
|
+
role: bestComparableProvider?.role,
|
|
1827
|
+
status: providers.length > 0 ? providerSwitchRecommended ? "warn" : bestProviders.length > 0 ? "pass" : bestProvider?.status ?? "fail" : withinBudget(maxProviderP95Ms, budgets.maxProviderP95Ms) ? "pass" : maxProviderP95Ms === undefined ? "fail" : "warn",
|
|
1813
1828
|
surface: "provider-path"
|
|
1814
1829
|
});
|
|
1815
1830
|
const runtimePass = withinBudget(runtimeChannel.maxFirstAudioLatencyMs, budgets.maxRuntimeFirstAudioLatencyMs) && withinBudget(runtimeChannel.maxInterruptionP95Ms, budgets.maxRuntimeInterruptionP95Ms) && withinBudget(runtimeChannel.maxJitterMs, budgets.maxRuntimeJitterMs) && withinBudget(runtimeChannel.maxTimestampDriftMs, budgets.maxRuntimeTimestampDriftMs) && withinBudget(runtimeChannel.maxBackpressureEvents, budgets.maxRuntimeBackpressureEvents);
|
|
@@ -1853,6 +1868,7 @@ var buildVoiceProofTrendRecommendationReport = (report, options = {}) => {
|
|
|
1853
1868
|
const status = issues.length > 0 ? "fail" : worstRecommendationStatus(recommendations);
|
|
1854
1869
|
return {
|
|
1855
1870
|
bestProvider,
|
|
1871
|
+
bestProviders,
|
|
1856
1872
|
generatedAt: new Date().toISOString(),
|
|
1857
1873
|
issues,
|
|
1858
1874
|
ok: status !== "fail",
|
|
@@ -1876,7 +1892,7 @@ var renderVoiceProofTrendRecommendationMarkdown = (report, title = "Voice Provid
|
|
|
1876
1892
|
"",
|
|
1877
1893
|
`- Status: ${report.status}`,
|
|
1878
1894
|
`- Source: ${report.source}`,
|
|
1879
|
-
`- Best provider: ${report.
|
|
1895
|
+
`- Best provider mix: ${formatProviderMix(report.bestProviders)}`,
|
|
1880
1896
|
`- Provider comparisons: ${String(report.summary.providerComparisonCount)}`,
|
|
1881
1897
|
`- Recommended actions: ${String(report.summary.recommendedActions)}`,
|
|
1882
1898
|
"",
|
|
@@ -1899,7 +1915,7 @@ var renderVoiceProofTrendRecommendationHTML = (report, title = "Voice Provider R
|
|
|
1899
1915
|
const cards = report.recommendations.map((recommendation) => `<article class="${escapeHtml5(recommendation.status)}"><p class="eyebrow">${escapeHtml5(recommendation.surface)} \xB7 ${escapeHtml5(recommendation.status)}</p><h2>${escapeHtml5(recommendation.recommendation)}</h2><p>${escapeHtml5(recommendation.nextMove)}</p><pre>${escapeHtml5(JSON.stringify(recommendation.evidence, null, 2))}</pre></article>`).join("");
|
|
1900
1916
|
const issues = report.issues.length === 0 ? "<li>None</li>" : report.issues.map((issue) => `<li>${escapeHtml5(issue)}</li>`).join("");
|
|
1901
1917
|
const providerRows = report.providers.length === 0 ? "<li>No provider-specific samples were present.</li>" : report.providers.map((provider) => `<li><strong>#${String(provider.rank)} ${escapeHtml5(provider.label ?? provider.id)}</strong><span>${escapeHtml5(provider.role ?? "provider")} \xB7 ${escapeHtml5(provider.status)} \xB7 p95 ${escapeHtml5(provider.p95Ms ?? "n/a")}ms \xB7 ${escapeHtml5(provider.samples ?? "n/a")} sample(s)</span><small>${escapeHtml5(provider.nextMove)}</small></li>`).join("");
|
|
1902
|
-
return `<!doctype html><html lang="en"><head><meta charset="utf-8" /><meta name="viewport" content="width=device-width,initial-scale=1" /><title>${escapeHtml5(title)}</title><style>body{background:#101418;color:#f7f3e8;font-family:ui-sans-serif,system-ui,sans-serif;margin:0}main{margin:auto;max-width:1120px;padding:32px}.hero,article{background:#17201d;border:1px solid #2e3d36;border-radius:24px;margin-bottom:16px;padding:22px}.hero{background:linear-gradient(135deg,rgba(20,184,166,.18),rgba(245,158,11,.12))}.eyebrow{color:#5eead4;font-weight:900;letter-spacing:.1em;text-transform:uppercase}h1{font-size:clamp(2.2rem,6vw,4.7rem);letter-spacing:-.06em;line-height:.92;margin:.2rem 0 1rem}.summary{display:flex;flex-wrap:wrap;gap:10px}.pill{border:1px solid #42534a;border-radius:999px;padding:8px 12px}.pass{border-color:rgba(34,197,94,.55)}.warn{border-color:rgba(245,158,11,.7)}.fail{border-color:rgba(239,68,68,.75)}pre{background:#0b1110;border-radius:14px;overflow:auto;padding:12px}a{color:#5eead4}li{margin:.45rem 0}li span,li small{display:block;color:#c9d3ca}</style></head><body><main><section class="hero"><p class="eyebrow">Sustained proof recommendations</p><h1>${escapeHtml5(title)}</h1><p>Generated ${escapeHtml5(report.generatedAt)} from ${escapeHtml5(report.source)}.</p><div class="summary"><span class="pill">Status ${escapeHtml5(report.status)}</span><span class="pill">Provider ${report.summary.keepCurrentProviderPath ? "keep" : "change"}</span><span class="pill">Best ${escapeHtml5(report.
|
|
1918
|
+
return `<!doctype html><html lang="en"><head><meta charset="utf-8" /><meta name="viewport" content="width=device-width,initial-scale=1" /><title>${escapeHtml5(title)}</title><style>body{background:#101418;color:#f7f3e8;font-family:ui-sans-serif,system-ui,sans-serif;margin:0}main{margin:auto;max-width:1120px;padding:32px}.hero,article{background:#17201d;border:1px solid #2e3d36;border-radius:24px;margin-bottom:16px;padding:22px}.hero{background:linear-gradient(135deg,rgba(20,184,166,.18),rgba(245,158,11,.12))}.eyebrow{color:#5eead4;font-weight:900;letter-spacing:.1em;text-transform:uppercase}h1{font-size:clamp(2.2rem,6vw,4.7rem);letter-spacing:-.06em;line-height:.92;margin:.2rem 0 1rem}.summary{display:flex;flex-wrap:wrap;gap:10px}.pill{border:1px solid #42534a;border-radius:999px;padding:8px 12px}.pass{border-color:rgba(34,197,94,.55)}.warn{border-color:rgba(245,158,11,.7)}.fail{border-color:rgba(239,68,68,.75)}pre{background:#0b1110;border-radius:14px;overflow:auto;padding:12px}a{color:#5eead4}li{margin:.45rem 0}li span,li small{display:block;color:#c9d3ca}</style></head><body><main><section class="hero"><p class="eyebrow">Sustained proof recommendations</p><h1>${escapeHtml5(title)}</h1><p>Generated ${escapeHtml5(report.generatedAt)} from ${escapeHtml5(report.source)}.</p><div class="summary"><span class="pill">Status ${escapeHtml5(report.status)}</span><span class="pill">Provider ${report.summary.keepCurrentProviderPath ? "keep" : "change"}</span><span class="pill">Best mix ${escapeHtml5(formatProviderMix(report.bestProviders))}</span><span class="pill">Runtime ${report.summary.keepCurrentRuntimeChannel ? "keep" : "tune"}</span><span class="pill">${String(report.summary.recommendedActions)} action(s)</span></div></section>${cards}<section class="hero"><h2>Provider Comparison</h2><ul>${providerRows}</ul></section><section class="hero"><h2>Issues</h2><ul>${issues}</ul></section></main></body></html>`;
|
|
1903
1919
|
};
|
|
1904
1920
|
var createVoiceProofTrendRecommendationRoutes = (options) => {
|
|
1905
1921
|
const path = options.path ?? "/api/voice/proof-trend-recommendations";
|
package/dist/vue/index.js
CHANGED
|
@@ -1593,6 +1593,18 @@ var shouldSwitchProvider = (current, best, options) => {
|
|
|
1593
1593
|
const improvementRatio = current.p95Ms > 0 ? improvementMs / current.p95Ms : 0;
|
|
1594
1594
|
return improvementMs >= minImprovementMs || improvementRatio >= minImprovementRatio;
|
|
1595
1595
|
};
|
|
1596
|
+
var bestProviderByRole = (providers) => {
|
|
1597
|
+
const best = new Map;
|
|
1598
|
+
for (const provider of providers) {
|
|
1599
|
+
const role = provider.role ?? provider.id;
|
|
1600
|
+
const existing = best.get(role);
|
|
1601
|
+
if (!existing || compareProviders(provider, existing) < 0) {
|
|
1602
|
+
best.set(role, provider);
|
|
1603
|
+
}
|
|
1604
|
+
}
|
|
1605
|
+
return [...best.values()].sort((left, right) => String(left.role ?? left.id).localeCompare(String(right.role ?? right.id)));
|
|
1606
|
+
};
|
|
1607
|
+
var formatProviderMix = (providers) => providers.length === 0 ? "n/a" : providers.map((provider) => provider.role ? `${provider.role.toUpperCase()} ${provider.label ?? provider.id}` : provider.label ?? provider.id).join(", ");
|
|
1596
1608
|
var evaluateVoiceProofTrendEvidence = (report, input = {}) => {
|
|
1597
1609
|
const issues = [];
|
|
1598
1610
|
const requiredStatus = input.requireStatus ?? "pass";
|
|
@@ -1709,8 +1721,10 @@ var buildVoiceProofTrendRecommendationReport = (report, options = {}) => {
|
|
|
1709
1721
|
const runtimeChannel = readProofTrendRuntimeChannel(report);
|
|
1710
1722
|
const providers = summarizeProofTrendProviders(report, budgets.maxProviderP95Ms);
|
|
1711
1723
|
const bestProvider = providers.find((provider) => provider.status === "pass") ?? providers[0];
|
|
1724
|
+
const bestProviders = bestProviderByRole(providers).filter((provider) => provider.status === "pass");
|
|
1712
1725
|
const currentProvider = options.currentProviderId ? providers.find((provider) => provider.id === options.currentProviderId) : undefined;
|
|
1713
|
-
const
|
|
1726
|
+
const bestComparableProvider = currentProvider?.role ? bestProviders.find((provider) => provider.role === currentProvider.role) : bestProvider;
|
|
1727
|
+
const providerSwitchRecommended = shouldSwitchProvider(currentProvider, bestComparableProvider, options);
|
|
1714
1728
|
const recommendations = [];
|
|
1715
1729
|
const issues = [];
|
|
1716
1730
|
if (report.ok !== true) {
|
|
@@ -1718,19 +1732,20 @@ var buildVoiceProofTrendRecommendationReport = (report, options = {}) => {
|
|
|
1718
1732
|
}
|
|
1719
1733
|
recommendations.push({
|
|
1720
1734
|
evidence: {
|
|
1721
|
-
bestProviderId: bestProvider?.id,
|
|
1722
|
-
|
|
1735
|
+
bestProviderId: bestComparableProvider?.id ?? bestProvider?.id,
|
|
1736
|
+
bestProviderMix: formatProviderMix(bestProviders),
|
|
1737
|
+
bestProviderP95Ms: bestComparableProvider?.p95Ms ?? bestProvider?.p95Ms,
|
|
1723
1738
|
budgetMs: budgets.maxProviderP95Ms,
|
|
1724
1739
|
currentProviderId: currentProvider?.id ?? options.currentProviderId,
|
|
1725
1740
|
currentProviderP95Ms: currentProvider?.p95Ms,
|
|
1726
1741
|
providerComparisonCount: providers.length,
|
|
1727
1742
|
providerP95Ms: maxProviderP95Ms
|
|
1728
1743
|
},
|
|
1729
|
-
nextMove: providers.length > 0 ? providerSwitchRecommended ? `Route latency-sensitive
|
|
1730
|
-
providerId:
|
|
1731
|
-
recommendation: providers.length > 0 ? providerSwitchRecommended ? `Switch latency-sensitive routing to ${
|
|
1732
|
-
role:
|
|
1733
|
-
status: providers.length > 0 ? providerSwitchRecommended ? "warn" : bestProvider?.status ?? "fail" : withinBudget(maxProviderP95Ms, budgets.maxProviderP95Ms) ? "pass" : maxProviderP95Ms === undefined ? "fail" : "warn",
|
|
1744
|
+
nextMove: providers.length > 0 ? providerSwitchRecommended ? `Route latency-sensitive ${currentProvider?.role ?? "provider"} traffic to ${bestComparableProvider?.label ?? bestComparableProvider?.id} for this call profile and keep the current path as fallback.` : bestProviders.length > 0 ? `Use the fastest proven provider mix for this call profile: ${formatProviderMix(bestProviders)}.` : "Collect provider-specific sustained samples before making provider-specific routing decisions." : withinBudget(maxProviderP95Ms, budgets.maxProviderP95Ms) ? "Keep the current provider route for latency-sensitive turns and keep collecting sustained proof." : "Route latency-sensitive turns to a faster provider profile or tighten fallback/circuit-breaker budgets before promotion.",
|
|
1745
|
+
providerId: providerSwitchRecommended ? bestComparableProvider?.id : bestProviders.length === 1 ? bestProviders[0]?.id : undefined,
|
|
1746
|
+
recommendation: providers.length > 0 ? providerSwitchRecommended ? `Switch latency-sensitive ${currentProvider?.role ?? "provider"} routing to ${bestComparableProvider?.label ?? bestComparableProvider?.id}` : bestProviders.length > 0 ? "Prefer the fastest proven provider mix for this call profile" : "Collect provider-specific latency samples" : withinBudget(maxProviderP95Ms, budgets.maxProviderP95Ms) ? "Keep current provider path" : "Change provider routing for latency-sensitive traffic",
|
|
1747
|
+
role: bestComparableProvider?.role,
|
|
1748
|
+
status: providers.length > 0 ? providerSwitchRecommended ? "warn" : bestProviders.length > 0 ? "pass" : bestProvider?.status ?? "fail" : withinBudget(maxProviderP95Ms, budgets.maxProviderP95Ms) ? "pass" : maxProviderP95Ms === undefined ? "fail" : "warn",
|
|
1734
1749
|
surface: "provider-path"
|
|
1735
1750
|
});
|
|
1736
1751
|
const runtimePass = withinBudget(runtimeChannel.maxFirstAudioLatencyMs, budgets.maxRuntimeFirstAudioLatencyMs) && withinBudget(runtimeChannel.maxInterruptionP95Ms, budgets.maxRuntimeInterruptionP95Ms) && withinBudget(runtimeChannel.maxJitterMs, budgets.maxRuntimeJitterMs) && withinBudget(runtimeChannel.maxTimestampDriftMs, budgets.maxRuntimeTimestampDriftMs) && withinBudget(runtimeChannel.maxBackpressureEvents, budgets.maxRuntimeBackpressureEvents);
|
|
@@ -1774,6 +1789,7 @@ var buildVoiceProofTrendRecommendationReport = (report, options = {}) => {
|
|
|
1774
1789
|
const status = issues.length > 0 ? "fail" : worstRecommendationStatus(recommendations);
|
|
1775
1790
|
return {
|
|
1776
1791
|
bestProvider,
|
|
1792
|
+
bestProviders,
|
|
1777
1793
|
generatedAt: new Date().toISOString(),
|
|
1778
1794
|
issues,
|
|
1779
1795
|
ok: status !== "fail",
|
|
@@ -1797,7 +1813,7 @@ var renderVoiceProofTrendRecommendationMarkdown = (report, title = "Voice Provid
|
|
|
1797
1813
|
"",
|
|
1798
1814
|
`- Status: ${report.status}`,
|
|
1799
1815
|
`- Source: ${report.source}`,
|
|
1800
|
-
`- Best provider: ${report.
|
|
1816
|
+
`- Best provider mix: ${formatProviderMix(report.bestProviders)}`,
|
|
1801
1817
|
`- Provider comparisons: ${String(report.summary.providerComparisonCount)}`,
|
|
1802
1818
|
`- Recommended actions: ${String(report.summary.recommendedActions)}`,
|
|
1803
1819
|
"",
|
|
@@ -1820,7 +1836,7 @@ var renderVoiceProofTrendRecommendationHTML = (report, title = "Voice Provider R
|
|
|
1820
1836
|
const cards = report.recommendations.map((recommendation) => `<article class="${escapeHtml5(recommendation.status)}"><p class="eyebrow">${escapeHtml5(recommendation.surface)} \xB7 ${escapeHtml5(recommendation.status)}</p><h2>${escapeHtml5(recommendation.recommendation)}</h2><p>${escapeHtml5(recommendation.nextMove)}</p><pre>${escapeHtml5(JSON.stringify(recommendation.evidence, null, 2))}</pre></article>`).join("");
|
|
1821
1837
|
const issues = report.issues.length === 0 ? "<li>None</li>" : report.issues.map((issue) => `<li>${escapeHtml5(issue)}</li>`).join("");
|
|
1822
1838
|
const providerRows = report.providers.length === 0 ? "<li>No provider-specific samples were present.</li>" : report.providers.map((provider) => `<li><strong>#${String(provider.rank)} ${escapeHtml5(provider.label ?? provider.id)}</strong><span>${escapeHtml5(provider.role ?? "provider")} \xB7 ${escapeHtml5(provider.status)} \xB7 p95 ${escapeHtml5(provider.p95Ms ?? "n/a")}ms \xB7 ${escapeHtml5(provider.samples ?? "n/a")} sample(s)</span><small>${escapeHtml5(provider.nextMove)}</small></li>`).join("");
|
|
1823
|
-
return `<!doctype html><html lang="en"><head><meta charset="utf-8" /><meta name="viewport" content="width=device-width,initial-scale=1" /><title>${escapeHtml5(title)}</title><style>body{background:#101418;color:#f7f3e8;font-family:ui-sans-serif,system-ui,sans-serif;margin:0}main{margin:auto;max-width:1120px;padding:32px}.hero,article{background:#17201d;border:1px solid #2e3d36;border-radius:24px;margin-bottom:16px;padding:22px}.hero{background:linear-gradient(135deg,rgba(20,184,166,.18),rgba(245,158,11,.12))}.eyebrow{color:#5eead4;font-weight:900;letter-spacing:.1em;text-transform:uppercase}h1{font-size:clamp(2.2rem,6vw,4.7rem);letter-spacing:-.06em;line-height:.92;margin:.2rem 0 1rem}.summary{display:flex;flex-wrap:wrap;gap:10px}.pill{border:1px solid #42534a;border-radius:999px;padding:8px 12px}.pass{border-color:rgba(34,197,94,.55)}.warn{border-color:rgba(245,158,11,.7)}.fail{border-color:rgba(239,68,68,.75)}pre{background:#0b1110;border-radius:14px;overflow:auto;padding:12px}a{color:#5eead4}li{margin:.45rem 0}li span,li small{display:block;color:#c9d3ca}</style></head><body><main><section class="hero"><p class="eyebrow">Sustained proof recommendations</p><h1>${escapeHtml5(title)}</h1><p>Generated ${escapeHtml5(report.generatedAt)} from ${escapeHtml5(report.source)}.</p><div class="summary"><span class="pill">Status ${escapeHtml5(report.status)}</span><span class="pill">Provider ${report.summary.keepCurrentProviderPath ? "keep" : "change"}</span><span class="pill">Best ${escapeHtml5(report.
|
|
1839
|
+
return `<!doctype html><html lang="en"><head><meta charset="utf-8" /><meta name="viewport" content="width=device-width,initial-scale=1" /><title>${escapeHtml5(title)}</title><style>body{background:#101418;color:#f7f3e8;font-family:ui-sans-serif,system-ui,sans-serif;margin:0}main{margin:auto;max-width:1120px;padding:32px}.hero,article{background:#17201d;border:1px solid #2e3d36;border-radius:24px;margin-bottom:16px;padding:22px}.hero{background:linear-gradient(135deg,rgba(20,184,166,.18),rgba(245,158,11,.12))}.eyebrow{color:#5eead4;font-weight:900;letter-spacing:.1em;text-transform:uppercase}h1{font-size:clamp(2.2rem,6vw,4.7rem);letter-spacing:-.06em;line-height:.92;margin:.2rem 0 1rem}.summary{display:flex;flex-wrap:wrap;gap:10px}.pill{border:1px solid #42534a;border-radius:999px;padding:8px 12px}.pass{border-color:rgba(34,197,94,.55)}.warn{border-color:rgba(245,158,11,.7)}.fail{border-color:rgba(239,68,68,.75)}pre{background:#0b1110;border-radius:14px;overflow:auto;padding:12px}a{color:#5eead4}li{margin:.45rem 0}li span,li small{display:block;color:#c9d3ca}</style></head><body><main><section class="hero"><p class="eyebrow">Sustained proof recommendations</p><h1>${escapeHtml5(title)}</h1><p>Generated ${escapeHtml5(report.generatedAt)} from ${escapeHtml5(report.source)}.</p><div class="summary"><span class="pill">Status ${escapeHtml5(report.status)}</span><span class="pill">Provider ${report.summary.keepCurrentProviderPath ? "keep" : "change"}</span><span class="pill">Best mix ${escapeHtml5(formatProviderMix(report.bestProviders))}</span><span class="pill">Runtime ${report.summary.keepCurrentRuntimeChannel ? "keep" : "tune"}</span><span class="pill">${String(report.summary.recommendedActions)} action(s)</span></div></section>${cards}<section class="hero"><h2>Provider Comparison</h2><ul>${providerRows}</ul></section><section class="hero"><h2>Issues</h2><ul>${issues}</ul></section></main></body></html>`;
|
|
1824
1840
|
};
|
|
1825
1841
|
var createVoiceProofTrendRecommendationRoutes = (options) => {
|
|
1826
1842
|
const path = options.path ?? "/api/voice/proof-trend-recommendations";
|