@absolutejs/voice 0.0.22-beta.241 → 0.0.22-beta.243

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/vue/index.js CHANGED
@@ -1410,8 +1410,389 @@ var VoicePlatformCoverage = defineComponent4({
1410
1410
  };
1411
1411
  }
1412
1412
  });
1413
+ // src/vue/VoiceProofTrends.ts
1414
+ import { defineComponent as defineComponent5, h as h5 } from "vue";
1415
+
1416
+ // src/proofTrends.ts
1417
+ import { Elysia } from "elysia";
1418
+ var DEFAULT_VOICE_PROOF_TRENDS_MAX_AGE_MS = 24 * 60 * 60 * 1000;
1419
+ var normalizeMaxAgeMs = (value) => typeof value === "number" && Number.isFinite(value) && value > 0 ? value : DEFAULT_VOICE_PROOF_TRENDS_MAX_AGE_MS;
1420
+ var toTimeMs = (value) => {
1421
+ if (value instanceof Date) {
1422
+ return value.getTime();
1423
+ }
1424
+ if (typeof value === "number") {
1425
+ return value;
1426
+ }
1427
+ if (typeof value === "string") {
1428
+ return Date.parse(value);
1429
+ }
1430
+ return Date.now();
1431
+ };
1432
+ var buildVoiceProofTrendReport = (input = {}) => {
1433
+ const maxAgeMs = normalizeMaxAgeMs(input.maxAgeMs);
1434
+ const nowMs = toTimeMs(input.now);
1435
+ const generatedAtMs = typeof input.generatedAt === "string" ? Date.parse(input.generatedAt) : Number.NaN;
1436
+ const ageMs = Number.isFinite(generatedAtMs) && Number.isFinite(nowMs) ? Math.max(0, nowMs - generatedAtMs) : undefined;
1437
+ const freshUntil = Number.isFinite(generatedAtMs) && Number.isFinite(maxAgeMs) ? new Date(generatedAtMs + maxAgeMs).toISOString() : undefined;
1438
+ const isFresh = ageMs !== undefined && ageMs <= maxAgeMs;
1439
+ const status = input.status === "empty" ? "empty" : !isFresh ? "stale" : input.ok === true ? "pass" : "fail";
1440
+ return {
1441
+ ageMs,
1442
+ baseUrl: input.baseUrl,
1443
+ cycles: input.cycles ?? [],
1444
+ freshUntil,
1445
+ generatedAt: input.generatedAt,
1446
+ maxAgeMs,
1447
+ ok: input.ok === true && status === "pass",
1448
+ outputDir: input.outputDir,
1449
+ runId: input.runId,
1450
+ source: input.source ?? "",
1451
+ status,
1452
+ summary: input.summary ?? {}
1453
+ };
1454
+ };
1455
+ var buildEmptyVoiceProofTrendReport = (source = "", maxAgeMs) => buildVoiceProofTrendReport({
1456
+ maxAgeMs,
1457
+ source,
1458
+ status: "empty"
1459
+ });
1460
+ var normalizeVoiceProofTrendReport = (value, options = {}) => {
1461
+ if ("status" in value && value.status === "empty") {
1462
+ return buildEmptyVoiceProofTrendReport(value.source || options.source || "", options.maxAgeMs ?? value.maxAgeMs);
1463
+ }
1464
+ return buildVoiceProofTrendReport({
1465
+ ...value,
1466
+ maxAgeMs: options.maxAgeMs ?? value.maxAgeMs,
1467
+ source: value.source ?? options.source
1468
+ });
1469
+ };
1470
+ var readVoiceProofTrendReportFile = async (path, options = {}) => {
1471
+ const file = Bun.file(path);
1472
+ if (!await file.exists()) {
1473
+ return buildEmptyVoiceProofTrendReport(path, options.maxAgeMs);
1474
+ }
1475
+ try {
1476
+ const parsed = await file.json();
1477
+ return normalizeVoiceProofTrendReport(parsed, {
1478
+ maxAgeMs: options.maxAgeMs,
1479
+ source: path
1480
+ });
1481
+ } catch {
1482
+ return buildVoiceProofTrendReport({
1483
+ maxAgeMs: options.maxAgeMs,
1484
+ source: path
1485
+ });
1486
+ }
1487
+ };
1488
+ var createVoiceProofTrendRoutes = (options) => {
1489
+ const path = options.path ?? "/api/voice/proof-trends";
1490
+ const routes = new Elysia({
1491
+ name: options.name ?? "absolutejs-voice-proof-trends"
1492
+ });
1493
+ routes.get(path, async () => {
1494
+ const value = options.source !== undefined ? typeof options.source === "function" ? await options.source() : options.source : options.jsonPath ? await readVoiceProofTrendReportFile(options.jsonPath, {
1495
+ maxAgeMs: options.maxAgeMs
1496
+ }) : buildEmptyVoiceProofTrendReport("", options.maxAgeMs);
1497
+ return Response.json(normalizeVoiceProofTrendReport(value, {
1498
+ maxAgeMs: options.maxAgeMs,
1499
+ source: options.jsonPath
1500
+ }), { headers: options.headers });
1501
+ });
1502
+ return routes;
1503
+ };
1504
+ var formatVoiceProofTrendAge = (ageMs) => {
1505
+ if (typeof ageMs !== "number" || !Number.isFinite(ageMs)) {
1506
+ return "unknown";
1507
+ }
1508
+ const minutes = Math.floor(ageMs / 60000);
1509
+ if (minutes < 1) {
1510
+ return "less than 1m";
1511
+ }
1512
+ if (minutes < 60) {
1513
+ return `${minutes}m`;
1514
+ }
1515
+ const hours = Math.floor(minutes / 60);
1516
+ if (hours < 48) {
1517
+ return `${hours}h ${minutes % 60}m`;
1518
+ }
1519
+ const days = Math.floor(hours / 24);
1520
+ return `${days}d ${hours % 24}h`;
1521
+ };
1522
+
1523
+ // src/client/proofTrends.ts
1524
+ var fetchVoiceProofTrends = async (path = "/api/voice/proof-trends", options = {}) => {
1525
+ const fetchImpl = options.fetch ?? globalThis.fetch;
1526
+ const response = await fetchImpl(path);
1527
+ if (!response.ok) {
1528
+ throw new Error(`Voice proof trends failed: HTTP ${response.status}`);
1529
+ }
1530
+ return await response.json();
1531
+ };
1532
+ var createVoiceProofTrendsStore = (path = "/api/voice/proof-trends", options = {}) => {
1533
+ const listeners = new Set;
1534
+ let closed = false;
1535
+ let timer;
1536
+ let snapshot = {
1537
+ error: null,
1538
+ isLoading: false
1539
+ };
1540
+ const emit = () => {
1541
+ for (const listener of listeners) {
1542
+ listener();
1543
+ }
1544
+ };
1545
+ const refresh = async () => {
1546
+ if (closed) {
1547
+ return snapshot.report;
1548
+ }
1549
+ snapshot = {
1550
+ ...snapshot,
1551
+ error: null,
1552
+ isLoading: true
1553
+ };
1554
+ emit();
1555
+ try {
1556
+ const report = await fetchVoiceProofTrends(path, options);
1557
+ snapshot = {
1558
+ error: null,
1559
+ isLoading: false,
1560
+ report,
1561
+ updatedAt: Date.now()
1562
+ };
1563
+ emit();
1564
+ return report;
1565
+ } catch (error) {
1566
+ snapshot = {
1567
+ ...snapshot,
1568
+ error: error instanceof Error ? error.message : String(error),
1569
+ isLoading: false
1570
+ };
1571
+ emit();
1572
+ throw error;
1573
+ }
1574
+ };
1575
+ const close = () => {
1576
+ closed = true;
1577
+ if (timer) {
1578
+ clearInterval(timer);
1579
+ timer = undefined;
1580
+ }
1581
+ listeners.clear();
1582
+ };
1583
+ if (typeof window !== "undefined" && options.intervalMs && options.intervalMs > 0) {
1584
+ timer = setInterval(() => {
1585
+ refresh().catch(() => {});
1586
+ }, options.intervalMs);
1587
+ }
1588
+ return {
1589
+ close,
1590
+ getServerSnapshot: () => snapshot,
1591
+ getSnapshot: () => snapshot,
1592
+ refresh,
1593
+ subscribe: (listener) => {
1594
+ listeners.add(listener);
1595
+ return () => {
1596
+ listeners.delete(listener);
1597
+ };
1598
+ }
1599
+ };
1600
+ };
1601
+
1602
+ // src/client/proofTrendsWidget.ts
1603
+ var DEFAULT_TITLE5 = "Sustained Proof Trends";
1604
+ var DEFAULT_DESCRIPTION5 = "Repeated-cycle provider, latency, recovery, and readiness evidence with freshness gating.";
1605
+ var DEFAULT_LINKS2 = [
1606
+ { href: "/voice/proof-trends", label: "Trend page" },
1607
+ { href: "/api/voice/proof-trends", label: "Trend JSON" }
1608
+ ];
1609
+ var escapeHtml5 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
1610
+ var formatMs = (value) => typeof value === "number" && Number.isFinite(value) ? `${Math.round(value)}ms` : "n/a";
1611
+ var statusLabel = (report) => {
1612
+ if (!report) {
1613
+ return "No trend report";
1614
+ }
1615
+ if (report.status === "pass") {
1616
+ return `${report.summary.cycles ?? report.cycles.length} cycles passing`;
1617
+ }
1618
+ return report.status;
1619
+ };
1620
+ var createVoiceProofTrendsViewModel = (snapshot, options = {}) => {
1621
+ const report = snapshot.report;
1622
+ const metrics = report ? [
1623
+ { label: "Status", value: report.status.toUpperCase() },
1624
+ {
1625
+ label: "Cycles",
1626
+ value: String(report.summary.cycles ?? report.cycles.length)
1627
+ },
1628
+ {
1629
+ label: "Provider p95",
1630
+ value: formatMs(report.summary.maxProviderP95Ms)
1631
+ },
1632
+ { label: "Turn p95", value: formatMs(report.summary.maxTurnP95Ms) },
1633
+ { label: "Live p95", value: formatMs(report.summary.maxLiveP95Ms) },
1634
+ {
1635
+ label: "Artifact age",
1636
+ value: formatVoiceProofTrendAge(report.ageMs)
1637
+ },
1638
+ {
1639
+ label: "Stale after",
1640
+ value: formatVoiceProofTrendAge(report.maxAgeMs)
1641
+ }
1642
+ ] : [];
1643
+ return {
1644
+ description: options.description ?? DEFAULT_DESCRIPTION5,
1645
+ error: snapshot.error,
1646
+ isLoading: snapshot.isLoading,
1647
+ label: snapshot.error ? "Unavailable" : report ? statusLabel(report) : snapshot.isLoading ? "Checking" : "No trend report",
1648
+ links: options.links ?? DEFAULT_LINKS2,
1649
+ metrics,
1650
+ report,
1651
+ status: snapshot.error ? "error" : report ? report.status === "pass" ? "ready" : "warning" : snapshot.isLoading ? "loading" : "empty",
1652
+ title: options.title ?? DEFAULT_TITLE5,
1653
+ updatedAt: snapshot.updatedAt
1654
+ };
1655
+ };
1656
+ var renderVoiceProofTrendsHTML = (snapshot, options = {}) => {
1657
+ const model = createVoiceProofTrendsViewModel(snapshot, options);
1658
+ const metrics = model.metrics.length ? `<div class="absolute-voice-proof-trends__metrics">${model.metrics.map((metric) => `<article>
1659
+ <span>${escapeHtml5(metric.label)}</span>
1660
+ <strong>${escapeHtml5(metric.value)}</strong>
1661
+ </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>`;
1662
+ 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>` : "";
1663
+ return `<section class="absolute-voice-proof-trends absolute-voice-proof-trends--${escapeHtml5(model.status)}">
1664
+ <header class="absolute-voice-proof-trends__header">
1665
+ <span class="absolute-voice-proof-trends__eyebrow">${escapeHtml5(model.title)}</span>
1666
+ <strong class="absolute-voice-proof-trends__label">${escapeHtml5(model.label)}</strong>
1667
+ </header>
1668
+ <p class="absolute-voice-proof-trends__description">${escapeHtml5(model.description)}</p>
1669
+ ${metrics}
1670
+ ${links}
1671
+ ${model.error ? `<p class="absolute-voice-proof-trends__error">${escapeHtml5(model.error)}</p>` : ""}
1672
+ </section>`;
1673
+ };
1674
+ 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}`;
1675
+ var mountVoiceProofTrends = (element, path = "/api/voice/proof-trends", options = {}) => {
1676
+ const store = createVoiceProofTrendsStore(path, options);
1677
+ const render = () => {
1678
+ element.innerHTML = renderVoiceProofTrendsHTML(store.getSnapshot(), options);
1679
+ };
1680
+ const unsubscribe = store.subscribe(render);
1681
+ render();
1682
+ store.refresh().catch(() => {});
1683
+ return {
1684
+ close: () => {
1685
+ unsubscribe();
1686
+ store.close();
1687
+ },
1688
+ refresh: store.refresh
1689
+ };
1690
+ };
1691
+ var defineVoiceProofTrendsElement = (tagName = "absolute-voice-proof-trends") => {
1692
+ if (typeof window === "undefined" || typeof customElements === "undefined" || customElements.get(tagName)) {
1693
+ return;
1694
+ }
1695
+ customElements.define(tagName, class AbsoluteVoiceProofTrendsElement extends HTMLElement {
1696
+ mounted;
1697
+ connectedCallback() {
1698
+ this.mounted = mountVoiceProofTrends(this, this.getAttribute("path") ?? "/api/voice/proof-trends", {
1699
+ description: this.getAttribute("description") ?? undefined,
1700
+ intervalMs: Number(this.getAttribute("interval-ms") ?? 0) || undefined,
1701
+ title: this.getAttribute("title") ?? undefined
1702
+ });
1703
+ }
1704
+ disconnectedCallback() {
1705
+ this.mounted?.close();
1706
+ this.mounted = undefined;
1707
+ }
1708
+ });
1709
+ };
1710
+
1711
+ // src/vue/useVoiceProofTrends.ts
1712
+ import { onUnmounted as onUnmounted5, ref as ref5, shallowRef as shallowRef5 } from "vue";
1713
+ function useVoiceProofTrends(path = "/api/voice/proof-trends", options = {}) {
1714
+ const store = createVoiceProofTrendsStore(path, options);
1715
+ const error = ref5(null);
1716
+ const isLoading = ref5(false);
1717
+ const report = shallowRef5(undefined);
1718
+ const updatedAt = ref5(undefined);
1719
+ const sync = () => {
1720
+ const snapshot = store.getSnapshot();
1721
+ error.value = snapshot.error;
1722
+ isLoading.value = snapshot.isLoading;
1723
+ report.value = snapshot.report;
1724
+ updatedAt.value = snapshot.updatedAt;
1725
+ };
1726
+ const unsubscribe = store.subscribe(sync);
1727
+ sync();
1728
+ if (typeof window !== "undefined") {
1729
+ store.refresh().catch(() => {});
1730
+ }
1731
+ onUnmounted5(() => {
1732
+ unsubscribe();
1733
+ store.close();
1734
+ });
1735
+ return {
1736
+ error,
1737
+ isLoading,
1738
+ refresh: store.refresh,
1739
+ report,
1740
+ updatedAt
1741
+ };
1742
+ }
1743
+
1744
+ // src/vue/VoiceProofTrends.ts
1745
+ var VoiceProofTrends = defineComponent5({
1746
+ name: "VoiceProofTrends",
1747
+ props: {
1748
+ description: String,
1749
+ intervalMs: Number,
1750
+ path: {
1751
+ default: "/api/voice/proof-trends",
1752
+ type: String
1753
+ },
1754
+ title: String
1755
+ },
1756
+ setup(props) {
1757
+ const state = useVoiceProofTrends(props.path, {
1758
+ description: props.description,
1759
+ intervalMs: props.intervalMs,
1760
+ title: props.title
1761
+ });
1762
+ return () => {
1763
+ const model = createVoiceProofTrendsViewModel({
1764
+ error: state.error.value,
1765
+ isLoading: state.isLoading.value,
1766
+ report: state.report.value,
1767
+ updatedAt: state.updatedAt.value
1768
+ }, {
1769
+ description: props.description,
1770
+ intervalMs: props.intervalMs,
1771
+ title: props.title
1772
+ });
1773
+ return h5("section", {
1774
+ class: [
1775
+ "absolute-voice-proof-trends",
1776
+ `absolute-voice-proof-trends--${model.status}`
1777
+ ]
1778
+ }, [
1779
+ h5("header", { class: "absolute-voice-proof-trends__header" }, [
1780
+ h5("span", { class: "absolute-voice-proof-trends__eyebrow" }, model.title),
1781
+ h5("strong", { class: "absolute-voice-proof-trends__label" }, model.label)
1782
+ ]),
1783
+ h5("p", { class: "absolute-voice-proof-trends__description" }, model.description),
1784
+ model.metrics.length ? h5("div", { class: "absolute-voice-proof-trends__metrics" }, model.metrics.map((metric) => h5("article", { key: metric.label }, [
1785
+ h5("span", metric.label),
1786
+ h5("strong", metric.value)
1787
+ ]))) : h5("p", { class: "absolute-voice-proof-trends__empty" }, model.error ?? "Run the sustained proof trends script to populate evidence."),
1788
+ model.links.length ? h5("p", { class: "absolute-voice-proof-trends__links" }, model.links.map((link) => h5("a", { href: link.href, key: link.href }, link.label))) : null,
1789
+ model.error ? h5("p", { class: "absolute-voice-proof-trends__error" }, model.error) : null
1790
+ ]);
1791
+ };
1792
+ }
1793
+ });
1413
1794
  // src/vue/VoiceProviderSimulationControls.ts
1414
- import { computed, defineComponent as defineComponent5, h as h5 } from "vue";
1795
+ import { computed, defineComponent as defineComponent6, h as h6 } from "vue";
1415
1796
 
1416
1797
  // src/client/providerSimulationControls.ts
1417
1798
  var postSimulation = async (pathPrefix, mode, provider, fetchImpl) => {
@@ -1493,7 +1874,7 @@ var createVoiceProviderSimulationControlsStore = (options) => {
1493
1874
  };
1494
1875
 
1495
1876
  // src/client/providerSimulationControlsWidget.ts
1496
- var escapeHtml5 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
1877
+ var escapeHtml6 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
1497
1878
  var formatKind = (kind) => (kind ?? "stt").toUpperCase();
1498
1879
  var createVoiceProviderSimulationControlsViewModel = (snapshot, options) => {
1499
1880
  const configuredProviders = options.providers.filter((provider) => provider.configured !== false);
@@ -1513,18 +1894,18 @@ var createVoiceProviderSimulationControlsViewModel = (snapshot, options) => {
1513
1894
  };
1514
1895
  var renderVoiceProviderSimulationControlsHTML = (snapshot, options) => {
1515
1896
  const model = createVoiceProviderSimulationControlsViewModel(snapshot, options);
1516
- const failureButtons = model.failureProviders.map((provider) => `<button type="button" data-voice-provider-fail="${escapeHtml5(provider.provider)}"${!model.canSimulateFailure || snapshot.isRunning ? " disabled" : ""}>Simulate ${escapeHtml5(provider.provider)} ${escapeHtml5(formatKind(options.kind))} failure</button>`).join("");
1517
- const recoveryButtons = model.providers.map((provider) => `<button type="button" data-voice-provider-recover="${escapeHtml5(provider.provider)}"${snapshot.isRunning ? " disabled" : ""}>Mark ${escapeHtml5(provider.provider)} recovered</button>`).join("");
1897
+ const failureButtons = model.failureProviders.map((provider) => `<button type="button" data-voice-provider-fail="${escapeHtml6(provider.provider)}"${!model.canSimulateFailure || snapshot.isRunning ? " disabled" : ""}>Simulate ${escapeHtml6(provider.provider)} ${escapeHtml6(formatKind(options.kind))} failure</button>`).join("");
1898
+ const recoveryButtons = model.providers.map((provider) => `<button type="button" data-voice-provider-recover="${escapeHtml6(provider.provider)}"${snapshot.isRunning ? " disabled" : ""}>Mark ${escapeHtml6(provider.provider)} recovered</button>`).join("");
1518
1899
  return `<section class="absolute-voice-provider-simulation absolute-voice-provider-simulation--${snapshot.error ? "error" : snapshot.isRunning ? "running" : "ready"}">
