@absolutejs/voice 0.0.22-beta.347 → 0.0.22-beta.349

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.
@@ -4087,6 +4087,84 @@ var buildVoiceProofTrendReportFromRealCallProfiles = (options) => {
4087
4087
  });
4088
4088
  };
4089
4089
  var flattenProofTrendCycles = (reports) => reports.flatMap((report) => report.cycles ?? []);
4090
+ var withLatencyHeadroom = (value, options) => typeof value === "number" && Number.isFinite(value) ? Math.ceil(value * (options.latencyBudgetHeadroomRatio ?? 1.2) + (options.latencyBudgetHeadroomMs ?? 50)) : undefined;
4091
+ var buildProviderRouteDefaults = (providers) => {
4092
+ const routes = {};
4093
+ for (const provider of providers) {
4094
+ routes[provider.role ?? provider.id] = provider.id;
4095
+ }
4096
+ return routes;
4097
+ };
4098
+ var buildVoiceRealCallProfileDefaults = (input, options = {}) => {
4099
+ const trend = "trend" in input ? input.trend : input;
4100
+ const source = "source" in input ? input.source : trend.source;
4101
+ const recommendationReport = "recommendations" in input ? input.recommendations : buildVoiceProofTrendRecommendationReport(trend, options);
4102
+ const requiredProviderRoles = [
4103
+ ...options.requiredProviderRoles ?? ["llm", "stt", "tts"]
4104
+ ];
4105
+ const profileRecommendationsById = new Map(recommendationReport.profiles.map((profile) => [profile.id, profile]));
4106
+ const profiles = (trend.summary.profiles ?? []).map((profile) => {
4107
+ const recommendation = profileRecommendationsById.get(profile.id);
4108
+ const providers = recommendation?.bestProviders ?? [];
4109
+ const providerRoutes = buildProviderRouteDefaults(providers);
4110
+ const missingRoles = requiredProviderRoles.filter((role) => providerRoutes[role] === undefined);
4111
+ const status2 = recommendation?.status === "fail" ? "fail" : missingRoles.length > 0 ? "warn" : recommendation?.status ?? "warn";
4112
+ return {
4113
+ evidence: {
4114
+ liveP95Ms: profile.maxLiveP95Ms,
4115
+ providerP95Ms: profile.maxProviderP95Ms,
4116
+ turnP95Ms: profile.maxTurnP95Ms
4117
+ },
4118
+ label: profile.label,
4119
+ latencyBudgets: {
4120
+ maxLiveP95Ms: withLatencyHeadroom(profile.maxLiveP95Ms, options),
4121
+ maxProviderP95Ms: withLatencyHeadroom(profile.maxProviderP95Ms, options),
4122
+ maxTurnP95Ms: withLatencyHeadroom(profile.maxTurnP95Ms, options)
4123
+ },
4124
+ nextMove: missingRoles.length > 0 ? `Collect passing provider evidence for ${missingRoles.join(", ")} before using this as a complete default profile.` : recommendation?.nextMove ?? `Use these measured defaults for ${profile.label ?? profile.id}.`,
4125
+ profileId: profile.id,
4126
+ providerRoutes,
4127
+ providers,
4128
+ runtimeChannel: profile.runtimeChannel ? {
4129
+ maxBackpressureEvents: profile.runtimeChannel.maxBackpressureEvents,
4130
+ maxFirstAudioLatencyMs: withLatencyHeadroom(profile.runtimeChannel.maxFirstAudioLatencyMs, options),
4131
+ maxInterruptionP95Ms: withLatencyHeadroom(profile.runtimeChannel.maxInterruptionP95Ms, options),
4132
+ maxJitterMs: withLatencyHeadroom(profile.runtimeChannel.maxJitterMs, options),
4133
+ maxTimestampDriftMs: withLatencyHeadroom(profile.runtimeChannel.maxTimestampDriftMs, options)
4134
+ } : undefined,
4135
+ status: status2
4136
+ };
4137
+ });
4138
+ const issues = [
4139
+ ...profiles.length === 0 ? ["No real-call profiles were available to derive defaults."] : [],
4140
+ ...profiles.flatMap((profile) => {
4141
+ const missingRoles = requiredProviderRoles.filter((role) => profile.providerRoutes[role] === undefined);
4142
+ return missingRoles.length > 0 ? [
4143
+ `${profile.label ?? profile.profileId} is missing provider defaults for ${missingRoles.join(", ")}.`
4144
+ ] : [];
4145
+ })
4146
+ ];
4147
+ const status = issues.length > 0 ? "warn" : worstRecommendationStatus(profiles.map((profile) => ({
4148
+ evidence: {},
4149
+ nextMove: profile.nextMove,
4150
+ recommendation: profile.label ?? profile.profileId,
4151
+ status: profile.status,
4152
+ surface: "provider-path"
4153
+ })));
4154
+ return {
4155
+ generatedAt: new Date().toISOString(),
4156
+ issues,
4157
+ ok: status !== "fail",
4158
+ profiles,
4159
+ source,
4160
+ status,
4161
+ summary: {
4162
+ actionableProfiles: profiles.filter((profile) => requiredProviderRoles.every((role) => profile.providerRoutes[role] !== undefined) && profile.status === "pass").length,
4163
+ profileCount: profiles.length,
4164
+ requiredProviderRoles
4165
+ }
4166
+ };
4167
+ };
4090
4168
  var buildVoiceRealCallProfileHistoryReport = (options = {}) => {
4091
4169
  const generatedAt = options.generatedAt ?? (options.now instanceof Date ? options.now.toISOString() : typeof options.now === "number" ? new Date(options.now).toISOString() : typeof options.now === "string" ? new Date(options.now).toISOString() : new Date().toISOString());
4092
4170
  const evidenceReport = options.evidence && options.evidence.length > 0 ? buildVoiceProofTrendReportFromRealCallProfiles({
@@ -4102,36 +4180,39 @@ var buildVoiceRealCallProfileHistoryReport = (options = {}) => {
4102
4180
  })),
4103
4181
  ...evidenceReport ? [evidenceReport] : []
4104
4182
  ];
4105
- const profiles = buildVoiceProofTrendProfileSummaries(history, options);
4183
+ const passingHistory = history.filter((report) => report.ok === true);
4184
+ const recommendationHistory = passingHistory.length > 0 ? passingHistory : history;
4185
+ const profiles = buildVoiceProofTrendProfileSummaries(recommendationHistory, options);
4106
4186
  const summary = {
4107
- cycles: history.reduce((total, report) => total + (report.summary.cycles ?? report.cycles.length), 0),
4187
+ cycles: recommendationHistory.reduce((total, report) => total + (report.summary.cycles ?? report.cycles.length), 0),
4108
4188
  failedReports: history.filter((report) => report.ok !== true).length,
4109
- maxLiveP95Ms: maxNumber(history.map(readProofTrendMaxLiveP95)),
4110
- maxProviderP95Ms: maxNumber(history.map(readProofTrendMaxProviderP95)),
4111
- maxTurnP95Ms: maxNumber(history.map(readProofTrendMaxTurnP95)),
4189
+ maxLiveP95Ms: maxNumber(recommendationHistory.map(readProofTrendMaxLiveP95)),
4190
+ maxProviderP95Ms: maxNumber(recommendationHistory.map(readProofTrendMaxProviderP95)),
4191
+ maxTurnP95Ms: maxNumber(recommendationHistory.map(readProofTrendMaxTurnP95)),
4112
4192
  profileCount: profiles.length,
4113
4193
  profiles,
4114
- providers: readProofTrendProviders(history),
4115
- runtimeChannel: aggregateProofTrendRuntimeChannel(history.map(readProofTrendRuntimeChannel).filter((channel) => channel !== undefined))
4194
+ providers: readProofTrendProviders(recommendationHistory),
4195
+ runtimeChannel: aggregateProofTrendRuntimeChannel(recommendationHistory.map(readProofTrendRuntimeChannel).filter((channel) => channel !== undefined))
4116
4196
  };
4117
4197
  const trend = buildVoiceProofTrendReport({
4118
4198
  baseUrl: options.baseUrl,
4119
- cycles: flattenProofTrendCycles(history),
4199
+ cycles: flattenProofTrendCycles(recommendationHistory),
4120
4200
  generatedAt,
4121
4201
  maxAgeMs: options.maxAgeMs,
4122
4202
  now: options.now,
4123
- ok: history.length > 0 && summary.failedReports === 0 && profiles.every((profile) => profile.status !== "fail"),
4203
+ ok: recommendationHistory.length > 0 && profiles.every((profile) => profile.status !== "fail"),
4124
4204
  source: options.source ?? "real-call-profile-history",
4125
4205
  summary
4126
4206
  });
4127
4207
  const recommendations = buildVoiceProofTrendRecommendationReport(trend, options);
4208
+ const defaults = buildVoiceRealCallProfileDefaults(trend, options);
4128
4209
  const issues = [
4129
- ...history.length === 0 ? ["No real-call profile reports were present."] : [],
4210
+ ...recommendationHistory.length === 0 ? ["No passing real-call profile reports were present."] : [],
4130
4211
  ...profiles.length === 0 ? ["No benchmark profiles were present."] : [],
4131
- ...summary.failedReports > 0 ? [`${summary.failedReports} real-call profile report(s) failed.`] : [],
4132
4212
  ...recommendations.issues
4133
4213
  ];
