@absolutejs/voice 0.0.22-beta.333 → 0.0.22-beta.334
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/client/index.js +323 -167
- package/dist/index.d.ts +2 -2
- package/dist/index.js +445 -285
- package/dist/proofTrends.d.ts +74 -0
- package/dist/react/index.js +283 -127
- package/dist/vue/index.js +258 -102
- package/package.json +1 -1
package/dist/react/index.js
CHANGED
|
@@ -1678,6 +1678,162 @@ var assertVoiceProofTrendEvidence = (report, input = {}) => {
|
|
|
1678
1678
|
}
|
|
1679
1679
|
return assertion;
|
|
1680
1680
|
};
|
|
1681
|
+
var DEFAULT_RECOMMENDATION_BUDGETS = {
|
|
1682
|
+
maxLiveP95Ms: 800,
|
|
1683
|
+
maxProviderP95Ms: 1000,
|
|
1684
|
+
maxRuntimeBackpressureEvents: 0,
|
|
1685
|
+
maxRuntimeFirstAudioLatencyMs: 600,
|
|
1686
|
+
maxRuntimeInterruptionP95Ms: 300,
|
|
1687
|
+
maxRuntimeJitterMs: 30,
|
|
1688
|
+
maxRuntimeTimestampDriftMs: 800,
|
|
1689
|
+
maxTurnP95Ms: 700
|
|
1690
|
+
};
|
|
1691
|
+
var withinBudget = (value, budget) => typeof value === "number" && Number.isFinite(value) && value <= budget;
|
|
1692
|
+
var recommendationStatusRank = {
|
|
1693
|
+
pass: 0,
|
|
1694
|
+
warn: 1,
|
|
1695
|
+
fail: 2
|
|
1696
|
+
};
|
|
1697
|
+
var worstRecommendationStatus = (recommendations) => recommendations.reduce((status, recommendation) => recommendationStatusRank[recommendation.status] > recommendationStatusRank[status] ? recommendation.status : status, "pass");
|
|
1698
|
+
var buildVoiceProofTrendRecommendationReport = (report, options = {}) => {
|
|
1699
|
+
const budgets = { ...DEFAULT_RECOMMENDATION_BUDGETS, ...options };
|
|
1700
|
+
const maxLiveP95Ms = readProofTrendMaxLiveP95(report);
|
|
1701
|
+
const maxProviderP95Ms = readProofTrendMaxProviderP95(report);
|
|
1702
|
+
const maxTurnP95Ms = readProofTrendMaxTurnP95(report);
|
|
1703
|
+
const runtimeChannel = readProofTrendRuntimeChannel(report);
|
|
1704
|
+
const recommendations = [];
|
|
1705
|
+
const issues = [];
|
|
1706
|
+
if (report.ok !== true) {
|
|
1707
|
+
issues.push(`Proof trend report is ${report.status}; recommendations need a fresh passing trend artifact.`);
|
|
1708
|
+
}
|
|
1709
|
+
recommendations.push({
|
|
1710
|
+
evidence: {
|
|
1711
|
+
budgetMs: budgets.maxProviderP95Ms,
|
|
1712
|
+
providerP95Ms: maxProviderP95Ms
|
|
1713
|
+
},
|
|
1714
|
+
nextMove: 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.",
|
|
1715
|
+
recommendation: withinBudget(maxProviderP95Ms, budgets.maxProviderP95Ms) ? "Keep current provider path" : "Change provider routing for latency-sensitive traffic",
|
|
1716
|
+
status: withinBudget(maxProviderP95Ms, budgets.maxProviderP95Ms) ? "pass" : maxProviderP95Ms === undefined ? "fail" : "warn",
|
|
1717
|
+
surface: "provider-path"
|
|
1718
|
+
});
|
|
1719
|
+
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);
|
|
1720
|
+
recommendations.push({
|
|
1721
|
+
evidence: {
|
|
1722
|
+
backpressureEvents: runtimeChannel.maxBackpressureEvents,
|
|
1723
|
+
firstAudioBudgetMs: budgets.maxRuntimeFirstAudioLatencyMs,
|
|
1724
|
+
firstAudioMs: runtimeChannel.maxFirstAudioLatencyMs,
|
|
1725
|
+
interruptionBudgetMs: budgets.maxRuntimeInterruptionP95Ms,
|
|
1726
|
+
interruptionP95Ms: runtimeChannel.maxInterruptionP95Ms,
|
|
1727
|
+
jitterBudgetMs: budgets.maxRuntimeJitterMs,
|
|
1728
|
+
jitterMs: runtimeChannel.maxJitterMs,
|
|
1729
|
+
samples: runtimeChannel.samples,
|
|
1730
|
+
timestampDriftMs: runtimeChannel.maxTimestampDriftMs
|
|
1731
|
+
},
|
|
1732
|
+
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.",
|
|
1733
|
+
recommendation: runtimePass ? "Keep current runtime channel" : "Tune runtime channel before promotion",
|
|
1734
|
+
status: runtimePass ? "pass" : runtimeChannel.samples === undefined ? "fail" : "warn",
|
|
1735
|
+
surface: "runtime-channel"
|
|
1736
|
+
});
|
|
1737
|
+
recommendations.push({
|
|
1738
|
+
evidence: {
|
|
1739
|
+
budgetMs: budgets.maxLiveP95Ms,
|
|
1740
|
+
liveP95Ms: maxLiveP95Ms
|
|
1741
|
+
},
|
|
1742
|
+
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.",
|
|
1743
|
+
recommendation: withinBudget(maxLiveP95Ms, budgets.maxLiveP95Ms) ? "Keep live-latency settings" : "Tune live-latency path",
|
|
1744
|
+
status: withinBudget(maxLiveP95Ms, budgets.maxLiveP95Ms) ? "pass" : maxLiveP95Ms === undefined ? "fail" : "warn",
|
|
1745
|
+
surface: "live-latency"
|
|
1746
|
+
});
|
|
1747
|
+
recommendations.push({
|
|
1748
|
+
evidence: {
|
|
1749
|
+
budgetMs: budgets.maxTurnP95Ms,
|
|
1750
|
+
turnP95Ms: maxTurnP95Ms
|
|
1751
|
+
},
|
|
1752
|
+
nextMove: withinBudget(maxTurnP95Ms, budgets.maxTurnP95Ms) ? "Keep current turn pipeline defaults." : "Reduce tool/provider latency or split the turn pipeline before promotion.",
|
|
1753
|
+
recommendation: withinBudget(maxTurnP95Ms, budgets.maxTurnP95Ms) ? "Keep turn pipeline" : "Tune turn pipeline",
|
|
1754
|
+
status: withinBudget(maxTurnP95Ms, budgets.maxTurnP95Ms) ? "pass" : maxTurnP95Ms === undefined ? "fail" : "warn",
|
|
1755
|
+
surface: "turn-latency"
|
|
1756
|
+
});
|
|
1757
|
+
const status = issues.length > 0 ? "fail" : worstRecommendationStatus(recommendations);
|
|
1758
|
+
return {
|
|
1759
|
+
generatedAt: new Date().toISOString(),
|
|
1760
|
+
issues,
|
|
1761
|
+
ok: status !== "fail",
|
|
1762
|
+
recommendations,
|
|
1763
|
+
source: report.source || report.outputDir || report.runId || "proof-trends",
|
|
1764
|
+
status,
|
|
1765
|
+
summary: {
|
|
1766
|
+
keepCurrentProviderPath: recommendations.find((item) => item.surface === "provider-path")?.status === "pass",
|
|
1767
|
+
keepCurrentRuntimeChannel: recommendations.find((item) => item.surface === "runtime-channel")?.status === "pass",
|
|
1768
|
+
recommendedActions: recommendations.filter((item) => item.status !== "pass").length
|
|
1769
|
+
}
|
|
1770
|
+
};
|
|
1771
|
+
};
|
|
1772
|
+
var escapeHtml5 = (value) => String(value).replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">").replaceAll('"', """).replaceAll("'", "'");
|
|
1773
|
+
var escapeMarkdown = (value) => value.replaceAll("|", "\\|");
|
|
1774
|
+
var renderVoiceProofTrendRecommendationMarkdown = (report, title = "Voice Provider Runtime Recommendations") => [
|
|
1775
|
+
`# ${title}`,
|
|
1776
|
+
"",
|
|
1777
|
+
`- Status: ${report.status}`,
|
|
1778
|
+
`- Source: ${report.source}`,
|
|
1779
|
+
`- Recommended actions: ${String(report.summary.recommendedActions)}`,
|
|
1780
|
+
"",
|
|
1781
|
+
"| Surface | Status | Recommendation | Next move |",
|
|
1782
|
+
"| --- | --- | --- | --- |",
|
|
1783
|
+
...report.recommendations.map((recommendation) => `| ${escapeMarkdown(recommendation.surface)} | ${recommendation.status} | ${escapeMarkdown(recommendation.recommendation)} | ${escapeMarkdown(recommendation.nextMove)} |`),
|
|
1784
|
+
"",
|
|
1785
|
+
"## Issues",
|
|
1786
|
+
"",
|
|
1787
|
+
...report.issues.length ? report.issues.map((issue) => `- ${issue}`) : ["- None"]
|
|
1788
|
+
].join(`
|
|
1789
|
+
`);
|
|
1790
|
+
var renderVoiceProofTrendRecommendationHTML = (report, title = "Voice Provider Runtime Recommendations") => {
|
|
1791
|
+
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("");
|
|
1792
|
+
const issues = report.issues.length === 0 ? "<li>None</li>" : report.issues.map((issue) => `<li>${escapeHtml5(issue)}</li>`).join("");
|
|
1793
|
+
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}</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">Runtime ${report.summary.keepCurrentRuntimeChannel ? "keep" : "tune"}</span><span class="pill">${String(report.summary.recommendedActions)} action(s)</span></div></section>${cards}<section class="hero"><h2>Issues</h2><ul>${issues}</ul></section></main></body></html>`;
|
|
1794
|
+
};
|
|
1795
|
+
var createVoiceProofTrendRecommendationRoutes = (options) => {
|
|
1796
|
+
const path = options.path ?? "/api/voice/proof-trend-recommendations";
|
|
1797
|
+
const htmlPath = options.htmlPath === undefined ? "/voice/proof-trend-recommendations" : options.htmlPath;
|
|
1798
|
+
const markdownPath = options.markdownPath === undefined ? "/voice/proof-trend-recommendations.md" : options.markdownPath;
|
|
1799
|
+
const title = options.title ?? "Voice Provider Runtime Recommendations";
|
|
1800
|
+
const routes = new Elysia({
|
|
1801
|
+
name: options.name ?? "absolutejs-voice-proof-trend-recommendations"
|
|
1802
|
+
});
|
|
1803
|
+
const loadReport = async () => {
|
|
1804
|
+
const value = options.source !== undefined ? typeof options.source === "function" ? await options.source() : options.source : options.jsonPath ? await readVoiceProofTrendReportFile(options.jsonPath, {
|
|
1805
|
+
maxAgeMs: options.maxAgeMs
|
|
1806
|
+
}) : buildEmptyVoiceProofTrendReport("", options.maxAgeMs);
|
|
1807
|
+
return buildVoiceProofTrendRecommendationReport(normalizeVoiceProofTrendReport(value, {
|
|
1808
|
+
maxAgeMs: options.maxAgeMs,
|
|
1809
|
+
source: options.jsonPath
|
|
1810
|
+
}), options);
|
|
1811
|
+
};
|
|
1812
|
+
routes.get(path, async () => Response.json(await loadReport(), { headers: options.headers }));
|
|
1813
|
+
if (htmlPath !== false) {
|
|
1814
|
+
routes.get(htmlPath, async () => {
|
|
1815
|
+
const report = await loadReport();
|
|
1816
|
+
return new Response(renderVoiceProofTrendRecommendationHTML(report, title), {
|
|
1817
|
+
headers: {
|
|
1818
|
+
"content-type": "text/html; charset=utf-8",
|
|
1819
|
+
...Object.fromEntries(new Headers(options.headers))
|
|
1820
|
+
}
|
|
1821
|
+
});
|
|
1822
|
+
});
|
|
1823
|
+
}
|
|
1824
|
+
if (markdownPath !== false) {
|
|
1825
|
+
routes.get(markdownPath, async () => {
|
|
1826
|
+
const report = await loadReport();
|
|
1827
|
+
return new Response(renderVoiceProofTrendRecommendationMarkdown(report, title), {
|
|
1828
|
+
headers: {
|
|
1829
|
+
"content-type": "text/markdown; charset=utf-8",
|
|
1830
|
+
...Object.fromEntries(new Headers(options.headers))
|
|
1831
|
+
}
|
|
1832
|
+
});
|
|
1833
|
+
});
|
|
1834
|
+
}
|
|
1835
|
+
return routes;
|
|
1836
|
+
};
|
|
1681
1837
|
var createVoiceProofTrendRoutes = (options) => {
|
|
1682
1838
|
const path = options.path ?? "/api/voice/proof-trends";
|
|
1683
1839
|
const routes = new Elysia({
|
|
@@ -1720,7 +1876,7 @@ var DEFAULT_LINKS2 = [
|
|
|
1720
1876
|
{ href: "/voice/proof-trends", label: "Trend page" },
|
|
1721
1877
|
{ href: "/api/voice/proof-trends", label: "Trend JSON" }
|
|
1722
1878
|
];
|
|
1723
|
-
var
|
|
1879
|
+
var escapeHtml6 = (value) => value.replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">").replaceAll('"', """).replaceAll("'", "'");
|
|
1724
1880
|
var formatMs = (value) => typeof value === "number" && Number.isFinite(value) ? `${Math.round(value)}ms` : "n/a";
|
|
1725
1881
|
var statusLabel = (report) => {
|
|
1726
1882
|
if (!report) {
|
|
@@ -1770,19 +1926,19 @@ var createVoiceProofTrendsViewModel = (snapshot, options = {}) => {
|
|
|
1770
1926
|
var renderVoiceProofTrendsHTML = (snapshot, options = {}) => {
|
|
1771
1927
|
const model = createVoiceProofTrendsViewModel(snapshot, options);
|
|
1772
1928
|
const metrics = model.metrics.length ? `<div class="absolute-voice-proof-trends__metrics">${model.metrics.map((metric) => `<article>
|
|
1773
|
-
<span>${
|
|
1774
|
-
<strong>${
|
|
1775
|
-
</article>`).join("")}</div>` : `<p class="absolute-voice-proof-trends__empty">${model.error ?
|
|
1776
|
-
const links = model.links.length ? `<p class="absolute-voice-proof-trends__links">${model.links.map((link) => `<a href="${
|
|
1777
|
-
return `<section class="absolute-voice-proof-trends absolute-voice-proof-trends--${
|
|
1929
|
+
<span>${escapeHtml6(metric.label)}</span>
|
|
1930
|
+
<strong>${escapeHtml6(metric.value)}</strong>
|
|
1931
|
+
</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>`;
|
|
1932
|
+
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>` : "";
|
|
1933
|
+
return `<section class="absolute-voice-proof-trends absolute-voice-proof-trends--${escapeHtml6(model.status)}">
|
|
1778
1934
|
<header class="absolute-voice-proof-trends__header">
|
|
1779
|
-
<span class="absolute-voice-proof-trends__eyebrow">${
|
|
1780
|
-
<strong class="absolute-voice-proof-trends__label">${
|
|
1935
|
+
<span class="absolute-voice-proof-trends__eyebrow">${escapeHtml6(model.title)}</span>
|
|
1936
|
+
<strong class="absolute-voice-proof-trends__label">${escapeHtml6(model.label)}</strong>
|
|
1781
1937
|
</header>
|
|
1782
|
-
<p class="absolute-voice-proof-trends__description">${
|
|
1938
|
+
<p class="absolute-voice-proof-trends__description">${escapeHtml6(model.description)}</p>
|
|
1783
1939
|
${metrics}
|
|
1784
1940
|
${links}
|
|
1785
|
-
${model.error ? `<p class="absolute-voice-proof-trends__error">${
|
|
1941
|
+
${model.error ? `<p class="absolute-voice-proof-trends__error">${escapeHtml6(model.error)}</p>` : ""}
|
|
1786
1942
|
</section>`;
|
|
1787
1943
|
};
|
|
1788
1944
|
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 +2123,7 @@ var DEFAULT_LINKS3 = [
|
|
|
1967
2123
|
{ href: "/production-readiness", label: "Readiness page" },
|
|
1968
2124
|
{ href: "/voice/slo-readiness-thresholds", label: "Gate thresholds" }
|
|
1969
2125
|
];
|
|
1970
|
-
var
|
|
2126
|
+
var escapeHtml7 = (value) => value.replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">").replaceAll('"', """).replaceAll("'", "'");
|
|
1971
2127
|
var formatExplanationValue = (value, unit) => {
|
|
1972
2128
|
if (value === undefined || value === null) {
|
|
1973
2129
|
return "n/a";
|
|
@@ -2008,23 +2164,23 @@ var createVoiceReadinessFailuresViewModel = (snapshot, options = {}) => {
|
|
|
2008
2164
|
};
|
|
2009
2165
|
var renderVoiceReadinessFailuresHTML = (snapshot, options = {}) => {
|
|
2010
2166
|
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--${
|
|
2012
|
-
<span>${
|
|
2013
|
-
<strong>${
|
|
2014
|
-
<p>Observed ${
|
|
2015
|
-
<p>${
|
|
2016
|
-
<p class="absolute-voice-readiness-failures__links">${failure.evidenceHref ? `<a href="${
|
|
2017
|
-
</article>`).join("")}</div>` : `<p class="absolute-voice-readiness-failures__empty">${model.error ?
|
|
2018
|
-
const links = model.links.length ? `<p class="absolute-voice-readiness-failures__links">${model.links.map((link) => `<a href="${
|
|
2019
|
-
return `<section class="absolute-voice-readiness-failures absolute-voice-readiness-failures--${
|
|
2167
|
+
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)}">
|
|
2168
|
+
<span>${escapeHtml7(failure.status.toUpperCase())}</span>
|
|
2169
|
+
<strong>${escapeHtml7(failure.label)}</strong>
|
|
2170
|
+
<p>Observed ${escapeHtml7(failure.observed)} against ${escapeHtml7(failure.thresholdLabel)} ${escapeHtml7(failure.threshold)}.</p>
|
|
2171
|
+
<p>${escapeHtml7(failure.remediation)}</p>
|
|
2172
|
+
<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>
|
|
2173
|
+
</article>`).join("")}</div>` : `<p class="absolute-voice-readiness-failures__empty">${model.error ? escapeHtml7(model.error) : "No calibrated readiness gate explanations are open."}</p>`;
|
|
2174
|
+
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>` : "";
|
|
2175
|
+
return `<section class="absolute-voice-readiness-failures absolute-voice-readiness-failures--${escapeHtml7(model.status)}">
|
|
2020
2176
|
<header class="absolute-voice-readiness-failures__header">
|
|
2021
|
-
<span class="absolute-voice-readiness-failures__eyebrow">${
|
|
2022
|
-
<strong class="absolute-voice-readiness-failures__label">${
|
|
2177
|
+
<span class="absolute-voice-readiness-failures__eyebrow">${escapeHtml7(model.title)}</span>
|
|
2178
|
+
<strong class="absolute-voice-readiness-failures__label">${escapeHtml7(model.label)}</strong>
|
|
2023
2179
|
</header>
|
|
2024
|
-
<p class="absolute-voice-readiness-failures__description">${
|
|
2180
|
+
<p class="absolute-voice-readiness-failures__description">${escapeHtml7(model.description)}</p>
|
|
2025
2181
|
${failures}
|
|
2026
2182
|
${links}
|
|
2027
|
-
${model.error ? `<p class="absolute-voice-readiness-failures__error">${
|
|
2183
|
+
${model.error ? `<p class="absolute-voice-readiness-failures__error">${escapeHtml7(model.error)}</p>` : ""}
|
|
2028
2184
|
</section>`;
|
|
2029
2185
|
};
|
|
2030
2186
|
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 +2409,7 @@ var createVoiceProviderSimulationControlsStore = (options) => {
|
|
|
2253
2409
|
};
|
|
2254
2410
|
|
|
2255
2411
|
// src/client/providerSimulationControlsWidget.ts
|
|
2256
|
-
var
|
|
2412
|
+
var escapeHtml8 = (value) => value.replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">").replaceAll('"', """).replaceAll("'", "'");
|
|
2257
2413
|
var formatKind = (kind) => (kind ?? "stt").toUpperCase();
|
|
2258
2414
|
var createVoiceProviderSimulationControlsViewModel = (snapshot, options) => {
|
|
2259
2415
|
const configuredProviders = options.providers.filter((provider) => provider.configured !== false);
|
|
@@ -2273,18 +2429,18 @@ var createVoiceProviderSimulationControlsViewModel = (snapshot, options) => {
|
|
|
2273
2429
|
};
|
|
2274
2430
|
var renderVoiceProviderSimulationControlsHTML = (snapshot, options) => {
|
|
2275
2431
|
const model = createVoiceProviderSimulationControlsViewModel(snapshot, options);
|
|
2276
|
-
const failureButtons = model.failureProviders.map((provider) => `<button type="button" data-voice-provider-fail="${
|
|
2277
|
-
const recoveryButtons = model.providers.map((provider) => `<button type="button" data-voice-provider-recover="${
|
|
2432
|
+
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("");
|
|
2433
|
+
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
2434
|
return `<section class="absolute-voice-provider-simulation absolute-voice-provider-simulation--${snapshot.error ? "error" : snapshot.isRunning ? "running" : "ready"}">
|
|
2279
2435
|
<header class="absolute-voice-provider-simulation__header">
|
|
2280
|
-
<span class="absolute-voice-provider-simulation__eyebrow">${
|
|
2281
|
-
<strong class="absolute-voice-provider-simulation__label">${
|
|
2436
|
+
<span class="absolute-voice-provider-simulation__eyebrow">${escapeHtml8(model.title)}</span>
|
|
2437
|
+
<strong class="absolute-voice-provider-simulation__label">${escapeHtml8(model.label)}</strong>
|
|
2282
2438
|
</header>
|
|
2283
|
-
<p class="absolute-voice-provider-simulation__description">${
|
|
2284
|
-
${model.canSimulateFailure ? "" : `<p class="absolute-voice-provider-simulation__empty">${
|
|
2439
|
+
<p class="absolute-voice-provider-simulation__description">${escapeHtml8(model.description)}</p>
|
|
2440
|
+
${model.canSimulateFailure ? "" : `<p class="absolute-voice-provider-simulation__empty">${escapeHtml8(options.fallbackRequiredMessage ?? "Configure fallback providers before simulating failure.")}</p>`}
|
|
2285
2441
|
<div class="absolute-voice-provider-simulation__actions">${failureButtons}${recoveryButtons}</div>
|
|
2286
|
-
${snapshot.error ? `<p class="absolute-voice-provider-simulation__error">${
|
|
2287
|
-
${model.resultText ? `<pre class="absolute-voice-provider-simulation__result">${
|
|
2442
|
+
${snapshot.error ? `<p class="absolute-voice-provider-simulation__error">${escapeHtml8(snapshot.error)}</p>` : ""}
|
|
2443
|
+
${model.resultText ? `<pre class="absolute-voice-provider-simulation__result">${escapeHtml8(model.resultText)}</pre>` : ""}
|
|
2288
2444
|
</section>`;
|
|
2289
2445
|
};
|
|
2290
2446
|
var bindVoiceProviderSimulationControls = (element, store) => {
|
|
@@ -2544,7 +2700,7 @@ var useVoiceProviderCapabilities = (path = "/api/provider-capabilities", options
|
|
|
2544
2700
|
// src/client/providerCapabilitiesWidget.ts
|
|
2545
2701
|
var DEFAULT_TITLE7 = "Provider Capabilities";
|
|
2546
2702
|
var DEFAULT_DESCRIPTION7 = "Configured, selected, and healthy voice providers for this deployment.";
|
|
2547
|
-
var
|
|
2703
|
+
var escapeHtml9 = (value) => value.replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">").replaceAll('"', """).replaceAll("'", "'");
|
|
2548
2704
|
var formatProvider = (provider) => provider.split(/[-_\s]+/).filter(Boolean).map((part) => `${part[0]?.toUpperCase() ?? ""}${part.slice(1)}`).join(" ") || provider;
|
|
2549
2705
|
var formatKind2 = (kind) => kind.toUpperCase();
|
|
2550
2706
|
var formatStatus2 = (status) => status.split("-").map((part) => `${part[0]?.toUpperCase() ?? ""}${part.slice(1)}`).join(" ");
|
|
@@ -2599,25 +2755,25 @@ var createVoiceProviderCapabilitiesViewModel = (snapshot, options = {}) => {
|
|
|
2599
2755
|
};
|
|
2600
2756
|
var renderVoiceProviderCapabilitiesHTML = (snapshot, options = {}) => {
|
|
2601
2757
|
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--${
|
|
2758
|
+
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
2759
|
<header>
|
|
2604
|
-
<strong>${
|
|
2605
|
-
<span>${
|
|
2760
|
+
<strong>${escapeHtml9(capability.label)}</strong>
|
|
2761
|
+
<span>${escapeHtml9(formatStatus2(capability.status))}</span>
|
|
2606
2762
|
</header>
|
|
2607
|
-
<p>${
|
|
2763
|
+
<p>${escapeHtml9(capability.detail)}</p>
|
|
2608
2764
|
<dl>${capability.rows.map((row) => `<div>
|
|
2609
|
-
<dt>${
|
|
2610
|
-
<dd>${
|
|
2765
|
+
<dt>${escapeHtml9(row.label)}</dt>
|
|
2766
|
+
<dd>${escapeHtml9(row.value)}</dd>
|
|
2611
2767
|
</div>`).join("")}</dl>
|
|
2612
2768
|
</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--${
|
|
2769
|
+
return `<section class="absolute-voice-provider-capabilities absolute-voice-provider-capabilities--${escapeHtml9(model.status)}">
|
|
2614
2770
|
<header class="absolute-voice-provider-capabilities__header">
|
|
2615
|
-
<span class="absolute-voice-provider-capabilities__eyebrow">${
|
|
2616
|
-
<strong class="absolute-voice-provider-capabilities__label">${
|
|
2771
|
+
<span class="absolute-voice-provider-capabilities__eyebrow">${escapeHtml9(model.title)}</span>
|
|
2772
|
+
<strong class="absolute-voice-provider-capabilities__label">${escapeHtml9(model.label)}</strong>
|
|
2617
2773
|
</header>
|
|
2618
|
-
<p class="absolute-voice-provider-capabilities__description">${
|
|
2774
|
+
<p class="absolute-voice-provider-capabilities__description">${escapeHtml9(model.description)}</p>
|
|
2619
2775
|
${capabilities}
|
|
2620
|
-
${model.error ? `<p class="absolute-voice-provider-capabilities__error">${
|
|
2776
|
+
${model.error ? `<p class="absolute-voice-provider-capabilities__error">${escapeHtml9(model.error)}</p>` : ""}
|
|
2621
2777
|
</section>`;
|
|
2622
2778
|
};
|
|
2623
2779
|
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 +2991,7 @@ var useVoiceProviderContracts = (path = "/api/provider-contracts", options = {})
|
|
|
2835
2991
|
// src/client/providerContractsWidget.ts
|
|
2836
2992
|
var DEFAULT_TITLE8 = "Provider Contracts";
|
|
2837
2993
|
var DEFAULT_DESCRIPTION8 = "Production contract coverage for provider env, latency, fallback, streaming, and capabilities.";
|
|
2838
|
-
var
|
|
2994
|
+
var escapeHtml10 = (value) => value.replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">").replaceAll('"', """).replaceAll("'", "'");
|
|
2839
2995
|
var formatProvider2 = (provider) => provider.split(/[-_\s]+/).filter(Boolean).map((part) => `${part[0]?.toUpperCase() ?? ""}${part.slice(1)}`).join(" ") || provider;
|
|
2840
2996
|
var formatStatus3 = (status) => status.split("-").map((part) => `${part[0]?.toUpperCase() ?? ""}${part.slice(1)}`).join(" ");
|
|
2841
2997
|
var contractDetail = (row) => {
|
|
@@ -2879,26 +3035,26 @@ var createVoiceProviderContractsViewModel = (snapshot, options = {}) => {
|
|
|
2879
3035
|
};
|
|
2880
3036
|
var renderVoiceProviderContractsHTML = (snapshot, options = {}) => {
|
|
2881
3037
|
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--${
|
|
3038
|
+
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
3039
|
<header>
|
|
2884
|
-
<strong>${
|
|
2885
|
-
<span>${
|
|
3040
|
+
<strong>${escapeHtml10(row.label)}</strong>
|
|
3041
|
+
<span>${escapeHtml10(formatStatus3(row.status))}</span>
|
|
2886
3042
|
</header>
|
|
2887
|
-
<p>${
|
|
2888
|
-
${row.remediations.length ? `<ul class="absolute-voice-provider-contracts__remediations">${row.remediations.map((remediation) => `<li>${remediation.href ? `<a href="${
|
|
3043
|
+
<p>${escapeHtml10(row.detail)}</p>
|
|
3044
|
+
${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
3045
|
<dl>${row.rows.map((item) => `<div>
|
|
2890
|
-
<dt>${
|
|
2891
|
-
<dd>${
|
|
3046
|
+
<dt>${escapeHtml10(item.label)}</dt>
|
|
3047
|
+
<dd>${escapeHtml10(item.value)}</dd>
|
|
2892
3048
|
</div>`).join("")}</dl>
|
|
2893
3049
|
</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--${
|
|
3050
|
+
return `<section class="absolute-voice-provider-contracts absolute-voice-provider-contracts--${escapeHtml10(model.status)}">
|
|
2895
3051
|
<header class="absolute-voice-provider-contracts__header">
|
|
2896
|
-
<span class="absolute-voice-provider-contracts__eyebrow">${
|
|
2897
|
-
<strong class="absolute-voice-provider-contracts__label">${
|
|
3052
|
+
<span class="absolute-voice-provider-contracts__eyebrow">${escapeHtml10(model.title)}</span>
|
|
3053
|
+
<strong class="absolute-voice-provider-contracts__label">${escapeHtml10(model.label)}</strong>
|
|
2898
3054
|
</header>
|
|
2899
|
-
<p class="absolute-voice-provider-contracts__description">${
|
|
3055
|
+
<p class="absolute-voice-provider-contracts__description">${escapeHtml10(model.description)}</p>
|
|
2900
3056
|
${rows}
|
|
2901
|
-
${model.error ? `<p class="absolute-voice-provider-contracts__error">${
|
|
3057
|
+
${model.error ? `<p class="absolute-voice-provider-contracts__error">${escapeHtml10(model.error)}</p>` : ""}
|
|
2902
3058
|
</section>`;
|
|
2903
3059
|
};
|
|
2904
3060
|
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 +3293,7 @@ var useVoiceProviderStatus = (path = "/api/provider-status", options = {}) => {
|
|
|
3137
3293
|
// src/client/providerStatusWidget.ts
|
|
3138
3294
|
var DEFAULT_TITLE9 = "Voice Providers";
|
|
3139
3295
|
var DEFAULT_DESCRIPTION9 = "Live provider health, fallback counts, latency, and suppression state from your self-hosted trace store.";
|
|
3140
|
-
var
|
|
3296
|
+
var escapeHtml11 = (value) => value.replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">").replaceAll('"', """).replaceAll("'", "'");
|
|
3141
3297
|
var formatProvider3 = (provider) => provider.split(/[-_\s]+/).filter(Boolean).map((part) => `${part[0]?.toUpperCase() ?? ""}${part.slice(1)}`).join(" ") || provider;
|
|
3142
3298
|
var formatStatus4 = (status) => status.split("-").map((part) => `${part[0]?.toUpperCase() ?? ""}${part.slice(1)}`).join(" ");
|
|
3143
3299
|
var formatLatency = (value) => typeof value === "number" ? `${value}ms` : "No samples";
|
|
@@ -3193,25 +3349,25 @@ var createVoiceProviderStatusViewModel = (snapshot, options = {}) => {
|
|
|
3193
3349
|
};
|
|
3194
3350
|
var renderVoiceProviderStatusHTML = (snapshot, options = {}) => {
|
|
3195
3351
|
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--${
|
|
3352
|
+
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
3353
|
<header>
|
|
3198
|
-
<strong>${
|
|
3199
|
-
<span>${
|
|
3354
|
+
<strong>${escapeHtml11(provider.label)}</strong>
|
|
3355
|
+
<span>${escapeHtml11(formatStatus4(provider.status))}</span>
|
|
3200
3356
|
</header>
|
|
3201
|
-
<p>${
|
|
3357
|
+
<p>${escapeHtml11(provider.detail)}</p>
|
|
3202
3358
|
<dl>${provider.rows.map((row) => `<div>
|
|
3203
|
-
<dt>${
|
|
3204
|
-
<dd>${
|
|
3359
|
+
<dt>${escapeHtml11(row.label)}</dt>
|
|
3360
|
+
<dd>${escapeHtml11(row.value)}</dd>
|
|
3205
3361
|
</div>`).join("")}</dl>
|
|
3206
3362
|
</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--${
|
|
3363
|
+
return `<section class="absolute-voice-provider-status absolute-voice-provider-status--${escapeHtml11(model.status)}">
|
|
3208
3364
|
<header class="absolute-voice-provider-status__header">
|
|
3209
|
-
<span class="absolute-voice-provider-status__eyebrow">${
|
|
3210
|
-
<strong class="absolute-voice-provider-status__label">${
|
|
3365
|
+
<span class="absolute-voice-provider-status__eyebrow">${escapeHtml11(model.title)}</span>
|
|
3366
|
+
<strong class="absolute-voice-provider-status__label">${escapeHtml11(model.label)}</strong>
|
|
3211
3367
|
</header>
|
|
3212
|
-
<p class="absolute-voice-provider-status__description">${
|
|
3368
|
+
<p class="absolute-voice-provider-status__description">${escapeHtml11(model.description)}</p>
|
|
3213
3369
|
${providers}
|
|
3214
|
-
${model.error ? `<p class="absolute-voice-provider-status__error">${
|
|
3370
|
+
${model.error ? `<p class="absolute-voice-provider-status__error">${escapeHtml11(model.error)}</p>` : ""}
|
|
3215
3371
|
</section>`;
|
|
3216
3372
|
};
|
|
3217
3373
|
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 +3590,7 @@ var useVoiceRoutingStatus = (path = "/api/routing/latest", options = {}) => {
|
|
|
3434
3590
|
// src/client/routingStatusWidget.ts
|
|
3435
3591
|
var DEFAULT_TITLE10 = "Voice Routing";
|
|
3436
3592
|
var DEFAULT_DESCRIPTION10 = "Latest provider routing decision from the self-hosted trace store.";
|
|
3437
|
-
var
|
|
3593
|
+
var escapeHtml12 = (value) => value.replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">").replaceAll('"', """).replaceAll("'", "'");
|
|
3438
3594
|
var formatValue = (value, fallback = "None") => typeof value === "string" && value.trim() ? value : typeof value === "number" && Number.isFinite(value) ? String(value) : fallback;
|
|
3439
3595
|
var createVoiceRoutingStatusViewModel = (snapshot, options = {}) => {
|
|
3440
3596
|
const decision = snapshot.decision;
|
|
@@ -3471,17 +3627,17 @@ var createVoiceRoutingStatusViewModel = (snapshot, options = {}) => {
|
|
|
3471
3627
|
var renderVoiceRoutingStatusHTML = (snapshot, options = {}) => {
|
|
3472
3628
|
const model = createVoiceRoutingStatusViewModel(snapshot, options);
|
|
3473
3629
|
const rows = model.rows.length ? `<div class="absolute-voice-routing-status__grid">${model.rows.map((row) => `<div>
|
|
3474
|
-
<span>${
|
|
3475
|
-
<strong>${
|
|
3630
|
+
<span>${escapeHtml12(row.label)}</span>
|
|
3631
|
+
<strong>${escapeHtml12(row.value)}</strong>
|
|
3476
3632
|
</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--${
|
|
3633
|
+
return `<section class="absolute-voice-routing-status absolute-voice-routing-status--${escapeHtml12(model.status)}">
|
|
3478
3634
|
<header class="absolute-voice-routing-status__header">
|
|
3479
|
-
<span class="absolute-voice-routing-status__eyebrow">${
|
|
3480
|
-
<strong class="absolute-voice-routing-status__label">${
|
|
3635
|
+
<span class="absolute-voice-routing-status__eyebrow">${escapeHtml12(model.title)}</span>
|
|
3636
|
+
<strong class="absolute-voice-routing-status__label">${escapeHtml12(model.label)}</strong>
|
|
3481
3637
|
</header>
|
|
3482
|
-
<p class="absolute-voice-routing-status__description">${
|
|
3638
|
+
<p class="absolute-voice-routing-status__description">${escapeHtml12(model.description)}</p>
|
|
3483
3639
|
${rows}
|
|
3484
|
-
${model.error ? `<p class="absolute-voice-routing-status__error">${
|
|
3640
|
+
${model.error ? `<p class="absolute-voice-routing-status__error">${escapeHtml12(model.error)}</p>` : ""}
|
|
3485
3641
|
</section>`;
|
|
3486
3642
|
};
|
|
3487
3643
|
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 +3817,7 @@ var createVoiceTraceTimelineStore = (path = "/api/voice-traces", options = {}) =
|
|
|
3661
3817
|
// src/client/traceTimelineWidget.ts
|
|
3662
3818
|
var DEFAULT_TITLE11 = "Voice Traces";
|
|
3663
3819
|
var DEFAULT_DESCRIPTION11 = "Latest call timelines with provider latency, fallbacks, handoffs, and errors from your self-hosted trace store.";
|
|
3664
|
-
var
|
|
3820
|
+
var escapeHtml13 = (value) => value.replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">").replaceAll('"', """).replaceAll("'", "'");
|
|
3665
3821
|
var formatMs2 = (value) => typeof value === "number" ? `${value}ms` : "n/a";
|
|
3666
3822
|
var formatProviders = (session) => session.providers.length ? session.providers.map((provider) => provider.provider).join(", ") : "No providers";
|
|
3667
3823
|
var createVoiceTraceTimelineViewModel = (snapshot, options = {}) => {
|
|
@@ -3691,27 +3847,27 @@ var renderVoiceTraceTimelineWidgetHTML = (snapshot, options = {}) => {
|
|
|
3691
3847
|
const model = createVoiceTraceTimelineViewModel(snapshot, options);
|
|
3692
3848
|
const sessions = model.sessions.length ? `<div class="absolute-voice-trace-timeline__sessions">${model.sessions.map((session) => {
|
|
3693
3849
|
const supportLinks = [
|
|
3694
|
-
`<a href="${
|
|
3695
|
-
session.operationsRecordHref ? `<a href="${
|
|
3696
|
-
session.incidentBundleHref ? `<a href="${
|
|
3850
|
+
`<a href="${escapeHtml13(session.detailHref)}">Open timeline</a>`,
|
|
3851
|
+
session.operationsRecordHref ? `<a href="${escapeHtml13(session.operationsRecordHref)}">Open operations record</a>` : undefined,
|
|
3852
|
+
session.incidentBundleHref ? `<a href="${escapeHtml13(session.incidentBundleHref)}">Export incident bundle</a>` : undefined
|
|
3697
3853
|
].filter(Boolean).join("");
|
|
3698
|
-
return `<article class="absolute-voice-trace-timeline__session absolute-voice-trace-timeline__session--${
|
|
3854
|
+
return `<article class="absolute-voice-trace-timeline__session absolute-voice-trace-timeline__session--${escapeHtml13(session.status)}">
|
|
3699
3855
|
<header>
|
|
3700
|
-
<strong>${
|
|
3701
|
-
<span>${
|
|
3856
|
+
<strong>${escapeHtml13(session.sessionId)}</strong>
|
|
3857
|
+
<span>${escapeHtml13(session.status)}</span>
|
|
3702
3858
|
</header>
|
|
3703
|
-
<p>${
|
|
3859
|
+
<p>${escapeHtml13(session.label)} \xB7 ${escapeHtml13(session.durationLabel)} \xB7 ${escapeHtml13(session.providerLabel)}</p>
|
|
3704
3860
|
<p class="absolute-voice-trace-timeline__actions">${supportLinks}</p>
|
|
3705
3861
|
</article>`;
|
|
3706
3862
|
}).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--${
|
|
3863
|
+
return `<section class="absolute-voice-trace-timeline absolute-voice-trace-timeline--${escapeHtml13(model.status)}">
|
|
3708
3864
|
<header class="absolute-voice-trace-timeline__header">
|
|
3709
|
-
<span class="absolute-voice-trace-timeline__eyebrow">${
|
|
3710
|
-
<strong class="absolute-voice-trace-timeline__label">${
|
|
3865
|
+
<span class="absolute-voice-trace-timeline__eyebrow">${escapeHtml13(model.title)}</span>
|
|
3866
|
+
<strong class="absolute-voice-trace-timeline__label">${escapeHtml13(model.label)}</strong>
|
|
3711
3867
|
</header>
|
|
3712
|
-
<p class="absolute-voice-trace-timeline__description">${
|
|
3868
|
+
<p class="absolute-voice-trace-timeline__description">${escapeHtml13(model.description)}</p>
|
|
3713
3869
|
${sessions}
|
|
3714
|
-
${model.error ? `<p class="absolute-voice-trace-timeline__error">${
|
|
3870
|
+
${model.error ? `<p class="absolute-voice-trace-timeline__error">${escapeHtml13(model.error)}</p>` : ""}
|
|
3715
3871
|
</section>`;
|
|
3716
3872
|
};
|
|
3717
3873
|
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 +4119,7 @@ var useVoiceAgentSquadStatus = (path = "/api/voice-traces", options = {}) => {
|
|
|
3963
4119
|
// src/client/agentSquadStatusWidget.ts
|
|
3964
4120
|
var DEFAULT_TITLE12 = "Voice Agent Squad";
|
|
3965
4121
|
var DEFAULT_DESCRIPTION12 = "Current specialist and recent handoffs from your self-hosted voice traces.";
|
|
3966
|
-
var
|
|
4122
|
+
var escapeHtml14 = (value) => value.replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">").replaceAll('"', """).replaceAll("'", "'");
|
|
3967
4123
|
var labelFor = (current) => {
|
|
3968
4124
|
if (!current)
|
|
3969
4125
|
return "Waiting for specialist activity";
|
|
@@ -3990,24 +4146,24 @@ var renderVoiceAgentSquadStatusHTML = (snapshot, options = {}) => {
|
|
|
3990
4146
|
const model = createVoiceAgentSquadStatusViewModel(snapshot, options);
|
|
3991
4147
|
const current = model.current;
|
|
3992
4148
|
const rows = model.sessions.length ? model.sessions.slice(0, 5).map((session) => `<li>
|
|
3993
|
-
<span>${
|
|
3994
|
-
<strong>${
|
|
3995
|
-
<em>${
|
|
3996
|
-
${session.summary || session.reason ? `<p>${
|
|
4149
|
+
<span>${escapeHtml14(session.sessionId)}</span>
|
|
4150
|
+
<strong>${escapeHtml14(session.targetAgentId ?? "none")}</strong>
|
|
4151
|
+
<em>${escapeHtml14(session.status)}</em>
|
|
4152
|
+
${session.summary || session.reason ? `<p>${escapeHtml14(session.summary ?? session.reason ?? "")}</p>` : ""}
|
|
3997
4153
|
</li>`).join("") : "<li><span>No squad traces yet.</span><strong>Waiting</strong></li>";
|
|
3998
4154
|
return `<section class="absolute-voice-agent-squad-status">
|
|
3999
4155
|
<header>
|
|
4000
|
-
<span>${
|
|
4001
|
-
<strong>${
|
|
4156
|
+
<span>${escapeHtml14(model.title)}</span>
|
|
4157
|
+
<strong>${escapeHtml14(model.label)}</strong>
|
|
4002
4158
|
</header>
|
|
4003
|
-
<p>${
|
|
4159
|
+
<p>${escapeHtml14(model.description)}</p>
|
|
4004
4160
|
<div>
|
|
4005
|
-
<span>Session</span><strong>${
|
|
4006
|
-
<span>From</span><strong>${
|
|
4007
|
-
<span>Status</span><strong>${
|
|
4161
|
+
<span>Session</span><strong>${escapeHtml14(current?.sessionId ?? "n/a")}</strong>
|
|
4162
|
+
<span>From</span><strong>${escapeHtml14(current?.fromAgentId ?? "n/a")}</strong>
|
|
4163
|
+
<span>Status</span><strong>${escapeHtml14(current?.status ?? "idle")}</strong>
|
|
4008
4164
|
</div>
|
|
4009
4165
|
<ul>${rows}</ul>
|
|
4010
|
-
${model.error ? `<p class="absolute-voice-agent-squad-status__error">${
|
|
4166
|
+
${model.error ? `<p class="absolute-voice-agent-squad-status__error">${escapeHtml14(model.error)}</p>` : ""}
|
|
4011
4167
|
</section>`;
|
|
4012
4168
|
};
|
|
4013
4169
|
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 +4400,7 @@ var useVoiceTurnLatency = (path = "/api/turn-latency", options = {}) => {
|
|
|
4244
4400
|
var DEFAULT_TITLE13 = "Turn Latency";
|
|
4245
4401
|
var DEFAULT_DESCRIPTION13 = "Per-turn timing from first transcript to commit and assistant response start.";
|
|
4246
4402
|
var DEFAULT_PROOF_LABEL = "Run latency proof";
|
|
4247
|
-
var
|
|
4403
|
+
var escapeHtml15 = (value) => value.replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">").replaceAll('"', """).replaceAll("'", "'");
|
|
4248
4404
|
var formatMs3 = (value) => typeof value === "number" ? `${Math.round(value)}ms` : "n/a";
|
|
4249
4405
|
var createVoiceTurnLatencyViewModel = (snapshot, options = {}) => {
|
|
4250
4406
|
const turns = (snapshot.report?.turns ?? []).map((turn) => ({
|
|
@@ -4272,25 +4428,25 @@ var createVoiceTurnLatencyViewModel = (snapshot, options = {}) => {
|
|
|
4272
4428
|
};
|
|
4273
4429
|
var renderVoiceTurnLatencyHTML = (snapshot, options = {}) => {
|
|
4274
4430
|
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--${
|
|
4431
|
+
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
4432
|
<header>
|
|
4277
|
-
<strong>${
|
|
4278
|
-
<span>${
|
|
4433
|
+
<strong>${escapeHtml15(turn.label)}</strong>
|
|
4434
|
+
<span>${escapeHtml15(turn.status)}</span>
|
|
4279
4435
|
</header>
|
|
4280
4436
|
<dl>${turn.rows.map((row) => `<div>
|
|
4281
|
-
<dt>${
|
|
4282
|
-
<dd>${
|
|
4437
|
+
<dt>${escapeHtml15(row.label)}</dt>
|
|
4438
|
+
<dd>${escapeHtml15(row.value)}</dd>
|
|
4283
4439
|
</div>`).join("")}</dl>
|
|
4284
4440
|
</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--${
|
|
4441
|
+
return `<section class="absolute-voice-turn-latency absolute-voice-turn-latency--${escapeHtml15(model.status)}">
|
|
4286
4442
|
<header class="absolute-voice-turn-latency__header">
|
|
4287
|
-
<span class="absolute-voice-turn-latency__eyebrow">${
|
|
4288
|
-
<strong class="absolute-voice-turn-latency__label">${
|
|
4443
|
+
<span class="absolute-voice-turn-latency__eyebrow">${escapeHtml15(model.title)}</span>
|
|
4444
|
+
<strong class="absolute-voice-turn-latency__label">${escapeHtml15(model.label)}</strong>
|
|
4289
4445
|
</header>
|
|
4290
|
-
<p class="absolute-voice-turn-latency__description">${
|
|
4291
|
-
${model.showProofAction ? `<button class="absolute-voice-turn-latency__proof" data-absolute-voice-turn-latency-proof type="button">${
|
|
4446
|
+
<p class="absolute-voice-turn-latency__description">${escapeHtml15(model.description)}</p>
|
|
4447
|
+
${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
4448
|
${turns}
|
|
4293
|
-
${model.error ? `<p class="absolute-voice-turn-latency__error">${
|
|
4449
|
+
${model.error ? `<p class="absolute-voice-turn-latency__error">${escapeHtml15(model.error)}</p>` : ""}
|
|
4294
4450
|
</section>`;
|
|
4295
4451
|
};
|
|
4296
4452
|
var mountVoiceTurnLatency = (element, path = "/api/turn-latency", options = {}) => {
|
|
@@ -4526,7 +4682,7 @@ var useVoiceTurnQuality = (path = "/api/turn-quality", options = {}) => {
|
|
|
4526
4682
|
// src/client/turnQualityWidget.ts
|
|
4527
4683
|
var DEFAULT_TITLE14 = "Turn Quality";
|
|
4528
4684
|
var DEFAULT_DESCRIPTION14 = "Per-turn STT confidence, fallback selection, corrections, and transcript coverage.";
|
|
4529
|
-
var
|
|
4685
|
+
var escapeHtml16 = (value) => value.replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">").replaceAll('"', """).replaceAll("'", "'");
|
|
4530
4686
|
var formatConfidence = (value) => typeof value === "number" ? `${Math.round(value * 100)}%` : "n/a";
|
|
4531
4687
|
var formatMaybe = (value) => value === undefined || value === "" ? "n/a" : String(value);
|
|
4532
4688
|
var getTurnDetail = (turn) => {
|
|
@@ -4576,25 +4732,25 @@ var createVoiceTurnQualityViewModel = (snapshot, options = {}) => {
|
|
|
4576
4732
|
};
|
|
4577
4733
|
var renderVoiceTurnQualityHTML = (snapshot, options = {}) => {
|
|
4578
4734
|
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--${
|
|
4735
|
+
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
4736
|
<header>
|
|
4581
|
-
<strong>${
|
|
4582
|
-
<span>${
|
|
4737
|
+
<strong>${escapeHtml16(turn.label)}</strong>
|
|
4738
|
+
<span>${escapeHtml16(turn.status)}</span>
|
|
4583
4739
|
</header>
|
|
4584
|
-
<p>${
|
|
4740
|
+
<p>${escapeHtml16(turn.detail)}</p>
|
|
4585
4741
|
<dl>${turn.rows.map((row) => `<div>
|
|
4586
|
-
<dt>${
|
|
4587
|
-
<dd>${
|
|
4742
|
+
<dt>${escapeHtml16(row.label)}</dt>
|
|
4743
|
+
<dd>${escapeHtml16(row.value)}</dd>
|
|
4588
4744
|
</div>`).join("")}</dl>
|
|
4589
4745
|
</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--${
|
|
4746
|
+
return `<section class="absolute-voice-turn-quality absolute-voice-turn-quality--${escapeHtml16(model.status)}">
|
|
4591
4747
|
<header class="absolute-voice-turn-quality__header">
|
|
4592
|
-
<span class="absolute-voice-turn-quality__eyebrow">${
|
|
4593
|
-
<strong class="absolute-voice-turn-quality__label">${
|
|
4748
|
+
<span class="absolute-voice-turn-quality__eyebrow">${escapeHtml16(model.title)}</span>
|
|
4749
|
+
<strong class="absolute-voice-turn-quality__label">${escapeHtml16(model.label)}</strong>
|
|
4594
4750
|
</header>
|
|
4595
|
-
<p class="absolute-voice-turn-quality__description">${
|
|
4751
|
+
<p class="absolute-voice-turn-quality__description">${escapeHtml16(model.description)}</p>
|
|
4596
4752
|
${turns}
|
|
4597
|
-
${model.error ? `<p class="absolute-voice-turn-quality__error">${
|
|
4753
|
+
${model.error ? `<p class="absolute-voice-turn-quality__error">${escapeHtml16(model.error)}</p>` : ""}
|
|
4598
4754
|
</section>`;
|
|
4599
4755
|
};
|
|
4600
4756
|
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}`;
|