1519
1900
  <header class="absolute-voice-provider-simulation__header">
1520
- <span class="absolute-voice-provider-simulation__eyebrow">${escapeHtml5(model.title)}</span>
1521
- <strong class="absolute-voice-provider-simulation__label">${escapeHtml5(model.label)}</strong>
1901
+ <span class="absolute-voice-provider-simulation__eyebrow">${escapeHtml6(model.title)}</span>
1902
+ <strong class="absolute-voice-provider-simulation__label">${escapeHtml6(model.label)}</strong>
1522
1903
  </header>
1523
- <p class="absolute-voice-provider-simulation__description">${escapeHtml5(model.description)}</p>
1524
- ${model.canSimulateFailure ? "" : `<p class="absolute-voice-provider-simulation__empty">${escapeHtml5(options.fallbackRequiredMessage ?? "Configure fallback providers before simulating failure.")}</p>`}
1904
+ <p class="absolute-voice-provider-simulation__description">${escapeHtml6(model.description)}</p>
1905
+ ${model.canSimulateFailure ? "" : `<p class="absolute-voice-provider-simulation__empty">${escapeHtml6(options.fallbackRequiredMessage ?? "Configure fallback providers before simulating failure.")}</p>`}
1525
1906
  <div class="absolute-voice-provider-simulation__actions">${failureButtons}${recoveryButtons}</div>
1526
- ${snapshot.error ? `<p class="absolute-voice-provider-simulation__error">${escapeHtml5(snapshot.error)}</p>` : ""}
1527
- ${model.resultText ? `<pre class="absolute-voice-provider-simulation__result">${escapeHtml5(model.resultText)}</pre>` : ""}
1907
+ ${snapshot.error ? `<p class="absolute-voice-provider-simulation__error">${escapeHtml6(snapshot.error)}</p>` : ""}
1908
+ ${model.resultText ? `<pre class="absolute-voice-provider-simulation__result">${escapeHtml6(model.resultText)}</pre>` : ""}
1528
1909
  </section>`;
1529
1910
  };
1530
1911
  var bindVoiceProviderSimulationControls = (element, store) => {
@@ -1590,15 +1971,15 @@ var defineVoiceProviderSimulationControlsElement = (tagName = "absolute-voice-pr
1590
1971
  };
1591
1972
 
1592
1973
  // src/vue/useVoiceProviderSimulationControls.ts
1593
- import { onUnmounted as onUnmounted5, ref as ref5 } from "vue";
1974
+ import { onUnmounted as onUnmounted6, ref as ref6 } from "vue";
1594
1975
  function useVoiceProviderSimulationControls(options) {
1595
1976
  const store = createVoiceProviderSimulationControlsStore(options);
1596
- const error = ref5(null);
1597
- const isRunning = ref5(false);
1598
- const lastResult = ref5(null);
1599
- const mode = ref5(null);
1600
- const provider = ref5(null);
1601
- const updatedAt = ref5(undefined);
1977
+ const error = ref6(null);
1978
+ const isRunning = ref6(false);
1979
+ const lastResult = ref6(null);
1980
+ const mode = ref6(null);
1981
+ const provider = ref6(null);
1982
+ const updatedAt = ref6(undefined);
1602
1983
  const sync = () => {
1603
1984
  const snapshot = store.getSnapshot();
1604
1985
  error.value = snapshot.error;
@@ -1610,7 +1991,7 @@ function useVoiceProviderSimulationControls(options) {
1610
1991
  };
1611
1992
  const unsubscribe = store.subscribe(sync);
1612
1993
  sync();
1613
- onUnmounted5(() => {
1994
+ onUnmounted6(() => {
1614
1995
  unsubscribe();
1615
1996
  store.close();
1616
1997
  });
@@ -1626,7 +2007,7 @@ function useVoiceProviderSimulationControls(options) {
1626
2007
  }
1627
2008
 
1628
2009
  // src/vue/VoiceProviderSimulationControls.ts
1629
- var VoiceProviderSimulationControls = defineComponent5({
2010
+ var VoiceProviderSimulationControls = defineComponent6({
1630
2011
  name: "VoiceProviderSimulationControls",
1631
2012
  props: {
1632
2013
  class: { default: "", type: String },
@@ -1668,40 +2049,40 @@ var VoiceProviderSimulationControls = defineComponent5({
1668
2049
  const run = (provider, mode) => {
1669
2050
  controls.run(provider, mode).catch(() => {});
1670
2051
  };
1671
- return () => h5("section", {
2052
+ return () => h6("section", {
1672
2053
  class: [
1673
2054
  "absolute-voice-provider-simulation",
1674
2055
  `absolute-voice-provider-simulation--${controls.error.value ? "error" : controls.isRunning.value ? "running" : "ready"}`,
1675
2056
  props.class
1676
2057
  ]
1677
2058
  }, [
1678
- h5("header", { class: "absolute-voice-provider-simulation__header" }, [
1679
- h5("span", { class: "absolute-voice-provider-simulation__eyebrow" }, model.value.title),
1680
- h5("strong", { class: "absolute-voice-provider-simulation__label" }, model.value.label)
2059
+ h6("header", { class: "absolute-voice-provider-simulation__header" }, [
2060
+ h6("span", { class: "absolute-voice-provider-simulation__eyebrow" }, model.value.title),
2061
+ h6("strong", { class: "absolute-voice-provider-simulation__label" }, model.value.label)
1681
2062
  ]),
1682
- h5("p", { class: "absolute-voice-provider-simulation__description" }, model.value.description),
1683
- model.value.canSimulateFailure ? null : h5("p", { class: "absolute-voice-provider-simulation__empty" }, props.fallbackRequiredMessage ?? "Configure fallback providers before simulating failure."),
1684
- h5("div", { class: "absolute-voice-provider-simulation__actions" }, [
1685
- ...model.value.failureProviders.map((provider) => h5("button", {
2063
+ h6("p", { class: "absolute-voice-provider-simulation__description" }, model.value.description),
2064
+ model.value.canSimulateFailure ? null : h6("p", { class: "absolute-voice-provider-simulation__empty" }, props.fallbackRequiredMessage ?? "Configure fallback providers before simulating failure."),
2065
+ h6("div", { class: "absolute-voice-provider-simulation__actions" }, [
2066
+ ...model.value.failureProviders.map((provider) => h6("button", {
1686
2067
  disabled: !model.value.canSimulateFailure || controls.isRunning.value,
1687
2068
  key: `fail-${provider.provider}`,
1688
2069
  onClick: () => run(provider.provider, "failure"),
1689
2070
  type: "button"
1690
2071
  }, `Simulate ${provider.provider} ${props.kind.toUpperCase()} failure`)),
1691
- ...model.value.providers.map((provider) => h5("button", {
2072
+ ...model.value.providers.map((provider) => h6("button", {
1692
2073
  disabled: controls.isRunning.value,
1693
2074
  key: `recover-${provider.provider}`,
1694
2075
  onClick: () => run(provider.provider, "recovery"),
1695
2076
  type: "button"
1696
2077
  }, `Mark ${provider.provider} recovered`))
1697
2078
  ]),
1698
- controls.error.value ? h5("p", { class: "absolute-voice-provider-simulation__error" }, controls.error.value) : null,
1699
- model.value.resultText ? h5("pre", { class: "absolute-voice-provider-simulation__result" }, model.value.resultText) : null
2079
+ controls.error.value ? h6("p", { class: "absolute-voice-provider-simulation__error" }, controls.error.value) : null,
2080
+ model.value.resultText ? h6("pre", { class: "absolute-voice-provider-simulation__result" }, model.value.resultText) : null
1700
2081
  ]);
1701
2082
  }
1702
2083
  });
1703
2084
  // src/vue/VoiceProviderCapabilities.ts
1704
- import { computed as computed2, defineComponent as defineComponent6, h as h6 } from "vue";
2085
+ import { computed as computed2, defineComponent as defineComponent7, h as h7 } from "vue";
1705
2086
 
1706
2087
  // src/client/providerCapabilities.ts
1707
2088
  var fetchVoiceProviderCapabilities = async (path = "/api/provider-capabilities", options = {}) => {
@@ -1783,9 +2164,9 @@ var createVoiceProviderCapabilitiesStore = (path = "/api/provider-capabilities",
1783
2164
  };
1784
2165
 
1785
2166
  // src/client/providerCapabilitiesWidget.ts
1786
- var DEFAULT_TITLE5 = "Provider Capabilities";
1787
- var DEFAULT_DESCRIPTION5 = "Configured, selected, and healthy voice providers for this deployment.";
1788
- var escapeHtml6 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
2167
+ var DEFAULT_TITLE6 = "Provider Capabilities";
2168
+ var DEFAULT_DESCRIPTION6 = "Configured, selected, and healthy voice providers for this deployment.";
2169
+ var escapeHtml7 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
1789
2170
  var formatProvider = (provider) => provider.split(/[-_\s]+/).filter(Boolean).map((part) => `${part[0]?.toUpperCase() ?? ""}${part.slice(1)}`).join(" ") || provider;
1790
2171
  var formatKind2 = (kind) => kind.toUpperCase();
1791
2172
  var formatStatus2 = (status) => status.split("-").map((part) => `${part[0]?.toUpperCase() ?? ""}${part.slice(1)}`).join(" ");
@@ -1829,36 +2210,36 @@ var createVoiceProviderCapabilitiesViewModel = (snapshot, options = {}) => {
1829
2210
  const selectedCount = snapshot.report?.selected ?? capabilities.filter((capability) => capability.selected).length;
1830
2211
  return {
1831
2212
  capabilities,
1832
- description: options.description ?? DEFAULT_DESCRIPTION5,
2213
+ description: options.description ?? DEFAULT_DESCRIPTION6,
1833
2214
  error: snapshot.error,
1834
2215
  isLoading: snapshot.isLoading,
1835
2216
  label: snapshot.error ? "Unavailable" : capabilities.length ? warningCount > 0 ? `${warningCount} needs attention` : `${selectedCount} selected` : snapshot.isLoading ? "Checking" : "No capabilities",
1836
2217
  status: snapshot.error ? "error" : capabilities.length ? warningCount > 0 ? "warning" : "ready" : snapshot.isLoading ? "loading" : "empty",
1837
- title: options.title ?? DEFAULT_TITLE5,
2218
+ title: options.title ?? DEFAULT_TITLE6,
1838
2219
  updatedAt: snapshot.updatedAt
1839
2220
  };
1840
2221
  };
1841
2222
  var renderVoiceProviderCapabilitiesHTML = (snapshot, options = {}) => {
1842
2223
  const model = createVoiceProviderCapabilitiesViewModel(snapshot, options);
1843
- 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--${escapeHtml6(capability.status)}">
2224
+ 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--${escapeHtml7(capability.status)}">
1844
2225
  <header>
1845
- <strong>${escapeHtml6(capability.label)}</strong>
1846
- <span>${escapeHtml6(formatStatus2(capability.status))}</span>
2226
+ <strong>${escapeHtml7(capability.label)}</strong>
2227
+ <span>${escapeHtml7(formatStatus2(capability.status))}</span>
1847
2228
  </header>
1848
- <p>${escapeHtml6(capability.detail)}</p>
2229
+ <p>${escapeHtml7(capability.detail)}</p>
1849
2230
  <dl>${capability.rows.map((row) => `<div>
