@absolutejs/voice 0.0.22-beta.333 → 0.0.22-beta.335

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.
@@ -1569,7 +1569,7 @@ var maxNumber = (values) => {
1569
1569
  return finite.length > 0 ? Math.max(...finite) : undefined;
1570
1570
  };
1571
1571
  var readProofTrendMaxLiveP95 = (report) => report.summary.maxLiveP95Ms ?? maxNumber(report.cycles.map((cycle) => cycle.liveLatency?.p95Ms));
1572
- var readProofTrendMaxProviderP95 = (report) => report.summary.maxProviderP95Ms;
1572
+ var readProofTrendMaxProviderP95 = (report) => report.summary.maxProviderP95Ms ?? maxNumber((report.summary.providers ?? []).map((provider) => provider.p95Ms)) ?? maxNumber(report.cycles.flatMap((cycle) => (cycle.providers ?? []).map((provider) => provider.p95Ms)));
1573
1573
  var readProofTrendMaxTurnP95 = (report) => report.summary.maxTurnP95Ms ?? maxNumber(report.cycles.map((cycle) => cycle.turnLatency?.p95Ms));
1574
1574
  var readRuntimeChannelMetric = (report, key) => {
1575
1575
  const summaryValue = report.summary.runtimeChannel?.[key];
@@ -1587,6 +1587,91 @@ var readProofTrendRuntimeChannel = (report) => ({
1587
1587
  samples: report.summary.runtimeChannel?.samples ?? maxNumber(report.cycles.map((cycle) => cycle.runtimeChannel?.samples)),
1588
1588
  status: report.summary.runtimeChannel?.status
1589
1589
  });
1590
+ var normalizeProviderStatus = (status) => status === "pass" ? "pass" : status === "fail" ? "fail" : "warn";
1591
+ var providerSortScore = (provider) => [
1592
+ recommendationStatusRank[provider.status],
1593
+ provider.p95Ms ?? Number.POSITIVE_INFINITY,
1594
+ provider.averageMs ?? Number.POSITIVE_INFINITY,
1595
+ provider.samples === undefined ? Number.POSITIVE_INFINITY : -provider.samples,
1596
+ provider.id
1597
+ ];
1598
+ var compareProviders = (left, right) => {
1599
+ const leftScore = providerSortScore(left);
1600
+ const rightScore = providerSortScore(right);
1601
+ for (let index = 0;index < leftScore.length; index += 1) {
1602
+ const leftValue = leftScore[index];
1603
+ const rightValue = rightScore[index];
1604
+ if (typeof leftValue === "number" && typeof rightValue === "number") {
1605
+ if (leftValue !== rightValue) {
1606
+ return leftValue - rightValue;
1607
+ }
1608
+ continue;
1609
+ }
1610
+ const compared = String(leftValue).localeCompare(String(rightValue));
1611
+ if (compared !== 0) {
1612
+ return compared;
1613
+ }
1614
+ }
1615
+ return 0;
1616
+ };
1617
+ var summarizeProofTrendProviders = (report, budgetMs) => {
1618
+ const sourceProviders = report.summary.providers && report.summary.providers.length > 0 ? report.summary.providers : undefined;
1619
+ const providersById = new Map;
1620
+ if (sourceProviders) {
1621
+ for (const provider of sourceProviders) {
1622
+ if (provider.id) {
1623
+ providersById.set(provider.id, provider);
1624
+ }
1625
+ }
1626
+ } else {
1627
+ for (const cycle of report.cycles) {
1628
+ for (const provider of cycle.providers ?? []) {
1629
+ if (!provider.id) {
1630
+ continue;
1631
+ }
1632
+ const existing = providersById.get(provider.id);
1633
+ providersById.set(provider.id, {
1634
+ averageMs: maxNumber([existing?.averageMs, provider.averageMs]),
1635
+ id: provider.id,
1636
+ label: existing?.label ?? provider.label,
1637
+ p50Ms: maxNumber([existing?.p50Ms, provider.p50Ms]),
1638
+ p95Ms: maxNumber([existing?.p95Ms, provider.p95Ms]),
1639
+ role: existing?.role ?? provider.role,
1640
+ samples: (existing?.samples ?? 0) + (provider.samples ?? 0),
1641
+ status: existing?.status === "fail" || provider.status === "fail" ? "fail" : existing?.status === "warn" || provider.status === "warn" ? "warn" : provider.status ?? existing?.status
1642
+ });
1643
+ }
1644
+ }
1645
+ }
1646
+ return [...providersById.values()].map((provider) => {
1647
+ const status = provider.p95Ms === undefined ? normalizeProviderStatus(provider.status) : withinBudget(provider.p95Ms, budgetMs) ? normalizeProviderStatus(provider.status) === "fail" ? "fail" : "pass" : normalizeProviderStatus(provider.status) === "fail" ? "fail" : "warn";
1648
+ return {
1649
+ averageMs: provider.averageMs,
1650
+ id: provider.id,
1651
+ label: provider.label,
1652
+ nextMove: status === "pass" ? "Eligible for latency-sensitive routing based on sustained proof." : provider.p95Ms === undefined ? "Collect provider-specific latency samples before routing latency-sensitive traffic here." : "Keep as fallback or tune provider/model/runtime budgets before using for latency-sensitive routing.",
1653
+ p50Ms: provider.p50Ms,
1654
+ p95Ms: provider.p95Ms,
1655
+ rank: 0,
1656
+ role: provider.role,
1657
+ samples: provider.samples,
1658
+ status
1659
+ };
1660
+ }).sort(compareProviders).map((provider, index) => ({ ...provider, rank: index + 1 }));
1661
+ };
1662
+ var shouldSwitchProvider = (current, best, options) => {
1663
+ if (!current || !best || current.id === best.id || best.status !== "pass") {
1664
+ return false;
1665
+ }
1666
+ if (current.p95Ms === undefined || best.p95Ms === undefined) {
1667
+ return false;
1668
+ }
1669
+ const minImprovementMs = options.providerSwitchMinImprovementMs ?? 100;
1670
+ const minImprovementRatio = options.providerSwitchMinImprovementRatio ?? 0.1;
1671
+ const improvementMs = current.p95Ms - best.p95Ms;
1672
+ const improvementRatio = current.p95Ms > 0 ? improvementMs / current.p95Ms : 0;
1673
+ return improvementMs >= minImprovementMs || improvementRatio >= minImprovementRatio;
1674
+ };
1590
1675
  var evaluateVoiceProofTrendEvidence = (report, input = {}) => {
1591
1676
  const issues = [];
1592
1677
  const requiredStatus = input.requireStatus ?? "pass";
@@ -1678,6 +1763,186 @@ var assertVoiceProofTrendEvidence = (report, input = {}) => {
1678
1763
  }
1679
1764
  return assertion;
1680
1765
  };
1766
+ var DEFAULT_RECOMMENDATION_BUDGETS = {
1767
+ maxLiveP95Ms: 800,
1768
+ maxProviderP95Ms: 1000,
1769
+ maxRuntimeBackpressureEvents: 0,
1770
+ maxRuntimeFirstAudioLatencyMs: 600,
1771
+ maxRuntimeInterruptionP95Ms: 300,
1772
+ maxRuntimeJitterMs: 30,
1773
+ maxRuntimeTimestampDriftMs: 800,
1774
+ maxTurnP95Ms: 700
1775
+ };
1776
+ var withinBudget = (value, budget) => typeof value === "number" && Number.isFinite(value) && value <= budget;
1777
+ var recommendationStatusRank = {
1778
+ pass: 0,
1779
+ warn: 1,
1780
+ fail: 2
1781
+ };
1782
+ var worstRecommendationStatus = (recommendations) => recommendations.reduce((status, recommendation) => recommendationStatusRank[recommendation.status] > recommendationStatusRank[status] ? recommendation.status : status, "pass");
1783
+ var buildVoiceProofTrendRecommendationReport = (report, options = {}) => {
1784
+ const budgets = { ...DEFAULT_RECOMMENDATION_BUDGETS, ...options };
1785
+ const maxLiveP95Ms = readProofTrendMaxLiveP95(report);
1786
+ const maxProviderP95Ms = readProofTrendMaxProviderP95(report);
1787
+ const maxTurnP95Ms = readProofTrendMaxTurnP95(report);
1788
+ const runtimeChannel = readProofTrendRuntimeChannel(report);
1789
+ const providers = summarizeProofTrendProviders(report, budgets.maxProviderP95Ms);
1790
+ const bestProvider = providers.find((provider) => provider.status === "pass") ?? providers[0];
1791
+ const currentProvider = options.currentProviderId ? providers.find((provider) => provider.id === options.currentProviderId) : undefined;
1792
+ const providerSwitchRecommended = shouldSwitchProvider(currentProvider, bestProvider, options);
1793
+ const recommendations = [];
1794
+ const issues = [];
1795
+ if (report.ok !== true) {
1796
+ issues.push(`Proof trend report is ${report.status}; recommendations need a fresh passing trend artifact.`);
1797
+ }
1798
+ recommendations.push({
1799
+ evidence: {
1800
+ bestProviderId: bestProvider?.id,
1801
+ bestProviderP95Ms: bestProvider?.p95Ms,
1802
+ budgetMs: budgets.maxProviderP95Ms,
1803
+ currentProviderId: currentProvider?.id ?? options.currentProviderId,
1804
+ currentProviderP95Ms: currentProvider?.p95Ms,
1805
+ providerComparisonCount: providers.length,
1806
+ providerP95Ms: maxProviderP95Ms
1807
+ },
1808
+ nextMove: providers.length > 0 ? providerSwitchRecommended ? `Route latency-sensitive turns to ${bestProvider?.label ?? bestProvider?.id} for this call profile and keep the current path as fallback.` : bestProvider ? `Use ${bestProvider.label ?? bestProvider.id} as the fastest proven provider path for this call profile and keep collecting sustained comparisons.` : "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.",
1809
+ providerId: bestProvider?.id,
1810
+ recommendation: providers.length > 0 ? providerSwitchRecommended ? `Switch latency-sensitive routing to ${bestProvider?.label ?? bestProvider?.id}` : bestProvider ? `Prefer ${bestProvider.label ?? bestProvider.id} for this call profile` : "Collect provider-specific latency samples" : withinBudget(maxProviderP95Ms, budgets.maxProviderP95Ms) ? "Keep current provider path" : "Change provider routing for latency-sensitive traffic",
1811
+ role: bestProvider?.role,
1812
+ status: providers.length > 0 ? providerSwitchRecommended ? "warn" : bestProvider?.status ?? "fail" : withinBudget(maxProviderP95Ms, budgets.maxProviderP95Ms) ? "pass" : maxProviderP95Ms === undefined ? "fail" : "warn",
1813
+ surface: "provider-path"
1814
+ });
1815
+ 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);
1816
+ recommendations.push({
1817
+ evidence: {
1818
+ backpressureEvents: runtimeChannel.maxBackpressureEvents,
1819
+ firstAudioBudgetMs: budgets.maxRuntimeFirstAudioLatencyMs,
1820
+ firstAudioMs: runtimeChannel.maxFirstAudioLatencyMs,
1821
+ interruptionBudgetMs: budgets.maxRuntimeInterruptionP95Ms,
1822
+ interruptionP95Ms: runtimeChannel.maxInterruptionP95Ms,
1823
+ jitterBudgetMs: budgets.maxRuntimeJitterMs,
1824
+ jitterMs: runtimeChannel.maxJitterMs,
1825
+ samples: runtimeChannel.samples,
1826
+ timestampDriftMs: runtimeChannel.maxTimestampDriftMs
1827
+ },
1828
+ nextMove: runtimePass ? "Keep the current runtime-channel settings and use this artifact as the deploy gate baseline." : "Tune capture/output format, buffering, interruption threshold, or transport backpressure before promoting this runtime path.",
1829
+ recommendation: runtimePass ? "Keep current runtime channel" : "Tune runtime channel before promotion",
1830
+ status: runtimePass ? "pass" : runtimeChannel.samples === undefined ? "fail" : "warn",
1831
+ surface: "runtime-channel"
1832
+ });
1833
+ recommendations.push({
1834
+ evidence: {
1835
+ budgetMs: budgets.maxLiveP95Ms,
1836
+ liveP95Ms: maxLiveP95Ms
1837
+ },
1838
+ nextMove: withinBudget(maxLiveP95Ms, budgets.maxLiveP95Ms) ? "Keep browser live-latency defaults and continue watching long-window drift." : "Tune browser streaming, chunking, or readiness thresholds before release.",
1839
+ recommendation: withinBudget(maxLiveP95Ms, budgets.maxLiveP95Ms) ? "Keep live-latency settings" : "Tune live-latency path",
1840
+ status: withinBudget(maxLiveP95Ms, budgets.maxLiveP95Ms) ? "pass" : maxLiveP95Ms === undefined ? "fail" : "warn",
1841
+ surface: "live-latency"
1842
+ });
1843
+ recommendations.push({
1844
+ evidence: {
1845
+ budgetMs: budgets.maxTurnP95Ms,
1846
+ turnP95Ms: maxTurnP95Ms
1847
+ },
1848
+ nextMove: withinBudget(maxTurnP95Ms, budgets.maxTurnP95Ms) ? "Keep current turn pipeline defaults." : "Reduce tool/provider latency or split the turn pipeline before promotion.",
1849
+ recommendation: withinBudget(maxTurnP95Ms, budgets.maxTurnP95Ms) ? "Keep turn pipeline" : "Tune turn pipeline",
1850
+ status: withinBudget(maxTurnP95Ms, budgets.maxTurnP95Ms) ? "pass" : maxTurnP95Ms === undefined ? "fail" : "warn",
1851
+ surface: "turn-latency"
1852
+ });
1853
+ const status = issues.length > 0 ? "fail" : worstRecommendationStatus(recommendations);
1854
+ return {
1855
+ bestProvider,
1856
+ generatedAt: new Date().toISOString(),
1857
+ issues,
1858
+ ok: status !== "fail",
1859
+ providers,
1860
+ recommendations,
1861
+ source: report.source || report.outputDir || report.runId || "proof-trends",
1862
+ status,
1863
+ summary: {
1864
+ keepCurrentProviderPath: !providerSwitchRecommended && recommendations.find((item) => item.surface === "provider-path")?.status !== "fail",
1865
+ keepCurrentRuntimeChannel: recommendations.find((item) => item.surface === "runtime-channel")?.status === "pass",
1866
+ providerComparisonCount: providers.length,
1867
+ recommendedActions: recommendations.filter((item) => item.status !== "pass").length,
1868
+ switchRecommended: providerSwitchRecommended
1869
+ }
1870
+ };
1871
+ };
1872
+ var escapeHtml5 = (value) => String(value).replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
1873
+ var escapeMarkdown = (value) => value.replaceAll("|", "\\|");
1874
+ var renderVoiceProofTrendRecommendationMarkdown = (report, title = "Voice Provider Runtime Recommendations") => [
1875
+ `# ${title}`,
1876
+ "",
1877
+ `- Status: ${report.status}`,
1878
+ `- Source: ${report.source}`,
1879
+ `- Best provider: ${report.bestProvider?.label ?? report.bestProvider?.id ?? "n/a"}`,
1880
+ `- Provider comparisons: ${String(report.summary.providerComparisonCount)}`,
1881
+ `- Recommended actions: ${String(report.summary.recommendedActions)}`,
1882
+ "",
1883
+ "| Surface | Status | Recommendation | Next move |",
1884
+ "| --- | --- | --- | --- |",
1885
+ ...report.recommendations.map((recommendation) => `| ${escapeMarkdown(recommendation.surface)} | ${recommendation.status} | ${escapeMarkdown(recommendation.recommendation)} | ${escapeMarkdown(recommendation.nextMove)} |`),
1886
+ "",
1887
+ "## Provider Comparison",
1888
+ "",
1889
+ "| Rank | Provider | Role | Status | P95 | Samples | Next move |",
1890
+ "| ---: | --- | --- | --- | ---: | ---: | --- |",
1891
+ ...report.providers.length ? report.providers.map((provider) => `| ${String(provider.rank)} | ${escapeMarkdown(provider.label ?? provider.id)} | ${escapeMarkdown(provider.role ?? "n/a")} | ${provider.status} | ${provider.p95Ms === undefined ? "n/a" : String(provider.p95Ms)} | ${provider.samples === undefined ? "n/a" : String(provider.samples)} | ${escapeMarkdown(provider.nextMove)} |`) : ["| n/a | n/a | n/a | n/a | n/a | n/a | No provider-specific samples were present. |"],
1892
+ "",
1893
+ "## Issues",
1894
+ "",
1895
+ ...report.issues.length ? report.issues.map((issue) => `- ${issue}`) : ["- None"]
1896
+ ].join(`
1897
+ `);
1898
+ var renderVoiceProofTrendRecommendationHTML = (report, title = "Voice Provider Runtime Recommendations") => {
1899
+ 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
+ const issues = report.issues.length === 0 ? "<li>None</li>" : report.issues.map((issue) => `<li>${escapeHtml5(issue)}</li>`).join("");
1901
+ 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.bestProvider?.label ?? report.bestProvider?.id ?? "n/a")}</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
+ };
1904
+ var createVoiceProofTrendRecommendationRoutes = (options) => {
1905
+ const path = options.path ?? "/api/voice/proof-trend-recommendations";
1906
+ const htmlPath = options.htmlPath === undefined ? "/voice/proof-trend-recommendations" : options.htmlPath;
1907
+ const markdownPath = options.markdownPath === undefined ? "/voice/proof-trend-recommendations.md" : options.markdownPath;
1908
+ const title = options.title ?? "Voice Provider Runtime Recommendations";
1909
+ const routes = new Elysia({
1910
+ name: options.name ?? "absolutejs-voice-proof-trend-recommendations"
1911
+ });
1912
+ const loadReport = async () => {
1913
+ const value = options.source !== undefined ? typeof options.source === "function" ? await options.source() : options.source : options.jsonPath ? await readVoiceProofTrendReportFile(options.jsonPath, {
1914
+ maxAgeMs: options.maxAgeMs
1915
+ }) : buildEmptyVoiceProofTrendReport("", options.maxAgeMs);
1916
+ return buildVoiceProofTrendRecommendationReport(normalizeVoiceProofTrendReport(value, {
1917
+ maxAgeMs: options.maxAgeMs,
1918
+ source: options.jsonPath
1919
+ }), options);
1920
+ };
1921
+ routes.get(path, async () => Response.json(await loadReport(), { headers: options.headers }));
1922
+ if (htmlPath !== false) {
1923
+ routes.get(htmlPath, async () => {
1924
+ const report = await loadReport();
1925
+ return new Response(renderVoiceProofTrendRecommendationHTML(report, title), {
1926
+ headers: {
1927
+ "content-type": "text/html; charset=utf-8",
1928
+ ...Object.fromEntries(new Headers(options.headers))
1929
+ }
1930
+ });
1931
+ });
1932
+ }
1933
+ if (markdownPath !== false) {
1934
+ routes.get(markdownPath, async () => {
1935
+ const report = await loadReport();
1936
+ return new Response(renderVoiceProofTrendRecommendationMarkdown(report, title), {
1937
+ headers: {
1938
+ "content-type": "text/markdown; charset=utf-8",
1939
+ ...Object.fromEntries(new Headers(options.headers))
1940
+ }
1941
+ });
1942
+ });
1943
+ }
1944
+ return routes;
1945
+ };
1681
1946
  var createVoiceProofTrendRoutes = (options) => {
1682
1947
  const path = options.path ?? "/api/voice/proof-trends";
1683
1948
  const routes = new Elysia({
@@ -1720,7 +1985,7 @@ var DEFAULT_LINKS2 = [
1720
1985
  { href: "/voice/proof-trends", label: "Trend page" },
1721
1986
  { href: "/api/voice/proof-trends", label: "Trend JSON" }
1722
1987
  ];
1723
- var escapeHtml5 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
1988
+ var escapeHtml6 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
1724
1989
  var formatMs = (value) => typeof value === "number" && Number.isFinite(value) ? `${Math.round(value)}ms` : "n/a";
1725
1990
  var statusLabel = (report) => {
1726
1991
  if (!report) {
@@ -1770,19 +2035,19 @@ var createVoiceProofTrendsViewModel = (snapshot, options = {}) => {
1770
2035
  var renderVoiceProofTrendsHTML = (snapshot, options = {}) => {
1771
2036
  const model = createVoiceProofTrendsViewModel(snapshot, options);
1772
2037
  const metrics = model.metrics.length ? `<div class="absolute-voice-proof-trends__metrics">${model.metrics.map((metric) => `<article>
1773
- <span>${escapeHtml5(metric.label)}</span>
1774
- <strong>${escapeHtml5(metric.value)}</strong>
1775
- </article>`).join("")}</div>` : `<p class="absolute-voice-proof-trends__empty">${model.error ? escapeHtml5(model.error) : "Run the sustained proof trends script to populate evidence."}</p>`;
1776
- const links = model.links.length ? `<p class="absolute-voice-proof-trends__links">${model.links.map((link) => `<a href="${escapeHtml5(link.href)}">${escapeHtml5(link.label)}</a>`).join("")}</p>` : "";
1777
- return `<section class="absolute-voice-proof-trends absolute-voice-proof-trends--${escapeHtml5(model.status)}">
2038
+ <span>${escapeHtml6(metric.label)}</span>
2039
+ <strong>${escapeHtml6(metric.value)}</strong>
2040
+ </article>`).join("")}</div>` : `<p class="absolute-voice-proof-trends__empty">${model.error ? escapeHtml6(model.error) : "Run the sustained proof trends script to populate evidence."}</p>`;
2041
+ const links = model.links.length ? `<p class="absolute-voice-proof-trends__links">${model.links.map((link) => `<a href="${escapeHtml6(link.href)}">${escapeHtml6(link.label)}</a>`).join("")}</p>` : "";
2042
+ return `<section class="absolute-voice-proof-trends absolute-voice-proof-trends--${escapeHtml6(model.status)}">
1778
2043
  <header class="absolute-voice-proof-trends__header">
1779
- <span class="absolute-voice-proof-trends__eyebrow">${escapeHtml5(model.title)}</span>
1780
- <strong class="absolute-voice-proof-trends__label">${escapeHtml5(model.label)}</strong>
2044
+ <span class="absolute-voice-proof-trends__eyebrow">${escapeHtml6(model.title)}</span>
2045
+ <strong class="absolute-voice-proof-trends__label">${escapeHtml6(model.label)}</strong>
1781
2046
  </header>
1782
- <p class="absolute-voice-proof-trends__description">${escapeHtml5(model.description)}</p>
2047
+ <p class="absolute-voice-proof-trends__description">${escapeHtml6(model.description)}</p>
1783
2048
  ${metrics}
1784
2049
  ${links}
1785
- ${model.error ? `<p class="absolute-voice-proof-trends__error">${escapeHtml5(model.error)}</p>` : ""}
2050
+ ${model.error ? `<p class="absolute-voice-proof-trends__error">${escapeHtml6(model.error)}</p>` : ""}
1786
2051
  </section>`;
1787
2052
  };
1788
2053
  var getVoiceProofTrendsCSS = () => `.absolute-voice-proof-trends{border:1px solid #99f6e4;border-radius:20px;background:#f0fdfa;color:#0f172a;padding:18px;box-shadow:0 18px 40px rgba(13,148,136,.12);font-family:inherit}.absolute-voice-proof-trends--warning,.absolute-voice-proof-trends--error{border-color:#f2a7a7;background:#fff7f4}.absolute-voice-proof-trends__header{align-items:start;display:flex;gap:12px;justify-content:space-between}.absolute-voice-proof-trends__eyebrow{color:#0f766e;font-size:12px;font-weight:800;letter-spacing:.08em;text-transform:uppercase}.absolute-voice-proof-trends__label{font-size:24px;line-height:1}.absolute-voice-proof-trends__description,.absolute-voice-proof-trends__empty{color:#475569}.absolute-voice-proof-trends__metrics{display:grid;gap:10px;grid-template-columns:repeat(auto-fit,minmax(130px,1fr));margin-top:14px}.absolute-voice-proof-trends__metrics article{background:#fff;border:1px solid #ccfbf1;border-radius:16px;padding:12px}.absolute-voice-proof-trends__metrics span{color:#64748b;display:block;font-size:12px;font-weight:800;text-transform:uppercase}.absolute-voice-proof-trends__metrics strong{display:block;font-size:20px;margin-top:4px}.absolute-voice-proof-trends__links{display:flex;flex-wrap:wrap;gap:8px;margin:14px 0 0}.absolute-voice-proof-trends__links a{border:1px solid #99f6e4;border-radius:999px;color:#0f766e;font-weight:800;padding:6px 10px;text-decoration:none}.absolute-voice-proof-trends__error{color:#9f1239;font-weight:700}`;
@@ -1967,7 +2232,7 @@ var DEFAULT_LINKS3 = [
1967
2232
  { href: "/production-readiness", label: "Readiness page" },
1968
2233
  { href: "/voice/slo-readiness-thresholds", label: "Gate thresholds" }
1969
2234
  ];
1970
- var escapeHtml6 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
2235
+ var escapeHtml7 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
1971
2236
  var formatExplanationValue = (value, unit) => {
1972
2237
  if (value === undefined || value === null) {
1973
2238
  return "n/a";
@@ -2008,23 +2273,23 @@ var createVoiceReadinessFailuresViewModel = (snapshot, options = {}) => {
2008
2273
  };
2009
2274
  var renderVoiceReadinessFailuresHTML = (snapshot, options = {}) => {
2010
2275
  const model = createVoiceReadinessFailuresViewModel(snapshot, options);
2011
- const failures = model.failures.length ? `<div class="absolute-voice-readiness-failures__items">${model.failures.map((failure) => `<article class="absolute-voice-readiness-failures__item absolute-voice-readiness-failures__item--${escapeHtml6(failure.status)}">
2012
- <span>${escapeHtml6(failure.status.toUpperCase())}</span>
2013
- <strong>${escapeHtml6(failure.label)}</strong>
2014
- <p>Observed ${escapeHtml6(failure.observed)} against ${escapeHtml6(failure.thresholdLabel)} ${escapeHtml6(failure.threshold)}.</p>
2015
- <p>${escapeHtml6(failure.remediation)}</p>
2016
- <p class="absolute-voice-readiness-failures__links">${failure.evidenceHref ? `<a href="${escapeHtml6(failure.evidenceHref)}">Evidence</a>` : ""}${failure.sourceHref ? `<a href="${escapeHtml6(failure.sourceHref)}">Threshold source</a>` : ""}</p>
2017
- </article>`).join("")}</div>` : `<p class="absolute-voice-readiness-failures__empty">${model.error ? escapeHtml6(model.error) : "No calibrated readiness gate explanations are open."}</p>`;
2018
- const links = model.links.length ? `<p class="absolute-voice-readiness-failures__links">${model.links.map((link) => `<a href="${escapeHtml6(link.href)}">${escapeHtml6(link.label)}</a>`).join("")}</p>` : "";
2019
- return `<section class="absolute-voice-readiness-failures absolute-voice-readiness-failures--${escapeHtml6(model.status)}">
2276
+ const failures = model.failures.length ? `<div class="absolute-voice-readiness-failures__items">${model.failures.map((failure) => `<article class="absolute-voice-readiness-failures__item absolute-voice-readiness-failures__item--${escapeHtml7(failure.status)}">
2277
+ <span>${escapeHtml7(failure.status.toUpperCase())}</span>
2278
+ <strong>${escapeHtml7(failure.label)}</strong>
2279
+ <p>Observed ${escapeHtml7(failure.observed)} against ${escapeHtml7(failure.thresholdLabel)} ${escapeHtml7(failure.threshold)}.</p>
2280
+ <p>${escapeHtml7(failure.remediation)}</p>
2281
+ <p class="absolute-voice-readiness-failures__links">${failure.evidenceHref ? `<a href="${escapeHtml7(failure.evidenceHref)}">Evidence</a>` : ""}${failure.sourceHref ? `<a href="${escapeHtml7(failure.sourceHref)}">Threshold source</a>` : ""}</p>
2282
+ </article>`).join("")}</div>` : `<p class="absolute-voice-readiness-failures__empty">${model.error ? escapeHtml7(model.error) : "No calibrated readiness gate explanations are open."}</p>`;
2283
+ const links = model.links.length ? `<p class="absolute-voice-readiness-failures__links">${model.links.map((link) => `<a href="${escapeHtml7(link.href)}">${escapeHtml7(link.label)}</a>`).join("")}</p>` : "";
2284
+ return `<section class="absolute-voice-readiness-failures absolute-voice-readiness-failures--${escapeHtml7(model.status)}">
2020
2285
  <header class="absolute-voice-readiness-failures__header">
2021
- <span class="absolute-voice-readiness-failures__eyebrow">${escapeHtml6(model.title)}</span>
2022
- <strong class="absolute-voice-readiness-failures__label">${escapeHtml6(model.label)}</strong>
2286
+ <span class="absolute-voice-readiness-failures__eyebrow">${escapeHtml7(model.title)}</span>
2287
+ <strong class="absolute-voice-readiness-failures__label">${escapeHtml7(model.label)}</strong>
2023
2288
  </header>
2024
- <p class="absolute-voice-readiness-failures__description">${escapeHtml6(model.description)}</p>
2289
+ <p class="absolute-voice-readiness-failures__description">${escapeHtml7(model.description)}</p>
2025
2290
  ${failures}
2026
2291
  ${links}
2027
- ${model.error ? `<p class="absolute-voice-readiness-failures__error">${escapeHtml6(model.error)}</p>` : ""}
2292
+ ${model.error ? `<p class="absolute-voice-readiness-failures__error">${escapeHtml7(model.error)}</p>` : ""}
2028
2293
  </section>`;
2029
2294
  };
2030
2295
  var getVoiceReadinessFailuresCSS = () => `.absolute-voice-readiness-failures{border:1px solid #fed7aa;border-radius:20px;background:#fff7ed;color:#1c1917;padding:18px;box-shadow:0 18px 40px rgba(234,88,12,.12);font-family:inherit}.absolute-voice-readiness-failures--ready{border-color:#86efac;background:#f0fdf4}.absolute-voice-readiness-failures--error{border-color:#fda4af;background:#fff1f2}.absolute-voice-readiness-failures__header{align-items:start;display:flex;gap:12px;justify-content:space-between}.absolute-voice-readiness-failures__eyebrow{color:#9a3412;font-size:12px;font-weight:800;letter-spacing:.08em;text-transform:uppercase}.absolute-voice-readiness-failures__label{font-size:24px;line-height:1}.absolute-voice-readiness-failures__description,.absolute-voice-readiness-failures__empty{color:#57534e}.absolute-voice-readiness-failures__items{display:grid;gap:10px;margin-top:14px}.absolute-voice-readiness-failures__item{background:white;border:1px solid #fed7aa;border-radius:16px;padding:12px}.absolute-voice-readiness-failures__item--fail{border-color:#fb7185}.absolute-voice-readiness-failures__item span{color:#9a3412;display:block;font-size:12px;font-weight:900;text-transform:uppercase}.absolute-voice-readiness-failures__item strong{display:block;font-size:18px;margin-top:4px}.absolute-voice-readiness-failures__item p{margin:.45rem 0 0}.absolute-voice-readiness-failures__links{display:flex;flex-wrap:wrap;gap:8px;margin:14px 0 0}.absolute-voice-readiness-failures__links a{border:1px solid #fdba74;border-radius:999px;color:#9a3412;font-weight:800;padding:6px 10px;text-decoration:none}.absolute-voice-readiness-failures__error{color:#9f1239;font-weight:700}`;
@@ -2253,7 +2518,7 @@ var createVoiceProviderSimulationControlsStore = (options) => {
2253
2518
  };
2254
2519
 
2255
2520
  // src/client/providerSimulationControlsWidget.ts
2256
- var escapeHtml7 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
2521
+ var escapeHtml8 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
2257
2522
  var formatKind = (kind) => (kind ?? "stt").toUpperCase();
2258
2523
  var createVoiceProviderSimulationControlsViewModel = (snapshot, options) => {
2259
2524
  const configuredProviders = options.providers.filter((provider) => provider.configured !== false);
@@ -2273,18 +2538,18 @@ var createVoiceProviderSimulationControlsViewModel = (snapshot, options) => {
2273
2538
  };
2274
2539
  var renderVoiceProviderSimulationControlsHTML = (snapshot, options) => {
2275
2540
  const model = createVoiceProviderSimulationControlsViewModel(snapshot, options);
2276
- const failureButtons = model.failureProviders.map((provider) => `<button type="button" data-voice-provider-fail="${escapeHtml7(provider.provider)}"${!model.canSimulateFailure || snapshot.isRunning ? " disabled" : ""}>Simulate ${escapeHtml7(provider.provider)} ${escapeHtml7(formatKind(options.kind))} failure</button>`).join("");
2277
- const recoveryButtons = model.providers.map((provider) => `<button type="button" data-voice-provider-recover="${escapeHtml7(provider.provider)}"${snapshot.isRunning ? " disabled" : ""}>Mark ${escapeHtml7(provider.provider)} recovered</button>`).join("");
2541
+ const failureButtons = model.failureProviders.map((provider) => `<button type="button" data-voice-provider-fail="${escapeHtml8(provider.provider)}"${!model.canSimulateFailure || snapshot.isRunning ? " disabled" : ""}>Simulate ${escapeHtml8(provider.provider)} ${escapeHtml8(formatKind(options.kind))} failure</button>`).join("");
2542
+ const recoveryButtons = model.providers.map((provider) => `<button type="button" data-voice-provider-recover="${escapeHtml8(provider.provider)}"${snapshot.isRunning ? " disabled" : ""}>Mark ${escapeHtml8(provider.provider)} recovered</button>`).join("");
2278
2543
  return `<section class="absolute-voice-provider-simulation absolute-voice-provider-simulation--${snapshot.error ? "error" : snapshot.isRunning ? "running" : "ready"}">
2279
2544
  <header class="absolute-voice-provider-simulation__header">
2280
- <span class="absolute-voice-provider-simulation__eyebrow">${escapeHtml7(model.title)}</span>
2281
- <strong class="absolute-voice-provider-simulation__label">${escapeHtml7(model.label)}</strong>
2545
+ <span class="absolute-voice-provider-simulation__eyebrow">${escapeHtml8(model.title)}</span>
2546
+ <strong class="absolute-voice-provider-simulation__label">${escapeHtml8(model.label)}</strong>
2282
2547
  </header>
2283
- <p class="absolute-voice-provider-simulation__description">${escapeHtml7(model.description)}</p>
2284
- ${model.canSimulateFailure ? "" : `<p class="absolute-voice-provider-simulation__empty">${escapeHtml7(options.fallbackRequiredMessage ?? "Configure fallback providers before simulating failure.")}</p>`}
2548
+ <p class="absolute-voice-provider-simulation__description">${escapeHtml8(model.description)}</p>
2549
+ ${model.canSimulateFailure ? "" : `<p class="absolute-voice-provider-simulation__empty">${escapeHtml8(options.fallbackRequiredMessage ?? "Configure fallback providers before simulating failure.")}</p>`}
2285
2550
  <div class="absolute-voice-provider-simulation__actions">${failureButtons}${recoveryButtons}</div>
2286
- ${snapshot.error ? `<p class="absolute-voice-provider-simulation__error">${escapeHtml7(snapshot.error)}</p>` : ""}
2287
- ${model.resultText ? `<pre class="absolute-voice-provider-simulation__result">${escapeHtml7(model.resultText)}</pre>` : ""}
2551
+ ${snapshot.error ? `<p class="absolute-voice-provider-simulation__error">${escapeHtml8(snapshot.error)}</p>` : ""}
2552
+ ${model.resultText ? `<pre class="absolute-voice-provider-simulation__result">${escapeHtml8(model.resultText)}</pre>` : ""}
2288
2553
  </section>`;
2289
2554
  };
2290
2555
  var bindVoiceProviderSimulationControls = (element, store) => {
@@ -2544,7 +2809,7 @@ var useVoiceProviderCapabilities = (path = "/api/provider-capabilities", options
2544
2809
  // src/client/providerCapabilitiesWidget.ts
2545
2810
  var DEFAULT_TITLE7 = "Provider Capabilities";
2546
2811
  var DEFAULT_DESCRIPTION7 = "Configured, selected, and healthy voice providers for this deployment.";
2547
- var escapeHtml8 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
2812
+ var escapeHtml9 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
2548
2813
  var formatProvider = (provider) => provider.split(/[-_\s]+/).filter(Boolean).map((part) => `${part[0]?.toUpperCase() ?? ""}${part.slice(1)}`).join(" ") || provider;
2549
2814
  var formatKind2 = (kind) => kind.toUpperCase();
2550
2815
  var formatStatus2 = (status) => status.split("-").map((part) => `${part[0]?.toUpperCase() ?? ""}${part.slice(1)}`).join(" ");
@@ -2599,25 +2864,25 @@ var createVoiceProviderCapabilitiesViewModel = (snapshot, options = {}) => {
2599
2864
  };
2600
2865
  var renderVoiceProviderCapabilitiesHTML = (snapshot, options = {}) => {
2601
2866
  const model = createVoiceProviderCapabilitiesViewModel(snapshot, options);
2602
- const capabilities = model.capabilities.length ? `<div class="absolute-voice-provider-capabilities__providers">${model.capabilities.map((capability) => `<article class="absolute-voice-provider-capabilities__provider absolute-voice-provider-capabilities__provider--${escapeHtml8(capability.status)}">
2867
+ const capabilities = model.capabilities.length ? `<div class="absolute-voice-provider-capabilities__providers">${model.capabilities.map((capability) => `<article class="absolute-voice-provider-capabilities__provider absolute-voice-provider-capabilities__provider--${escapeHtml9(capability.status)}">
2603
2868
  <header>
2604
- <strong>${escapeHtml8(capability.label)}</strong>
2605
- <span>${escapeHtml8(formatStatus2(capability.status))}</span>
2869
+ <strong>${escapeHtml9(capability.label)}</strong>
2870
+ <span>${escapeHtml9(formatStatus2(capability.status))}</span>
2606
2871
  </header>
2607
- <p>${escapeHtml8(capability.detail)}</p>
2872
+ <p>${escapeHtml9(capability.detail)}</p>
2608
2873
  <dl>${capability.rows.map((row) => `<div>
2609
- <dt>${escapeHtml8(row.label)}</dt>
2610
- <dd>${escapeHtml8(row.value)}</dd>
2874
+ <dt>${escapeHtml9(row.label)}</dt>
2875
+ <dd>${escapeHtml9(row.value)}</dd>
2611
2876
  </div>`).join("")}</dl>
2612
2877
  </article>`).join("")}</div>` : '<p class="absolute-voice-provider-capabilities__empty">Configure provider capabilities to see deployment coverage.</p>';
2613
- return `<section class="absolute-voice-provider-capabilities absolute-voice-provider-capabilities--${escapeHtml8(model.status)}">
2878
+ return `<section class="absolute-voice-provider-capabilities absolute-voice-provider-capabilities--${escapeHtml9(model.status)}">
2614
2879
  <header class="absolute-voice-provider-capabilities__header">
2615
- <span class="absolute-voice-provider-capabilities__eyebrow">${escapeHtml8(model.title)}</span>
2616
- <strong class="absolute-voice-provider-capabilities__label">${escapeHtml8(model.label)}</strong>
2880
+ <span class="absolute-voice-provider-capabilities__eyebrow">${escapeHtml9(model.title)}</span>
2881
+ <strong class="absolute-voice-provider-capabilities__label">${escapeHtml9(model.label)}</strong>
2617
2882
  </header>
2618
- <p class="absolute-voice-provider-capabilities__description">${escapeHtml8(model.description)}</p>
2883
+ <p class="absolute-voice-provider-capabilities__description">${escapeHtml9(model.description)}</p>
2619
2884
  ${capabilities}
2620
- ${model.error ? `<p class="absolute-voice-provider-capabilities__error">${escapeHtml8(model.error)}</p>` : ""}
2885
+ ${model.error ? `<p class="absolute-voice-provider-capabilities__error">${escapeHtml9(model.error)}</p>` : ""}
2621
2886
  </section>`;
2622
2887
  };
2623
2888
  var getVoiceProviderCapabilitiesCSS = () => `.absolute-voice-provider-capabilities{border:1px solid #bfd7ea;border-radius:20px;background:#f6fbff;color:#08131f;padding:18px;box-shadow:0 18px 40px rgba(14,51,78,.12);font-family:inherit}.absolute-voice-provider-capabilities--error,.absolute-voice-provider-capabilities--warning{border-color:#f2a7a7;background:#fff5f3}.absolute-voice-provider-capabilities__header,.absolute-voice-provider-capabilities__provider header{align-items:start;display:flex;gap:12px;justify-content:space-between}.absolute-voice-provider-capabilities__eyebrow{color:#255f85;font-size:12px;font-weight:800;letter-spacing:.08em;text-transform:uppercase}.absolute-voice-provider-capabilities__label{font-size:24px;line-height:1}.absolute-voice-provider-capabilities__description,.absolute-voice-provider-capabilities__provider p,.absolute-voice-provider-capabilities__provider dt,.absolute-voice-provider-capabilities__empty{color:#405467}.absolute-voice-provider-capabilities__providers{display:grid;gap:12px;margin-top:14px}.absolute-voice-provider-capabilities__provider{background:#fff;border:1px solid #d7e7f3;border-radius:16px;padding:14px}.absolute-voice-provider-capabilities__provider--selected,.absolute-voice-provider-capabilities__provider--healthy{border-color:#86efac}.absolute-voice-provider-capabilities__provider--degraded,.absolute-voice-provider-capabilities__provider--rate-limited,.absolute-voice-provider-capabilities__provider--suppressed,.absolute-voice-provider-capabilities__provider--unconfigured{border-color:#f2a7a7}.absolute-voice-provider-capabilities__provider p{margin:10px 0}.absolute-voice-provider-capabilities__provider dl{display:grid;gap:8px;grid-template-columns:repeat(2,minmax(0,1fr));margin:0}.absolute-voice-provider-capabilities__provider div{background:#f6fbff;border:1px solid #d7e7f3;border-radius:12px;padding:8px}.absolute-voice-provider-capabilities__provider dt{font-size:12px}.absolute-voice-provider-capabilities__provider dd{font-weight:800;margin:4px 0 0}.absolute-voice-provider-capabilities__empty{margin:14px 0 0}.absolute-voice-provider-capabilities__error{color:#9f1239;font-weight:700}`;
@@ -2835,7 +3100,7 @@ var useVoiceProviderContracts = (path = "/api/provider-contracts", options = {})
2835
3100
  // src/client/providerContractsWidget.ts
2836
3101
  var DEFAULT_TITLE8 = "Provider Contracts";
2837
3102
  var DEFAULT_DESCRIPTION8 = "Production contract coverage for provider env, latency, fallback, streaming, and capabilities.";
2838
- var escapeHtml9 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
3103
+ var escapeHtml10 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
2839
3104
  var formatProvider2 = (provider) => provider.split(/[-_\s]+/).filter(Boolean).map((part) => `${part[0]?.toUpperCase() ?? ""}${part.slice(1)}`).join(" ") || provider;
2840
3105
  var formatStatus3 = (status) => status.split("-").map((part) => `${part[0]?.toUpperCase() ?? ""}${part.slice(1)}`).join(" ");
2841
3106
  var contractDetail = (row) => {
@@ -2879,26 +3144,26 @@ var createVoiceProviderContractsViewModel = (snapshot, options = {}) => {
2879
3144
  };
2880
3145
  var renderVoiceProviderContractsHTML = (snapshot, options = {}) => {
2881
3146
  const model = createVoiceProviderContractsViewModel(snapshot, options);
2882
- const rows = model.rows.length ? `<div class="absolute-voice-provider-contracts__rows">${model.rows.map((row) => `<article class="absolute-voice-provider-contracts__row absolute-voice-provider-contracts__row--${escapeHtml9(row.status)}">
3147
+ const rows = model.rows.length ? `<div class="absolute-voice-provider-contracts__rows">${model.rows.map((row) => `<article class="absolute-voice-provider-contracts__row absolute-voice-provider-contracts__row--${escapeHtml10(row.status)}">
2883
3148
  <header>
2884
- <strong>${escapeHtml9(row.label)}</strong>
2885
- <span>${escapeHtml9(formatStatus3(row.status))}</span>
3149
+ <strong>${escapeHtml10(row.label)}</strong>
3150
+ <span>${escapeHtml10(formatStatus3(row.status))}</span>
2886
3151
  </header>
2887
- <p>${escapeHtml9(row.detail)}</p>
2888
- ${row.remediations.length ? `<ul class="absolute-voice-provider-contracts__remediations">${row.remediations.map((remediation) => `<li>${remediation.href ? `<a href="${escapeHtml9(remediation.href)}">${escapeHtml9(remediation.label)}</a>` : `<strong>${escapeHtml9(remediation.label)}</strong>`}<span>${escapeHtml9(remediation.detail)}</span></li>`).join("")}</ul>` : ""}
3152
+ <p>${escapeHtml10(row.detail)}</p>
3153
+ ${row.remediations.length ? `<ul class="absolute-voice-provider-contracts__remediations">${row.remediations.map((remediation) => `<li>${remediation.href ? `<a href="${escapeHtml10(remediation.href)}">${escapeHtml10(remediation.label)}</a>` : `<strong>${escapeHtml10(remediation.label)}</strong>`}<span>${escapeHtml10(remediation.detail)}</span></li>`).join("")}</ul>` : ""}
2889
3154
  <dl>${row.rows.map((item) => `<div>
2890
- <dt>${escapeHtml9(item.label)}</dt>
2891
- <dd>${escapeHtml9(item.value)}</dd>
3155
+ <dt>${escapeHtml10(item.label)}</dt>
3156
+ <dd>${escapeHtml10(item.value)}</dd>
2892
3157
  </div>`).join("")}</dl>
2893
3158
  </article>`).join("")}</div>` : '<p class="absolute-voice-provider-contracts__empty">Configure provider contracts to see production coverage.</p>';
2894
- return `<section class="absolute-voice-provider-contracts absolute-voice-provider-contracts--${escapeHtml9(model.status)}">
3159
+ return `<section class="absolute-voice-provider-contracts absolute-voice-provider-contracts--${escapeHtml10(model.status)}">
2895
3160
  <header class="absolute-voice-provider-contracts__header">
2896
- <span class="absolute-voice-provider-contracts__eyebrow">${escapeHtml9(model.title)}</span>
2897
- <strong class="absolute-voice-provider-contracts__label">${escapeHtml9(model.label)}</strong>
3161
+ <span class="absolute-voice-provider-contracts__eyebrow">${escapeHtml10(model.title)}</span>
3162
+ <strong class="absolute-voice-provider-contracts__label">${escapeHtml10(model.label)}</strong>
2898
3163
  </header>
2899
- <p class="absolute-voice-provider-contracts__description">${escapeHtml9(model.description)}</p>
3164
+ <p class="absolute-voice-provider-contracts__description">${escapeHtml10(model.description)}</p>
2900
3165
  ${rows}
2901
- ${model.error ? `<p class="absolute-voice-provider-contracts__error">${escapeHtml9(model.error)}</p>` : ""}
3166
+ ${model.error ? `<p class="absolute-voice-provider-contracts__error">${escapeHtml10(model.error)}</p>` : ""}
2902
3167
  </section>`;
2903
3168
  };
2904
3169
  var getVoiceProviderContractsCSS = () => `.absolute-voice-provider-contracts{border:1px solid #b8dcc7;border-radius:20px;background:#f7fff9;color:#09140d;padding:18px;box-shadow:0 18px 40px rgba(21,83,45,.12);font-family:inherit}.absolute-voice-provider-contracts--error,.absolute-voice-provider-contracts--warning{border-color:#f2a7a7;background:#fff7f4}.absolute-voice-provider-contracts__header,.absolute-voice-provider-contracts__row header{align-items:start;display:flex;gap:12px;justify-content:space-between}.absolute-voice-provider-contracts__eyebrow{color:#166534;font-size:12px;font-weight:800;letter-spacing:.08em;text-transform:uppercase}.absolute-voice-provider-contracts__label{font-size:24px;line-height:1}.absolute-voice-provider-contracts__description,.absolute-voice-provider-contracts__row p,.absolute-voice-provider-contracts__row dt,.absolute-voice-provider-contracts__empty{color:#405448}.absolute-voice-provider-contracts__rows{display:grid;gap:12px;margin-top:14px}.absolute-voice-provider-contracts__row{background:#fff;border:1px solid #d6eadb;border-radius:16px;padding:14px}.absolute-voice-provider-contracts__row--pass{border-color:#86efac}.absolute-voice-provider-contracts__row--warn,.absolute-voice-provider-contracts__row--fail{border-color:#f2a7a7}.absolute-voice-provider-contracts__row p{margin:10px 0}.absolute-voice-provider-contracts__remediations{display:grid;gap:8px;list-style:none;margin:0 0 10px;padding:0}.absolute-voice-provider-contracts__remediations li{background:#fff7ed;border:1px solid #fed7aa;border-radius:12px;display:grid;gap:3px;padding:8px}.absolute-voice-provider-contracts__remediations a,.absolute-voice-provider-contracts__remediations strong{color:#9a3412}.absolute-voice-provider-contracts__remediations span{color:#7c2d12}.absolute-voice-provider-contracts__row dl{display:grid;gap:8px;grid-template-columns:repeat(2,minmax(0,1fr));margin:0}.absolute-voice-provider-contracts__row div{background:#f7fff9;border:1px solid #d6eadb;border-radius:12px;padding:8px}.absolute-voice-provider-contracts__row dt{font-size:12px}.absolute-voice-provider-contracts__row dd{font-weight:800;margin:4px 0 0}.absolute-voice-provider-contracts__error{color:#9f1239;font-weight:700}`;
@@ -3137,7 +3402,7 @@ var useVoiceProviderStatus = (path = "/api/provider-status", options = {}) => {
3137
3402
  // src/client/providerStatusWidget.ts
3138
3403
  var DEFAULT_TITLE9 = "Voice Providers";
3139
3404
  var DEFAULT_DESCRIPTION9 = "Live provider health, fallback counts, latency, and suppression state from your self-hosted trace store.";
3140
- var escapeHtml10 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
3405
+ var escapeHtml11 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
3141
3406
  var formatProvider3 = (provider) => provider.split(/[-_\s]+/).filter(Boolean).map((part) => `${part[0]?.toUpperCase() ?? ""}${part.slice(1)}`).join(" ") || provider;
3142
3407
  var formatStatus4 = (status) => status.split("-").map((part) => `${part[0]?.toUpperCase() ?? ""}${part.slice(1)}`).join(" ");
3143
3408
  var formatLatency = (value) => typeof value === "number" ? `${value}ms` : "No samples";
@@ -3193,25 +3458,25 @@ var createVoiceProviderStatusViewModel = (snapshot, options = {}) => {
3193
3458
  };
3194
3459
  var renderVoiceProviderStatusHTML = (snapshot, options = {}) => {
3195
3460
  const model = createVoiceProviderStatusViewModel(snapshot, options);
3196
- const providers = model.providers.length ? `<div class="absolute-voice-provider-status__providers">${model.providers.map((provider) => `<article class="absolute-voice-provider-status__provider absolute-voice-provider-status__provider--${escapeHtml10(provider.status)}">
3461
+ const providers = model.providers.length ? `<div class="absolute-voice-provider-status__providers">${model.providers.map((provider) => `<article class="absolute-voice-provider-status__provider absolute-voice-provider-status__provider--${escapeHtml11(provider.status)}">
3197
3462
  <header>
3198
- <strong>${escapeHtml10(provider.label)}</strong>
3199
- <span>${escapeHtml10(formatStatus4(provider.status))}</span>
3463
+ <strong>${escapeHtml11(provider.label)}</strong>
3464
+ <span>${escapeHtml11(formatStatus4(provider.status))}</span>
3200
3465
  </header>
3201
- <p>${escapeHtml10(provider.detail)}</p>
3466
+ <p>${escapeHtml11(provider.detail)}</p>
3202
3467
  <dl>${provider.rows.map((row) => `<div>
3203
- <dt>${escapeHtml10(row.label)}</dt>
3204
- <dd>${escapeHtml10(row.value)}</dd>
3468
+ <dt>${escapeHtml11(row.label)}</dt>
3469
+ <dd>${escapeHtml11(row.value)}</dd>
3205
3470
  </div>`).join("")}</dl>
3206
3471
  </article>`).join("")}</div>` : '<p class="absolute-voice-provider-status__empty">Run voice traffic to see provider health.</p>';
3207
- return `<section class="absolute-voice-provider-status absolute-voice-provider-status--${escapeHtml10(model.status)}">
3472
+ return `<section class="absolute-voice-provider-status absolute-voice-provider-status--${escapeHtml11(model.status)}">
3208
3473
  <header class="absolute-voice-provider-status__header">
3209
- <span class="absolute-voice-provider-status__eyebrow">${escapeHtml10(model.title)}</span>
3210
- <strong class="absolute-voice-provider-status__label">${escapeHtml10(model.label)}</strong>
3474
+ <span class="absolute-voice-provider-status__eyebrow">${escapeHtml11(model.title)}</span>
3475
+ <strong class="absolute-voice-provider-status__label">${escapeHtml11(model.label)}</strong>
3211
3476
  </header>
3212
- <p class="absolute-voice-provider-status__description">${escapeHtml10(model.description)}</p>
3477
+ <p class="absolute-voice-provider-status__description">${escapeHtml11(model.description)}</p>
3213
3478
  ${providers}
3214
- ${model.error ? `<p class="absolute-voice-provider-status__error">${escapeHtml10(model.error)}</p>` : ""}
3479
+ ${model.error ? `<p class="absolute-voice-provider-status__error">${escapeHtml11(model.error)}</p>` : ""}
3215
3480
  </section>`;
3216
3481
  };
3217
3482
  var getVoiceProviderStatusCSS = () => `.absolute-voice-provider-status{border:1px solid #d8d2c4;border-radius:20px;background:#fffaf0;color:#16130d;padding:18px;box-shadow:0 18px 40px rgba(47,37,18,.12);font-family:inherit}.absolute-voice-provider-status--error,.absolute-voice-provider-status--warning{border-color:#f2a7a7;background:#fff5f3}.absolute-voice-provider-status__header,.absolute-voice-provider-status__provider header{align-items:start;display:flex;gap:12px;justify-content:space-between}.absolute-voice-provider-status__eyebrow{color:#73664f;font-size:12px;font-weight:800;letter-spacing:.08em;text-transform:uppercase}.absolute-voice-provider-status__label{font-size:24px;line-height:1}.absolute-voice-provider-status__description,.absolute-voice-provider-status__provider p,.absolute-voice-provider-status__provider dt,.absolute-voice-provider-status__empty{color:#514733}.absolute-voice-provider-status__providers{display:grid;gap:12px;margin-top:14px}.absolute-voice-provider-status__provider{background:#fff;border:1px solid #eee4d2;border-radius:16px;padding:14px}.absolute-voice-provider-status__provider--degraded,.absolute-voice-provider-status__provider--rate-limited,.absolute-voice-provider-status__provider--suppressed{border-color:#f2a7a7}.absolute-voice-provider-status__provider--recoverable{border-color:#fbbf24}.absolute-voice-provider-status__provider p{margin:10px 0}.absolute-voice-provider-status__provider dl{display:grid;gap:8px;grid-template-columns:repeat(2,minmax(0,1fr));margin:0}.absolute-voice-provider-status__provider div{background:#fffaf0;border:1px solid #eee4d2;border-radius:12px;padding:8px}.absolute-voice-provider-status__provider dt{font-size:12px}.absolute-voice-provider-status__provider dd{font-weight:800;margin:4px 0 0}.absolute-voice-provider-status__empty{margin:14px 0 0}.absolute-voice-provider-status__error{color:#9f1239;font-weight:700}`;
@@ -3434,7 +3699,7 @@ var useVoiceRoutingStatus = (path = "/api/routing/latest", options = {}) => {
3434
3699
  // src/client/routingStatusWidget.ts
3435
3700
  var DEFAULT_TITLE10 = "Voice Routing";
3436
3701
  var DEFAULT_DESCRIPTION10 = "Latest provider routing decision from the self-hosted trace store.";
3437
- var escapeHtml11 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
3702
+ var escapeHtml12 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
3438
3703
  var formatValue = (value, fallback = "None") => typeof value === "string" && value.trim() ? value : typeof value === "number" && Number.isFinite(value) ? String(value) : fallback;
3439
3704
  var createVoiceRoutingStatusViewModel = (snapshot, options = {}) => {
3440
3705
  const decision = snapshot.decision;
@@ -3471,17 +3736,17 @@ var createVoiceRoutingStatusViewModel = (snapshot, options = {}) => {
3471
3736
  var renderVoiceRoutingStatusHTML = (snapshot, options = {}) => {
3472
3737
  const model = createVoiceRoutingStatusViewModel(snapshot, options);
3473
3738
  const rows = model.rows.length ? `<div class="absolute-voice-routing-status__grid">${model.rows.map((row) => `<div>
3474
- <span>${escapeHtml11(row.label)}</span>
3475
- <strong>${escapeHtml11(row.value)}</strong>
3739
+ <span>${escapeHtml12(row.label)}</span>
3740
+ <strong>${escapeHtml12(row.value)}</strong>
3476
3741
  </div>`).join("")}</div>` : '<p class="absolute-voice-routing-status__empty">Start a voice session to see the selected provider.</p>';
3477
- return `<section class="absolute-voice-routing-status absolute-voice-routing-status--${escapeHtml11(model.status)}">
3742
+ return `<section class="absolute-voice-routing-status absolute-voice-routing-status--${escapeHtml12(model.status)}">
3478
3743
  <header class="absolute-voice-routing-status__header">
3479
- <span class="absolute-voice-routing-status__eyebrow">${escapeHtml11(model.title)}</span>
3480
- <strong class="absolute-voice-routing-status__label">${escapeHtml11(model.label)}</strong>
3744
+ <span class="absolute-voice-routing-status__eyebrow">${escapeHtml12(model.title)}</span>
3745
+ <strong class="absolute-voice-routing-status__label">${escapeHtml12(model.label)}</strong>
3481
3746
  </header>
3482
- <p class="absolute-voice-routing-status__description">${escapeHtml11(model.description)}</p>
3747
+ <p class="absolute-voice-routing-status__description">${escapeHtml12(model.description)}</p>
3483
3748
  ${rows}
3484
- ${model.error ? `<p class="absolute-voice-routing-status__error">${escapeHtml11(model.error)}</p>` : ""}
3749
+ ${model.error ? `<p class="absolute-voice-routing-status__error">${escapeHtml12(model.error)}</p>` : ""}
3485
3750
  </section>`;
3486
3751
  };
3487
3752
  var getVoiceRoutingStatusCSS = () => `.absolute-voice-routing-status{border:1px solid #d8d2c4;border-radius:20px;background:#fffaf0;color:#16130d;padding:18px;box-shadow:0 18px 40px rgba(47,37,18,.12);font-family:inherit}.absolute-voice-routing-status--error{border-color:#f2a7a7;background:#fff5f3}.absolute-voice-routing-status__header{align-items:start;display:flex;gap:12px;justify-content:space-between}.absolute-voice-routing-status__eyebrow{color:#73664f;font-size:12px;font-weight:800;letter-spacing:.08em;text-transform:uppercase}.absolute-voice-routing-status__label{font-size:24px;line-height:1}.absolute-voice-routing-status__description{color:#514733;margin:12px 0 0}.absolute-voice-routing-status__grid{display:grid;gap:8px;grid-template-columns:repeat(2,minmax(0,1fr));margin-top:14px}.absolute-voice-routing-status__grid div{background:#fff;border:1px solid #eee4d2;border-radius:14px;padding:10px 12px}.absolute-voice-routing-status__grid span{color:#655944;display:block;font-size:12px;margin-bottom:4px}.absolute-voice-routing-status__grid strong{overflow-wrap:anywhere}.absolute-voice-routing-status__empty{color:#655944;margin:14px 0 0}.absolute-voice-routing-status__error{color:#9f1239;font-weight:700}`;
@@ -3661,7 +3926,7 @@ var createVoiceTraceTimelineStore = (path = "/api/voice-traces", options = {}) =
3661
3926
  // src/client/traceTimelineWidget.ts
3662
3927
  var DEFAULT_TITLE11 = "Voice Traces";
3663
3928
  var DEFAULT_DESCRIPTION11 = "Latest call timelines with provider latency, fallbacks, handoffs, and errors from your self-hosted trace store.";
3664
- var escapeHtml12 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
3929
+ var escapeHtml13 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
3665
3930
  var formatMs2 = (value) => typeof value === "number" ? `${value}ms` : "n/a";
3666
3931
  var formatProviders = (session) => session.providers.length ? session.providers.map((provider) => provider.provider).join(", ") : "No providers";
3667
3932
  var createVoiceTraceTimelineViewModel = (snapshot, options = {}) => {
@@ -3691,27 +3956,27 @@ var renderVoiceTraceTimelineWidgetHTML = (snapshot, options = {}) => {
3691
3956
  const model = createVoiceTraceTimelineViewModel(snapshot, options);
3692
3957
  const sessions = model.sessions.length ? `<div class="absolute-voice-trace-timeline__sessions">${model.sessions.map((session) => {
3693
3958
  const supportLinks = [
3694
- `<a href="${escapeHtml12(session.detailHref)}">Open timeline</a>`,
3695
- session.operationsRecordHref ? `<a href="${escapeHtml12(session.operationsRecordHref)}">Open operations record</a>` : undefined,
3696
- session.incidentBundleHref ? `<a href="${escapeHtml12(session.incidentBundleHref)}">Export incident bundle</a>` : undefined
3959
+ `<a href="${escapeHtml13(session.detailHref)}">Open timeline</a>`,
3960
+ session.operationsRecordHref ? `<a href="${escapeHtml13(session.operationsRecordHref)}">Open operations record</a>` : undefined,
3961
+ session.incidentBundleHref ? `<a href="${escapeHtml13(session.incidentBundleHref)}">Export incident bundle</a>` : undefined
3697
3962
  ].filter(Boolean).join("");
3698
- return `<article class="absolute-voice-trace-timeline__session absolute-voice-trace-timeline__session--${escapeHtml12(session.status)}">
3963
+ return `<article class="absolute-voice-trace-timeline__session absolute-voice-trace-timeline__session--${escapeHtml13(session.status)}">
3699
3964
  <header>
3700
- <strong>${escapeHtml12(session.sessionId)}</strong>
3701
- <span>${escapeHtml12(session.status)}</span>
3965
+ <strong>${escapeHtml13(session.sessionId)}</strong>
3966
+ <span>${escapeHtml13(session.status)}</span>
3702
3967
  </header>
3703
- <p>${escapeHtml12(session.label)} \xB7 ${escapeHtml12(session.durationLabel)} \xB7 ${escapeHtml12(session.providerLabel)}</p>
3968
+ <p>${escapeHtml13(session.label)} \xB7 ${escapeHtml13(session.durationLabel)} \xB7 ${escapeHtml13(session.providerLabel)}</p>
3704
3969
  <p class="absolute-voice-trace-timeline__actions">${supportLinks}</p>
3705
3970
  </article>`;
3706
3971
  }).join("")}</div>` : '<p class="absolute-voice-trace-timeline__empty">Run a voice session to see call timelines.</p>';
3707
- return `<section class="absolute-voice-trace-timeline absolute-voice-trace-timeline--${escapeHtml12(model.status)}">
3972
+ return `<section class="absolute-voice-trace-timeline absolute-voice-trace-timeline--${escapeHtml13(model.status)}">
3708
3973
  <header class="absolute-voice-trace-timeline__header">
3709
- <span class="absolute-voice-trace-timeline__eyebrow">${escapeHtml12(model.title)}</span>
3710
- <strong class="absolute-voice-trace-timeline__label">${escapeHtml12(model.label)}</strong>
3974
+ <span class="absolute-voice-trace-timeline__eyebrow">${escapeHtml13(model.title)}</span>
3975
+ <strong class="absolute-voice-trace-timeline__label">${escapeHtml13(model.label)}</strong>
3711
3976
  </header>
3712
- <p class="absolute-voice-trace-timeline__description">${escapeHtml12(model.description)}</p>
3977
+ <p class="absolute-voice-trace-timeline__description">${escapeHtml13(model.description)}</p>
3713
3978
  ${sessions}
3714
- ${model.error ? `<p class="absolute-voice-trace-timeline__error">${escapeHtml12(model.error)}</p>` : ""}
3979
+ ${model.error ? `<p class="absolute-voice-trace-timeline__error">${escapeHtml13(model.error)}</p>` : ""}
3715
3980
  </section>`;
3716
3981
  };
3717
3982
  var getVoiceTraceTimelineCSS = () => `.absolute-voice-trace-timeline{border:1px solid #bad7d3;border-radius:20px;background:#f3fffb;color:#09201c;padding:18px;box-shadow:0 18px 40px rgba(9,32,28,.12);font-family:inherit}.absolute-voice-trace-timeline--error,.absolute-voice-trace-timeline--failed{border-color:#f2a7a7;background:#fff5f3}.absolute-voice-trace-timeline--warning{border-color:#fbbf24;background:#fffaf0}.absolute-voice-trace-timeline__header,.absolute-voice-trace-timeline__session header{align-items:start;display:flex;gap:12px;justify-content:space-between}.absolute-voice-trace-timeline__eyebrow{color:#17665b;font-size:12px;font-weight:800;letter-spacing:.08em;text-transform:uppercase}.absolute-voice-trace-timeline__label{font-size:24px;line-height:1}.absolute-voice-trace-timeline__description,.absolute-voice-trace-timeline__session p,.absolute-voice-trace-timeline__empty{color:#35544f}.absolute-voice-trace-timeline__sessions{display:grid;gap:12px;margin-top:14px}.absolute-voice-trace-timeline__session{background:#fff;border:1px solid #cfe7e2;border-radius:16px;padding:14px}.absolute-voice-trace-timeline__session--failed{border-color:#f2a7a7}.absolute-voice-trace-timeline__session--warning{border-color:#fbbf24}.absolute-voice-trace-timeline__session p{margin:10px 0}.absolute-voice-trace-timeline__actions{display:flex;flex-wrap:wrap;gap:10px}.absolute-voice-trace-timeline__session a{color:#0f766e;font-weight:800}.absolute-voice-trace-timeline__empty{margin:14px 0 0}.absolute-voice-trace-timeline__error{color:#9f1239;font-weight:700}`;
@@ -3963,7 +4228,7 @@ var useVoiceAgentSquadStatus = (path = "/api/voice-traces", options = {}) => {
3963
4228
  // src/client/agentSquadStatusWidget.ts
3964
4229
  var DEFAULT_TITLE12 = "Voice Agent Squad";
3965
4230
  var DEFAULT_DESCRIPTION12 = "Current specialist and recent handoffs from your self-hosted voice traces.";
3966
- var escapeHtml13 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
4231
+ var escapeHtml14 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
3967
4232
  var labelFor = (current) => {
3968
4233
  if (!current)
3969
4234
  return "Waiting for specialist activity";
@@ -3990,24 +4255,24 @@ var renderVoiceAgentSquadStatusHTML = (snapshot, options = {}) => {
3990
4255
  const model = createVoiceAgentSquadStatusViewModel(snapshot, options);
3991
4256
  const current = model.current;
3992
4257
  const rows = model.sessions.length ? model.sessions.slice(0, 5).map((session) => `<li>
3993
- <span>${escapeHtml13(session.sessionId)}</span>
3994
- <strong>${escapeHtml13(session.targetAgentId ?? "none")}</strong>
3995
- <em>${escapeHtml13(session.status)}</em>
3996
- ${session.summary || session.reason ? `<p>${escapeHtml13(session.summary ?? session.reason ?? "")}</p>` : ""}
4258
+ <span>${escapeHtml14(session.sessionId)}</span>
4259
+ <strong>${escapeHtml14(session.targetAgentId ?? "none")}</strong>
4260
+ <em>${escapeHtml14(session.status)}</em>
4261
+ ${session.summary || session.reason ? `<p>${escapeHtml14(session.summary ?? session.reason ?? "")}</p>` : ""}
3997
4262
  </li>`).join("") : "<li><span>No squad traces yet.</span><strong>Waiting</strong></li>";
3998
4263
  return `<section class="absolute-voice-agent-squad-status">
3999
4264
  <header>
4000
- <span>${escapeHtml13(model.title)}</span>
4001
- <strong>${escapeHtml13(model.label)}</strong>
4265
+ <span>${escapeHtml14(model.title)}</span>
4266
+ <strong>${escapeHtml14(model.label)}</strong>
4002
4267
  </header>
4003
- <p>${escapeHtml13(model.description)}</p>
4268
+ <p>${escapeHtml14(model.description)}</p>
4004
4269
  <div>
4005
- <span>Session</span><strong>${escapeHtml13(current?.sessionId ?? "n/a")}</strong>
4006
- <span>From</span><strong>${escapeHtml13(current?.fromAgentId ?? "n/a")}</strong>
4007
- <span>Status</span><strong>${escapeHtml13(current?.status ?? "idle")}</strong>
4270
+ <span>Session</span><strong>${escapeHtml14(current?.sessionId ?? "n/a")}</strong>
4271
+ <span>From</span><strong>${escapeHtml14(current?.fromAgentId ?? "n/a")}</strong>
4272
+ <span>Status</span><strong>${escapeHtml14(current?.status ?? "idle")}</strong>
4008
4273
  </div>
4009
4274
  <ul>${rows}</ul>
4010
- ${model.error ? `<p class="absolute-voice-agent-squad-status__error">${escapeHtml13(model.error)}</p>` : ""}
4275
+ ${model.error ? `<p class="absolute-voice-agent-squad-status__error">${escapeHtml14(model.error)}</p>` : ""}
4011
4276
  </section>`;
4012
4277
  };
4013
4278
  var getVoiceAgentSquadStatusCSS = () => `.absolute-voice-agent-squad-status{border:1px solid #38bdf866;border-radius:20px;background:#0f172a;color:#f8fafc;padding:18px;font-family:inherit}.absolute-voice-agent-squad-status header{display:grid;gap:4px}.absolute-voice-agent-squad-status header span{color:#7dd3fc;font-size:12px;font-weight:900;letter-spacing:.08em;text-transform:uppercase}.absolute-voice-agent-squad-status header strong{font-size:20px}.absolute-voice-agent-squad-status p{color:#cbd5e1}.absolute-voice-agent-squad-status div{display:grid;gap:6px;grid-template-columns:max-content 1fr;margin:14px 0}.absolute-voice-agent-squad-status div span{color:#94a3b8}.absolute-voice-agent-squad-status ul{display:grid;gap:8px;list-style:none;margin:0;padding:0}.absolute-voice-agent-squad-status li{background:#020617;border:1px solid #1e293b;border-radius:14px;padding:10px}.absolute-voice-agent-squad-status li span{color:#94a3b8;display:block;font-size:12px}.absolute-voice-agent-squad-status li strong{display:block}.absolute-voice-agent-squad-status li em{color:#7dd3fc;font-style:normal}.absolute-voice-agent-squad-status__error{color:#fecaca;font-weight:800}`;
@@ -4244,7 +4509,7 @@ var useVoiceTurnLatency = (path = "/api/turn-latency", options = {}) => {
4244
4509
  var DEFAULT_TITLE13 = "Turn Latency";
4245
4510
  var DEFAULT_DESCRIPTION13 = "Per-turn timing from first transcript to commit and assistant response start.";
4246
4511
  var DEFAULT_PROOF_LABEL = "Run latency proof";
4247
- var escapeHtml14 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
4512
+ var escapeHtml15 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
4248
4513
  var formatMs3 = (value) => typeof value === "number" ? `${Math.round(value)}ms` : "n/a";
4249
4514
  var createVoiceTurnLatencyViewModel = (snapshot, options = {}) => {
4250
4515
  const turns = (snapshot.report?.turns ?? []).map((turn) => ({
@@ -4272,25 +4537,25 @@ var createVoiceTurnLatencyViewModel = (snapshot, options = {}) => {
4272
4537
  };
4273
4538
  var renderVoiceTurnLatencyHTML = (snapshot, options = {}) => {
4274
4539
  const model = createVoiceTurnLatencyViewModel(snapshot, options);
4275
- const turns = model.turns.length ? `<div class="absolute-voice-turn-latency__turns">${model.turns.map((turn) => `<article class="absolute-voice-turn-latency__turn absolute-voice-turn-latency__turn--${escapeHtml14(turn.status)}">
4540
+ const turns = model.turns.length ? `<div class="absolute-voice-turn-latency__turns">${model.turns.map((turn) => `<article class="absolute-voice-turn-latency__turn absolute-voice-turn-latency__turn--${escapeHtml15(turn.status)}">
4276
4541
  <header>
4277
- <strong>${escapeHtml14(turn.label)}</strong>
4278
- <span>${escapeHtml14(turn.status)}</span>
4542
+ <strong>${escapeHtml15(turn.label)}</strong>
4543
+ <span>${escapeHtml15(turn.status)}</span>
4279
4544
  </header>
4280
4545
  <dl>${turn.rows.map((row) => `<div>
4281
- <dt>${escapeHtml14(row.label)}</dt>
4282
- <dd>${escapeHtml14(row.value)}</dd>
4546
+ <dt>${escapeHtml15(row.label)}</dt>
4547
+ <dd>${escapeHtml15(row.value)}</dd>
4283
4548
  </div>`).join("")}</dl>
4284
4549
  </article>`).join("")}</div>` : '<p class="absolute-voice-turn-latency__empty">Complete a voice turn to see latency diagnostics.</p>';
4285
- return `<section class="absolute-voice-turn-latency absolute-voice-turn-latency--${escapeHtml14(model.status)}">
4550
+ return `<section class="absolute-voice-turn-latency absolute-voice-turn-latency--${escapeHtml15(model.status)}">
4286
4551
  <header class="absolute-voice-turn-latency__header">
4287
- <span class="absolute-voice-turn-latency__eyebrow">${escapeHtml14(model.title)}</span>
4288
- <strong class="absolute-voice-turn-latency__label">${escapeHtml14(model.label)}</strong>
4552
+ <span class="absolute-voice-turn-latency__eyebrow">${escapeHtml15(model.title)}</span>
4553
+ <strong class="absolute-voice-turn-latency__label">${escapeHtml15(model.label)}</strong>
4289
4554
  </header>
4290
- <p class="absolute-voice-turn-latency__description">${escapeHtml14(model.description)}</p>
4291
- ${model.showProofAction ? `<button class="absolute-voice-turn-latency__proof" data-absolute-voice-turn-latency-proof type="button">${escapeHtml14(model.proofLabel ?? DEFAULT_PROOF_LABEL)}</button>` : ""}
4555
+ <p class="absolute-voice-turn-latency__description">${escapeHtml15(model.description)}</p>
4556
+ ${model.showProofAction ? `<button class="absolute-voice-turn-latency__proof" data-absolute-voice-turn-latency-proof type="button">${escapeHtml15(model.proofLabel ?? DEFAULT_PROOF_LABEL)}</button>` : ""}
4292
4557
  ${turns}
4293
- ${model.error ? `<p class="absolute-voice-turn-latency__error">${escapeHtml14(model.error)}</p>` : ""}
4558
+ ${model.error ? `<p class="absolute-voice-turn-latency__error">${escapeHtml15(model.error)}</p>` : ""}
4294
4559
  </section>`;
4295
4560
  };
4296
4561
  var mountVoiceTurnLatency = (element, path = "/api/turn-latency", options = {}) => {
@@ -4526,7 +4791,7 @@ var useVoiceTurnQuality = (path = "/api/turn-quality", options = {}) => {
4526
4791
  // src/client/turnQualityWidget.ts
4527
4792
  var DEFAULT_TITLE14 = "Turn Quality";
4528
4793
  var DEFAULT_DESCRIPTION14 = "Per-turn STT confidence, fallback selection, corrections, and transcript coverage.";
4529
- var escapeHtml15 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
4794
+ var escapeHtml16 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
4530
4795
  var formatConfidence = (value) => typeof value === "number" ? `${Math.round(value * 100)}%` : "n/a";
4531
4796
  var formatMaybe = (value) => value === undefined || value === "" ? "n/a" : String(value);
4532
4797
  var getTurnDetail = (turn) => {
@@ -4576,25 +4841,25 @@ var createVoiceTurnQualityViewModel = (snapshot, options = {}) => {
4576
4841
  };
4577
4842
  var renderVoiceTurnQualityHTML = (snapshot, options = {}) => {
4578
4843
  const model = createVoiceTurnQualityViewModel(snapshot, options);
4579
- const turns = model.turns.length ? `<div class="absolute-voice-turn-quality__turns">${model.turns.map((turn) => `<article class="absolute-voice-turn-quality__turn absolute-voice-turn-quality__turn--${escapeHtml15(turn.status)}">
4844
+ const turns = model.turns.length ? `<div class="absolute-voice-turn-quality__turns">${model.turns.map((turn) => `<article class="absolute-voice-turn-quality__turn absolute-voice-turn-quality__turn--${escapeHtml16(turn.status)}">
4580
4845
  <header>
4581
- <strong>${escapeHtml15(turn.label)}</strong>
4582
- <span>${escapeHtml15(turn.status)}</span>
4846
+ <strong>${escapeHtml16(turn.label)}</strong>
4847
+ <span>${escapeHtml16(turn.status)}</span>
4583
4848
  </header>
4584
- <p>${escapeHtml15(turn.detail)}</p>
4849
+ <p>${escapeHtml16(turn.detail)}</p>
4585
4850
  <dl>${turn.rows.map((row) => `<div>
4586
- <dt>${escapeHtml15(row.label)}</dt>
4587
- <dd>${escapeHtml15(row.value)}</dd>
4851
+ <dt>${escapeHtml16(row.label)}</dt>
4852
+ <dd>${escapeHtml16(row.value)}</dd>
4588
4853
  </div>`).join("")}</dl>
4589
4854
  </article>`).join("")}</div>` : '<p class="absolute-voice-turn-quality__empty">Complete a voice turn to see STT quality diagnostics.</p>';
4590
- return `<section class="absolute-voice-turn-quality absolute-voice-turn-quality--${escapeHtml15(model.status)}">
4855
+ return `<section class="absolute-voice-turn-quality absolute-voice-turn-quality--${escapeHtml16(model.status)}">
4591
4856
  <header class="absolute-voice-turn-quality__header">
4592
- <span class="absolute-voice-turn-quality__eyebrow">${escapeHtml15(model.title)}</span>
4593
- <strong class="absolute-voice-turn-quality__label">${escapeHtml15(model.label)}</strong>
4857
+ <span class="absolute-voice-turn-quality__eyebrow">${escapeHtml16(model.title)}</span>
4858
+ <strong class="absolute-voice-turn-quality__label">${escapeHtml16(model.label)}</strong>
4594
4859
  </header>
4595
- <p class="absolute-voice-turn-quality__description">${escapeHtml15(model.description)}</p>
4860
+ <p class="absolute-voice-turn-quality__description">${escapeHtml16(model.description)}</p>
4596
4861
  ${turns}
4597
- ${model.error ? `<p class="absolute-voice-turn-quality__error">${escapeHtml15(model.error)}</p>` : ""}
4862
+ ${model.error ? `<p class="absolute-voice-turn-quality__error">${escapeHtml16(model.error)}</p>` : ""}
4598
4863
  </section>`;
4599
4864
  };
4600
4865
  var getVoiceTurnQualityCSS = () => `.absolute-voice-turn-quality{border:1px solid #e4d1a3;border-radius:20px;background:#fff9eb;color:#17120a;padding:18px;box-shadow:0 18px 40px rgba(73,48,14,.12);font-family:inherit}.absolute-voice-turn-quality--error,.absolute-voice-turn-quality--warning{border-color:#f2a7a7;background:#fff5f3}.absolute-voice-turn-quality__header,.absolute-voice-turn-quality__turn header{align-items:start;display:flex;gap:12px;justify-content:space-between}.absolute-voice-turn-quality__eyebrow{color:#8a5a0a;font-size:12px;font-weight:800;letter-spacing:.08em;text-transform:uppercase}.absolute-voice-turn-quality__label{font-size:24px;line-height:1}.absolute-voice-turn-quality__description,.absolute-voice-turn-quality__turn p,.absolute-voice-turn-quality__turn dt,.absolute-voice-turn-quality__empty{color:#5a4930}.absolute-voice-turn-quality__turns{display:grid;gap:12px;margin-top:14px}.absolute-voice-turn-quality__turn{background:#fff;border:1px solid #f0dfba;border-radius:16px;padding:14px}.absolute-voice-turn-quality__turn--pass{border-color:#86efac}.absolute-voice-turn-quality__turn--warn,.absolute-voice-turn-quality__turn--unknown{border-color:#fbbf24}.absolute-voice-turn-quality__turn--fail{border-color:#f2a7a7}.absolute-voice-turn-quality__turn p{margin:10px 0}.absolute-voice-turn-quality__turn dl{display:grid;gap:8px;grid-template-columns:repeat(2,minmax(0,1fr));margin:0}.absolute-voice-turn-quality__turn div{background:#fff9eb;border:1px solid #f0dfba;border-radius:12px;padding:8px}.absolute-voice-turn-quality__turn dt{font-size:12px}.absolute-voice-turn-quality__turn dd{font-weight:800;margin:4px 0 0}.absolute-voice-turn-quality__empty{margin:14px 0 0}.absolute-voice-turn-quality__error{color:#9f1239;font-weight:700}`;