4134
4214
  return {
4215
+ defaults,
4135
4216
  generatedAt,
4136
4217
  history,
4137
4218
  issues,
@@ -4540,6 +4621,12 @@ var renderVoiceRealCallProfileHistoryMarkdown = (report, title = "Voice Real-Cal
4540
4621
  "",
4541
4622
  ...report.recommendations.recommendations.map((recommendation) => `- ${recommendation.status}: ${recommendation.recommendation} ${recommendation.nextMove}`),
4542
4623
  "",
4624
+ "## Actionable Defaults",
4625
+ "",
4626
+ "| Profile | Status | Provider routes | Live budget | Provider budget | Turn budget |",
4627
+ "| --- | --- | --- | ---: | ---: | ---: |",
4628
+ ...report.defaults.profiles.length ? report.defaults.profiles.map((profile) => `| ${escapeMarkdown(profile.label ?? profile.profileId)} | ${profile.status} | ${escapeMarkdown(Object.entries(profile.providerRoutes).map(([role, provider]) => `${role}: ${provider}`).join(", ") || "n/a")} | ${profile.latencyBudgets.maxLiveP95Ms ?? "n/a"} | ${profile.latencyBudgets.maxProviderP95Ms ?? "n/a"} | ${profile.latencyBudgets.maxTurnP95Ms ?? "n/a"} |`) : ["| n/a | n/a | n/a | n/a | n/a | n/a |"],
4629
+ "",
4543
4630
  "## Issues",
4544
4631
  "",
4545
4632
  ...report.issues.length ? report.issues.map((issue) => `- ${issue}`) : ["- None"]
@@ -4547,9 +4634,10 @@ var renderVoiceRealCallProfileHistoryMarkdown = (report, title = "Voice Real-Cal
4547
4634
  `);
4548
4635
  var renderVoiceRealCallProfileHistoryHTML = (report, title = "Voice Real-Call Profile History") => {
4549
4636
  const profileRows = report.summary.profiles?.length ? report.summary.profiles.map((profile) => `<tr><td>${escapeHtml3(profile.label ?? profile.id)}</td><td>${escapeHtml3(profile.status ?? "unknown")}</td><td>${escapeHtml3(profile.maxLiveP95Ms ?? "n/a")}</td><td>${escapeHtml3(profile.maxProviderP95Ms ?? "n/a")}</td><td>${escapeHtml3(profile.maxTurnP95Ms ?? "n/a")}</td><td>${escapeHtml3(formatProviderMix(profile.providers ?? []))}</td></tr>`).join("") : '<tr><td colspan="6">No profiles present.</td></tr>';
4637
+ const defaultRows = report.defaults.profiles.length > 0 ? report.defaults.profiles.map((profile) => `<tr><td>${escapeHtml3(profile.label ?? profile.profileId)}</td><td>${escapeHtml3(profile.status)}</td><td>${escapeHtml3(Object.entries(profile.providerRoutes).map(([role, provider]) => `${role}: ${provider}`).join(", ") || "n/a")}</td><td>${escapeHtml3(profile.latencyBudgets.maxLiveP95Ms ?? "n/a")}</td><td>${escapeHtml3(profile.latencyBudgets.maxProviderP95Ms ?? "n/a")}</td><td>${escapeHtml3(profile.latencyBudgets.maxTurnP95Ms ?? "n/a")}</td></tr>`).join("") : '<tr><td colspan="6">No actionable defaults present.</td></tr>';
4550
4638
  const recommendations = report.recommendations.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></article>`).join("");
4551
4639
  const issues = report.issues.length === 0 ? "<li>None</li>" : report.issues.map((issue) => `<li>${escapeHtml3(issue)}</li>`).join("");
4552
- 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:#111510;color:#f6f0dd;font-family:ui-sans-serif,system-ui,sans-serif;margin:0}main{margin:auto;max-width:1120px;padding:32px}.hero,article,.card{background:#182117;border:1px solid #32412d;border-radius:24px;margin-bottom:16px;padding:22px}.hero{background:linear-gradient(135deg,rgba(132,204,22,.16),rgba(20,184,166,.12))}.eyebrow{color:#bef264;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 #52624b;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)}table{border-collapse:collapse;width:100%}td,th{border-bottom:1px solid #32412d;padding:10px;text-align:left}</style></head><body><main><section class="hero"><p class="eyebrow">Real-call benchmark history</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">Reports ${String(report.reports)}</span><span class="pill">Profiles ${String(report.summary.profileCount)}</span><span class="pill">Cycles ${String(report.summary.cycles ?? 0)}</span><span class="pill">Best mix ${escapeHtml3(formatProviderMix(report.recommendations.bestProviders))}</span></div></section><section class="card"><h2>Profiles</h2><table><thead><tr><th>Profile</th><th>Status</th><th>Live p95</th><th>Provider p95</th><th>Turn p95</th><th>Provider mix</th></tr></thead><tbody>${profileRows}</tbody></table></section>${recommendations}<section class="card"><h2>Issues</h2><ul>${issues}</ul></section></main></body></html>`;
4640
+ 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:#111510;color:#f6f0dd;font-family:ui-sans-serif,system-ui,sans-serif;margin:0}main{margin:auto;max-width:1120px;padding:32px}.hero,article,.card{background:#182117;border:1px solid #32412d;border-radius:24px;margin-bottom:16px;padding:22px}.hero{background:linear-gradient(135deg,rgba(132,204,22,.16),rgba(20,184,166,.12))}.eyebrow{color:#bef264;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 #52624b;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)}table{border-collapse:collapse;width:100%}td,th{border-bottom:1px solid #32412d;padding:10px;text-align:left}</style></head><body><main><section class="hero"><p class="eyebrow">Real-call benchmark history</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">Reports ${String(report.reports)}</span><span class="pill">Profiles ${String(report.summary.profileCount)}</span><span class="pill">Defaults ${String(report.defaults.summary.actionableProfiles)}/${String(report.defaults.summary.profileCount)}</span><span class="pill">Cycles ${String(report.summary.cycles ?? 0)}</span><span class="pill">Best mix ${escapeHtml3(formatProviderMix(report.recommendations.bestProviders))}</span></div></section><section class="card"><h2>Profiles</h2><table><thead><tr><th>Profile</th><th>Status</th><th>Live p95</th><th>Provider p95</th><th>Turn p95</th><th>Provider mix</th></tr></thead><tbody>${profileRows}</tbody></table></section><section class="card"><h2>Actionable Defaults</h2><table><thead><tr><th>Profile</th><th>Status</th><th>Provider routes</th><th>Live budget</th><th>Provider budget</th><th>Turn budget</th></tr></thead><tbody>${defaultRows}</tbody></table></section>${recommendations}<section class="card"><h2>Issues</h2><ul>${issues}</ul></section></main></body></html>`;
4553
4641
  };
4554
4642
  var createVoiceProofTrendRecommendationRoutes = (options) => {
4555
4643
  const path = options.path ?? "/api/voice/proof-trend-recommendations";
package/dist/index.d.ts CHANGED
@@ -30,10 +30,10 @@ export { assertVoicePlatformCoverage, buildVoicePlatformCoverageSummary, createV
30
30
  export { assertVoiceCompetitiveCoverage, buildVoiceCompetitiveCoverageReport, createVoiceCompetitiveCoverageRoutes, evaluateVoiceCompetitiveCoverage, renderVoiceCompetitiveCoverageHTML, renderVoiceCompetitiveCoverageMarkdown } from './competitiveCoverage';
31
31
  export type { VoiceCompetitiveCoverageAssertionInput, VoiceCompetitiveCoverageAssertionReport, VoiceCompetitiveCoverageIssue, VoiceCompetitiveCoverageLevel, VoiceCompetitiveCoverageReport, VoiceCompetitiveCoverageReportInput, VoiceCompetitiveCoverageRoutesOptions, VoiceCompetitiveCoverageStatus, VoiceCompetitiveCoverageSummary, VoiceCompetitiveDepthLevel, VoiceCompetitiveEvidence, VoiceCompetitiveSurface } from './competitiveCoverage';
32
32
  export type { VoicePlatformCoverageAssertionInput, VoicePlatformCoverageAssertionReport, VoicePlatformCoverageEvidence, VoicePlatformCoverageRoutesOptions, VoicePlatformCoverageStatus, VoicePlatformCoverageSummary, VoicePlatformCoverageSummaryInput, VoicePlatformCoverageSurface } from './platformCoverage';
33
- export { assertVoiceProofTrendEvidence, buildEmptyVoiceProofTrendReport, buildVoiceProofTrendProfileSummaries, buildVoiceProofTrendRecommendationReport, buildVoiceProofTrendReportFromRealCallProfiles, buildVoiceProofTrendReport, buildVoiceRealCallProfileHistoryReport, createVoiceProofTrendRecommendationRoutes, createVoiceProofTrendRoutes, createVoiceRealCallProfileHistoryRoutes, DEFAULT_VOICE_PROOF_TREND_PROFILE_DEFINITIONS, DEFAULT_VOICE_PROOF_TRENDS_MAX_AGE_MS, evaluateVoiceProofTrendEvidence, formatVoiceProofTrendAge, normalizeVoiceProofTrendReport, readVoiceProofTrendReportFile, renderVoiceProofTrendRecommendationHTML, renderVoiceProofTrendRecommendationMarkdown, renderVoiceRealCallProfileHistoryHTML, renderVoiceRealCallProfileHistoryMarkdown } from './proofTrends';
33
+ export { assertVoiceProofTrendEvidence, buildEmptyVoiceProofTrendReport, buildVoiceProofTrendProfileSummaries, buildVoiceProofTrendRecommendationReport, buildVoiceProofTrendReportFromRealCallProfiles, buildVoiceProofTrendReport, buildVoiceRealCallProfileDefaults, buildVoiceRealCallProfileHistoryReport, createVoiceProofTrendRecommendationRoutes, createVoiceProofTrendRoutes, createVoiceRealCallProfileHistoryRoutes, DEFAULT_VOICE_PROOF_TREND_PROFILE_DEFINITIONS, DEFAULT_VOICE_PROOF_TRENDS_MAX_AGE_MS, evaluateVoiceProofTrendEvidence, formatVoiceProofTrendAge, normalizeVoiceProofTrendReport, readVoiceProofTrendReportFile, renderVoiceProofTrendRecommendationHTML, renderVoiceProofTrendRecommendationMarkdown, renderVoiceRealCallProfileHistoryHTML, renderVoiceRealCallProfileHistoryMarkdown } from './proofTrends';
34
34
  export { buildVoiceProviderDecisionTraceReport, createVoiceProviderDecisionTraceEvent, createVoiceProviderDecisionTraceRoutes, listVoiceProviderDecisionTraces, renderVoiceProviderDecisionTraceHTML, renderVoiceProviderDecisionTraceMarkdown } from './providerDecisionTraces';
35
35
  export type { VoiceProviderDecisionStatus, VoiceProviderDecisionSurfaceReport, VoiceProviderDecisionTrace, VoiceProviderDecisionTraceInput, VoiceProviderDecisionTraceIssue, VoiceProviderDecisionTraceReport, VoiceProviderDecisionTraceReportOptions, VoiceProviderDecisionTraceRoutesOptions } from './providerDecisionTraces';
36
- export type { VoiceProofTrendAssertionInput, VoiceProofTrendAssertionReport, VoiceProofTrendCycle, VoiceProofTrendProfileDefinition, VoiceProofTrendProfileRecommendation, VoiceProofTrendProfileSummaryOptions, VoiceProofTrendProfileSummary, VoiceProofTrendProviderRecommendation, VoiceProofTrendProviderSummary, VoiceProofTrendRecommendation, VoiceProofTrendRecommendationOptions, VoiceProofTrendRecommendationReport, VoiceProofTrendRecommendationRoutesOptions, VoiceProofTrendRecommendationStatus, VoiceProofTrendRecommendationSurface, VoiceProofTrendRealCallProfileEvidence, VoiceProofTrendRealCallProfileReportOptions, VoiceProofTrendReport, VoiceProofTrendReportInput, VoiceProofTrendRoutesOptions, VoiceProofTrendRuntimeChannelSummary, VoiceProofTrendStatus, VoiceProofTrendSummary, VoiceRealCallProfileHistoryOptions, VoiceRealCallProfileHistoryReport, VoiceRealCallProfileHistoryRoutesOptions } from './proofTrends';
36
+ export type { VoiceProofTrendAssertionInput, VoiceProofTrendAssertionReport, VoiceProofTrendCycle, VoiceProofTrendProfileDefinition, VoiceProofTrendProfileRecommendation, VoiceProofTrendProfileSummaryOptions, VoiceProofTrendProfileSummary, VoiceProofTrendProviderRecommendation, VoiceProofTrendProviderSummary, VoiceProofTrendRecommendation, VoiceProofTrendRecommendationOptions, VoiceProofTrendRecommendationReport, VoiceProofTrendRecommendationRoutesOptions, VoiceProofTrendRecommendationStatus, VoiceProofTrendRecommendationSurface, VoiceProofTrendRealCallProfileEvidence, VoiceProofTrendRealCallProfileReportOptions, VoiceProofTrendReport, VoiceProofTrendReportInput, VoiceProofTrendRoutesOptions, VoiceProofTrendRuntimeChannelSummary, VoiceProofTrendStatus, VoiceProofTrendSummary, VoiceRealCallProfileDefault, VoiceRealCallProfileDefaultsOptions, VoiceRealCallProfileDefaultsReport, VoiceRealCallProfileHistoryOptions, VoiceRealCallProfileHistoryReport, VoiceRealCallProfileHistoryRoutesOptions } from './proofTrends';
37
37
  export { assertVoiceSloCalibration, buildVoiceSloCalibrationReport, buildVoiceSloReadinessThresholdReport, createVoiceSloReadinessThresholdOptions, createVoiceSloReadinessThresholdRoutes, createVoiceSloThresholdProfile, createVoiceSloCalibrationRoutes, renderVoiceSloCalibrationMarkdown, renderVoiceSloReadinessThresholdHTML, renderVoiceSloReadinessThresholdMarkdown } from './sloCalibration';
38
38
  export type { VoiceSloCalibrationMetricKey, VoiceSloCalibrationOptions, VoiceSloCalibrationReport, VoiceSloCalibrationRoutesOptions, VoiceSloCalibrationSample, VoiceSloCalibrationStatus, VoiceSloCalibrationThreshold, VoiceSloCalibrationThresholds, VoiceSloReadinessThresholdReport, VoiceSloReadinessThresholdReportOptions, VoiceSloReadinessThresholdOptions, VoiceSloReadinessThresholdRoutesOptions, VoiceSloThresholdProfile } from './sloCalibration';
39
39
  export { assertVoiceLiveOpsControlEvidence, assertVoiceLiveOpsEvidence, buildVoiceLiveOpsControlState, createVoiceLiveOpsController, createVoiceLiveOpsRoutes, createVoiceMemoryLiveOpsControlStore, evaluateVoiceLiveOpsControlEvidence, evaluateVoiceLiveOpsEvidence, getVoiceLiveOpsControlStatus, VOICE_LIVE_OPS_ACTIONS } from './liveOps';
package/dist/index.js CHANGED
@@ -14989,6 +14989,84 @@ var buildVoiceProofTrendReportFromRealCallProfiles = (options) => {
14989
14989
  });
14990
14990
  };
14991
14991
  var flattenProofTrendCycles = (reports) => reports.flatMap((report) => report.cycles ?? []);
14992
+ var withLatencyHeadroom = (value, options) => typeof value === "number" && Number.isFinite(value) ? Math.ceil(value * (options.latencyBudgetHeadroomRatio ?? 1.2) + (options.latencyBudgetHeadroomMs ?? 50)) : undefined;
14993
+ var buildProviderRouteDefaults = (providers) => {
14994
+ const routes = {};
14995
+ for (const provider of providers) {
14996
+ routes[provider.role ?? provider.id] = provider.id;
14997
+ }
14998
+ return routes;
14999
+ };
15000
+ var buildVoiceRealCallProfileDefaults = (input, options = {}) => {
15001
+ const trend = "trend" in input ? input.trend : input;
15002
+ const source = "source" in input ? input.source : trend.source;
15003
+ const recommendationReport = "recommendations" in input ? input.recommendations : buildVoiceProofTrendRecommendationReport(trend, options);
15004
+ const requiredProviderRoles = [
15005
+ ...options.requiredProviderRoles ?? ["llm", "stt", "tts"]
15006
+ ];
15007
+ const profileRecommendationsById = new Map(recommendationReport.profiles.map((profile) => [profile.id, profile]));
15008
+ const profiles = (trend.summary.profiles ?? []).map((profile) => {
15009
+ const recommendation = profileRecommendationsById.get(profile.id);
15010
+ const providers = recommendation?.bestProviders ?? [];
15011
+ const providerRoutes = buildProviderRouteDefaults(providers);
15012
+ const missingRoles = requiredProviderRoles.filter((role) => providerRoutes[role] === undefined);
15013
+ const status2 = recommendation?.status === "fail" ? "fail" : missingRoles.length > 0 ? "warn" : recommendation?.status ?? "warn";
15014
+ return {
15015
+ evidence: {
15016
+ liveP95Ms: profile.maxLiveP95Ms,
15017
+ providerP95Ms: profile.maxProviderP95Ms,
15018
+ turnP95Ms: profile.maxTurnP95Ms
15019
+ },
15020
+ label: profile.label,
15021
+ latencyBudgets: {
15022
+ maxLiveP95Ms: withLatencyHeadroom(profile.maxLiveP95Ms, options),
15023
+ maxProviderP95Ms: withLatencyHeadroom(profile.maxProviderP95Ms, options),
15024
+ maxTurnP95Ms: withLatencyHeadroom(profile.maxTurnP95Ms, options)
15025
+ },
15026
+ nextMove: missingRoles.length > 0 ? `Collect passing provider evidence for ${missingRoles.join(", ")} before using this as a complete default profile.` : recommendation?.nextMove ?? `Use these measured defaults for ${profile.label ?? profile.id}.`,
15027
+ profileId: profile.id,
15028
+ providerRoutes,
15029
+ providers,
15030
+ runtimeChannel: profile.runtimeChannel ? {
15031
+ maxBackpressureEvents: profile.runtimeChannel.maxBackpressureEvents,
15032
+ maxFirstAudioLatencyMs: withLatencyHeadroom(profile.runtimeChannel.maxFirstAudioLatencyMs, options),
15033
+ maxInterruptionP95Ms: withLatencyHeadroom(profile.runtimeChannel.maxInterruptionP95Ms, options),
15034
+ maxJitterMs: withLatencyHeadroom(profile.runtimeChannel.maxJitterMs, options),
15035
+ maxTimestampDriftMs: withLatencyHeadroom(profile.runtimeChannel.maxTimestampDriftMs, options)
15036
+ } : undefined,
15037
+ status: status2
15038
+ };
15039
+ });
15040
+ const issues = [
15041
+ ...profiles.length === 0 ? ["No real-call profiles were available to derive defaults."] : [],
15042
+ ...profiles.flatMap((profile) => {
15043
+ const missingRoles = requiredProviderRoles.filter((role) => profile.providerRoutes[role] === undefined);
15044
+ return missingRoles.length > 0 ? [
15045
+ `${profile.label ?? profile.profileId} is missing provider defaults for ${missingRoles.join(", ")}.`
15046
+ ] : [];
15047
+ })
15048
+ ];
15049
+ const status = issues.length > 0 ? "warn" : worstRecommendationStatus(profiles.map((profile) => ({
15050
+ evidence: {},
15051
+ nextMove: profile.nextMove,
15052
+ recommendation: profile.label ?? profile.profileId,
15053
+ status: profile.status,
15054
+ surface: "provider-path"
15055
+ })));
15056
+ return {
15057
+ generatedAt: new Date().toISOString(),
15058
+ issues,
15059
+ ok: status !== "fail",
15060
+ profiles,
15061
+ source,
15062
+ status,
15063
+ summary: {
15064
+ actionableProfiles: profiles.filter((profile) => requiredProviderRoles.every((role) => profile.providerRoutes[role] !== undefined) && profile.status === "pass").length,
15065
+ profileCount: profiles.length,
15066
+ requiredProviderRoles
15067
+ }
15068
+ };
15069
+ };
14992
15070
  var buildVoiceRealCallProfileHistoryReport = (options = {}) => {
14993
15071
  const generatedAt = options.generatedAt ?? (options.now instanceof Date ? options.now.toISOString() : typeof options.now === "number" ? new Date(options.now).toISOString() : typeof options.now === "string" ? new Date(options.now).toISOString() : new Date().toISOString());
14994
15072
  const evidenceReport = options.evidence && options.evidence.length > 0 ? buildVoiceProofTrendReportFromRealCallProfiles({
@@ -15004,36 +15082,39 @@ var buildVoiceRealCallProfileHistoryReport = (options = {}) => {
15004
15082
  })),
15005
15083
  ...evidenceReport ? [evidenceReport] : []
15006
15084
  ];
15007
- const profiles = buildVoiceProofTrendProfileSummaries(history, options);
15085
+ const passingHistory = history.filter((report) => report.ok === true);
15086
+ const recommendationHistory = passingHistory.length > 0 ? passingHistory : history;
15087
+ const profiles = buildVoiceProofTrendProfileSummaries(recommendationHistory, options);
15008
15088
  const summary = {
15009
- cycles: history.reduce((total, report) => total + (report.summary.cycles ?? report.cycles.length), 0),
15089
+ cycles: recommendationHistory.reduce((total, report) => total + (report.summary.cycles ?? report.cycles.length), 0),
15010
15090
  failedReports: history.filter((report) => report.ok !== true).length,
15011
- maxLiveP95Ms: maxNumber(history.map(readProofTrendMaxLiveP95)),
15012
- maxProviderP95Ms: maxNumber(history.map(readProofTrendMaxProviderP95)),
15013
- maxTurnP95Ms: maxNumber(history.map(readProofTrendMaxTurnP95)),
15091
+ maxLiveP95Ms: maxNumber(recommendationHistory.map(readProofTrendMaxLiveP95)),
15092
+ maxProviderP95Ms: maxNumber(recommendationHistory.map(readProofTrendMaxProviderP95)),
15093
+ maxTurnP95Ms: maxNumber(recommendationHistory.map(readProofTrendMaxTurnP95)),
15014
15094
  profileCount: profiles.length,
15015
15095
  profiles,
15016
- providers: readProofTrendProviders(history),
15017
- runtimeChannel: aggregateProofTrendRuntimeChannel(history.map(readProofTrendRuntimeChannel).filter((channel) => channel !== undefined))
15096
+ providers: readProofTrendProviders(recommendationHistory),
15097
+ runtimeChannel: aggregateProofTrendRuntimeChannel(recommendationHistory.map(readProofTrendRuntimeChannel).filter((channel) => channel !== undefined))
15018
15098
  };
15019
15099
  const trend = buildVoiceProofTrendReport({
15020
15100
  baseUrl: options.baseUrl,
15021
- cycles: flattenProofTrendCycles(history),
15101
+ cycles: flattenProofTrendCycles(recommendationHistory),
15022
15102
  generatedAt,
15023
15103
  maxAgeMs: options.maxAgeMs,
15024
15104
  now: options.now,
15025
- ok: history.length > 0 && summary.failedReports === 0 && profiles.every((profile) => profile.status !== "fail"),
15105
+ ok: recommendationHistory.length > 0 && profiles.every((profile) => profile.status !== "fail"),
15026
15106
  source: options.source ?? "real-call-profile-history",
15027
15107
  summary
15028
15108
  });
15029
15109
  const recommendations = buildVoiceProofTrendRecommendationReport(trend, options);
15110
+ const defaults = buildVoiceRealCallProfileDefaults(trend, options);
15030
15111
  const issues = [
15031
- ...history.length === 0 ? ["No real-call profile reports were present."] : [],
15112
+ ...recommendationHistory.length === 0 ? ["No passing real-call profile reports were present."] : [],
15032
15113
  ...profiles.length === 0 ? ["No benchmark profiles were present."] : [],
15033
- ...summary.failedReports > 0 ? [`${summary.failedReports} real-call profile report(s) failed.`] : [],
15034
15114
  ...recommendations.issues
15035
15115
  ];
15036
15116
  return {
15117
+ defaults,
15037
15118
  generatedAt,
15038
15119
  history,
15039
15120
  issues,
@@ -15442,6 +15523,12 @@ var renderVoiceRealCallProfileHistoryMarkdown = (report, title = "Voice Real-Cal
15442
15523
  "",
15443
15524
  ...report.recommendations.recommendations.map((recommendation) => `- ${recommendation.status}: ${recommendation.recommendation} ${recommendation.nextMove}`),
15444
15525
  "",
15526
+ "## Actionable Defaults",
15527
+ "",
15528
+ "| Profile | Status | Provider routes | Live budget | Provider budget | Turn budget |",
15529
+ "| --- | --- | --- | ---: | ---: | ---: |",
15530
+ ...report.defaults.profiles.length ? report.defaults.profiles.map((profile) => `| ${escapeMarkdown2(profile.label ?? profile.profileId)} | ${profile.status} | ${escapeMarkdown2(Object.entries(profile.providerRoutes).map(([role, provider]) => `${role}: ${provider}`).join(", ") || "n/a")} | ${profile.latencyBudgets.maxLiveP95Ms ?? "n/a"} | ${profile.latencyBudgets.maxProviderP95Ms ?? "n/a"} | ${profile.latencyBudgets.maxTurnP95Ms ?? "n/a"} |`) : ["| n/a | n/a | n/a | n/a | n/a | n/a |"],
15531
+ "",
15445
15532
  "## Issues",
15446
15533
  "",
15447
15534
  ...report.issues.length ? report.issues.map((issue) => `- ${issue}`) : ["- None"]
@@ -15449,9 +15536,10 @@ var renderVoiceRealCallProfileHistoryMarkdown = (report, title = "Voice Real-Cal
15449
15536
  `);
15450
15537
  var renderVoiceRealCallProfileHistoryHTML = (report, title = "Voice Real-Call Profile History") => {
15451
15538
  const profileRows = report.summary.profiles?.length ? report.summary.profiles.map((profile) => `<tr><td>${escapeHtml23(profile.label ?? profile.id)}</td><td>${escapeHtml23(profile.status ?? "unknown")}</td><td>${escapeHtml23(profile.maxLiveP95Ms ?? "n/a")}</td><td>${escapeHtml23(profile.maxProviderP95Ms ?? "n/a")}</td><td>${escapeHtml23(profile.maxTurnP95Ms ?? "n/a")}</td><td>${escapeHtml23(formatProviderMix(profile.providers ?? []))}</td></tr>`).join("") : '<tr><td colspan="6">No profiles present.</td></tr>';
15539
+ const defaultRows = report.defaults.profiles.length > 0 ? report.defaults.profiles.map((profile) => `<tr><td>${escapeHtml23(profile.label ?? profile.profileId)}</td><td>${escapeHtml23(profile.status)}</td><td>${escapeHtml23(Object.entries(profile.providerRoutes).map(([role, provider]) => `${role}: ${provider}`).join(", ") || "n/a")}</td><td>${escapeHtml23(profile.latencyBudgets.maxLiveP95Ms ?? "n/a")}</td><td>${escapeHtml23(profile.latencyBudgets.maxProviderP95Ms ?? "n/a")}</td><td>${escapeHtml23(profile.latencyBudgets.maxTurnP95Ms ?? "n/a")}</td></tr>`).join("") : '<tr><td colspan="6">No actionable defaults present.</td></tr>';
15452
15540
  const recommendations = report.recommendations.recommendations.map((recommendation) => `<article class="${escapeHtml23(recommendation.status)}"><p class="eyebrow">${escapeHtml23(recommendation.surface)} \xB7 ${escapeHtml23(recommendation.status)}</p><h2>${escapeHtml23(recommendation.recommendation)}</h2><p>${escapeHtml23(recommendation.nextMove)}</p></article>`).join("");
15453
15541
  const issues = report.issues.length === 0 ? "<li>None</li>" : report.issues.map((issue) => `<li>${escapeHtml23(issue)}</li>`).join("");
15454
- return `<!doctype html><html lang="en"><head><meta charset="utf-8" /><meta name="viewport" content="width=device-width,initial-scale=1" /><title>${escapeHtml23(title)}</title><style>body{background:#111510;color:#f6f0dd;font-family:ui-sans-serif,system-ui,sans-serif;margin:0}main{margin:auto;max-width:1120px;padding:32px}.hero,article,.card{background:#182117;border:1px solid #32412d;border-radius:24px;margin-bottom:16px;padding:22px}.hero{background:linear-gradient(135deg,rgba(132,204,22,.16),rgba(20,184,166,.12))}.eyebrow{color:#bef264;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 #52624b;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)}table{border-collapse:collapse;width:100%}td,th{border-bottom:1px solid #32412d;padding:10px;text-align:left}</style></head><body><main><section class="hero"><p class="eyebrow">Real-call benchmark history</p><h1>${escapeHtml23(title)}</h1><p>Generated ${escapeHtml23(report.generatedAt)} from ${escapeHtml23(report.source)}.</p><div class="summary"><span class="pill">Status ${escapeHtml23(report.status)}</span><span class="pill">Reports ${String(report.reports)}</span><span class="pill">Profiles ${String(report.summary.profileCount)}</span><span class="pill">Cycles ${String(report.summary.cycles ?? 0)}</span><span class="pill">Best mix ${escapeHtml23(formatProviderMix(report.recommendations.bestProviders))}</span></div></section><section class="card"><h2>Profiles</h2><table><thead><tr><th>Profile</th><th>Status</th><th>Live p95</th><th>Provider p95</th><th>Turn p95</th><th>Provider mix</th></tr></thead><tbody>${profileRows}</tbody></table></section>${recommendations}<section class="card"><h2>Issues</h2><ul>${issues}</ul></section></main></body></html>`;
15542
+ return `<!doctype html><html lang="en"><head><meta charset="utf-8" /><meta name="viewport" content="width=device-width,initial-scale=1" /><title>${escapeHtml23(title)}</title><style>body{background:#111510;color:#f6f0dd;font-family:ui-sans-serif,system-ui,sans-serif;margin:0}main{margin:auto;max-width:1120px;padding:32px}.hero,article,.card{background:#182117;border:1px solid #32412d;border-radius:24px;margin-bottom:16px;padding:22px}.hero{background:linear-gradient(135deg,rgba(132,204,22,.16),rgba(20,184,166,.12))}.eyebrow{color:#bef264;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 #52624b;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)}table{border-collapse:collapse;width:100%}td,th{border-bottom:1px solid #32412d;padding:10px;text-align:left}</style></head><body><main><section class="hero"><p class="eyebrow">Real-call benchmark history</p><h1>${escapeHtml23(title)}</h1><p>Generated ${escapeHtml23(report.generatedAt)} from ${escapeHtml23(report.source)}.</p><div class="summary"><span class="pill">Status ${escapeHtml23(report.status)}</span><span class="pill">Reports ${String(report.reports)}</span><span class="pill">Profiles ${String(report.summary.profileCount)}</span><span class="pill">Defaults ${String(report.defaults.summary.actionableProfiles)}/${String(report.defaults.summary.profileCount)}</span><span class="pill">Cycles ${String(report.summary.cycles ?? 0)}</span><span class="pill">Best mix ${escapeHtml23(formatProviderMix(report.recommendations.bestProviders))}</span></div></section><section class="card"><h2>Profiles</h2><table><thead><tr><th>Profile</th><th>Status</th><th>Live p95</th><th>Provider p95</th><th>Turn p95</th><th>Provider mix</th></tr></thead><tbody>${profileRows}</tbody></table></section><section class="card"><h2>Actionable Defaults</h2><table><thead><tr><th>Profile</th><th>Status</th><th>Provider routes</th><th>Live budget</th><th>Provider budget</th><th>Turn budget</th></tr></thead><tbody>${defaultRows}</tbody></table></section>${recommendations}<section class="card"><h2>Issues</h2><ul>${issues}</ul></section></main></body></html>`;
15455
15543
  };
15456
15544
  var createVoiceProofTrendRecommendationRoutes = (options) => {
15457
15545
  const path = options.path ?? "/api/voice/proof-trend-recommendations";
@@ -37573,6 +37661,7 @@ export {
37573
37661
  buildVoiceRealtimeChannelRuntimeSamplesFromTrace,
37574
37662
  buildVoiceRealtimeChannelReport,
37575
37663
  buildVoiceRealCallProfileHistoryReport,
37664
+ buildVoiceRealCallProfileDefaults,
37576
37665
  buildVoiceProviderSloReport,
37577
37666
  buildVoiceProviderOrchestrationReport,
37578
37667
  buildVoiceProviderDecisionTraceReport,
@@ -258,6 +258,7 @@ export type VoiceProofTrendRecommendationRoutesOptions = VoiceProofTrendRecommen
258
258
  title?: string;
259
259
  };
260
260
  export type VoiceRealCallProfileHistoryReport = {
261
+ defaults: VoiceRealCallProfileDefaultsReport;
261
262
  generatedAt: string;
262
263
  history: VoiceProofTrendReport[];
263
264
  issues: string[];
@@ -281,6 +282,49 @@ export type VoiceRealCallProfileHistoryOptions = VoiceProofTrendProfileSummaryOp
281
282
  reports?: readonly (VoiceProofTrendReport | VoiceProofTrendReportInput)[];
282
283
  source?: string;
283
284
  };
285
+ export type VoiceRealCallProfileDefault = {
286
+ evidence: {
287
+ liveP95Ms?: number;
288
+ providerP95Ms?: number;
289
+ turnP95Ms?: number;
290
+ };
291
+ label?: string;
292
+ latencyBudgets: {
293
+ maxLiveP95Ms?: number;
294
+ maxProviderP95Ms?: number;
295
+ maxTurnP95Ms?: number;
296
+ };
297
+ nextMove: string;
298
+ profileId: string;
299
+ providerRoutes: Record<string, string>;
300
+ providers: VoiceProofTrendProviderRecommendation[];
301
+ runtimeChannel?: {
302
+ maxBackpressureEvents?: number;
303
+ maxFirstAudioLatencyMs?: number;
304
+ maxInterruptionP95Ms?: number;
305
+ maxJitterMs?: number;
306
+ maxTimestampDriftMs?: number;
307
+ };
308
+ status: VoiceProofTrendRecommendationStatus;
309
+ };
310
+ export type VoiceRealCallProfileDefaultsReport = {
311
+ generatedAt: string;
312
+ issues: string[];
313
+ ok: boolean;
314
+ profiles: VoiceRealCallProfileDefault[];
315
+ source: string;
316
+ status: VoiceProofTrendRecommendationStatus;
317
+ summary: {
318
+ actionableProfiles: number;
319
+ profileCount: number;
320
+ requiredProviderRoles: string[];
321
+ };
322
+ };
323
+ export type VoiceRealCallProfileDefaultsOptions = VoiceProofTrendRecommendationOptions & {
324
+ latencyBudgetHeadroomMs?: number;
325
+ latencyBudgetHeadroomRatio?: number;
326
+ requiredProviderRoles?: readonly string[];
327
+ };
284
328
  export type VoiceRealCallProfileHistoryRoutesOptions = Omit<VoiceRealCallProfileHistoryOptions, 'source'> & {
285
329
  headers?: HeadersInit;
286
330
  htmlPath?: false | string;
@@ -320,6 +364,7 @@ export declare const readVoiceProofTrendReportFile: (path: string, options?: {
320
364
  }) => Promise<VoiceProofTrendReport>;
321
365
  export declare const buildVoiceProofTrendProfileSummaries: (input: VoiceProofTrendReport | readonly VoiceProofTrendReport[], options?: VoiceProofTrendProfileSummaryOptions) => VoiceProofTrendProfileSummary[];
322
366
  export declare const buildVoiceProofTrendReportFromRealCallProfiles: (options: VoiceProofTrendRealCallProfileReportOptions) => VoiceProofTrendReport;
367
+ export declare const buildVoiceRealCallProfileDefaults: (input: VoiceRealCallProfileHistoryReport | VoiceProofTrendReport, options?: VoiceRealCallProfileDefaultsOptions) => VoiceRealCallProfileDefaultsReport;
323
368
  export declare const buildVoiceRealCallProfileHistoryReport: (options?: VoiceRealCallProfileHistoryOptions) => VoiceRealCallProfileHistoryReport;
324
369
  export declare const evaluateVoiceProofTrendEvidence: (report: VoiceProofTrendReport, input?: VoiceProofTrendAssertionInput) => VoiceProofTrendAssertionReport;
325
370
  export declare const assertVoiceProofTrendEvidence: (report: VoiceProofTrendReport, input?: VoiceProofTrendAssertionInput) => VoiceProofTrendAssertionReport;
@@ -1835,6 +1835,84 @@ var buildVoiceProofTrendReportFromRealCallProfiles = (options) => {
1835
1835
  });
1836
1836
  };
1837
1837
  var flattenProofTrendCycles = (reports) => reports.flatMap((report) => report.cycles ?? []);
1838
+ var withLatencyHeadroom = (value, options) => typeof value === "number" && Number.isFinite(value) ? Math.ceil(value * (options.latencyBudgetHeadroomRatio ?? 1.2) + (options.latencyBudgetHeadroomMs ?? 50)) : undefined;
1839
+ var buildProviderRouteDefaults = (providers) => {
1840
+ const routes = {};
1841
+ for (const provider of providers) {
1842
+ routes[provider.role ?? provider.id] = provider.id;
1843
+ }
1844
+ return routes;
1845
+ };
1846
+ var buildVoiceRealCallProfileDefaults = (input, options = {}) => {
1847
+ const trend = "trend" in input ? input.trend : input;
1848
+ const source = "source" in input ? input.source : trend.source;
1849
+ const recommendationReport = "recommendations" in input ? input.recommendations : buildVoiceProofTrendRecommendationReport(trend, options);
1850
+ const requiredProviderRoles = [
1851
+ ...options.requiredProviderRoles ?? ["llm", "stt", "tts"]
1852
+ ];
1853
+ const profileRecommendationsById = new Map(recommendationReport.profiles.map((profile) => [profile.id, profile]));
1854
+ const profiles = (trend.summary.profiles ?? []).map((profile) => {
1855
+ const recommendation = profileRecommendationsById.get(profile.id);
1856
+ const providers = recommendation?.bestProviders ?? [];
1857
+ const providerRoutes = buildProviderRouteDefaults(providers);
1858
+ const missingRoles = requiredProviderRoles.filter((role) => providerRoutes[role] === undefined);
1859
+ const status2 = recommendation?.status === "fail" ? "fail" : missingRoles.length > 0 ? "warn" : recommendation?.status ?? "warn";
1860
+ return {
1861
+ evidence: {
1862
+ liveP95Ms: profile.maxLiveP95Ms,
1863
+ providerP95Ms: profile.maxProviderP95Ms,
1864
+ turnP95Ms: profile.maxTurnP95Ms
1865
+ },
1866
+ label: profile.label,
1867
+ latencyBudgets: {
1868
+ maxLiveP95Ms: withLatencyHeadroom(profile.maxLiveP95Ms, options),
1869
+ maxProviderP95Ms: withLatencyHeadroom(profile.maxProviderP95Ms, options),
1870
+ maxTurnP95Ms: withLatencyHeadroom(profile.maxTurnP95Ms, options)
1871
+ },
1872
+ nextMove: missingRoles.length > 0 ? `Collect passing provider evidence for ${missingRoles.join(", ")} before using this as a complete default profile.` : recommendation?.nextMove ?? `Use these measured defaults for ${profile.label ?? profile.id}.`,
1873
+ profileId: profile.id,
1874
+ providerRoutes,
1875
+ providers,
1876
+ runtimeChannel: profile.runtimeChannel ? {
1877
+ maxBackpressureEvents: profile.runtimeChannel.maxBackpressureEvents,
1878
+ maxFirstAudioLatencyMs: withLatencyHeadroom(profile.runtimeChannel.maxFirstAudioLatencyMs, options),
1879
+ maxInterruptionP95Ms: withLatencyHeadroom(profile.runtimeChannel.maxInterruptionP95Ms, options),
1880
+ maxJitterMs: withLatencyHeadroom(profile.runtimeChannel.maxJitterMs, options),
1881
+ maxTimestampDriftMs: withLatencyHeadroom(profile.runtimeChannel.maxTimestampDriftMs, options)
1882
+ } : undefined,
1883
+ status: status2
1884
+ };
1885
+ });
1886
+ const issues = [
1887
+ ...profiles.length === 0 ? ["No real-call profiles were available to derive defaults."] : [],
1888
+ ...profiles.flatMap((profile) => {
1889
+ const missingRoles = requiredProviderRoles.filter((role) => profile.providerRoutes[role] === undefined);
1890
+ return missingRoles.length > 0 ? [
1891
+ `${profile.label ?? profile.profileId} is missing provider defaults for ${missingRoles.join(", ")}.`
1892
+ ] : [];
1893
+ })
1894
+ ];
1895
+ const status = issues.length > 0 ? "warn" : worstRecommendationStatus(profiles.map((profile) => ({
1896
+ evidence: {},
1897
+ nextMove: profile.nextMove,
1898
+ recommendation: profile.label ?? profile.profileId,
1899
+ status: profile.status,
1900
+ surface: "provider-path"
1901
+ })));
1902
+ return {
1903
+ generatedAt: new Date().toISOString(),
1904
+ issues,
1905
+ ok: status !== "fail",
1906
+ profiles,
1907
+ source,
1908
+ status,
1909
+ summary: {
1910
+ actionableProfiles: profiles.filter((profile) => requiredProviderRoles.every((role) => profile.providerRoutes[role] !== undefined) && profile.status === "pass").length,
1911
+ profileCount: profiles.length,
1912
+ requiredProviderRoles
1913
+ }
1914
+ };
1915
+ };
1838
1916
  var buildVoiceRealCallProfileHistoryReport = (options = {}) => {
1839
1917
  const generatedAt = options.generatedAt ?? (options.now instanceof Date ? options.now.toISOString() : typeof options.now === "number" ? new Date(options.now).toISOString() : typeof options.now === "string" ? new Date(options.now).toISOString() : new Date().toISOString());
1840
1918
  const evidenceReport = options.evidence && options.evidence.length > 0 ? buildVoiceProofTrendReportFromRealCallProfiles({
@@ -1850,36 +1928,39 @@ var buildVoiceRealCallProfileHistoryReport = (options = {}) => {
1850
1928
  })),
1851
1929
  ...evidenceReport ? [evidenceReport] : []
1852
1930
  ];
1853
- const profiles = buildVoiceProofTrendProfileSummaries(history, options);
1931
+ const passingHistory = history.filter((report) => report.ok === true);
1932
+ const recommendationHistory = passingHistory.length > 0 ? passingHistory : history;
1933
+ const profiles = buildVoiceProofTrendProfileSummaries(recommendationHistory, options);
1854
1934
  const summary = {
1855
- cycles: history.reduce((total, report) => total + (report.summary.cycles ?? report.cycles.length), 0),
1935
+ cycles: recommendationHistory.reduce((total, report) => total + (report.summary.cycles ?? report.cycles.length), 0),
1856
1936
  failedReports: history.filter((report) => report.ok !== true).length,
1857
- maxLiveP95Ms: maxNumber(history.map(readProofTrendMaxLiveP95)),
1858
- maxProviderP95Ms: maxNumber(history.map(readProofTrendMaxProviderP95)),
1859
- maxTurnP95Ms: maxNumber(history.map(readProofTrendMaxTurnP95)),
1937
+ maxLiveP95Ms: maxNumber(recommendationHistory.map(readProofTrendMaxLiveP95)),
1938
+ maxProviderP95Ms: maxNumber(recommendationHistory.map(readProofTrendMaxProviderP95)),
1939
+ maxTurnP95Ms: maxNumber(recommendationHistory.map(readProofTrendMaxTurnP95)),
1860
1940
  profileCount: profiles.length,
1861
1941
  profiles,
1862
- providers: readProofTrendProviders(history),
1863
- runtimeChannel: aggregateProofTrendRuntimeChannel(history.map(readProofTrendRuntimeChannel).filter((channel) => channel !== undefined))
1942
+ providers: readProofTrendProviders(recommendationHistory),
1943
+ runtimeChannel: aggregateProofTrendRuntimeChannel(recommendationHistory.map(readProofTrendRuntimeChannel).filter((channel) => channel !== undefined))
1864
1944
  };
1865
1945
  const trend = buildVoiceProofTrendReport({
1866
1946
  baseUrl: options.baseUrl,
1867
- cycles: flattenProofTrendCycles(history),
1947
+ cycles: flattenProofTrendCycles(recommendationHistory),
1868
1948
  generatedAt,
1869
1949
  maxAgeMs: options.maxAgeMs,
1870
1950
  now: options.now,
1871
- ok: history.length > 0 && summary.failedReports === 0 && profiles.every((profile) => profile.status !== "fail"),
1951
+ ok: recommendationHistory.length > 0 && profiles.every((profile) => profile.status !== "fail"),
1872
1952
  source: options.source ?? "real-call-profile-history",
1873
1953
  summary
1874
1954
  });
1875
1955
  const recommendations = buildVoiceProofTrendRecommendationReport(trend, options);
1956
+ const defaults = buildVoiceRealCallProfileDefaults(trend, options);
1876
1957
  const issues = [
1877
- ...history.length === 0 ? ["No real-call profile reports were present."] : [],
1958
+ ...recommendationHistory.length === 0 ? ["No passing real-call profile reports were present."] : [],
1878
1959
  ...profiles.length === 0 ? ["No benchmark profiles were present."] : [],
1879
- ...summary.failedReports > 0 ? [`${summary.failedReports} real-call profile report(s) failed.`] : [],
1880
1960
  ...recommendations.issues
1881
1961
  ];
1882
1962
  return {
1963
+ defaults,
1883
1964
  generatedAt,
1884
1965
  history,
1885
1966
  issues,
@@ -2288,6 +2369,12 @@ var renderVoiceRealCallProfileHistoryMarkdown = (report, title = "Voice Real-Cal
2288
2369
  "",
2289
2370
  ...report.recommendations.recommendations.map((recommendation) => `- ${recommendation.status}: ${recommendation.recommendation} ${recommendation.nextMove}`),
2290
2371
  "",
2372
+ "## Actionable Defaults",
2373
+ "",
2374
+ "| Profile | Status | Provider routes | Live budget | Provider budget | Turn budget |",
2375
+ "| --- | --- | --- | ---: | ---: | ---: |",
2376
+ ...report.defaults.profiles.length ? report.defaults.profiles.map((profile) => `| ${escapeMarkdown(profile.label ?? profile.profileId)} | ${profile.status} | ${escapeMarkdown(Object.entries(profile.providerRoutes).map(([role, provider]) => `${role}: ${provider}`).join(", ") || "n/a")} | ${profile.latencyBudgets.maxLiveP95Ms ?? "n/a"} | ${profile.latencyBudgets.maxProviderP95Ms ?? "n/a"} | ${profile.latencyBudgets.maxTurnP95Ms ?? "n/a"} |`) : ["| n/a | n/a | n/a | n/a | n/a | n/a |"],
2377
+ "",
2291
2378
  "## Issues",
2292
2379
  "",
2293
2380
  ...report.issues.length ? report.issues.map((issue) => `- ${issue}`) : ["- None"]
@@ -2295,9 +2382,10 @@ var renderVoiceRealCallProfileHistoryMarkdown = (report, title = "Voice Real-Cal
2295
2382
  `);
2296
2383
  var renderVoiceRealCallProfileHistoryHTML = (report, title = "Voice Real-Call Profile History") => {
2297
2384
  const profileRows = report.summary.profiles?.length ? report.summary.profiles.map((profile) => `<tr><td>${escapeHtml5(profile.label ?? profile.id)}</td><td>${escapeHtml5(profile.status ?? "unknown")}</td><td>${escapeHtml5(profile.maxLiveP95Ms ?? "n/a")}</td><td>${escapeHtml5(profile.maxProviderP95Ms ?? "n/a")}</td><td>${escapeHtml5(profile.maxTurnP95Ms ?? "n/a")}</td><td>${escapeHtml5(formatProviderMix(profile.providers ?? []))}</td></tr>`).join("") : '<tr><td colspan="6">No profiles present.</td></tr>';
2385
+ const defaultRows = report.defaults.profiles.length > 0 ? report.defaults.profiles.map((profile) => `<tr><td>${escapeHtml5(profile.label ?? profile.profileId)}</td><td>${escapeHtml5(profile.status)}</td><td>${escapeHtml5(Object.entries(profile.providerRoutes).map(([role, provider]) => `${role}: ${provider}`).join(", ") || "n/a")}</td><td>${escapeHtml5(profile.latencyBudgets.maxLiveP95Ms ?? "n/a")}</td><td>${escapeHtml5(profile.latencyBudgets.maxProviderP95Ms ?? "n/a")}</td><td>${escapeHtml5(profile.latencyBudgets.maxTurnP95Ms ?? "n/a")}</td></tr>`).join("") : '<tr><td colspan="6">No actionable defaults present.</td></tr>';
2298
2386
  const recommendations = report.recommendations.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></article>`).join("");
2299
2387
  const issues = report.issues.length === 0 ? "<li>None</li>" : report.issues.map((issue) => `<li>${escapeHtml5(issue)}</li>`).join("");
2300
- 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:#111510;color:#f6f0dd;font-family:ui-sans-serif,system-ui,sans-serif;margin:0}main{margin:auto;max-width:1120px;padding:32px}.hero,article,.card{background:#182117;border:1px solid #32412d;border-radius:24px;margin-bottom:16px;padding:22px}.hero{background:linear-gradient(135deg,rgba(132,204,22,.16),rgba(20,184,166,.12))}.eyebrow{color:#bef264;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 #52624b;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)}table{border-collapse:collapse;width:100%}td,th{border-bottom:1px solid #32412d;padding:10px;text-align:left}</style></head><body><main><section class="hero"><p class="eyebrow">Real-call benchmark history</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">Reports ${String(report.reports)}</span><span class="pill">Profiles ${String(report.summary.profileCount)}</span><span class="pill">Cycles ${String(report.summary.cycles ?? 0)}</span><span class="pill">Best mix ${escapeHtml5(formatProviderMix(report.recommendations.bestProviders))}</span></div></section><section class="card"><h2>Profiles</h2><table><thead><tr><th>Profile</th><th>Status</th><th>Live p95</th><th>Provider p95</th><th>Turn p95</th><th>Provider mix</th></tr></thead><tbody>${profileRows}</tbody></table></section>${recommendations}<section class="card"><h2>Issues</h2><ul>${issues}</ul></section></main></body></html>`;
2388
+ 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:#111510;color:#f6f0dd;font-family:ui-sans-serif,system-ui,sans-serif;margin:0}main{margin:auto;max-width:1120px;padding:32px}.hero,article,.card{background:#182117;border:1px solid #32412d;border-radius:24px;margin-bottom:16px;padding:22px}.hero{background:linear-gradient(135deg,rgba(132,204,22,.16),rgba(20,184,166,.12))}.eyebrow{color:#bef264;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 #52624b;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)}table{border-collapse:collapse;width:100%}td,th{border-bottom:1px solid #32412d;padding:10px;text-align:left}</style></head><body><main><section class="hero"><p class="eyebrow">Real-call benchmark history</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">Reports ${String(report.reports)}</span><span class="pill">Profiles ${String(report.summary.profileCount)}</span><span class="pill">Defaults ${String(report.defaults.summary.actionableProfiles)}/${String(report.defaults.summary.profileCount)}</span><span class="pill">Cycles ${String(report.summary.cycles ?? 0)}</span><span class="pill">Best mix ${escapeHtml5(formatProviderMix(report.recommendations.bestProviders))}</span></div></section><section class="card"><h2>Profiles</h2><table><thead><tr><th>Profile</th><th>Status</th><th>Live p95</th><th>Provider p95</th><th>Turn p95</th><th>Provider mix</th></tr></thead><tbody>${profileRows}</tbody></table></section><section class="card"><h2>Actionable Defaults</h2><table><thead><tr><th>Profile</th><th>Status</th><th>Provider routes</th><th>Live budget</th><th>Provider budget</th><th>Turn budget</th></tr></thead><tbody>${defaultRows}</tbody></table></section>${recommendations}<section class="card"><h2>Issues</h2><ul>${issues}</ul></section></main></body></html>`;
2301
2389
  };
2302
2390
  var createVoiceProofTrendRecommendationRoutes = (options) => {
2303
2391
  const path = options.path ?? "/api/voice/proof-trend-recommendations";
package/dist/vue/index.js CHANGED
@@ -1756,6 +1756,84 @@ var buildVoiceProofTrendReportFromRealCallProfiles = (options) => {
1756
1756
  });
1757
1757
  };
1758
1758
  var flattenProofTrendCycles = (reports) => reports.flatMap((report) => report.cycles ?? []);
1759
+ var withLatencyHeadroom = (value, options) => typeof value === "number" && Number.isFinite(value) ? Math.ceil(value * (options.latencyBudgetHeadroomRatio ?? 1.2) + (options.latencyBudgetHeadroomMs ?? 50)) : undefined;
1760
+ var buildProviderRouteDefaults = (providers) => {
1761
+ const routes = {};
1762
+ for (const provider of providers) {
1763
+ routes[provider.role ?? provider.id] = provider.id;
1764
+ }
1765
+ return routes;
1766
+ };
1767
+ var buildVoiceRealCallProfileDefaults = (input, options = {}) => {
1768
+ const trend = "trend" in input ? input.trend : input;
1769
+ const source = "source" in input ? input.source : trend.source;
1770
+ const recommendationReport = "recommendations" in input ? input.recommendations : buildVoiceProofTrendRecommendationReport(trend, options);
1771
+ const requiredProviderRoles = [
1772
+ ...options.requiredProviderRoles ?? ["llm", "stt", "tts"]
1773
+ ];
1774
+ const profileRecommendationsById = new Map(recommendationReport.profiles.map((profile) => [profile.id, profile]));
1775
+ const profiles = (trend.summary.profiles ?? []).map((profile) => {
1776
+ const recommendation = profileRecommendationsById.get(profile.id);
1777
+ const providers = recommendation?.bestProviders ?? [];
1778
+ const providerRoutes = buildProviderRouteDefaults(providers);
1779
+ const missingRoles = requiredProviderRoles.filter((role) => providerRoutes[role] === undefined);
1780
+ const status2 = recommendation?.status === "fail" ? "fail" : missingRoles.length > 0 ? "warn" : recommendation?.status ?? "warn";
1781
+ return {
1782
+ evidence: {
1783
+ liveP95Ms: profile.maxLiveP95Ms,
1784
+ providerP95Ms: profile.maxProviderP95Ms,
1785
+ turnP95Ms: profile.maxTurnP95Ms
1786
+ },
1787
+ label: profile.label,
1788
+ latencyBudgets: {
1789
+ maxLiveP95Ms: withLatencyHeadroom(profile.maxLiveP95Ms, options),
1790
+ maxProviderP95Ms: withLatencyHeadroom(profile.maxProviderP95Ms, options),
1791
+ maxTurnP95Ms: withLatencyHeadroom(profile.maxTurnP95Ms, options)
1792
+ },
1793
+ nextMove: missingRoles.length > 0 ? `Collect passing provider evidence for ${missingRoles.join(", ")} before using this as a complete default profile.` : recommendation?.nextMove ?? `Use these measured defaults for ${profile.label ?? profile.id}.`,
1794
+ profileId: profile.id,
1795
+ providerRoutes,
1796
+ providers,
1797
+ runtimeChannel: profile.runtimeChannel ? {
1798
+ maxBackpressureEvents: profile.runtimeChannel.maxBackpressureEvents,
1799
+ maxFirstAudioLatencyMs: withLatencyHeadroom(profile.runtimeChannel.maxFirstAudioLatencyMs, options),
1800
+ maxInterruptionP95Ms: withLatencyHeadroom(profile.runtimeChannel.maxInterruptionP95Ms, options),
1801
+ maxJitterMs: withLatencyHeadroom(profile.runtimeChannel.maxJitterMs, options),
1802
+ maxTimestampDriftMs: withLatencyHeadroom(profile.runtimeChannel.maxTimestampDriftMs, options)
1803
+ } : undefined,
1804
+ status: status2
1805
+ };
1806
+ });
1807
+ const issues = [
1808
+ ...profiles.length === 0 ? ["No real-call profiles were available to derive defaults."] : [],
1809
+ ...profiles.flatMap((profile) => {
1810
+ const missingRoles = requiredProviderRoles.filter((role) => profile.providerRoutes[role] === undefined);
1811
+ return missingRoles.length > 0 ? [
1812
+ `${profile.label ?? profile.profileId} is missing provider defaults for ${missingRoles.join(", ")}.`
1813
+ ] : [];
1814
+ })
1815
+ ];
1816
+ const status = issues.length > 0 ? "warn" : worstRecommendationStatus(profiles.map((profile) => ({
1817
+ evidence: {},
1818
+ nextMove: profile.nextMove,
1819
+ recommendation: profile.label ?? profile.profileId,
1820
+ status: profile.status,
1821
+ surface: "provider-path"
1822
+ })));
1823
+ return {
1824
+ generatedAt: new Date().toISOString(),
1825
+ issues,
1826
+ ok: status !== "fail",
1827
+ profiles,
1828
+ source,
1829
+ status,
1830
+ summary: {
1831
+ actionableProfiles: profiles.filter((profile) => requiredProviderRoles.every((role) => profile.providerRoutes[role] !== undefined) && profile.status === "pass").length,
1832
+ profileCount: profiles.length,
1833
+ requiredProviderRoles
1834
+ }
1835
+ };
1836
+ };
1759
1837
  var buildVoiceRealCallProfileHistoryReport = (options = {}) => {
1760
1838
  const generatedAt = options.generatedAt ?? (options.now instanceof Date ? options.now.toISOString() : typeof options.now === "number" ? new Date(options.now).toISOString() : typeof options.now === "string" ? new Date(options.now).toISOString() : new Date().toISOString());
1761
1839
  const evidenceReport = options.evidence && options.evidence.length > 0 ? buildVoiceProofTrendReportFromRealCallProfiles({
@@ -1771,36 +1849,39 @@ var buildVoiceRealCallProfileHistoryReport = (options = {}) => {
1771
1849
  })),
1772
1850
  ...evidenceReport ? [evidenceReport] : []
1773
1851
  ];
1774
- const profiles = buildVoiceProofTrendProfileSummaries(history, options);
1852
+ const passingHistory = history.filter((report) => report.ok === true);
1853
+ const recommendationHistory = passingHistory.length > 0 ? passingHistory : history;
1854
+ const profiles = buildVoiceProofTrendProfileSummaries(recommendationHistory, options);
1775
1855
  const summary = {
1776
- cycles: history.reduce((total, report) => total + (report.summary.cycles ?? report.cycles.length), 0),
1856
+ cycles: recommendationHistory.reduce((total, report) => total + (report.summary.cycles ?? report.cycles.length), 0),
1777
1857
  failedReports: history.filter((report) => report.ok !== true).length,
1778
- maxLiveP95Ms: maxNumber(history.map(readProofTrendMaxLiveP95)),
1779
- maxProviderP95Ms: maxNumber(history.map(readProofTrendMaxProviderP95)),
1780
- maxTurnP95Ms: maxNumber(history.map(readProofTrendMaxTurnP95)),
1858
+ maxLiveP95Ms: maxNumber(recommendationHistory.map(readProofTrendMaxLiveP95)),
1859
+ maxProviderP95Ms: maxNumber(recommendationHistory.map(readProofTrendMaxProviderP95)),
1860
+ maxTurnP95Ms: maxNumber(recommendationHistory.map(readProofTrendMaxTurnP95)),
1781
1861
  profileCount: profiles.length,
1782
1862
  profiles,
1783
- providers: readProofTrendProviders(history),
1784
- runtimeChannel: aggregateProofTrendRuntimeChannel(history.map(readProofTrendRuntimeChannel).filter((channel) => channel !== undefined))
1863
+ providers: readProofTrendProviders(recommendationHistory),
1864
+ runtimeChannel: aggregateProofTrendRuntimeChannel(recommendationHistory.map(readProofTrendRuntimeChannel).filter((channel) => channel !== undefined))
1785
1865
  };
1786
1866
  const trend = buildVoiceProofTrendReport({
1787
1867
  baseUrl: options.baseUrl,
1788
- cycles: flattenProofTrendCycles(history),
1868
+ cycles: flattenProofTrendCycles(recommendationHistory),
1789
1869
  generatedAt,
1790
1870
  maxAgeMs: options.maxAgeMs,
1791
1871
  now: options.now,
1792
- ok: history.length > 0 && summary.failedReports === 0 && profiles.every((profile) => profile.status !== "fail"),
1872
+ ok: recommendationHistory.length > 0 && profiles.every((profile) => profile.status !== "fail"),
1793
1873
  source: options.source ?? "real-call-profile-history",
1794
1874
  summary
1795
1875
  });
1796
1876
  const recommendations = buildVoiceProofTrendRecommendationReport(trend, options);
1877
+ const defaults = buildVoiceRealCallProfileDefaults(trend, options);
1797
1878
  const issues = [
1798
- ...history.length === 0 ? ["No real-call profile reports were present."] : [],
1879
+ ...recommendationHistory.length === 0 ? ["No passing real-call profile reports were present."] : [],
1799
1880
  ...profiles.length === 0 ? ["No benchmark profiles were present."] : [],
1800
- ...summary.failedReports > 0 ? [`${summary.failedReports} real-call profile report(s) failed.`] : [],
1801
1881
  ...recommendations.issues
1802
1882
  ];
1803
1883
  return {
1884
+ defaults,
1804
1885
  generatedAt,
1805
1886
  history,
1806
1887
  issues,
@@ -2209,6 +2290,12 @@ var renderVoiceRealCallProfileHistoryMarkdown = (report, title = "Voice Real-Cal
2209
2290
  "",
2210
2291
  ...report.recommendations.recommendations.map((recommendation) => `- ${recommendation.status}: ${recommendation.recommendation} ${recommendation.nextMove}`),
2211
2292
  "",
2293
+ "## Actionable Defaults",
2294
+ "",
2295
+ "| Profile | Status | Provider routes | Live budget | Provider budget | Turn budget |",
2296
+ "| --- | --- | --- | ---: | ---: | ---: |",
2297
+ ...report.defaults.profiles.length ? report.defaults.profiles.map((profile) => `| ${escapeMarkdown(profile.label ?? profile.profileId)} | ${profile.status} | ${escapeMarkdown(Object.entries(profile.providerRoutes).map(([role, provider]) => `${role}: ${provider}`).join(", ") || "n/a")} | ${profile.latencyBudgets.maxLiveP95Ms ?? "n/a"} | ${profile.latencyBudgets.maxProviderP95Ms ?? "n/a"} | ${profile.latencyBudgets.maxTurnP95Ms ?? "n/a"} |`) : ["| n/a | n/a | n/a | n/a | n/a | n/a |"],
2298
+ "",
2212
2299
  "## Issues",
2213
2300
  "",
2214
2301
  ...report.issues.length ? report.issues.map((issue) => `- ${issue}`) : ["- None"]
@@ -2216,9 +2303,10 @@ var renderVoiceRealCallProfileHistoryMarkdown = (report, title = "Voice Real-Cal
2216
2303
  `);
2217
2304
  var renderVoiceRealCallProfileHistoryHTML = (report, title = "Voice Real-Call Profile History") => {
2218
2305
  const profileRows = report.summary.profiles?.length ? report.summary.profiles.map((profile) => `<tr><td>${escapeHtml5(profile.label ?? profile.id)}</td><td>${escapeHtml5(profile.status ?? "unknown")}</td><td>${escapeHtml5(profile.maxLiveP95Ms ?? "n/a")}</td><td>${escapeHtml5(profile.maxProviderP95Ms ?? "n/a")}</td><td>${escapeHtml5(profile.maxTurnP95Ms ?? "n/a")}</td><td>${escapeHtml5(formatProviderMix(profile.providers ?? []))}</td></tr>`).join("") : '<tr><td colspan="6">No profiles present.</td></tr>';
2306
+ const defaultRows = report.defaults.profiles.length > 0 ? report.defaults.profiles.map((profile) => `<tr><td>${escapeHtml5(profile.label ?? profile.profileId)}</td><td>${escapeHtml5(profile.status)}</td><td>${escapeHtml5(Object.entries(profile.providerRoutes).map(([role, provider]) => `${role}: ${provider}`).join(", ") || "n/a")}</td><td>${escapeHtml5(profile.latencyBudgets.maxLiveP95Ms ?? "n/a")}</td><td>${escapeHtml5(profile.latencyBudgets.maxProviderP95Ms ?? "n/a")}</td><td>${escapeHtml5(profile.latencyBudgets.maxTurnP95Ms ?? "n/a")}</td></tr>`).join("") : '<tr><td colspan="6">No actionable defaults present.</td></tr>';
2219
2307
  const recommendations = report.recommendations.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></article>`).join("");
2220
2308
  const issues = report.issues.length === 0 ? "<li>None</li>" : report.issues.map((issue) => `<li>${escapeHtml5(issue)}</li>`).join("");
2221
- 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:#111510;color:#f6f0dd;font-family:ui-sans-serif,system-ui,sans-serif;margin:0}main{margin:auto;max-width:1120px;padding:32px}.hero,article,.card{background:#182117;border:1px solid #32412d;border-radius:24px;margin-bottom:16px;padding:22px}.hero{background:linear-gradient(135deg,rgba(132,204,22,.16),rgba(20,184,166,.12))}.eyebrow{color:#bef264;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 #52624b;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)}table{border-collapse:collapse;width:100%}td,th{border-bottom:1px solid #32412d;padding:10px;text-align:left}</style></head><body><main><section class="hero"><p class="eyebrow">Real-call benchmark history</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">Reports ${String(report.reports)}</span><span class="pill">Profiles ${String(report.summary.profileCount)}</span><span class="pill">Cycles ${String(report.summary.cycles ?? 0)}</span><span class="pill">Best mix ${escapeHtml5(formatProviderMix(report.recommendations.bestProviders))}</span></div></section><section class="card"><h2>Profiles</h2><table><thead><tr><th>Profile</th><th>Status</th><th>Live p95</th><th>Provider p95</th><th>Turn p95</th><th>Provider mix</th></tr></thead><tbody>${profileRows}</tbody></table></section>${recommendations}<section class="card"><h2>Issues</h2><ul>${issues}</ul></section></main></body></html>`;
2309
+ 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:#111510;color:#f6f0dd;font-family:ui-sans-serif,system-ui,sans-serif;margin:0}main{margin:auto;max-width:1120px;padding:32px}.hero,article,.card{background:#182117;border:1px solid #32412d;border-radius:24px;margin-bottom:16px;padding:22px}.hero{background:linear-gradient(135deg,rgba(132,204,22,.16),rgba(20,184,166,.12))}.eyebrow{color:#bef264;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 #52624b;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)}table{border-collapse:collapse;width:100%}td,th{border-bottom:1px solid #32412d;padding:10px;text-align:left}</style></head><body><main><section class="hero"><p class="eyebrow">Real-call benchmark history</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">Reports ${String(report.reports)}</span><span class="pill">Profiles ${String(report.summary.profileCount)}</span><span class="pill">Defaults ${String(report.defaults.summary.actionableProfiles)}/${String(report.defaults.summary.profileCount)}</span><span class="pill">Cycles ${String(report.summary.cycles ?? 0)}</span><span class="pill">Best mix ${escapeHtml5(formatProviderMix(report.recommendations.bestProviders))}</span></div></section><section class="card"><h2>Profiles</h2><table><thead><tr><th>Profile</th><th>Status</th><th>Live p95</th><th>Provider p95</th><th>Turn p95</th><th>Provider mix</th></tr></thead><tbody>${profileRows}</tbody></table></section><section class="card"><h2>Actionable Defaults</h2><table><thead><tr><th>Profile</th><th>Status</th><th>Provider routes</th><th>Live budget</th><th>Provider budget</th><th>Turn budget</th></tr></thead><tbody>${defaultRows}</tbody></table></section>${recommendations}<section class="card"><h2>Issues</h2><ul>${issues}</ul></section></main></body></html>`;
2222
2310
  };
2223
2311
  var createVoiceProofTrendRecommendationRoutes = (options) => {
2224
2312
  const path = options.path ?? "/api/voice/proof-trend-recommendations";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@absolutejs/voice",
3
- "version": "0.0.22-beta.347",
3
+ "version": "0.0.22-beta.349",
4
4
  "description": "Voice primitives and Elysia plugin for AbsoluteJS",
5
5
  "repository": {
6
6
  "type": "git",