1850
- <dt>${escapeHtml6(row.label)}</dt>
1851
- <dd>${escapeHtml6(row.value)}</dd>
2231
+ <dt>${escapeHtml7(row.label)}</dt>
2232
+ <dd>${escapeHtml7(row.value)}</dd>
1852
2233
  </div>`).join("")}</dl>
1853
2234
  </article>`).join("")}</div>` : '<p class="absolute-voice-provider-capabilities__empty">Configure provider capabilities to see deployment coverage.</p>';
1854
- return `<section class="absolute-voice-provider-capabilities absolute-voice-provider-capabilities--${escapeHtml6(model.status)}">
2235
+ return `<section class="absolute-voice-provider-capabilities absolute-voice-provider-capabilities--${escapeHtml7(model.status)}">
1855
2236
  <header class="absolute-voice-provider-capabilities__header">
1856
- <span class="absolute-voice-provider-capabilities__eyebrow">${escapeHtml6(model.title)}</span>
1857
- <strong class="absolute-voice-provider-capabilities__label">${escapeHtml6(model.label)}</strong>
2237
+ <span class="absolute-voice-provider-capabilities__eyebrow">${escapeHtml7(model.title)}</span>
2238
+ <strong class="absolute-voice-provider-capabilities__label">${escapeHtml7(model.label)}</strong>
1858
2239
  </header>
1859
- <p class="absolute-voice-provider-capabilities__description">${escapeHtml6(model.description)}</p>
2240
+ <p class="absolute-voice-provider-capabilities__description">${escapeHtml7(model.description)}</p>
1860
2241
  ${capabilities}
1861
- ${model.error ? `<p class="absolute-voice-provider-capabilities__error">${escapeHtml6(model.error)}</p>` : ""}
2242
+ ${model.error ? `<p class="absolute-voice-provider-capabilities__error">${escapeHtml7(model.error)}</p>` : ""}
1862
2243
  </section>`;
1863
2244
  };
1864
2245
  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}`;
@@ -1900,13 +2281,13 @@ var defineVoiceProviderCapabilitiesElement = (tagName = "absolute-voice-provider
1900
2281
  };
1901
2282
 
1902
2283
  // src/vue/useVoiceProviderCapabilities.ts
1903
- import { onUnmounted as onUnmounted6, shallowRef as shallowRef5 } from "vue";
2284
+ import { onUnmounted as onUnmounted7, shallowRef as shallowRef6 } from "vue";
1904
2285
  function useVoiceProviderCapabilities(path = "/api/provider-capabilities", options = {}) {
1905
2286
  const store = createVoiceProviderCapabilitiesStore(path, options);
1906
- const error = shallowRef5(null);
1907
- const isLoading = shallowRef5(false);
1908
- const report = shallowRef5();
1909
- const updatedAt = shallowRef5(undefined);
2287
+ const error = shallowRef6(null);
2288
+ const isLoading = shallowRef6(false);
2289
+ const report = shallowRef6();
2290
+ const updatedAt = shallowRef6(undefined);
1910
2291
  const sync = () => {
1911
2292
  const snapshot = store.getSnapshot();
1912
2293
  error.value = snapshot.error;
@@ -1917,7 +2298,7 @@ function useVoiceProviderCapabilities(path = "/api/provider-capabilities", optio
1917
2298
  const unsubscribe = store.subscribe(sync);
1918
2299
  sync();
1919
2300
  store.refresh().catch(() => {});
1920
- onUnmounted6(() => {
2301
+ onUnmounted7(() => {
1921
2302
  unsubscribe();
1922
2303
  store.close();
1923
2304
  });
@@ -1931,7 +2312,7 @@ function useVoiceProviderCapabilities(path = "/api/provider-capabilities", optio
1931
2312
  }
1932
2313
 
1933
2314
  // src/vue/VoiceProviderCapabilities.ts
1934
- var VoiceProviderCapabilities = defineComponent6({
2315
+ var VoiceProviderCapabilities = defineComponent7({
1935
2316
  name: "VoiceProviderCapabilities",
1936
2317
  props: {
1937
2318
  class: {
@@ -1968,44 +2349,44 @@ var VoiceProviderCapabilities = defineComponent6({
1968
2349
  report: capabilities.report.value,
1969
2350
  updatedAt: capabilities.updatedAt.value
1970
2351
  }, options));
1971
- return () => h6("section", {
2352
+ return () => h7("section", {
1972
2353
  class: [
1973
2354
  "absolute-voice-provider-capabilities",
1974
2355
  `absolute-voice-provider-capabilities--${model.value.status}`,
1975
2356
  props.class
1976
2357
  ]
1977
2358
  }, [
1978
- h6("header", { class: "absolute-voice-provider-capabilities__header" }, [
1979
- h6("span", { class: "absolute-voice-provider-capabilities__eyebrow" }, model.value.title),
1980
- h6("strong", { class: "absolute-voice-provider-capabilities__label" }, model.value.label)
2359
+ h7("header", { class: "absolute-voice-provider-capabilities__header" }, [
2360
+ h7("span", { class: "absolute-voice-provider-capabilities__eyebrow" }, model.value.title),
2361
+ h7("strong", { class: "absolute-voice-provider-capabilities__label" }, model.value.label)
1981
2362
  ]),
1982
- h6("p", { class: "absolute-voice-provider-capabilities__description" }, model.value.description),
1983
- model.value.capabilities.length ? h6("div", { class: "absolute-voice-provider-capabilities__providers" }, model.value.capabilities.map((capability) => h6("article", {
2363
+ h7("p", { class: "absolute-voice-provider-capabilities__description" }, model.value.description),
2364
+ model.value.capabilities.length ? h7("div", { class: "absolute-voice-provider-capabilities__providers" }, model.value.capabilities.map((capability) => h7("article", {
1984
2365
  class: [
1985
2366
  "absolute-voice-provider-capabilities__provider",
1986
2367
  `absolute-voice-provider-capabilities__provider--${capability.status}`
1987
2368
  ],
1988
2369
  key: `${capability.kind}:${capability.provider}`
1989
2370
  }, [
1990
- h6("header", [
1991
- h6("strong", capability.label),
1992
- h6("span", capability.status)
2371
+ h7("header", [
2372
+ h7("strong", capability.label),
2373
+ h7("span", capability.status)
1993
2374
  ]),
1994
- h6("p", capability.detail),
1995
- h6("dl", capability.rows.map((row) => h6("div", { key: row.label }, [
1996
- h6("dt", row.label),
1997
- h6("dd", row.value)
2375
+ h7("p", capability.detail),
2376
+ h7("dl", capability.rows.map((row) => h7("div", { key: row.label }, [
2377
+ h7("dt", row.label),
2378
+ h7("dd", row.value)
1998
2379
  ])))
1999
- ]))) : h6("p", { class: "absolute-voice-provider-capabilities__empty" }, "Configure provider capabilities to see deployment coverage."),
2000
- model.value.error ? h6("p", { class: "absolute-voice-provider-capabilities__error" }, model.value.error) : null
2380
+ ]))) : h7("p", { class: "absolute-voice-provider-capabilities__empty" }, "Configure provider capabilities to see deployment coverage."),
2381
+ model.value.error ? h7("p", { class: "absolute-voice-provider-capabilities__error" }, model.value.error) : null
2001
2382
  ]);
2002
2383
  }
2003
2384
  });
2004
2385
  // src/vue/VoiceProviderContracts.ts
2005
- import { defineComponent as defineComponent7, h as h7 } from "vue";
2386
+ import { defineComponent as defineComponent8, h as h8 } from "vue";
2006
2387
 
2007
2388
  // src/vue/useVoiceProviderContracts.ts
2008
- import { onUnmounted as onUnmounted7, shallowRef as shallowRef6 } from "vue";
2389
+ import { onUnmounted as onUnmounted8, shallowRef as shallowRef7 } from "vue";
2009
2390
 
2010
2391
  // src/client/providerContracts.ts
2011
2392
  var fetchVoiceProviderContracts = async (path = "/api/provider-contracts", options = {}) => {
@@ -2085,10 +2466,10 @@ var createVoiceProviderContractsStore = (path = "/api/provider-contracts", optio
2085
2466
  // src/vue/useVoiceProviderContracts.ts
2086
2467
  function useVoiceProviderContracts(path = "/api/provider-contracts", options = {}) {
2087
2468
  const store = createVoiceProviderContractsStore(path, options);
2088
- const error = shallowRef6(null);
2089
- const isLoading = shallowRef6(false);
2090
- const report = shallowRef6();
2091
- const updatedAt = shallowRef6(undefined);
2469
+ const error = shallowRef7(null);
2470
+ const isLoading = shallowRef7(false);
2471
+ const report = shallowRef7();
2472
+ const updatedAt = shallowRef7(undefined);
2092
2473
  const sync = () => {
2093
2474
  const snapshot = store.getSnapshot();
2094
2475
  error.value = snapshot.error;
@@ -2099,7 +2480,7 @@ function useVoiceProviderContracts(path = "/api/provider-contracts", options = {
2099
2480
  const unsubscribe = store.subscribe(sync);
2100
2481
  sync();
2101
2482
  store.refresh().catch(() => {});
2102
- onUnmounted7(() => {
2483
+ onUnmounted8(() => {
2103
2484
  unsubscribe();
2104
2485
  store.close();
2105
2486
  });
@@ -2113,9 +2494,9 @@ function useVoiceProviderContracts(path = "/api/provider-contracts", options = {
2113
2494
  }
2114
2495
 
2115
2496
  // src/client/providerContractsWidget.ts
2116
- var DEFAULT_TITLE6 = "Provider Contracts";
2117
- var DEFAULT_DESCRIPTION6 = "Production contract coverage for provider env, latency, fallback, streaming, and capabilities.";
2118
- var escapeHtml7 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
2497
+ var DEFAULT_TITLE7 = "Provider Contracts";
2498
+ var DEFAULT_DESCRIPTION7 = "Production contract coverage for provider env, latency, fallback, streaming, and capabilities.";
2499
+ var escapeHtml8 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
2119
2500
  var formatProvider2 = (provider) => provider.split(/[-_\s]+/).filter(Boolean).map((part) => `${part[0]?.toUpperCase() ?? ""}${part.slice(1)}`).join(" ") || provider;
2120
2501
  var formatStatus3 = (status) => status.split("-").map((part) => `${part[0]?.toUpperCase() ?? ""}${part.slice(1)}`).join(" ");
2121
2502
  var contractDetail = (row) => {
@@ -2147,38 +2528,38 @@ var createVoiceProviderContractsViewModel = (snapshot, options = {}) => {
2147
2528
  }));
2148
2529
  const warningCount = snapshot.report ? snapshot.report.failed + snapshot.report.warned : rows.filter((row) => row.status !== "pass").length;
2149
2530
  return {
2150
- description: options.description ?? DEFAULT_DESCRIPTION6,
2531
+ description: options.description ?? DEFAULT_DESCRIPTION7,
2151
2532
  error: snapshot.error,
2152
2533
  isLoading: snapshot.isLoading,
2153
2534
  label: snapshot.error ? "Unavailable" : rows.length ? warningCount > 0 ? `${warningCount} needs attention` : `${rows.length} passing` : snapshot.isLoading ? "Checking" : "No contracts",
2154
2535
  rows,
2155
2536
  status: snapshot.error ? "error" : rows.length ? warningCount > 0 ? "warning" : "ready" : snapshot.isLoading ? "loading" : "empty",
2156
- title: options.title ?? DEFAULT_TITLE6,
2537
+ title: options.title ?? DEFAULT_TITLE7,
2157
2538
  updatedAt: snapshot.updatedAt
2158
2539
  };
2159
2540
  };
2160
2541
  var renderVoiceProviderContractsHTML = (snapshot, options = {}) => {
2161
2542
  const model = createVoiceProviderContractsViewModel(snapshot, options);
2162
- 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--${escapeHtml7(row.status)}">
2543
+ 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--${escapeHtml8(row.status)}">
2163
2544
  <header>
2164
- <strong>${escapeHtml7(row.label)}</strong>
2165
- <span>${escapeHtml7(formatStatus3(row.status))}</span>
2545
+ <strong>${escapeHtml8(row.label)}</strong>
2546
+ <span>${escapeHtml8(formatStatus3(row.status))}</span>
2166
2547
  </header>
2167
- <p>${escapeHtml7(row.detail)}</p>
2168
- ${row.remediations.length ? `<ul class="absolute-voice-provider-contracts__remediations">${row.remediations.map((remediation) => `<li>${remediation.href ? `<a href="${escapeHtml7(remediation.href)}">${escapeHtml7(remediation.label)}</a>` : `<strong>${escapeHtml7(remediation.label)}</strong>`}<span>${escapeHtml7(remediation.detail)}</span></li>`).join("")}</ul>` : ""}
2548
+ <p>${escapeHtml8(row.detail)}</p>
2549
+ ${row.remediations.length ? `<ul class="absolute-voice-provider-contracts__remediations">${row.remediations.map((remediation) => `<li>${remediation.href ? `<a href="${escapeHtml8(remediation.href)}">${escapeHtml8(remediation.label)}</a>` : `<strong>${escapeHtml8(remediation.label)}</strong>`}<span>${escapeHtml8(remediation.detail)}</span></li>`).join("")}</ul>` : ""}
2169
2550
  <dl>${row.rows.map((item) => `<div>
2170
- <dt>${escapeHtml7(item.label)}</dt>
2171
- <dd>${escapeHtml7(item.value)}</dd>
2551
+ <dt>${escapeHtml8(item.label)}</dt>
2552
+ <dd>${escapeHtml8(item.value)}</dd>
2172
2553
  </div>`).join("")}</dl>
2173
2554
  </article>`).join("")}</div>` : '<p class="absolute-voice-provider-contracts__empty">Configure provider contracts to see production coverage.</p>';
2174
- return `<section class="absolute-voice-provider-contracts absolute-voice-provider-contracts--${escapeHtml7(model.status)}">
2555
+ return `<section class="absolute-voice-provider-contracts absolute-voice-provider-contracts--${escapeHtml8(model.status)}">
2175
2556
  <header class="absolute-voice-provider-contracts__header">
2176
- <span class="absolute-voice-provider-contracts__eyebrow">${escapeHtml7(model.title)}</span>
2177
- <strong class="absolute-voice-provider-contracts__label">${escapeHtml7(model.label)}</strong>
2557
+ <span class="absolute-voice-provider-contracts__eyebrow">${escapeHtml8(model.title)}</span>
2558
+ <strong class="absolute-voice-provider-contracts__label">${escapeHtml8(model.label)}</strong>
2178
2559
  </header>
2179
- <p class="absolute-voice-provider-contracts__description">${escapeHtml7(model.description)}</p>
2560
+ <p class="absolute-voice-provider-contracts__description">${escapeHtml8(model.description)}</p>
2180
2561
  ${rows}
2181
- ${model.error ? `<p class="absolute-voice-provider-contracts__error">${escapeHtml7(model.error)}</p>` : ""}
2562
+ ${model.error ? `<p class="absolute-voice-provider-contracts__error">${escapeHtml8(model.error)}</p>` : ""}
2182
2563
  </section>`;
2183
2564
  };
2184
2565
  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}`;
@@ -2220,7 +2601,7 @@ var defineVoiceProviderContractsElement = (tagName = "absolute-voice-provider-co
2220
2601
  };
2221
2602
 
2222
2603
  // src/vue/VoiceProviderContracts.ts
2223
- var VoiceProviderContracts = defineComponent7({
2604
+ var VoiceProviderContracts = defineComponent8({
2224
2605
  name: "VoiceProviderContracts",
2225
2606
  props: {
2226
2607
  description: String,
@@ -2248,49 +2629,49 @@ var VoiceProviderContracts = defineComponent7({
2248
2629
  intervalMs: props.intervalMs,
2249
2630
  title: props.title
2250
2631
  });
2251
- return h7("section", {
2632
+ return h8("section", {
2252
2633
  class: [
2253
2634
  "absolute-voice-provider-contracts",
2254
2635
  `absolute-voice-provider-contracts--${model.status}`
2255
2636
  ]
2256
2637
  }, [
2257
- h7("header", { class: "absolute-voice-provider-contracts__header" }, [
2258
- h7("span", { class: "absolute-voice-provider-contracts__eyebrow" }, model.title),
2259
- h7("strong", { class: "absolute-voice-provider-contracts__label" }, model.label)
2638
+ h8("header", { class: "absolute-voice-provider-contracts__header" }, [
2639
+ h8("span", { class: "absolute-voice-provider-contracts__eyebrow" }, model.title),
2640
+ h8("strong", { class: "absolute-voice-provider-contracts__label" }, model.label)
2260
2641
  ]),
2261
- h7("p", { class: "absolute-voice-provider-contracts__description" }, model.description),
2262
- model.rows.length ? h7("div", { class: "absolute-voice-provider-contracts__rows" }, model.rows.map((row) => h7("article", {
2642
+ h8("p", { class: "absolute-voice-provider-contracts__description" }, model.description),
2643
+ model.rows.length ? h8("div", { class: "absolute-voice-provider-contracts__rows" }, model.rows.map((row) => h8("article", {
2263
2644
  class: [
2264
2645
  "absolute-voice-provider-contracts__row",
2265
2646
  `absolute-voice-provider-contracts__row--${row.status}`
2266
2647
  ],
2267
2648
  key: `${row.kind}:${row.provider}`
2268
2649
  }, [
2269
- h7("header", [
2270
- h7("strong", row.label),
2271
- h7("span", row.status)
2650
+ h8("header", [
2651
+ h8("strong", row.label),
2652
+ h8("span", row.status)
2272
2653
  ]),
2273
- h7("p", row.detail),
2274
- row.remediations.length ? h7("ul", {
2654
+ h8("p", row.detail),
2655
+ row.remediations.length ? h8("ul", {
2275
2656
  class: "absolute-voice-provider-contracts__remediations"
2276
- }, row.remediations.map((remediation) => h7("li", {
2657
+ }, row.remediations.map((remediation) => h8("li", {
2277
2658
  key: `${row.kind}:${row.provider}:${remediation.label}`
2278
2659
  }, [
2279
- remediation.href ? h7("a", { href: remediation.href }, remediation.label) : h7("strong", remediation.label),
2280
- h7("span", remediation.detail)
2660
+ remediation.href ? h8("a", { href: remediation.href }, remediation.label) : h8("strong", remediation.label),
2661
+ h8("span", remediation.detail)
2281
2662
  ]))) : null,
2282
- h7("dl", row.rows.map((item) => h7("div", { key: item.label }, [
2283
- h7("dt", item.label),
2284
- h7("dd", item.value)
2663
+ h8("dl", row.rows.map((item) => h8("div", { key: item.label }, [
2664
+ h8("dt", item.label),
2665
+ h8("dd", item.value)
2285
2666
  ])))
2286
- ]))) : h7("p", { class: "absolute-voice-provider-contracts__empty" }, "Configure provider contracts to see production coverage."),
2287
- model.error ? h7("p", { class: "absolute-voice-provider-contracts__error" }, model.error) : null
2667
+ ]))) : h8("p", { class: "absolute-voice-provider-contracts__empty" }, "Configure provider contracts to see production coverage."),
2668
+ model.error ? h8("p", { class: "absolute-voice-provider-contracts__error" }, model.error) : null
2288
2669
  ]);
2289
2670
  };
2290
2671
  }
2291
2672
  });
2292
2673
  // src/vue/VoiceProviderStatus.ts
2293
- import { computed as computed3, defineComponent as defineComponent8, h as h8 } from "vue";
2674
+ import { computed as computed3, defineComponent as defineComponent9, h as h9 } from "vue";
2294
2675
 
2295
2676
  // src/client/providerStatus.ts
2296
2677
  var fetchVoiceProviderStatus = async (path = "/api/provider-status", options = {}) => {
@@ -2373,9 +2754,9 @@ var createVoiceProviderStatusStore = (path = "/api/provider-status", options = {
2373
2754
  };
2374
2755
 
2375
2756
  // src/client/providerStatusWidget.ts
2376
- var DEFAULT_TITLE7 = "Voice Providers";
2377
- var DEFAULT_DESCRIPTION7 = "Live provider health, fallback counts, latency, and suppression state from your self-hosted trace store.";
2378
- var escapeHtml8 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
2757
+ var DEFAULT_TITLE8 = "Voice Providers";
2758
+ var DEFAULT_DESCRIPTION8 = "Live provider health, fallback counts, latency, and suppression state from your self-hosted trace store.";
2759
+ var escapeHtml9 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
2379
2760
  var formatProvider3 = (provider) => provider.split(/[-_\s]+/).filter(Boolean).map((part) => `${part[0]?.toUpperCase() ?? ""}${part.slice(1)}`).join(" ") || provider;
2380
2761
  var formatStatus4 = (status) => status.split("-").map((part) => `${part[0]?.toUpperCase() ?? ""}${part.slice(1)}`).join(" ");
2381
2762
  var formatLatency = (value) => typeof value === "number" ? `${value}ms` : "No samples";
@@ -2419,37 +2800,37 @@ var createVoiceProviderStatusViewModel = (snapshot, options = {}) => {
2419
2800
  const warningCount = providers.filter((provider) => isWarningStatus2(provider.status)).length;
2420
2801
  const healthyCount = providers.filter((provider) => provider.status === "healthy").length;
2421
2802
  return {
2422
- description: options.description ?? DEFAULT_DESCRIPTION7,
2803
+ description: options.description ?? DEFAULT_DESCRIPTION8,
2423
2804
  error: snapshot.error,
2424
2805
  isLoading: snapshot.isLoading,
2425
2806
  label: snapshot.error ? "Unavailable" : providers.length ? warningCount > 0 ? `${warningCount} needs attention` : `${healthyCount} healthy` : snapshot.isLoading ? "Checking" : "No provider traffic",
2426
2807
  providers,
2427
2808
  status: snapshot.error ? "error" : providers.length ? warningCount > 0 ? "warning" : "ready" : snapshot.isLoading ? "loading" : "empty",
2428
- title: options.title ?? DEFAULT_TITLE7,
2809
+ title: options.title ?? DEFAULT_TITLE8,
2429
2810
  updatedAt: snapshot.updatedAt
2430
2811
  };
2431
2812
  };
2432
2813
  var renderVoiceProviderStatusHTML = (snapshot, options = {}) => {
2433
2814
  const model = createVoiceProviderStatusViewModel(snapshot, options);
2434
- 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--${escapeHtml8(provider.status)}">
2815
+ 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--${escapeHtml9(provider.status)}">
2435
2816
  <header>
2436
- <strong>${escapeHtml8(provider.label)}</strong>
2437
- <span>${escapeHtml8(formatStatus4(provider.status))}</span>
2817
+ <strong>${escapeHtml9(provider.label)}</strong>
2818
+ <span>${escapeHtml9(formatStatus4(provider.status))}</span>
2438
2819
  </header>
2439
- <p>${escapeHtml8(provider.detail)}</p>
2820
+ <p>${escapeHtml9(provider.detail)}</p>
2440
2821
  <dl>${provider.rows.map((row) => `<div>
2441
- <dt>${escapeHtml8(row.label)}</dt>
2442
- <dd>${escapeHtml8(row.value)}</dd>
2822
+ <dt>${escapeHtml9(row.label)}</dt>
2823
+ <dd>${escapeHtml9(row.value)}</dd>
2443
2824
  </div>`).join("")}</dl>
2444
2825
  </article>`).join("")}</div>` : '<p class="absolute-voice-provider-status__empty">Run voice traffic to see provider health.</p>';
2445
- return `<section class="absolute-voice-provider-status absolute-voice-provider-status--${escapeHtml8(model.status)}">
2826
+ return `<section class="absolute-voice-provider-status absolute-voice-provider-status--${escapeHtml9(model.status)}">
2446
2827
  <header class="absolute-voice-provider-status__header">
2447
- <span class="absolute-voice-provider-status__eyebrow">${escapeHtml8(model.title)}</span>
2448
- <strong class="absolute-voice-provider-status__label">${escapeHtml8(model.label)}</strong>
2828
+ <span class="absolute-voice-provider-status__eyebrow">${escapeHtml9(model.title)}</span>
2829
+ <strong class="absolute-voice-provider-status__label">${escapeHtml9(model.label)}</strong>
2449
2830
  </header>
2450
- <p class="absolute-voice-provider-status__description">${escapeHtml8(model.description)}</p>
2831
+ <p class="absolute-voice-provider-status__description">${escapeHtml9(model.description)}</p>
2451
2832
  ${providers}
2452
- ${model.error ? `<p class="absolute-voice-provider-status__error">${escapeHtml8(model.error)}</p>` : ""}
2833
+ ${model.error ? `<p class="absolute-voice-provider-status__error">${escapeHtml9(model.error)}</p>` : ""}
2453
2834
  </section>`;
2454
2835
  };
2455
2836
  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}`;
@@ -2491,13 +2872,13 @@ var defineVoiceProviderStatusElement = (tagName = "absolute-voice-provider-statu
2491
2872
  };
2492
2873
 
2493
2874
  // src/vue/useVoiceProviderStatus.ts
2494
- import { onUnmounted as onUnmounted8, ref as ref6, shallowRef as shallowRef7 } from "vue";
2875
+ import { onUnmounted as onUnmounted9, ref as ref7, shallowRef as shallowRef8 } from "vue";
2495
2876
  function useVoiceProviderStatus(path = "/api/provider-status", options = {}) {
2496
2877
  const store = createVoiceProviderStatusStore(path, options);
2497
- const error = ref6(null);
2498
- const isLoading = ref6(false);
2499
- const providers = shallowRef7([]);
2500
- const updatedAt = ref6(undefined);
2878
+ const error = ref7(null);
2879
+ const isLoading = ref7(false);
2880
+ const providers = shallowRef8([]);
2881
+ const updatedAt = ref7(undefined);
2501
2882
  const sync = () => {
2502
2883
  const snapshot = store.getSnapshot();
2503
2884
  error.value = snapshot.error;
@@ -2508,7 +2889,7 @@ function useVoiceProviderStatus(path = "/api/provider-status", options = {}) {
2508
2889
  const unsubscribe = store.subscribe(sync);
2509
2890
  sync();
2510
2891
  store.refresh().catch(() => {});
2511
- onUnmounted8(() => {
2892
+ onUnmounted9(() => {
2512
2893
  unsubscribe();
2513
2894
  store.close();
2514
2895
  });
@@ -2522,7 +2903,7 @@ function useVoiceProviderStatus(path = "/api/provider-status", options = {}) {
2522
2903
  }
2523
2904
 
2524
2905
  // src/vue/VoiceProviderStatus.ts
2525
- var VoiceProviderStatus = defineComponent8({
2906
+ var VoiceProviderStatus = defineComponent9({
2526
2907
  name: "VoiceProviderStatus",
2527
2908
  props: {
2528
2909
  class: {
@@ -2559,41 +2940,41 @@ var VoiceProviderStatus = defineComponent8({
2559
2940
  providers: status.providers.value,
2560
2941
  updatedAt: status.updatedAt.value
2561
2942
  }, options));
2562
- return () => h8("section", {
2943
+ return () => h9("section", {
2563
2944
  class: [
2564
2945
  "absolute-voice-provider-status",
2565
2946
  `absolute-voice-provider-status--${model.value.status}`,
2566
2947
  props.class
2567
2948
  ]
2568
2949
  }, [
2569
- h8("header", { class: "absolute-voice-provider-status__header" }, [
2570
- h8("span", { class: "absolute-voice-provider-status__eyebrow" }, model.value.title),
2571
- h8("strong", { class: "absolute-voice-provider-status__label" }, model.value.label)
2950
+ h9("header", { class: "absolute-voice-provider-status__header" }, [
2951
+ h9("span", { class: "absolute-voice-provider-status__eyebrow" }, model.value.title),
2952
+ h9("strong", { class: "absolute-voice-provider-status__label" }, model.value.label)
2572
2953
  ]),
2573
- h8("p", { class: "absolute-voice-provider-status__description" }, model.value.description),
2574
- model.value.providers.length ? h8("div", { class: "absolute-voice-provider-status__providers" }, model.value.providers.map((provider) => h8("article", {
2954
+ h9("p", { class: "absolute-voice-provider-status__description" }, model.value.description),
2955
+ model.value.providers.length ? h9("div", { class: "absolute-voice-provider-status__providers" }, model.value.providers.map((provider) => h9("article", {
2575
2956
  class: [
2576
2957
  "absolute-voice-provider-status__provider",
2577
2958
  `absolute-voice-provider-status__provider--${provider.status}`
2578
2959
  ],
2579
2960
  key: provider.provider
2580
2961
  }, [
2581
- h8("header", [
2582
- h8("strong", provider.label),
2583
- h8("span", provider.status)
2962
+ h9("header", [
2963
+ h9("strong", provider.label),
2964
+ h9("span", provider.status)
2584
2965
  ]),
2585
- h8("p", provider.detail),
2586
- h8("dl", provider.rows.map((row) => h8("div", { key: row.label }, [
2587
- h8("dt", row.label),
2588
- h8("dd", row.value)
2966
+ h9("p", provider.detail),
2967
+ h9("dl", provider.rows.map((row) => h9("div", { key: row.label }, [
2968
+ h9("dt", row.label),
2969
+ h9("dd", row.value)
2589
2970
  ])))
2590
- ]))) : h8("p", { class: "absolute-voice-provider-status__empty" }, "Run voice traffic to see provider health."),
2591
- model.value.error ? h8("p", { class: "absolute-voice-provider-status__error" }, model.value.error) : null
2971
+ ]))) : h9("p", { class: "absolute-voice-provider-status__empty" }, "Run voice traffic to see provider health."),
2972
+ model.value.error ? h9("p", { class: "absolute-voice-provider-status__error" }, model.value.error) : null
2592
2973
  ]);
2593
2974
  }
2594
2975
  });
2595
2976
  // src/vue/VoiceRoutingStatus.ts
2596
- import { computed as computed4, defineComponent as defineComponent9, h as h9 } from "vue";
2977
+ import { computed as computed4, defineComponent as defineComponent10, h as h10 } from "vue";
2597
2978
 
2598
2979
  // src/client/routingStatus.ts
2599
2980
  var fetchVoiceRoutingStatus = async (path = "/api/routing/latest", options = {}) => {
@@ -2676,9 +3057,9 @@ var createVoiceRoutingStatusStore = (path = "/api/routing/latest", options = {})
2676
3057
  };
2677
3058
 
2678
3059
  // src/client/routingStatusWidget.ts
2679
- var DEFAULT_TITLE8 = "Voice Routing";
2680
- var DEFAULT_DESCRIPTION8 = "Latest provider routing decision from the self-hosted trace store.";
2681
- var escapeHtml9 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
3060
+ var DEFAULT_TITLE9 = "Voice Routing";
3061
+ var DEFAULT_DESCRIPTION9 = "Latest provider routing decision from the self-hosted trace store.";
3062
+ var escapeHtml10 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
2682
3063
  var formatValue = (value, fallback = "None") => typeof value === "string" && value.trim() ? value : typeof value === "number" && Number.isFinite(value) ? String(value) : fallback;
2683
3064
  var createVoiceRoutingStatusViewModel = (snapshot, options = {}) => {
2684
3065
  const decision = snapshot.decision;
@@ -2702,30 +3083,30 @@ var createVoiceRoutingStatusViewModel = (snapshot, options = {}) => {
2702
3083
  ] : [];
2703
3084
  return {
2704
3085
  decision,
2705
- description: options.description ?? DEFAULT_DESCRIPTION8,
3086
+ description: options.description ?? DEFAULT_DESCRIPTION9,
2706
3087
  error: snapshot.error,
2707
3088
  isLoading: snapshot.isLoading,
2708
3089
  label: snapshot.error ? "Unavailable" : decision ? `${formatValue(decision.kind).toUpperCase()} ${formatValue(decision.status, "unknown")}` : snapshot.isLoading ? "Checking" : "No routing yet",
2709
3090
  rows,
2710
3091
  status: snapshot.error ? "error" : decision ? "ready" : snapshot.isLoading ? "loading" : "empty",
2711
- title: options.title ?? DEFAULT_TITLE8,
3092
+ title: options.title ?? DEFAULT_TITLE9,
2712
3093
  updatedAt: snapshot.updatedAt
2713
3094
  };
2714
3095
  };
2715
3096
  var renderVoiceRoutingStatusHTML = (snapshot, options = {}) => {
2716
3097
  const model = createVoiceRoutingStatusViewModel(snapshot, options);
2717
3098
  const rows = model.rows.length ? `<div class="absolute-voice-routing-status__grid">${model.rows.map((row) => `<div>
2718
- <span>${escapeHtml9(row.label)}</span>
2719
- <strong>${escapeHtml9(row.value)}</strong>
3099
+ <span>${escapeHtml10(row.label)}</span>
3100
+ <strong>${escapeHtml10(row.value)}</strong>
2720
3101
  </div>`).join("")}</div>` : '<p class="absolute-voice-routing-status__empty">Start a voice session to see the selected provider.</p>';
2721
- return `<section class="absolute-voice-routing-status absolute-voice-routing-status--${escapeHtml9(model.status)}">
3102
+ return `<section class="absolute-voice-routing-status absolute-voice-routing-status--${escapeHtml10(model.status)}">
2722
3103
  <header class="absolute-voice-routing-status__header">
2723
- <span class="absolute-voice-routing-status__eyebrow">${escapeHtml9(model.title)}</span>
2724
- <strong class="absolute-voice-routing-status__label">${escapeHtml9(model.label)}</strong>
3104
+ <span class="absolute-voice-routing-status__eyebrow">${escapeHtml10(model.title)}</span>
3105
+ <strong class="absolute-voice-routing-status__label">${escapeHtml10(model.label)}</strong>
2725
3106
  </header>
2726
- <p class="absolute-voice-routing-status__description">${escapeHtml9(model.description)}</p>
3107
+ <p class="absolute-voice-routing-status__description">${escapeHtml10(model.description)}</p>
2727
3108
  ${rows}
2728
- ${model.error ? `<p class="absolute-voice-routing-status__error">${escapeHtml9(model.error)}</p>` : ""}
3109
+ ${model.error ? `<p class="absolute-voice-routing-status__error">${escapeHtml10(model.error)}</p>` : ""}
2729
3110
  </section>`;
2730
3111
  };
2731
3112
  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}`;
@@ -2767,13 +3148,13 @@ var defineVoiceRoutingStatusElement = (tagName = "absolute-voice-routing-status"
2767
3148
  };
2768
3149
 
2769
3150
  // src/vue/useVoiceRoutingStatus.ts
2770
- import { onUnmounted as onUnmounted9, ref as ref7, shallowRef as shallowRef8 } from "vue";
3151
+ import { onUnmounted as onUnmounted10, ref as ref8, shallowRef as shallowRef9 } from "vue";
2771
3152
  function useVoiceRoutingStatus(path = "/api/routing/latest", options = {}) {
2772
3153
  const store = createVoiceRoutingStatusStore(path, options);
2773
- const decision = shallowRef8(null);
2774
- const error = ref7(null);
2775
- const isLoading = ref7(false);
2776
- const updatedAt = ref7(undefined);
3154
+ const decision = shallowRef9(null);
3155
+ const error = ref8(null);
3156
+ const isLoading = ref8(false);
3157
+ const updatedAt = ref8(undefined);
2777
3158
  const sync = () => {
2778
3159
  const snapshot = store.getSnapshot();
2779
3160
  decision.value = snapshot.decision;
@@ -2784,7 +3165,7 @@ function useVoiceRoutingStatus(path = "/api/routing/latest", options = {}) {
2784
3165
  const unsubscribe = store.subscribe(sync);
2785
3166
  sync();
2786
3167
  store.refresh().catch(() => {});
2787
- onUnmounted9(() => {
3168
+ onUnmounted10(() => {
2788
3169
  unsubscribe();
2789
3170
  store.close();
2790
3171
  });
@@ -2798,7 +3179,7 @@ function useVoiceRoutingStatus(path = "/api/routing/latest", options = {}) {
2798
3179
  }
2799
3180
 
2800
3181
  // src/vue/VoiceRoutingStatus.ts
2801
- var VoiceRoutingStatus = defineComponent9({
3182
+ var VoiceRoutingStatus = defineComponent10({
2802
3183
  name: "VoiceRoutingStatus",
2803
3184
  props: {
2804
3185
  class: {
@@ -2835,28 +3216,28 @@ var VoiceRoutingStatus = defineComponent9({
2835
3216
  isLoading: status.isLoading.value,
2836
3217
  updatedAt: status.updatedAt.value
2837
3218
  }, options));
2838
- return () => h9("section", {
3219
+ return () => h10("section", {
2839
3220
  class: [
2840
3221
  "absolute-voice-routing-status",
2841
3222
  `absolute-voice-routing-status--${model.value.status}`,
2842
3223
  props.class
2843
3224
  ]
2844
3225
  }, [
2845
- h9("header", { class: "absolute-voice-routing-status__header" }, [
2846
- h9("span", { class: "absolute-voice-routing-status__eyebrow" }, model.value.title),
2847
- h9("strong", { class: "absolute-voice-routing-status__label" }, model.value.label)
3226
+ h10("header", { class: "absolute-voice-routing-status__header" }, [
3227
+ h10("span", { class: "absolute-voice-routing-status__eyebrow" }, model.value.title),
3228
+ h10("strong", { class: "absolute-voice-routing-status__label" }, model.value.label)
2848
3229
  ]),
2849
- h9("p", { class: "absolute-voice-routing-status__description" }, model.value.description),
2850
- model.value.rows.length ? h9("div", { class: "absolute-voice-routing-status__grid" }, model.value.rows.map((row) => h9("div", { key: row.label }, [
2851
- h9("span", row.label),
2852
- h9("strong", row.value)
2853
- ]))) : h9("p", { class: "absolute-voice-routing-status__empty" }, "Start a voice session to see the selected provider."),
2854
- model.value.error ? h9("p", { class: "absolute-voice-routing-status__error" }, model.value.error) : null
3230
+ h10("p", { class: "absolute-voice-routing-status__description" }, model.value.description),
3231
+ model.value.rows.length ? h10("div", { class: "absolute-voice-routing-status__grid" }, model.value.rows.map((row) => h10("div", { key: row.label }, [
3232
+ h10("span", row.label),
3233
+ h10("strong", row.value)
3234
+ ]))) : h10("p", { class: "absolute-voice-routing-status__empty" }, "Start a voice session to see the selected provider."),
3235
+ model.value.error ? h10("p", { class: "absolute-voice-routing-status__error" }, model.value.error) : null
2855
3236
  ]);
2856
3237
  }
2857
3238
  });
2858
3239
  // src/vue/useVoiceAgentSquadStatus.ts
2859
- import { onUnmounted as onUnmounted10, ref as ref8, shallowRef as shallowRef9 } from "vue";
3240
+ import { onUnmounted as onUnmounted11, ref as ref9, shallowRef as shallowRef10 } from "vue";
2860
3241
 
2861
3242
  // src/client/traceTimeline.ts
2862
3243
  var fetchVoiceTraceTimeline = async (path = "/api/voice-traces", options = {}) => {
@@ -3015,11 +3396,11 @@ var createVoiceAgentSquadStatusStore = (path = "/api/voice-traces", options = {}
3015
3396
  // src/vue/useVoiceAgentSquadStatus.ts
3016
3397
  function useVoiceAgentSquadStatus(path = "/api/voice-traces", options = {}) {
3017
3398
  const store = createVoiceAgentSquadStatusStore(path, options);
3018
- const current = shallowRef9(undefined);
3019
- const error = ref8(null);
3020
- const isLoading = ref8(false);
3021
- const report = shallowRef9(undefined);
3022
- const updatedAt = ref8(undefined);
3399
+ const current = shallowRef10(undefined);
3400
+ const error = ref9(null);
3401
+ const isLoading = ref9(false);
3402
+ const report = shallowRef10(undefined);
3403
+ const updatedAt = ref9(undefined);
3023
3404
  const sync = () => {
3024
3405
  const snapshot = store.getSnapshot();
3025
3406
  current.value = snapshot.report.current;
@@ -3033,7 +3414,7 @@ function useVoiceAgentSquadStatus(path = "/api/voice-traces", options = {}) {
3033
3414
  if (typeof window !== "undefined") {
3034
3415
  store.refresh().catch(() => {});
3035
3416
  }
3036
- onUnmounted10(() => {
3417
+ onUnmounted11(() => {
3037
3418
  unsubscribe();
3038
3419
  store.close();
3039
3420
  });
@@ -3047,7 +3428,7 @@ function useVoiceAgentSquadStatus(path = "/api/voice-traces", options = {}) {
3047
3428
  };
3048
3429
  }
3049
3430
  // src/vue/VoiceTurnLatency.ts
3050
- import { computed as computed5, defineComponent as defineComponent10, h as h10 } from "vue";
3431
+ import { computed as computed5, defineComponent as defineComponent11, h as h11 } from "vue";
3051
3432
 
3052
3433
  // src/client/turnLatency.ts
3053
3434
  var fetchVoiceTurnLatency = async (path = "/api/turn-latency", options = {}) => {
@@ -3153,56 +3534,56 @@ var createVoiceTurnLatencyStore = (path = "/api/turn-latency", options = {}) =>
3153
3534
  };
3154
3535
 
3155
3536
  // src/client/turnLatencyWidget.ts
3156
- var DEFAULT_TITLE9 = "Turn Latency";
3157
- var DEFAULT_DESCRIPTION9 = "Per-turn timing from first transcript to commit and assistant response start.";
3537
+ var DEFAULT_TITLE10 = "Turn Latency";
3538
+ var DEFAULT_DESCRIPTION10 = "Per-turn timing from first transcript to commit and assistant response start.";
3158
3539
  var DEFAULT_PROOF_LABEL = "Run latency proof";
3159
- var escapeHtml10 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
3160
- var formatMs = (value) => typeof value === "number" ? `${Math.round(value)}ms` : "n/a";
3540
+ var escapeHtml11 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
3541
+ var formatMs2 = (value) => typeof value === "number" ? `${Math.round(value)}ms` : "n/a";
3161
3542
  var createVoiceTurnLatencyViewModel = (snapshot, options = {}) => {
3162
3543
  const turns = (snapshot.report?.turns ?? []).map((turn) => ({
3163
3544
  ...turn,
3164
3545
  label: turn.text || "Empty turn",
3165
3546
  rows: turn.stages.map((stage) => ({
3166
3547
  label: stage.label,
3167
- value: formatMs(stage.valueMs)
3548
+ value: formatMs2(stage.valueMs)
3168
3549
  }))
3169
3550
  }));
3170
3551
  const warningCount = snapshot.report?.warnings ?? turns.filter((turn) => turn.status === "warn").length;
3171
3552
  const failedCount = snapshot.report?.failed ?? turns.filter((turn) => turn.status === "fail").length;
3172
3553
  return {
3173
- description: options.description ?? DEFAULT_DESCRIPTION9,
3554
+ description: options.description ?? DEFAULT_DESCRIPTION10,
3174
3555
  error: snapshot.error,
3175
3556
  isLoading: snapshot.isLoading,
3176
- label: snapshot.error ? "Unavailable" : turns.length ? failedCount > 0 ? `${failedCount} slow` : warningCount > 0 ? `${warningCount} warnings` : `avg ${formatMs(snapshot.report?.averageTotalMs)}` : snapshot.isLoading ? "Checking" : "No turns",
3557
+ label: snapshot.error ? "Unavailable" : turns.length ? failedCount > 0 ? `${failedCount} slow` : warningCount > 0 ? `${warningCount} warnings` : `avg ${formatMs2(snapshot.report?.averageTotalMs)}` : snapshot.isLoading ? "Checking" : "No turns",
3177
3558
  proofLabel: options.proofPath ? options.proofLabel ?? DEFAULT_PROOF_LABEL : undefined,
3178
3559
  showProofAction: Boolean(options.proofPath),
3179
3560
  status: snapshot.error ? "error" : turns.length ? failedCount > 0 || warningCount > 0 ? "warning" : "ready" : snapshot.isLoading ? "loading" : "empty",
3180
- title: options.title ?? DEFAULT_TITLE9,
3561
+ title: options.title ?? DEFAULT_TITLE10,
3181
3562
  turns,
3182
3563
  updatedAt: snapshot.updatedAt
3183
3564
  };
3184
3565
  };
3185
3566
  var renderVoiceTurnLatencyHTML = (snapshot, options = {}) => {
3186
3567
  const model = createVoiceTurnLatencyViewModel(snapshot, options);
3187
- 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--${escapeHtml10(turn.status)}">
3568
+ 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--${escapeHtml11(turn.status)}">
3188
3569
  <header>
3189
- <strong>${escapeHtml10(turn.label)}</strong>
3190
- <span>${escapeHtml10(turn.status)}</span>
3570
+ <strong>${escapeHtml11(turn.label)}</strong>
3571
+ <span>${escapeHtml11(turn.status)}</span>
3191
3572
  </header>
3192
3573
  <dl>${turn.rows.map((row) => `<div>
3193
- <dt>${escapeHtml10(row.label)}</dt>
3194
- <dd>${escapeHtml10(row.value)}</dd>
3574
+ <dt>${escapeHtml11(row.label)}</dt>
3575
+ <dd>${escapeHtml11(row.value)}</dd>
3195
3576
  </div>`).join("")}</dl>
3196
3577
  </article>`).join("")}</div>` : '<p class="absolute-voice-turn-latency__empty">Complete a voice turn to see latency diagnostics.</p>';
3197
- return `<section class="absolute-voice-turn-latency absolute-voice-turn-latency--${escapeHtml10(model.status)}">
3578
+ return `<section class="absolute-voice-turn-latency absolute-voice-turn-latency--${escapeHtml11(model.status)}">
3198
3579
  <header class="absolute-voice-turn-latency__header">
3199
- <span class="absolute-voice-turn-latency__eyebrow">${escapeHtml10(model.title)}</span>
3200
- <strong class="absolute-voice-turn-latency__label">${escapeHtml10(model.label)}</strong>
3580
+ <span class="absolute-voice-turn-latency__eyebrow">${escapeHtml11(model.title)}</span>
3581
+ <strong class="absolute-voice-turn-latency__label">${escapeHtml11(model.label)}</strong>
3201
3582
  </header>
3202
- <p class="absolute-voice-turn-latency__description">${escapeHtml10(model.description)}</p>
3203
- ${model.showProofAction ? `<button class="absolute-voice-turn-latency__proof" data-absolute-voice-turn-latency-proof type="button">${escapeHtml10(model.proofLabel ?? DEFAULT_PROOF_LABEL)}</button>` : ""}
3583
+ <p class="absolute-voice-turn-latency__description">${escapeHtml11(model.description)}</p>
3584
+ ${model.showProofAction ? `<button class="absolute-voice-turn-latency__proof" data-absolute-voice-turn-latency-proof type="button">${escapeHtml11(model.proofLabel ?? DEFAULT_PROOF_LABEL)}</button>` : ""}
3204
3585
  ${turns}
3205
- ${model.error ? `<p class="absolute-voice-turn-latency__error">${escapeHtml10(model.error)}</p>` : ""}
3586
+ ${model.error ? `<p class="absolute-voice-turn-latency__error">${escapeHtml11(model.error)}</p>` : ""}
3206
3587
  </section>`;
3207
3588
  };
3208
3589
  var mountVoiceTurnLatency = (element, path = "/api/turn-latency", options = {}) => {
@@ -3253,13 +3634,13 @@ var defineVoiceTurnLatencyElement = (tagName = "absolute-voice-turn-latency") =>
3253
3634
  };
3254
3635
 
3255
3636
  // src/vue/useVoiceTurnLatency.ts
3256
- import { onUnmounted as onUnmounted11, shallowRef as shallowRef10 } from "vue";
3637
+ import { onUnmounted as onUnmounted12, shallowRef as shallowRef11 } from "vue";
3257
3638
  function useVoiceTurnLatency(path = "/api/turn-latency", options = {}) {
3258
3639
  const store = createVoiceTurnLatencyStore(path, options);
3259
- const error = shallowRef10(null);
3260
- const isLoading = shallowRef10(false);
3261
- const report = shallowRef10();
3262
- const updatedAt = shallowRef10(undefined);
3640
+ const error = shallowRef11(null);
3641
+ const isLoading = shallowRef11(false);
3642
+ const report = shallowRef11();
3643
+ const updatedAt = shallowRef11(undefined);
3263
3644
  const sync = () => {
3264
3645
  const snapshot = store.getSnapshot();
3265
3646
  error.value = snapshot.error;
@@ -3270,7 +3651,7 @@ function useVoiceTurnLatency(path = "/api/turn-latency", options = {}) {
3270
3651
  const unsubscribe = store.subscribe(sync);
3271
3652
  sync();
3272
3653
  store.refresh().catch(() => {});
3273
- onUnmounted11(() => {
3654
+ onUnmounted12(() => {
3274
3655
  unsubscribe();
3275
3656
  store.close();
3276
3657
  });
@@ -3285,7 +3666,7 @@ function useVoiceTurnLatency(path = "/api/turn-latency", options = {}) {
3285
3666
  }
3286
3667
 
3287
3668
  // src/vue/VoiceTurnLatency.ts
3288
- var VoiceTurnLatency = defineComponent10({
3669
+ var VoiceTurnLatency = defineComponent11({
3289
3670
  name: "VoiceTurnLatency",
3290
3671
  props: {
3291
3672
  class: { default: "", type: String },
@@ -3311,47 +3692,47 @@ var VoiceTurnLatency = defineComponent10({
3311
3692
  report: latency.report.value,
3312
3693
  updatedAt: latency.updatedAt.value
3313
3694
  }, options));
3314
- return () => h10("section", {
3695
+ return () => h11("section", {
3315
3696
  class: [
3316
3697
  "absolute-voice-turn-latency",
3317
3698
  `absolute-voice-turn-latency--${model.value.status}`,
3318
3699
  props.class
3319
3700
  ]
3320
3701
  }, [
3321
- h10("header", { class: "absolute-voice-turn-latency__header" }, [
3322
- h10("span", { class: "absolute-voice-turn-latency__eyebrow" }, model.value.title),
3323
- h10("strong", { class: "absolute-voice-turn-latency__label" }, model.value.label)
3702
+ h11("header", { class: "absolute-voice-turn-latency__header" }, [
3703
+ h11("span", { class: "absolute-voice-turn-latency__eyebrow" }, model.value.title),
3704
+ h11("strong", { class: "absolute-voice-turn-latency__label" }, model.value.label)
3324
3705
  ]),
3325
- h10("p", { class: "absolute-voice-turn-latency__description" }, model.value.description),
3326
- model.value.showProofAction ? h10("button", {
3706
+ h11("p", { class: "absolute-voice-turn-latency__description" }, model.value.description),
3707
+ model.value.showProofAction ? h11("button", {
3327
3708
  class: "absolute-voice-turn-latency__proof",
3328
3709
  onClick: () => {
3329
3710
  latency.runProof().catch(() => {});
3330
3711
  },
3331
3712
  type: "button"
3332
3713
  }, model.value.proofLabel) : null,
3333
- model.value.turns.length ? h10("div", { class: "absolute-voice-turn-latency__turns" }, model.value.turns.map((turn) => h10("article", {
3714
+ model.value.turns.length ? h11("div", { class: "absolute-voice-turn-latency__turns" }, model.value.turns.map((turn) => h11("article", {
3334
3715
  class: [
3335
3716
  "absolute-voice-turn-latency__turn",
3336
3717
  `absolute-voice-turn-latency__turn--${turn.status}`
3337
3718
  ],
3338
3719
  key: `${turn.sessionId}:${turn.turnId}`
3339
3720
  }, [
3340
- h10("header", [
3341
- h10("strong", turn.label),
3342
- h10("span", turn.status)
3721
+ h11("header", [
3722
+ h11("strong", turn.label),
3723
+ h11("span", turn.status)
3343
3724
  ]),
3344
- h10("dl", turn.rows.map((row) => h10("div", { key: row.label }, [
3345
- h10("dt", row.label),
3346
- h10("dd", row.value)
3725
+ h11("dl", turn.rows.map((row) => h11("div", { key: row.label }, [
3726
+ h11("dt", row.label),
3727
+ h11("dd", row.value)
3347
3728
  ])))
3348
- ]))) : h10("p", { class: "absolute-voice-turn-latency__empty" }, "Complete a voice turn to see latency diagnostics."),
3349
- model.value.error ? h10("p", { class: "absolute-voice-turn-latency__error" }, model.value.error) : null
3729
+ ]))) : h11("p", { class: "absolute-voice-turn-latency__empty" }, "Complete a voice turn to see latency diagnostics."),
3730
+ model.value.error ? h11("p", { class: "absolute-voice-turn-latency__error" }, model.value.error) : null
3350
3731
  ]);
3351
3732
  }
3352
3733
  });
3353
3734
  // src/vue/VoiceTurnQuality.ts
3354
- import { computed as computed6, defineComponent as defineComponent11, h as h11 } from "vue";
3735
+ import { computed as computed6, defineComponent as defineComponent12, h as h12 } from "vue";
3355
3736
 
3356
3737
  // src/client/turnQuality.ts
3357
3738
  var fetchVoiceTurnQuality = async (path = "/api/turn-quality", options = {}) => {
@@ -3433,9 +3814,9 @@ var createVoiceTurnQualityStore = (path = "/api/turn-quality", options = {}) =>
3433
3814
  };
3434
3815
 
3435
3816
  // src/client/turnQualityWidget.ts
3436
- var DEFAULT_TITLE10 = "Turn Quality";
3437
- var DEFAULT_DESCRIPTION10 = "Per-turn STT confidence, fallback selection, corrections, and transcript coverage.";
3438
- var escapeHtml11 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
3817
+ var DEFAULT_TITLE11 = "Turn Quality";
3818
+ var DEFAULT_DESCRIPTION11 = "Per-turn STT confidence, fallback selection, corrections, and transcript coverage.";
3819
+ var escapeHtml12 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
3439
3820
  var formatConfidence = (value) => typeof value === "number" ? `${Math.round(value * 100)}%` : "n/a";
3440
3821
  var formatMaybe = (value) => value === undefined || value === "" ? "n/a" : String(value);
3441
3822
  var getTurnDetail = (turn) => {
@@ -3473,37 +3854,37 @@ var createVoiceTurnQualityViewModel = (snapshot, options = {}) => {
3473
3854
  const warningCount = snapshot.report?.warnings ?? turns.filter((turn) => turn.status === "warn").length;
3474
3855
  const failedCount = snapshot.report?.failed ?? turns.filter((turn) => turn.status === "fail").length;
3475
3856
  return {
3476
- description: options.description ?? DEFAULT_DESCRIPTION10,
3857
+ description: options.description ?? DEFAULT_DESCRIPTION11,
3477
3858
  error: snapshot.error,
3478
3859
  isLoading: snapshot.isLoading,
3479
3860
  label: snapshot.error ? "Unavailable" : turns.length ? failedCount > 0 ? `${failedCount} failed` : warningCount > 0 ? `${warningCount} warnings` : `${turns.length} healthy` : snapshot.isLoading ? "Checking" : "No turns",
3480
3861
  status: snapshot.error ? "error" : turns.length ? failedCount > 0 || warningCount > 0 ? "warning" : "ready" : snapshot.isLoading ? "loading" : "empty",
3481
- title: options.title ?? DEFAULT_TITLE10,
3862
+ title: options.title ?? DEFAULT_TITLE11,
3482
3863
  turns,
3483
3864
  updatedAt: snapshot.updatedAt
3484
3865
  };
3485
3866
  };
3486
3867
  var renderVoiceTurnQualityHTML = (snapshot, options = {}) => {
3487
3868
  const model = createVoiceTurnQualityViewModel(snapshot, options);
3488
- 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--${escapeHtml11(turn.status)}">
3869
+ 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--${escapeHtml12(turn.status)}">
3489
3870
  <header>
3490
- <strong>${escapeHtml11(turn.label)}</strong>
3491
- <span>${escapeHtml11(turn.status)}</span>
3871
+ <strong>${escapeHtml12(turn.label)}</strong>
3872
+ <span>${escapeHtml12(turn.status)}</span>
3492
3873
  </header>
3493
- <p>${escapeHtml11(turn.detail)}</p>
3874
+ <p>${escapeHtml12(turn.detail)}</p>
3494
3875
  <dl>${turn.rows.map((row) => `<div>
3495
- <dt>${escapeHtml11(row.label)}</dt>
3496
- <dd>${escapeHtml11(row.value)}</dd>
3876
+ <dt>${escapeHtml12(row.label)}</dt>
3877
+ <dd>${escapeHtml12(row.value)}</dd>
3497
3878
  </div>`).join("")}</dl>
3498
3879
  </article>`).join("")}</div>` : '<p class="absolute-voice-turn-quality__empty">Complete a voice turn to see STT quality diagnostics.</p>';
3499
- return `<section class="absolute-voice-turn-quality absolute-voice-turn-quality--${escapeHtml11(model.status)}">
3880
+ return `<section class="absolute-voice-turn-quality absolute-voice-turn-quality--${escapeHtml12(model.status)}">
3500
3881
  <header class="absolute-voice-turn-quality__header">
3501
- <span class="absolute-voice-turn-quality__eyebrow">${escapeHtml11(model.title)}</span>
3502
- <strong class="absolute-voice-turn-quality__label">${escapeHtml11(model.label)}</strong>
3882
+ <span class="absolute-voice-turn-quality__eyebrow">${escapeHtml12(model.title)}</span>
3883
+ <strong class="absolute-voice-turn-quality__label">${escapeHtml12(model.label)}</strong>
3503
3884
  </header>
3504
- <p class="absolute-voice-turn-quality__description">${escapeHtml11(model.description)}</p>
3885
+ <p class="absolute-voice-turn-quality__description">${escapeHtml12(model.description)}</p>
3505
3886
  ${turns}
3506
- ${model.error ? `<p class="absolute-voice-turn-quality__error">${escapeHtml11(model.error)}</p>` : ""}
3887
+ ${model.error ? `<p class="absolute-voice-turn-quality__error">${escapeHtml12(model.error)}</p>` : ""}
3507
3888
  </section>`;
3508
3889
  };
3509
3890
  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}`;
@@ -3545,13 +3926,13 @@ var defineVoiceTurnQualityElement = (tagName = "absolute-voice-turn-quality") =>
3545
3926
  };
3546
3927
 
3547
3928
  // src/vue/useVoiceTurnQuality.ts
3548
- import { onUnmounted as onUnmounted12, shallowRef as shallowRef11 } from "vue";
3929
+ import { onUnmounted as onUnmounted13, shallowRef as shallowRef12 } from "vue";
3549
3930
  function useVoiceTurnQuality(path = "/api/turn-quality", options = {}) {
3550
3931
  const store = createVoiceTurnQualityStore(path, options);
3551
- const error = shallowRef11(null);
3552
- const isLoading = shallowRef11(false);
3553
- const report = shallowRef11();
3554
- const updatedAt = shallowRef11(undefined);
3932
+ const error = shallowRef12(null);
3933
+ const isLoading = shallowRef12(false);
3934
+ const report = shallowRef12();
3935
+ const updatedAt = shallowRef12(undefined);
3555
3936
  const sync = () => {
3556
3937
  const snapshot = store.getSnapshot();
3557
3938
  error.value = snapshot.error;
@@ -3562,7 +3943,7 @@ function useVoiceTurnQuality(path = "/api/turn-quality", options = {}) {
3562
3943
  const unsubscribe = store.subscribe(sync);
3563
3944
  sync();
3564
3945
  store.refresh().catch(() => {});
3565
- onUnmounted12(() => {
3946
+ onUnmounted13(() => {
3566
3947
  unsubscribe();
3567
3948
  store.close();
3568
3949
  });
@@ -3570,7 +3951,7 @@ function useVoiceTurnQuality(path = "/api/turn-quality", options = {}) {
3570
3951
  }
3571
3952
 
3572
3953
  // src/vue/VoiceTurnQuality.ts
3573
- var VoiceTurnQuality = defineComponent11({
3954
+ var VoiceTurnQuality = defineComponent12({
3574
3955
  name: "VoiceTurnQuality",
3575
3956
  props: {
3576
3957
  class: { default: "", type: String },
@@ -3592,41 +3973,41 @@ var VoiceTurnQuality = defineComponent11({
3592
3973
  report: quality.report.value,
3593
3974
  updatedAt: quality.updatedAt.value
3594
3975
  }, options));
3595
- return () => h11("section", {
3976
+ return () => h12("section", {
3596
3977
  class: [
3597
3978
  "absolute-voice-turn-quality",
3598
3979
  `absolute-voice-turn-quality--${model.value.status}`,
3599
3980
  props.class
3600
3981
  ]
3601
3982
  }, [
3602
- h11("header", { class: "absolute-voice-turn-quality__header" }, [
3603
- h11("span", { class: "absolute-voice-turn-quality__eyebrow" }, model.value.title),
3604
- h11("strong", { class: "absolute-voice-turn-quality__label" }, model.value.label)
3983
+ h12("header", { class: "absolute-voice-turn-quality__header" }, [
3984
+ h12("span", { class: "absolute-voice-turn-quality__eyebrow" }, model.value.title),
3985
+ h12("strong", { class: "absolute-voice-turn-quality__label" }, model.value.label)
3605
3986
  ]),
3606
- h11("p", { class: "absolute-voice-turn-quality__description" }, model.value.description),
3607
- model.value.turns.length ? h11("div", { class: "absolute-voice-turn-quality__turns" }, model.value.turns.map((turn) => h11("article", {
3987
+ h12("p", { class: "absolute-voice-turn-quality__description" }, model.value.description),
3988
+ model.value.turns.length ? h12("div", { class: "absolute-voice-turn-quality__turns" }, model.value.turns.map((turn) => h12("article", {
3608
3989
  class: [
3609
3990
  "absolute-voice-turn-quality__turn",
3610
3991
  `absolute-voice-turn-quality__turn--${turn.status}`
3611
3992
  ],
3612
3993
  key: `${turn.sessionId}:${turn.turnId}`
3613
3994
  }, [
3614
- h11("header", [
3615
- h11("strong", turn.label),
3616
- h11("span", turn.status)
3995
+ h12("header", [
3996
+ h12("strong", turn.label),
3997
+ h12("span", turn.status)
3617
3998
  ]),
3618
- h11("p", turn.detail),
3619
- h11("dl", turn.rows.map((row) => h11("div", { key: row.label }, [
3620
- h11("dt", row.label),
3621
- h11("dd", row.value)
3999
+ h12("p", turn.detail),
4000
+ h12("dl", turn.rows.map((row) => h12("div", { key: row.label }, [
4001
+ h12("dt", row.label),
4002
+ h12("dd", row.value)
3622
4003
  ])))
3623
- ]))) : h11("p", { class: "absolute-voice-turn-quality__empty" }, "Complete a voice turn to see STT quality diagnostics."),
3624
- model.value.error ? h11("p", { class: "absolute-voice-turn-quality__error" }, model.value.error) : null
4004
+ ]))) : h12("p", { class: "absolute-voice-turn-quality__empty" }, "Complete a voice turn to see STT quality diagnostics."),
4005
+ model.value.error ? h12("p", { class: "absolute-voice-turn-quality__error" }, model.value.error) : null
3625
4006
  ]);
3626
4007
  }
3627
4008
  });
3628
4009
  // src/vue/useVoiceLiveOps.ts
3629
- import { onUnmounted as onUnmounted13, ref as ref9, shallowRef as shallowRef12 } from "vue";
4010
+ import { onUnmounted as onUnmounted14, ref as ref10, shallowRef as shallowRef13 } from "vue";
3630
4011
 
3631
4012
  // src/client/liveOps.ts
3632
4013
  var postVoiceLiveOpsAction = async (input, options = {}) => {
@@ -3717,11 +4098,11 @@ var createVoiceLiveOpsStore = (options = {}) => {
3717
4098
  // src/vue/useVoiceLiveOps.ts
3718
4099
  function useVoiceLiveOps(options = {}) {
3719
4100
  const store = createVoiceLiveOpsStore(options);
3720
- const error = ref9(null);
3721
- const isRunning = ref9(false);
3722
- const lastResult = shallowRef12(undefined);
3723
- const runningAction = ref9(undefined);
3724
- const updatedAt = ref9(undefined);
4101
+ const error = ref10(null);
4102
+ const isRunning = ref10(false);
4103
+ const lastResult = shallowRef13(undefined);
4104
+ const runningAction = ref10(undefined);
4105
+ const updatedAt = ref10(undefined);
3725
4106
  const sync = () => {
3726
4107
  const snapshot = store.getSnapshot();
3727
4108
  error.value = snapshot.error;
@@ -3732,7 +4113,7 @@ function useVoiceLiveOps(options = {}) {
3732
4113
  };
3733
4114
  const unsubscribe = store.subscribe(sync);
3734
4115
  sync();
3735
- onUnmounted13(() => {
4116
+ onUnmounted14(() => {
3736
4117
  unsubscribe();
3737
4118
  store.close();
3738
4119
  });
@@ -3746,7 +4127,7 @@ function useVoiceLiveOps(options = {}) {
3746
4127
  };
3747
4128
  }
3748
4129
  // src/vue/useVoiceCampaignDialerProof.ts
3749
- import { onUnmounted as onUnmounted14, shallowRef as shallowRef13 } from "vue";
4130
+ import { onUnmounted as onUnmounted15, shallowRef as shallowRef14 } from "vue";
3750
4131
 
3751
4132
  // src/client/campaignDialerProof.ts
3752
4133
  var fetchVoiceCampaignDialerProofStatus = async (path = "/api/voice/campaigns/dialer-proof", options = {}) => {
@@ -3869,11 +4250,11 @@ var createVoiceCampaignDialerProofStore = (path = "/api/voice/campaigns/dialer-p
3869
4250
  // src/vue/useVoiceCampaignDialerProof.ts
3870
4251
  function useVoiceCampaignDialerProof(path = "/api/voice/campaigns/dialer-proof", options = {}) {
3871
4252
  const store = createVoiceCampaignDialerProofStore(path, options);
3872
- const error = shallowRef13(null);
3873
- const isLoading = shallowRef13(false);
3874
- const report = shallowRef13();
3875
- const status = shallowRef13();
3876
- const updatedAt = shallowRef13(undefined);
4253
+ const error = shallowRef14(null);
4254
+ const isLoading = shallowRef14(false);
4255
+ const report = shallowRef14();
4256
+ const status = shallowRef14();
4257
+ const updatedAt = shallowRef14(undefined);
3877
4258
  const sync = () => {
3878
4259
  const snapshot = store.getSnapshot();
3879
4260
  error.value = snapshot.error;
@@ -3887,7 +4268,7 @@ function useVoiceCampaignDialerProof(path = "/api/voice/campaigns/dialer-proof",
3887
4268
  if (typeof window !== "undefined") {
3888
4269
  store.refresh().catch(() => {});
3889
4270
  }
3890
- onUnmounted14(() => {
4271
+ onUnmounted15(() => {
3891
4272
  unsubscribe();
3892
4273
  store.close();
3893
4274
  });
@@ -3902,7 +4283,7 @@ function useVoiceCampaignDialerProof(path = "/api/voice/campaigns/dialer-proof",
3902
4283
  };
3903
4284
  }
3904
4285
  // src/vue/useVoiceStream.ts
3905
- import { onUnmounted as onUnmounted15, ref as ref10, shallowRef as shallowRef14 } from "vue";
4286
+ import { onUnmounted as onUnmounted16, ref as ref11, shallowRef as shallowRef15 } from "vue";
3906
4287
 
3907
4288
  // src/client/actions.ts
3908
4289
  var normalizeErrorMessage = (value) => {
@@ -4547,16 +4928,16 @@ var createVoiceStream = (path, options = {}) => {
4547
4928
  // src/vue/useVoiceStream.ts
4548
4929
  function useVoiceStream(path, options = {}) {
4549
4930
  const stream = createVoiceStream(path, options);
4550
- const assistantAudio = shallowRef14([]);
4551
- const assistantTexts = shallowRef14([]);
4552
- const call = shallowRef14(null);
4553
- const error = ref10(null);
4554
- const isConnected = ref10(false);
4555
- const partial = ref10("");
4556
- const reconnect = shallowRef14(stream.reconnect);
4557
- const sessionId = ref10(stream.sessionId);
4558
- const status = ref10(stream.status);
4559
- const turns = shallowRef14([]);
4931
+ const assistantAudio = shallowRef15([]);
4932
+ const assistantTexts = shallowRef15([]);
4933
+ const call = shallowRef15(null);
4934
+ const error = ref11(null);
4935
+ const isConnected = ref11(false);
4936
+ const partial = ref11("");
4937
+ const reconnect = shallowRef15(stream.reconnect);
4938
+ const sessionId = ref11(stream.sessionId);
4939
+ const status = ref11(stream.status);
4940
+ const turns = shallowRef15([]);
4560
4941
  const sync = () => {
4561
4942
  assistantAudio.value = [...stream.assistantAudio];
4562
4943
  assistantTexts.value = [...stream.assistantTexts];
@@ -4575,7 +4956,7 @@ function useVoiceStream(path, options = {}) {
4575
4956
  unsubscribe();
4576
4957
  stream.close();
4577
4958
  };
4578
- onUnmounted15(destroy);
4959
+ onUnmounted16(destroy);
4579
4960
  return {
4580
4961
  assistantAudio,
4581
4962
  assistantTexts,
@@ -4594,7 +4975,7 @@ function useVoiceStream(path, options = {}) {
4594
4975
  };
4595
4976
  }
4596
4977
  // src/vue/useVoiceController.ts
4597
- import { onUnmounted as onUnmounted16, ref as ref11, shallowRef as shallowRef15 } from "vue";
4978
+ import { onUnmounted as onUnmounted17, ref as ref12, shallowRef as shallowRef16 } from "vue";
4598
4979
 
4599
4980
  // src/client/htmx.ts
4600
4981
  var DEFAULT_EVENT_NAME = "voice-refresh";
@@ -5240,17 +5621,17 @@ var createVoiceController = (path, options = {}) => {
5240
5621
  // src/vue/useVoiceController.ts
5241
5622
  function useVoiceController(path, options = {}) {
5242
5623
  const controller = createVoiceController(path, options);
5243
- const assistantAudio = shallowRef15([]);
5244
- const assistantTexts = shallowRef15([]);
5245
- const error = ref11(null);
5246
- const isConnected = ref11(false);
5247
- const isRecording = ref11(false);
5248
- const partial = ref11("");
5249
- const reconnect = shallowRef15(controller.reconnect);
5250
- const recordingError = ref11(null);
5251
- const sessionId = ref11(controller.sessionId);
5252
- const status = ref11(controller.status);
5253
- const turns = shallowRef15([]);
5624
+ const assistantAudio = shallowRef16([]);
5625
+ const assistantTexts = shallowRef16([]);
5626
+ const error = ref12(null);
5627
+ const isConnected = ref12(false);
5628
+ const isRecording = ref12(false);
5629
+ const partial = ref12("");
5630
+ const reconnect = shallowRef16(controller.reconnect);
5631
+ const recordingError = ref12(null);
5632
+ const sessionId = ref12(controller.sessionId);
5633
+ const status = ref12(controller.status);
5634
+ const turns = shallowRef16([]);
5254
5635
  const sync = () => {
5255
5636
  assistantAudio.value = [...controller.assistantAudio];
5256
5637
  assistantTexts.value = [...controller.assistantTexts];
@@ -5270,7 +5651,7 @@ function useVoiceController(path, options = {}) {
5270
5651
  unsubscribe();
5271
5652
  controller.close();
5272
5653
  };
5273
- onUnmounted16(destroy);
5654
+ onUnmounted17(destroy);
5274
5655
  return {
5275
5656
  assistantAudio,
5276
5657
  assistantTexts,
@@ -5293,13 +5674,13 @@ function useVoiceController(path, options = {}) {
5293
5674
  };
5294
5675
  }
5295
5676
  // src/vue/useVoiceTraceTimeline.ts
5296
- import { onUnmounted as onUnmounted17, ref as ref12, shallowRef as shallowRef16 } from "vue";
5677
+ import { onUnmounted as onUnmounted18, ref as ref13, shallowRef as shallowRef17 } from "vue";
5297
5678
  function useVoiceTraceTimeline(path = "/api/voice-traces", options = {}) {
5298
5679
  const store = createVoiceTraceTimelineStore(path, options);
5299
- const error = ref12(null);
5300
- const isLoading = ref12(false);
5301
- const report = shallowRef16(null);
5302
- const updatedAt = ref12(undefined);
5680
+ const error = ref13(null);
5681
+ const isLoading = ref13(false);
5682
+ const report = shallowRef17(null);
5683
+ const updatedAt = ref13(undefined);
5303
5684
  const sync = () => {
5304
5685
  const snapshot = store.getSnapshot();
5305
5686
  error.value = snapshot.error;
@@ -5310,7 +5691,7 @@ function useVoiceTraceTimeline(path = "/api/voice-traces", options = {}) {
5310
5691
  const unsubscribe = store.subscribe(sync);
5311
5692
  sync();
5312
5693
  store.refresh().catch(() => {});
5313
- onUnmounted17(() => {
5694
+ onUnmounted18(() => {
5314
5695
  unsubscribe();
5315
5696
  store.close();
5316
5697
  });
@@ -5323,7 +5704,7 @@ function useVoiceTraceTimeline(path = "/api/voice-traces", options = {}) {
5323
5704
  };
5324
5705
  }
5325
5706
  // src/vue/useVoiceWorkflowStatus.ts
5326
- import { onUnmounted as onUnmounted18, ref as ref13, shallowRef as shallowRef17 } from "vue";
5707
+ import { onUnmounted as onUnmounted19, ref as ref14, shallowRef as shallowRef18 } from "vue";
5327
5708
 
5328
5709
  // src/client/workflowStatus.ts
5329
5710
  var fetchVoiceWorkflowStatus = async (path = "/evals/scenarios/json", options = {}) => {
@@ -5407,10 +5788,10 @@ var createVoiceWorkflowStatusStore = (path = "/evals/scenarios/json", options =
5407
5788
  // src/vue/useVoiceWorkflowStatus.ts
5408
5789
  function useVoiceWorkflowStatus(path = "/evals/scenarios/json", options = {}) {
5409
5790
  const store = createVoiceWorkflowStatusStore(path, options);
5410
- const error = ref13(null);
5411
- const isLoading = ref13(false);
5412
- const report = shallowRef17(undefined);
5413
- const updatedAt = ref13(undefined);
5791
+ const error = ref14(null);
5792
+ const isLoading = ref14(false);
5793
+ const report = shallowRef18(undefined);
5794
+ const updatedAt = ref14(undefined);
5414
5795
  const sync = () => {
5415
5796
  const snapshot = store.getSnapshot();
5416
5797
  error.value = snapshot.error;
@@ -5423,7 +5804,7 @@ function useVoiceWorkflowStatus(path = "/evals/scenarios/json", options = {}) {
5423
5804
  if (typeof window !== "undefined") {
5424
5805
  store.refresh().catch(() => {});
5425
5806
  }
5426
- onUnmounted18(() => {
5807
+ onUnmounted19(() => {
5427
5808
  unsubscribe();
5428
5809
  store.close();
5429
5810
  });
@@ -5446,6 +5827,7 @@ export {
5446
5827
  useVoiceProviderSimulationControls,
5447
5828
  useVoiceProviderContracts,
5448
5829
  useVoiceProviderCapabilities,
5830
+ useVoiceProofTrends,
5449
5831
  useVoicePlatformCoverage,
5450
5832
  useVoiceOpsStatus,
5451
5833
  useVoiceOpsActionCenter,
@@ -5461,6 +5843,7 @@ export {
5461
5843
  VoiceProviderSimulationControls,
5462
5844
  VoiceProviderContracts,
5463
5845
  VoiceProviderCapabilities,
5846
+ VoiceProofTrends,
5464
5847
  VoicePlatformCoverage,
5465
5848
  VoiceOpsStatus,
5466
5849
  VoiceOpsActionCenter,