@absolutejs/voice 0.0.22-beta.166 → 0.0.22-beta.168
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/angular/index.d.ts +1 -0
- package/dist/angular/index.js +177 -58
- package/dist/angular/voice-provider-contracts.service.d.ts +12 -0
- package/dist/client/index.d.ts +4 -0
- package/dist/client/index.js +228 -47
- package/dist/client/providerContracts.d.ts +19 -0
- package/dist/client/providerContractsWidget.d.ts +32 -0
- package/dist/index.d.ts +2 -2
- package/dist/index.js +94 -33
- package/dist/providerStackRecommendations.d.ts +46 -0
- package/dist/react/VoiceProviderContracts.d.ts +6 -0
- package/dist/react/index.d.ts +2 -0
- package/dist/react/index.js +472 -195
- package/dist/react/useVoiceProviderContracts.d.ts +8 -0
- package/dist/svelte/createVoiceProviderContracts.d.ts +10 -0
- package/dist/svelte/index.d.ts +1 -0
- package/dist/svelte/index.js +264 -78
- package/dist/vue/VoiceProviderContracts.d.ts +21 -0
- package/dist/vue/index.d.ts +2 -0
- package/dist/vue/index.js +446 -170
- package/dist/vue/useVoiceProviderContracts.d.ts +9 -0
- package/package.json +1 -1
package/dist/react/index.js
CHANGED
|
@@ -1674,9 +1674,284 @@ var VoiceProviderCapabilities = ({
|
|
|
1674
1674
|
]
|
|
1675
1675
|
}, undefined, true, undefined, this);
|
|
1676
1676
|
};
|
|
1677
|
-
// src/react/
|
|
1677
|
+
// src/react/useVoiceProviderContracts.tsx
|
|
1678
1678
|
import { useEffect as useEffect6, useRef as useRef6, useSyncExternalStore as useSyncExternalStore6 } from "react";
|
|
1679
1679
|
|
|
1680
|
+
// src/client/providerContracts.ts
|
|
1681
|
+
var fetchVoiceProviderContracts = async (path = "/api/provider-contracts", options = {}) => {
|
|
1682
|
+
const fetchImpl = options.fetch ?? globalThis.fetch;
|
|
1683
|
+
const response = await fetchImpl(path);
|
|
1684
|
+
if (!response.ok) {
|
|
1685
|
+
throw new Error(`Voice provider contracts failed: HTTP ${response.status}`);
|
|
1686
|
+
}
|
|
1687
|
+
return await response.json();
|
|
1688
|
+
};
|
|
1689
|
+
var createVoiceProviderContractsStore = (path = "/api/provider-contracts", options = {}) => {
|
|
1690
|
+
const listeners = new Set;
|
|
1691
|
+
let closed = false;
|
|
1692
|
+
let timer;
|
|
1693
|
+
let snapshot = {
|
|
1694
|
+
error: null,
|
|
1695
|
+
isLoading: false
|
|
1696
|
+
};
|
|
1697
|
+
const emit = () => {
|
|
1698
|
+
for (const listener of listeners) {
|
|
1699
|
+
listener();
|
|
1700
|
+
}
|
|
1701
|
+
};
|
|
1702
|
+
const refresh = async () => {
|
|
1703
|
+
if (closed) {
|
|
1704
|
+
return snapshot.report;
|
|
1705
|
+
}
|
|
1706
|
+
snapshot = { ...snapshot, error: null, isLoading: true };
|
|
1707
|
+
emit();
|
|
1708
|
+
try {
|
|
1709
|
+
const report = await fetchVoiceProviderContracts(path, options);
|
|
1710
|
+
snapshot = {
|
|
1711
|
+
error: null,
|
|
1712
|
+
isLoading: false,
|
|
1713
|
+
report,
|
|
1714
|
+
updatedAt: Date.now()
|
|
1715
|
+
};
|
|
1716
|
+
emit();
|
|
1717
|
+
return report;
|
|
1718
|
+
} catch (error) {
|
|
1719
|
+
snapshot = {
|
|
1720
|
+
...snapshot,
|
|
1721
|
+
error: error instanceof Error ? error.message : String(error),
|
|
1722
|
+
isLoading: false
|
|
1723
|
+
};
|
|
1724
|
+
emit();
|
|
1725
|
+
throw error;
|
|
1726
|
+
}
|
|
1727
|
+
};
|
|
1728
|
+
const close = () => {
|
|
1729
|
+
closed = true;
|
|
1730
|
+
if (timer) {
|
|
1731
|
+
clearInterval(timer);
|
|
1732
|
+
timer = undefined;
|
|
1733
|
+
}
|
|
1734
|
+
listeners.clear();
|
|
1735
|
+
};
|
|
1736
|
+
if (options.intervalMs && options.intervalMs > 0) {
|
|
1737
|
+
timer = setInterval(() => {
|
|
1738
|
+
refresh().catch(() => {});
|
|
1739
|
+
}, options.intervalMs);
|
|
1740
|
+
}
|
|
1741
|
+
return {
|
|
1742
|
+
close,
|
|
1743
|
+
getServerSnapshot: () => snapshot,
|
|
1744
|
+
getSnapshot: () => snapshot,
|
|
1745
|
+
refresh,
|
|
1746
|
+
subscribe: (listener) => {
|
|
1747
|
+
listeners.add(listener);
|
|
1748
|
+
return () => {
|
|
1749
|
+
listeners.delete(listener);
|
|
1750
|
+
};
|
|
1751
|
+
}
|
|
1752
|
+
};
|
|
1753
|
+
};
|
|
1754
|
+
|
|
1755
|
+
// src/react/useVoiceProviderContracts.tsx
|
|
1756
|
+
var useVoiceProviderContracts = (path = "/api/provider-contracts", options = {}) => {
|
|
1757
|
+
const storeRef = useRef6(null);
|
|
1758
|
+
if (!storeRef.current) {
|
|
1759
|
+
storeRef.current = createVoiceProviderContractsStore(path, options);
|
|
1760
|
+
}
|
|
1761
|
+
const store = storeRef.current;
|
|
1762
|
+
useEffect6(() => {
|
|
1763
|
+
store.refresh().catch(() => {});
|
|
1764
|
+
return () => store.close();
|
|
1765
|
+
}, [store]);
|
|
1766
|
+
return {
|
|
1767
|
+
...useSyncExternalStore6(store.subscribe, store.getSnapshot, store.getServerSnapshot),
|
|
1768
|
+
refresh: store.refresh
|
|
1769
|
+
};
|
|
1770
|
+
};
|
|
1771
|
+
|
|
1772
|
+
// src/client/providerContractsWidget.ts
|
|
1773
|
+
var DEFAULT_TITLE5 = "Provider Contracts";
|
|
1774
|
+
var DEFAULT_DESCRIPTION5 = "Production contract coverage for provider env, latency, fallback, streaming, and capabilities.";
|
|
1775
|
+
var escapeHtml6 = (value) => value.replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">").replaceAll('"', """).replaceAll("'", "'");
|
|
1776
|
+
var formatProvider2 = (provider) => provider.split(/[-_\s]+/).filter(Boolean).map((part) => `${part[0]?.toUpperCase() ?? ""}${part.slice(1)}`).join(" ") || provider;
|
|
1777
|
+
var formatStatus2 = (status) => status.split("-").map((part) => `${part[0]?.toUpperCase() ?? ""}${part.slice(1)}`).join(" ");
|
|
1778
|
+
var contractDetail = (row) => {
|
|
1779
|
+
const failing = row.checks.filter((check) => check.status !== "pass");
|
|
1780
|
+
if (failing.length === 0) {
|
|
1781
|
+
return "Provider contract is production-ready.";
|
|
1782
|
+
}
|
|
1783
|
+
return failing.map((check) => `${check.label}: ${check.detail ?? check.status}`).join(" ");
|
|
1784
|
+
};
|
|
1785
|
+
var createVoiceProviderContractsViewModel = (snapshot, options = {}) => {
|
|
1786
|
+
const rows = (snapshot.report?.rows ?? []).map((row) => ({
|
|
1787
|
+
...row,
|
|
1788
|
+
detail: contractDetail(row),
|
|
1789
|
+
label: `${formatProvider2(row.provider)} ${row.kind.toUpperCase()}`,
|
|
1790
|
+
rows: [
|
|
1791
|
+
{ label: "Status", value: formatStatus2(row.status) },
|
|
1792
|
+
{ label: "Selected", value: row.selected ? "Yes" : "No" },
|
|
1793
|
+
{ label: "Configured", value: row.configured ? "Yes" : "No" },
|
|
1794
|
+
{
|
|
1795
|
+
label: "Checks",
|
|
1796
|
+
value: row.checks.map((check) => `${check.label}: ${formatStatus2(check.status)}`).join(", ")
|
|
1797
|
+
}
|
|
1798
|
+
]
|
|
1799
|
+
}));
|
|
1800
|
+
const warningCount = snapshot.report ? snapshot.report.failed + snapshot.report.warned : rows.filter((row) => row.status !== "pass").length;
|
|
1801
|
+
return {
|
|
1802
|
+
description: options.description ?? DEFAULT_DESCRIPTION5,
|
|
1803
|
+
error: snapshot.error,
|
|
1804
|
+
isLoading: snapshot.isLoading,
|
|
1805
|
+
label: snapshot.error ? "Unavailable" : rows.length ? warningCount > 0 ? `${warningCount} needs attention` : `${rows.length} passing` : snapshot.isLoading ? "Checking" : "No contracts",
|
|
1806
|
+
rows,
|
|
1807
|
+
status: snapshot.error ? "error" : rows.length ? warningCount > 0 ? "warning" : "ready" : snapshot.isLoading ? "loading" : "empty",
|
|
1808
|
+
title: options.title ?? DEFAULT_TITLE5,
|
|
1809
|
+
updatedAt: snapshot.updatedAt
|
|
1810
|
+
};
|
|
1811
|
+
};
|
|
1812
|
+
var renderVoiceProviderContractsHTML = (snapshot, options = {}) => {
|
|
1813
|
+
const model = createVoiceProviderContractsViewModel(snapshot, options);
|
|
1814
|
+
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--${escapeHtml6(row.status)}">
|
|
1815
|
+
<header>
|
|
1816
|
+
<strong>${escapeHtml6(row.label)}</strong>
|
|
1817
|
+
<span>${escapeHtml6(formatStatus2(row.status))}</span>
|
|
1818
|
+
</header>
|
|
1819
|
+
<p>${escapeHtml6(row.detail)}</p>
|
|
1820
|
+
<dl>${row.rows.map((item) => `<div>
|
|
1821
|
+
<dt>${escapeHtml6(item.label)}</dt>
|
|
1822
|
+
<dd>${escapeHtml6(item.value)}</dd>
|
|
1823
|
+
</div>`).join("")}</dl>
|
|
1824
|
+
</article>`).join("")}</div>` : '<p class="absolute-voice-provider-contracts__empty">Configure provider contracts to see production coverage.</p>';
|
|
1825
|
+
return `<section class="absolute-voice-provider-contracts absolute-voice-provider-contracts--${escapeHtml6(model.status)}">
|
|
1826
|
+
<header class="absolute-voice-provider-contracts__header">
|
|
1827
|
+
<span class="absolute-voice-provider-contracts__eyebrow">${escapeHtml6(model.title)}</span>
|
|
1828
|
+
<strong class="absolute-voice-provider-contracts__label">${escapeHtml6(model.label)}</strong>
|
|
1829
|
+
</header>
|
|
1830
|
+
<p class="absolute-voice-provider-contracts__description">${escapeHtml6(model.description)}</p>
|
|
1831
|
+
${rows}
|
|
1832
|
+
${model.error ? `<p class="absolute-voice-provider-contracts__error">${escapeHtml6(model.error)}</p>` : ""}
|
|
1833
|
+
</section>`;
|
|
1834
|
+
};
|
|
1835
|
+
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__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}`;
|
|
1836
|
+
var mountVoiceProviderContracts = (element, path = "/api/provider-contracts", options = {}) => {
|
|
1837
|
+
const store = createVoiceProviderContractsStore(path, options);
|
|
1838
|
+
const render = () => {
|
|
1839
|
+
element.innerHTML = renderVoiceProviderContractsHTML(store.getSnapshot(), options);
|
|
1840
|
+
};
|
|
1841
|
+
const unsubscribe = store.subscribe(render);
|
|
1842
|
+
render();
|
|
1843
|
+
store.refresh().catch(() => {});
|
|
1844
|
+
return {
|
|
1845
|
+
close: () => {
|
|
1846
|
+
unsubscribe();
|
|
1847
|
+
store.close();
|
|
1848
|
+
},
|
|
1849
|
+
refresh: store.refresh
|
|
1850
|
+
};
|
|
1851
|
+
};
|
|
1852
|
+
var defineVoiceProviderContractsElement = (tagName = "absolute-voice-provider-contracts") => {
|
|
1853
|
+
if (typeof window === "undefined" || typeof customElements === "undefined" || customElements.get(tagName)) {
|
|
1854
|
+
return;
|
|
1855
|
+
}
|
|
1856
|
+
customElements.define(tagName, class AbsoluteVoiceProviderContractsElement extends HTMLElement {
|
|
1857
|
+
mounted;
|
|
1858
|
+
connectedCallback() {
|
|
1859
|
+
const intervalMs = Number(this.getAttribute("interval-ms") ?? 5000);
|
|
1860
|
+
this.mounted = mountVoiceProviderContracts(this, this.getAttribute("path") ?? "/api/provider-contracts", {
|
|
1861
|
+
description: this.getAttribute("description") ?? undefined,
|
|
1862
|
+
intervalMs: Number.isFinite(intervalMs) ? intervalMs : 5000,
|
|
1863
|
+
title: this.getAttribute("title") ?? undefined
|
|
1864
|
+
});
|
|
1865
|
+
}
|
|
1866
|
+
disconnectedCallback() {
|
|
1867
|
+
this.mounted?.close();
|
|
1868
|
+
this.mounted = undefined;
|
|
1869
|
+
}
|
|
1870
|
+
});
|
|
1871
|
+
};
|
|
1872
|
+
|
|
1873
|
+
// src/react/VoiceProviderContracts.tsx
|
|
1874
|
+
import { jsxDEV as jsxDEV6 } from "react/jsx-dev-runtime";
|
|
1875
|
+
var VoiceProviderContracts = ({
|
|
1876
|
+
className,
|
|
1877
|
+
path = "/api/provider-contracts",
|
|
1878
|
+
...options
|
|
1879
|
+
}) => {
|
|
1880
|
+
const snapshot = useVoiceProviderContracts(path, options);
|
|
1881
|
+
const model = createVoiceProviderContractsViewModel(snapshot, options);
|
|
1882
|
+
return /* @__PURE__ */ jsxDEV6("section", {
|
|
1883
|
+
className: [
|
|
1884
|
+
"absolute-voice-provider-contracts",
|
|
1885
|
+
`absolute-voice-provider-contracts--${model.status}`,
|
|
1886
|
+
className
|
|
1887
|
+
].filter(Boolean).join(" "),
|
|
1888
|
+
children: [
|
|
1889
|
+
/* @__PURE__ */ jsxDEV6("header", {
|
|
1890
|
+
className: "absolute-voice-provider-contracts__header",
|
|
1891
|
+
children: [
|
|
1892
|
+
/* @__PURE__ */ jsxDEV6("span", {
|
|
1893
|
+
className: "absolute-voice-provider-contracts__eyebrow",
|
|
1894
|
+
children: model.title
|
|
1895
|
+
}, undefined, false, undefined, this),
|
|
1896
|
+
/* @__PURE__ */ jsxDEV6("strong", {
|
|
1897
|
+
className: "absolute-voice-provider-contracts__label",
|
|
1898
|
+
children: model.label
|
|
1899
|
+
}, undefined, false, undefined, this)
|
|
1900
|
+
]
|
|
1901
|
+
}, undefined, true, undefined, this),
|
|
1902
|
+
/* @__PURE__ */ jsxDEV6("p", {
|
|
1903
|
+
className: "absolute-voice-provider-contracts__description",
|
|
1904
|
+
children: model.description
|
|
1905
|
+
}, undefined, false, undefined, this),
|
|
1906
|
+
model.rows.length ? /* @__PURE__ */ jsxDEV6("div", {
|
|
1907
|
+
className: "absolute-voice-provider-contracts__rows",
|
|
1908
|
+
children: model.rows.map((row) => /* @__PURE__ */ jsxDEV6("article", {
|
|
1909
|
+
className: [
|
|
1910
|
+
"absolute-voice-provider-contracts__row",
|
|
1911
|
+
`absolute-voice-provider-contracts__row--${row.status}`
|
|
1912
|
+
].join(" "),
|
|
1913
|
+
children: [
|
|
1914
|
+
/* @__PURE__ */ jsxDEV6("header", {
|
|
1915
|
+
children: [
|
|
1916
|
+
/* @__PURE__ */ jsxDEV6("strong", {
|
|
1917
|
+
children: row.label
|
|
1918
|
+
}, undefined, false, undefined, this),
|
|
1919
|
+
/* @__PURE__ */ jsxDEV6("span", {
|
|
1920
|
+
children: row.status
|
|
1921
|
+
}, undefined, false, undefined, this)
|
|
1922
|
+
]
|
|
1923
|
+
}, undefined, true, undefined, this),
|
|
1924
|
+
/* @__PURE__ */ jsxDEV6("p", {
|
|
1925
|
+
children: row.detail
|
|
1926
|
+
}, undefined, false, undefined, this),
|
|
1927
|
+
/* @__PURE__ */ jsxDEV6("dl", {
|
|
1928
|
+
children: row.rows.map((item) => /* @__PURE__ */ jsxDEV6("div", {
|
|
1929
|
+
children: [
|
|
1930
|
+
/* @__PURE__ */ jsxDEV6("dt", {
|
|
1931
|
+
children: item.label
|
|
1932
|
+
}, undefined, false, undefined, this),
|
|
1933
|
+
/* @__PURE__ */ jsxDEV6("dd", {
|
|
1934
|
+
children: item.value
|
|
1935
|
+
}, undefined, false, undefined, this)
|
|
1936
|
+
]
|
|
1937
|
+
}, item.label, true, undefined, this))
|
|
1938
|
+
}, undefined, false, undefined, this)
|
|
1939
|
+
]
|
|
1940
|
+
}, `${row.kind}:${row.provider}`, true, undefined, this))
|
|
1941
|
+
}, undefined, false, undefined, this) : /* @__PURE__ */ jsxDEV6("p", {
|
|
1942
|
+
className: "absolute-voice-provider-contracts__empty",
|
|
1943
|
+
children: "Configure provider contracts to see production coverage."
|
|
1944
|
+
}, undefined, false, undefined, this),
|
|
1945
|
+
model.error ? /* @__PURE__ */ jsxDEV6("p", {
|
|
1946
|
+
className: "absolute-voice-provider-contracts__error",
|
|
1947
|
+
children: model.error
|
|
1948
|
+
}, undefined, false, undefined, this) : null
|
|
1949
|
+
]
|
|
1950
|
+
}, undefined, true, undefined, this);
|
|
1951
|
+
};
|
|
1952
|
+
// src/react/useVoiceProviderStatus.tsx
|
|
1953
|
+
import { useEffect as useEffect7, useRef as useRef7, useSyncExternalStore as useSyncExternalStore7 } from "react";
|
|
1954
|
+
|
|
1680
1955
|
// src/client/providerStatus.ts
|
|
1681
1956
|
var fetchVoiceProviderStatus = async (path = "/api/provider-status", options = {}) => {
|
|
1682
1957
|
const fetchImpl = options.fetch ?? globalThis.fetch;
|
|
@@ -1759,27 +2034,27 @@ var createVoiceProviderStatusStore = (path = "/api/provider-status", options = {
|
|
|
1759
2034
|
|
|
1760
2035
|
// src/react/useVoiceProviderStatus.tsx
|
|
1761
2036
|
var useVoiceProviderStatus = (path = "/api/provider-status", options = {}) => {
|
|
1762
|
-
const storeRef =
|
|
2037
|
+
const storeRef = useRef7(null);
|
|
1763
2038
|
if (!storeRef.current) {
|
|
1764
2039
|
storeRef.current = createVoiceProviderStatusStore(path, options);
|
|
1765
2040
|
}
|
|
1766
2041
|
const store = storeRef.current;
|
|
1767
|
-
|
|
2042
|
+
useEffect7(() => {
|
|
1768
2043
|
store.refresh().catch(() => {});
|
|
1769
2044
|
return () => store.close();
|
|
1770
2045
|
}, [store]);
|
|
1771
2046
|
return {
|
|
1772
|
-
...
|
|
2047
|
+
...useSyncExternalStore7(store.subscribe, store.getSnapshot, store.getServerSnapshot),
|
|
1773
2048
|
refresh: store.refresh
|
|
1774
2049
|
};
|
|
1775
2050
|
};
|
|
1776
2051
|
|
|
1777
2052
|
// src/client/providerStatusWidget.ts
|
|
1778
|
-
var
|
|
1779
|
-
var
|
|
1780
|
-
var
|
|
1781
|
-
var
|
|
1782
|
-
var
|
|
2053
|
+
var DEFAULT_TITLE6 = "Voice Providers";
|
|
2054
|
+
var DEFAULT_DESCRIPTION6 = "Live provider health, fallback counts, latency, and suppression state from your self-hosted trace store.";
|
|
2055
|
+
var escapeHtml7 = (value) => value.replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">").replaceAll('"', """).replaceAll("'", "'");
|
|
2056
|
+
var formatProvider3 = (provider) => provider.split(/[-_\s]+/).filter(Boolean).map((part) => `${part[0]?.toUpperCase() ?? ""}${part.slice(1)}`).join(" ") || provider;
|
|
2057
|
+
var formatStatus3 = (status) => status.split("-").map((part) => `${part[0]?.toUpperCase() ?? ""}${part.slice(1)}`).join(" ");
|
|
1783
2058
|
var formatLatency = (value) => typeof value === "number" ? `${value}ms` : "No samples";
|
|
1784
2059
|
var formatSuppression = (value) => typeof value === "number" ? `${Math.ceil(value / 1000)}s` : "None";
|
|
1785
2060
|
var getProviderDetail = (provider) => {
|
|
@@ -1805,7 +2080,7 @@ var createVoiceProviderStatusViewModel = (snapshot, options = {}) => {
|
|
|
1805
2080
|
const providers = snapshot.providers.map((provider) => ({
|
|
1806
2081
|
...provider,
|
|
1807
2082
|
detail: getProviderDetail(provider),
|
|
1808
|
-
label: `${
|
|
2083
|
+
label: `${formatProvider3(provider.provider)}${provider.recommended ? " recommended" : ""}`,
|
|
1809
2084
|
rows: [
|
|
1810
2085
|
{ label: "Runs", value: String(provider.runCount) },
|
|
1811
2086
|
{ label: "Avg latency", value: formatLatency(provider.averageElapsedMs) },
|
|
@@ -1821,37 +2096,37 @@ var createVoiceProviderStatusViewModel = (snapshot, options = {}) => {
|
|
|
1821
2096
|
const warningCount = providers.filter((provider) => isWarningStatus2(provider.status)).length;
|
|
1822
2097
|
const healthyCount = providers.filter((provider) => provider.status === "healthy").length;
|
|
1823
2098
|
return {
|
|
1824
|
-
description: options.description ??
|
|
2099
|
+
description: options.description ?? DEFAULT_DESCRIPTION6,
|
|
1825
2100
|
error: snapshot.error,
|
|
1826
2101
|
isLoading: snapshot.isLoading,
|
|
1827
2102
|
label: snapshot.error ? "Unavailable" : providers.length ? warningCount > 0 ? `${warningCount} needs attention` : `${healthyCount} healthy` : snapshot.isLoading ? "Checking" : "No provider traffic",
|
|
1828
2103
|
providers,
|
|
1829
2104
|
status: snapshot.error ? "error" : providers.length ? warningCount > 0 ? "warning" : "ready" : snapshot.isLoading ? "loading" : "empty",
|
|
1830
|
-
title: options.title ??
|
|
2105
|
+
title: options.title ?? DEFAULT_TITLE6,
|
|
1831
2106
|
updatedAt: snapshot.updatedAt
|
|
1832
2107
|
};
|
|
1833
2108
|
};
|
|
1834
2109
|
var renderVoiceProviderStatusHTML = (snapshot, options = {}) => {
|
|
1835
2110
|
const model = createVoiceProviderStatusViewModel(snapshot, options);
|
|
1836
|
-
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--${
|
|
2111
|
+
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--${escapeHtml7(provider.status)}">
|
|
1837
2112
|
<header>
|
|
1838
|
-
<strong>${
|
|
1839
|
-
<span>${
|
|
2113
|
+
<strong>${escapeHtml7(provider.label)}</strong>
|
|
2114
|
+
<span>${escapeHtml7(formatStatus3(provider.status))}</span>
|
|
1840
2115
|
</header>
|
|
1841
|
-
<p>${
|
|
2116
|
+
<p>${escapeHtml7(provider.detail)}</p>
|
|
1842
2117
|
<dl>${provider.rows.map((row) => `<div>
|
|
1843
|
-
<dt>${
|
|
1844
|
-
<dd>${
|
|
2118
|
+
<dt>${escapeHtml7(row.label)}</dt>
|
|
2119
|
+
<dd>${escapeHtml7(row.value)}</dd>
|
|
1845
2120
|
</div>`).join("")}</dl>
|
|
1846
2121
|
</article>`).join("")}</div>` : '<p class="absolute-voice-provider-status__empty">Run voice traffic to see provider health.</p>';
|
|
1847
|
-
return `<section class="absolute-voice-provider-status absolute-voice-provider-status--${
|
|
2122
|
+
return `<section class="absolute-voice-provider-status absolute-voice-provider-status--${escapeHtml7(model.status)}">
|
|
1848
2123
|
<header class="absolute-voice-provider-status__header">
|
|
1849
|
-
<span class="absolute-voice-provider-status__eyebrow">${
|
|
1850
|
-
<strong class="absolute-voice-provider-status__label">${
|
|
2124
|
+
<span class="absolute-voice-provider-status__eyebrow">${escapeHtml7(model.title)}</span>
|
|
2125
|
+
<strong class="absolute-voice-provider-status__label">${escapeHtml7(model.label)}</strong>
|
|
1851
2126
|
</header>
|
|
1852
|
-
<p class="absolute-voice-provider-status__description">${
|
|
2127
|
+
<p class="absolute-voice-provider-status__description">${escapeHtml7(model.description)}</p>
|
|
1853
2128
|
${providers}
|
|
1854
|
-
${model.error ? `<p class="absolute-voice-provider-status__error">${
|
|
2129
|
+
${model.error ? `<p class="absolute-voice-provider-status__error">${escapeHtml7(model.error)}</p>` : ""}
|
|
1855
2130
|
</section>`;
|
|
1856
2131
|
};
|
|
1857
2132
|
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}`;
|
|
@@ -1893,7 +2168,7 @@ var defineVoiceProviderStatusElement = (tagName = "absolute-voice-provider-statu
|
|
|
1893
2168
|
};
|
|
1894
2169
|
|
|
1895
2170
|
// src/react/VoiceProviderStatus.tsx
|
|
1896
|
-
import { jsxDEV as
|
|
2171
|
+
import { jsxDEV as jsxDEV7 } from "react/jsx-dev-runtime";
|
|
1897
2172
|
var VoiceProviderStatus = ({
|
|
1898
2173
|
className,
|
|
1899
2174
|
path = "/api/provider-status",
|
|
@@ -1901,58 +2176,58 @@ var VoiceProviderStatus = ({
|
|
|
1901
2176
|
}) => {
|
|
1902
2177
|
const snapshot = useVoiceProviderStatus(path, options);
|
|
1903
2178
|
const model = createVoiceProviderStatusViewModel(snapshot, options);
|
|
1904
|
-
return /* @__PURE__ */
|
|
2179
|
+
return /* @__PURE__ */ jsxDEV7("section", {
|
|
1905
2180
|
className: [
|
|
1906
2181
|
"absolute-voice-provider-status",
|
|
1907
2182
|
`absolute-voice-provider-status--${model.status}`,
|
|
1908
2183
|
className
|
|
1909
2184
|
].filter(Boolean).join(" "),
|
|
1910
2185
|
children: [
|
|
1911
|
-
/* @__PURE__ */
|
|
2186
|
+
/* @__PURE__ */ jsxDEV7("header", {
|
|
1912
2187
|
className: "absolute-voice-provider-status__header",
|
|
1913
2188
|
children: [
|
|
1914
|
-
/* @__PURE__ */
|
|
2189
|
+
/* @__PURE__ */ jsxDEV7("span", {
|
|
1915
2190
|
className: "absolute-voice-provider-status__eyebrow",
|
|
1916
2191
|
children: model.title
|
|
1917
2192
|
}, undefined, false, undefined, this),
|
|
1918
|
-
/* @__PURE__ */
|
|
2193
|
+
/* @__PURE__ */ jsxDEV7("strong", {
|
|
1919
2194
|
className: "absolute-voice-provider-status__label",
|
|
1920
2195
|
children: model.label
|
|
1921
2196
|
}, undefined, false, undefined, this)
|
|
1922
2197
|
]
|
|
1923
2198
|
}, undefined, true, undefined, this),
|
|
1924
|
-
/* @__PURE__ */
|
|
2199
|
+
/* @__PURE__ */ jsxDEV7("p", {
|
|
1925
2200
|
className: "absolute-voice-provider-status__description",
|
|
1926
2201
|
children: model.description
|
|
1927
2202
|
}, undefined, false, undefined, this),
|
|
1928
|
-
model.providers.length ? /* @__PURE__ */
|
|
2203
|
+
model.providers.length ? /* @__PURE__ */ jsxDEV7("div", {
|
|
1929
2204
|
className: "absolute-voice-provider-status__providers",
|
|
1930
|
-
children: model.providers.map((provider) => /* @__PURE__ */
|
|
2205
|
+
children: model.providers.map((provider) => /* @__PURE__ */ jsxDEV7("article", {
|
|
1931
2206
|
className: [
|
|
1932
2207
|
"absolute-voice-provider-status__provider",
|
|
1933
2208
|
`absolute-voice-provider-status__provider--${provider.status}`
|
|
1934
2209
|
].join(" "),
|
|
1935
2210
|
children: [
|
|
1936
|
-
/* @__PURE__ */
|
|
2211
|
+
/* @__PURE__ */ jsxDEV7("header", {
|
|
1937
2212
|
children: [
|
|
1938
|
-
/* @__PURE__ */
|
|
2213
|
+
/* @__PURE__ */ jsxDEV7("strong", {
|
|
1939
2214
|
children: provider.label
|
|
1940
2215
|
}, undefined, false, undefined, this),
|
|
1941
|
-
/* @__PURE__ */
|
|
2216
|
+
/* @__PURE__ */ jsxDEV7("span", {
|
|
1942
2217
|
children: provider.status
|
|
1943
2218
|
}, undefined, false, undefined, this)
|
|
1944
2219
|
]
|
|
1945
2220
|
}, undefined, true, undefined, this),
|
|
1946
|
-
/* @__PURE__ */
|
|
2221
|
+
/* @__PURE__ */ jsxDEV7("p", {
|
|
1947
2222
|
children: provider.detail
|
|
1948
2223
|
}, undefined, false, undefined, this),
|
|
1949
|
-
/* @__PURE__ */
|
|
1950
|
-
children: provider.rows.map((row) => /* @__PURE__ */
|
|
2224
|
+
/* @__PURE__ */ jsxDEV7("dl", {
|
|
2225
|
+
children: provider.rows.map((row) => /* @__PURE__ */ jsxDEV7("div", {
|
|
1951
2226
|
children: [
|
|
1952
|
-
/* @__PURE__ */
|
|
2227
|
+
/* @__PURE__ */ jsxDEV7("dt", {
|
|
1953
2228
|
children: row.label
|
|
1954
2229
|
}, undefined, false, undefined, this),
|
|
1955
|
-
/* @__PURE__ */
|
|
2230
|
+
/* @__PURE__ */ jsxDEV7("dd", {
|
|
1956
2231
|
children: row.value
|
|
1957
2232
|
}, undefined, false, undefined, this)
|
|
1958
2233
|
]
|
|
@@ -1960,11 +2235,11 @@ var VoiceProviderStatus = ({
|
|
|
1960
2235
|
}, undefined, false, undefined, this)
|
|
1961
2236
|
]
|
|
1962
2237
|
}, provider.provider, true, undefined, this))
|
|
1963
|
-
}, undefined, false, undefined, this) : /* @__PURE__ */
|
|
2238
|
+
}, undefined, false, undefined, this) : /* @__PURE__ */ jsxDEV7("p", {
|
|
1964
2239
|
className: "absolute-voice-provider-status__empty",
|
|
1965
2240
|
children: "Run voice traffic to see provider health."
|
|
1966
2241
|
}, undefined, false, undefined, this),
|
|
1967
|
-
model.error ? /* @__PURE__ */
|
|
2242
|
+
model.error ? /* @__PURE__ */ jsxDEV7("p", {
|
|
1968
2243
|
className: "absolute-voice-provider-status__error",
|
|
1969
2244
|
children: model.error
|
|
1970
2245
|
}, undefined, false, undefined, this) : null
|
|
@@ -1972,7 +2247,7 @@ var VoiceProviderStatus = ({
|
|
|
1972
2247
|
}, undefined, true, undefined, this);
|
|
1973
2248
|
};
|
|
1974
2249
|
// src/react/useVoiceRoutingStatus.tsx
|
|
1975
|
-
import { useEffect as
|
|
2250
|
+
import { useEffect as useEffect8, useRef as useRef8, useSyncExternalStore as useSyncExternalStore8 } from "react";
|
|
1976
2251
|
|
|
1977
2252
|
// src/client/routingStatus.ts
|
|
1978
2253
|
var fetchVoiceRoutingStatus = async (path = "/api/routing/latest", options = {}) => {
|
|
@@ -2056,25 +2331,25 @@ var createVoiceRoutingStatusStore = (path = "/api/routing/latest", options = {})
|
|
|
2056
2331
|
|
|
2057
2332
|
// src/react/useVoiceRoutingStatus.tsx
|
|
2058
2333
|
var useVoiceRoutingStatus = (path = "/api/routing/latest", options = {}) => {
|
|
2059
|
-
const storeRef =
|
|
2334
|
+
const storeRef = useRef8(null);
|
|
2060
2335
|
if (!storeRef.current) {
|
|
2061
2336
|
storeRef.current = createVoiceRoutingStatusStore(path, options);
|
|
2062
2337
|
}
|
|
2063
2338
|
const store = storeRef.current;
|
|
2064
|
-
|
|
2339
|
+
useEffect8(() => {
|
|
2065
2340
|
store.refresh().catch(() => {});
|
|
2066
2341
|
return () => store.close();
|
|
2067
2342
|
}, [store]);
|
|
2068
2343
|
return {
|
|
2069
|
-
...
|
|
2344
|
+
...useSyncExternalStore8(store.subscribe, store.getSnapshot, store.getServerSnapshot),
|
|
2070
2345
|
refresh: store.refresh
|
|
2071
2346
|
};
|
|
2072
2347
|
};
|
|
2073
2348
|
|
|
2074
2349
|
// src/client/routingStatusWidget.ts
|
|
2075
|
-
var
|
|
2076
|
-
var
|
|
2077
|
-
var
|
|
2350
|
+
var DEFAULT_TITLE7 = "Voice Routing";
|
|
2351
|
+
var DEFAULT_DESCRIPTION7 = "Latest provider routing decision from the self-hosted trace store.";
|
|
2352
|
+
var escapeHtml8 = (value) => value.replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">").replaceAll('"', """).replaceAll("'", "'");
|
|
2078
2353
|
var formatValue = (value, fallback = "None") => typeof value === "string" && value.trim() ? value : typeof value === "number" && Number.isFinite(value) ? String(value) : fallback;
|
|
2079
2354
|
var createVoiceRoutingStatusViewModel = (snapshot, options = {}) => {
|
|
2080
2355
|
const decision = snapshot.decision;
|
|
@@ -2098,30 +2373,30 @@ var createVoiceRoutingStatusViewModel = (snapshot, options = {}) => {
|
|
|
2098
2373
|
] : [];
|
|
2099
2374
|
return {
|
|
2100
2375
|
decision,
|
|
2101
|
-
description: options.description ??
|
|
2376
|
+
description: options.description ?? DEFAULT_DESCRIPTION7,
|
|
2102
2377
|
error: snapshot.error,
|
|
2103
2378
|
isLoading: snapshot.isLoading,
|
|
2104
2379
|
label: snapshot.error ? "Unavailable" : decision ? `${formatValue(decision.kind).toUpperCase()} ${formatValue(decision.status, "unknown")}` : snapshot.isLoading ? "Checking" : "No routing yet",
|
|
2105
2380
|
rows,
|
|
2106
2381
|
status: snapshot.error ? "error" : decision ? "ready" : snapshot.isLoading ? "loading" : "empty",
|
|
2107
|
-
title: options.title ??
|
|
2382
|
+
title: options.title ?? DEFAULT_TITLE7,
|
|
2108
2383
|
updatedAt: snapshot.updatedAt
|
|
2109
2384
|
};
|
|
2110
2385
|
};
|
|
2111
2386
|
var renderVoiceRoutingStatusHTML = (snapshot, options = {}) => {
|
|
2112
2387
|
const model = createVoiceRoutingStatusViewModel(snapshot, options);
|
|
2113
2388
|
const rows = model.rows.length ? `<div class="absolute-voice-routing-status__grid">${model.rows.map((row) => `<div>
|
|
2114
|
-
<span>${
|
|
2115
|
-
<strong>${
|
|
2389
|
+
<span>${escapeHtml8(row.label)}</span>
|
|
2390
|
+
<strong>${escapeHtml8(row.value)}</strong>
|
|
2116
2391
|
</div>`).join("")}</div>` : '<p class="absolute-voice-routing-status__empty">Start a voice session to see the selected provider.</p>';
|
|
2117
|
-
return `<section class="absolute-voice-routing-status absolute-voice-routing-status--${
|
|
2392
|
+
return `<section class="absolute-voice-routing-status absolute-voice-routing-status--${escapeHtml8(model.status)}">
|
|
2118
2393
|
<header class="absolute-voice-routing-status__header">
|
|
2119
|
-
<span class="absolute-voice-routing-status__eyebrow">${
|
|
2120
|
-
<strong class="absolute-voice-routing-status__label">${
|
|
2394
|
+
<span class="absolute-voice-routing-status__eyebrow">${escapeHtml8(model.title)}</span>
|
|
2395
|
+
<strong class="absolute-voice-routing-status__label">${escapeHtml8(model.label)}</strong>
|
|
2121
2396
|
</header>
|
|
2122
|
-
<p class="absolute-voice-routing-status__description">${
|
|
2397
|
+
<p class="absolute-voice-routing-status__description">${escapeHtml8(model.description)}</p>
|
|
2123
2398
|
${rows}
|
|
2124
|
-
${model.error ? `<p class="absolute-voice-routing-status__error">${
|
|
2399
|
+
${model.error ? `<p class="absolute-voice-routing-status__error">${escapeHtml8(model.error)}</p>` : ""}
|
|
2125
2400
|
</section>`;
|
|
2126
2401
|
};
|
|
2127
2402
|
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}`;
|
|
@@ -2163,7 +2438,7 @@ var defineVoiceRoutingStatusElement = (tagName = "absolute-voice-routing-status"
|
|
|
2163
2438
|
};
|
|
2164
2439
|
|
|
2165
2440
|
// src/react/VoiceRoutingStatus.tsx
|
|
2166
|
-
import { jsxDEV as
|
|
2441
|
+
import { jsxDEV as jsxDEV8 } from "react/jsx-dev-runtime";
|
|
2167
2442
|
var VoiceRoutingStatus = ({
|
|
2168
2443
|
className,
|
|
2169
2444
|
path = "/api/routing/latest",
|
|
@@ -2171,47 +2446,47 @@ var VoiceRoutingStatus = ({
|
|
|
2171
2446
|
}) => {
|
|
2172
2447
|
const snapshot = useVoiceRoutingStatus(path, options);
|
|
2173
2448
|
const model = createVoiceRoutingStatusViewModel(snapshot, options);
|
|
2174
|
-
return /* @__PURE__ */
|
|
2449
|
+
return /* @__PURE__ */ jsxDEV8("section", {
|
|
2175
2450
|
className: [
|
|
2176
2451
|
"absolute-voice-routing-status",
|
|
2177
2452
|
`absolute-voice-routing-status--${model.status}`,
|
|
2178
2453
|
className
|
|
2179
2454
|
].filter(Boolean).join(" "),
|
|
2180
2455
|
children: [
|
|
2181
|
-
/* @__PURE__ */
|
|
2456
|
+
/* @__PURE__ */ jsxDEV8("header", {
|
|
2182
2457
|
className: "absolute-voice-routing-status__header",
|
|
2183
2458
|
children: [
|
|
2184
|
-
/* @__PURE__ */
|
|
2459
|
+
/* @__PURE__ */ jsxDEV8("span", {
|
|
2185
2460
|
className: "absolute-voice-routing-status__eyebrow",
|
|
2186
2461
|
children: model.title
|
|
2187
2462
|
}, undefined, false, undefined, this),
|
|
2188
|
-
/* @__PURE__ */
|
|
2463
|
+
/* @__PURE__ */ jsxDEV8("strong", {
|
|
2189
2464
|
className: "absolute-voice-routing-status__label",
|
|
2190
2465
|
children: model.label
|
|
2191
2466
|
}, undefined, false, undefined, this)
|
|
2192
2467
|
]
|
|
2193
2468
|
}, undefined, true, undefined, this),
|
|
2194
|
-
/* @__PURE__ */
|
|
2469
|
+
/* @__PURE__ */ jsxDEV8("p", {
|
|
2195
2470
|
className: "absolute-voice-routing-status__description",
|
|
2196
2471
|
children: model.description
|
|
2197
2472
|
}, undefined, false, undefined, this),
|
|
2198
|
-
model.rows.length ? /* @__PURE__ */
|
|
2473
|
+
model.rows.length ? /* @__PURE__ */ jsxDEV8("div", {
|
|
2199
2474
|
className: "absolute-voice-routing-status__grid",
|
|
2200
|
-
children: model.rows.map((row) => /* @__PURE__ */
|
|
2475
|
+
children: model.rows.map((row) => /* @__PURE__ */ jsxDEV8("div", {
|
|
2201
2476
|
children: [
|
|
2202
|
-
/* @__PURE__ */
|
|
2477
|
+
/* @__PURE__ */ jsxDEV8("span", {
|
|
2203
2478
|
children: row.label
|
|
2204
2479
|
}, undefined, false, undefined, this),
|
|
2205
|
-
/* @__PURE__ */
|
|
2480
|
+
/* @__PURE__ */ jsxDEV8("strong", {
|
|
2206
2481
|
children: row.value
|
|
2207
2482
|
}, undefined, false, undefined, this)
|
|
2208
2483
|
]
|
|
2209
2484
|
}, row.label, true, undefined, this))
|
|
2210
|
-
}, undefined, false, undefined, this) : /* @__PURE__ */
|
|
2485
|
+
}, undefined, false, undefined, this) : /* @__PURE__ */ jsxDEV8("p", {
|
|
2211
2486
|
className: "absolute-voice-routing-status__empty",
|
|
2212
2487
|
children: "Start a voice session to see the selected provider."
|
|
2213
2488
|
}, undefined, false, undefined, this),
|
|
2214
|
-
model.error ? /* @__PURE__ */
|
|
2489
|
+
model.error ? /* @__PURE__ */ jsxDEV8("p", {
|
|
2215
2490
|
className: "absolute-voice-routing-status__error",
|
|
2216
2491
|
children: model.error
|
|
2217
2492
|
}, undefined, false, undefined, this) : null
|
|
@@ -2299,9 +2574,9 @@ var createVoiceTraceTimelineStore = (path = "/api/voice-traces", options = {}) =
|
|
|
2299
2574
|
};
|
|
2300
2575
|
|
|
2301
2576
|
// src/client/traceTimelineWidget.ts
|
|
2302
|
-
var
|
|
2303
|
-
var
|
|
2304
|
-
var
|
|
2577
|
+
var DEFAULT_TITLE8 = "Voice Traces";
|
|
2578
|
+
var DEFAULT_DESCRIPTION8 = "Latest call timelines with provider latency, fallbacks, handoffs, and errors from your self-hosted trace store.";
|
|
2579
|
+
var escapeHtml9 = (value) => value.replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">").replaceAll('"', """).replaceAll("'", "'");
|
|
2305
2580
|
var formatMs = (value) => typeof value === "number" ? `${value}ms` : "n/a";
|
|
2306
2581
|
var formatProviders = (session) => session.providers.length ? session.providers.map((provider) => provider.provider).join(", ") : "No providers";
|
|
2307
2582
|
var createVoiceTraceTimelineViewModel = (snapshot, options = {}) => {
|
|
@@ -2315,34 +2590,34 @@ var createVoiceTraceTimelineViewModel = (snapshot, options = {}) => {
|
|
|
2315
2590
|
const failed = sessions.filter((session) => session.status === "failed").length;
|
|
2316
2591
|
const warnings = sessions.filter((session) => session.status === "warning").length;
|
|
2317
2592
|
return {
|
|
2318
|
-
description: options.description ??
|
|
2593
|
+
description: options.description ?? DEFAULT_DESCRIPTION8,
|
|
2319
2594
|
error: snapshot.error,
|
|
2320
2595
|
isLoading: snapshot.isLoading,
|
|
2321
2596
|
label: snapshot.error ? "Unavailable" : failed > 0 ? `${failed} failed` : warnings > 0 ? `${warnings} warning` : sessions.length ? `${sessions.length} recent` : snapshot.isLoading ? "Checking" : "No traces yet",
|
|
2322
2597
|
sessions,
|
|
2323
2598
|
status: snapshot.error ? "error" : failed > 0 ? "failed" : warnings > 0 ? "warning" : sessions.length ? "ready" : snapshot.isLoading ? "loading" : "empty",
|
|
2324
|
-
title: options.title ??
|
|
2599
|
+
title: options.title ?? DEFAULT_TITLE8,
|
|
2325
2600
|
updatedAt: snapshot.updatedAt
|
|
2326
2601
|
};
|
|
2327
2602
|
};
|
|
2328
2603
|
var renderVoiceTraceTimelineWidgetHTML = (snapshot, options = {}) => {
|
|
2329
2604
|
const model = createVoiceTraceTimelineViewModel(snapshot, options);
|
|
2330
|
-
const sessions = model.sessions.length ? `<div class="absolute-voice-trace-timeline__sessions">${model.sessions.map((session) => `<article class="absolute-voice-trace-timeline__session absolute-voice-trace-timeline__session--${
|
|
2605
|
+
const sessions = model.sessions.length ? `<div class="absolute-voice-trace-timeline__sessions">${model.sessions.map((session) => `<article class="absolute-voice-trace-timeline__session absolute-voice-trace-timeline__session--${escapeHtml9(session.status)}">
|
|
2331
2606
|
<header>
|
|
2332
|
-
<strong>${
|
|
2333
|
-
<span>${
|
|
2607
|
+
<strong>${escapeHtml9(session.sessionId)}</strong>
|
|
2608
|
+
<span>${escapeHtml9(session.status)}</span>
|
|
2334
2609
|
</header>
|
|
2335
|
-
<p>${
|
|
2336
|
-
<a href="${
|
|
2610
|
+
<p>${escapeHtml9(session.label)} \xB7 ${escapeHtml9(session.durationLabel)} \xB7 ${escapeHtml9(session.providerLabel)}</p>
|
|
2611
|
+
<a href="${escapeHtml9(session.detailHref)}">Open timeline</a>
|
|
2337
2612
|
</article>`).join("")}</div>` : '<p class="absolute-voice-trace-timeline__empty">Run a voice session to see call timelines.</p>';
|
|
2338
|
-
return `<section class="absolute-voice-trace-timeline absolute-voice-trace-timeline--${
|
|
2613
|
+
return `<section class="absolute-voice-trace-timeline absolute-voice-trace-timeline--${escapeHtml9(model.status)}">
|
|
2339
2614
|
<header class="absolute-voice-trace-timeline__header">
|
|
2340
|
-
<span class="absolute-voice-trace-timeline__eyebrow">${
|
|
2341
|
-
<strong class="absolute-voice-trace-timeline__label">${
|
|
2615
|
+
<span class="absolute-voice-trace-timeline__eyebrow">${escapeHtml9(model.title)}</span>
|
|
2616
|
+
<strong class="absolute-voice-trace-timeline__label">${escapeHtml9(model.label)}</strong>
|
|
2342
2617
|
</header>
|
|
2343
|
-
<p class="absolute-voice-trace-timeline__description">${
|
|
2618
|
+
<p class="absolute-voice-trace-timeline__description">${escapeHtml9(model.description)}</p>
|
|
2344
2619
|
${sessions}
|
|
2345
|
-
${model.error ? `<p class="absolute-voice-trace-timeline__error">${
|
|
2620
|
+
${model.error ? `<p class="absolute-voice-trace-timeline__error">${escapeHtml9(model.error)}</p>` : ""}
|
|
2346
2621
|
</section>`;
|
|
2347
2622
|
};
|
|
2348
2623
|
var getVoiceTraceTimelineCSS = () => `.absolute-voice-trace-timeline{border:1px solid #bad7d3;border-radius:20px;background:#f3fffb;color:#09201c;padding:18px;box-shadow:0 18px 40px rgba(9,32,28,.12);font-family:inherit}.absolute-voice-trace-timeline--error,.absolute-voice-trace-timeline--failed{border-color:#f2a7a7;background:#fff5f3}.absolute-voice-trace-timeline--warning{border-color:#fbbf24;background:#fffaf0}.absolute-voice-trace-timeline__header,.absolute-voice-trace-timeline__session header{align-items:start;display:flex;gap:12px;justify-content:space-between}.absolute-voice-trace-timeline__eyebrow{color:#17665b;font-size:12px;font-weight:800;letter-spacing:.08em;text-transform:uppercase}.absolute-voice-trace-timeline__label{font-size:24px;line-height:1}.absolute-voice-trace-timeline__description,.absolute-voice-trace-timeline__session p,.absolute-voice-trace-timeline__empty{color:#35544f}.absolute-voice-trace-timeline__sessions{display:grid;gap:12px;margin-top:14px}.absolute-voice-trace-timeline__session{background:#fff;border:1px solid #cfe7e2;border-radius:16px;padding:14px}.absolute-voice-trace-timeline__session--failed{border-color:#f2a7a7}.absolute-voice-trace-timeline__session--warning{border-color:#fbbf24}.absolute-voice-trace-timeline__session p{margin:10px 0}.absolute-voice-trace-timeline__session a{color:#0f766e;font-weight:800}.absolute-voice-trace-timeline__empty{margin:14px 0 0}.absolute-voice-trace-timeline__error{color:#9f1239;font-weight:700}`;
|
|
@@ -2387,25 +2662,25 @@ var defineVoiceTraceTimelineElement = (tagName = "absolute-voice-trace-timeline"
|
|
|
2387
2662
|
};
|
|
2388
2663
|
|
|
2389
2664
|
// src/react/useVoiceTraceTimeline.tsx
|
|
2390
|
-
import { useEffect as
|
|
2665
|
+
import { useEffect as useEffect9, useRef as useRef9, useSyncExternalStore as useSyncExternalStore9 } from "react";
|
|
2391
2666
|
var useVoiceTraceTimeline = (path = "/api/voice-traces", options = {}) => {
|
|
2392
|
-
const storeRef =
|
|
2667
|
+
const storeRef = useRef9(null);
|
|
2393
2668
|
if (!storeRef.current) {
|
|
2394
2669
|
storeRef.current = createVoiceTraceTimelineStore(path, options);
|
|
2395
2670
|
}
|
|
2396
2671
|
const store = storeRef.current;
|
|
2397
|
-
|
|
2672
|
+
useEffect9(() => {
|
|
2398
2673
|
store.refresh().catch(() => {});
|
|
2399
2674
|
return () => store.close();
|
|
2400
2675
|
}, [store]);
|
|
2401
2676
|
return {
|
|
2402
|
-
...
|
|
2677
|
+
...useSyncExternalStore9(store.subscribe, store.getSnapshot, store.getServerSnapshot),
|
|
2403
2678
|
refresh: store.refresh
|
|
2404
2679
|
};
|
|
2405
2680
|
};
|
|
2406
2681
|
|
|
2407
2682
|
// src/react/VoiceTraceTimeline.tsx
|
|
2408
|
-
import { jsxDEV as
|
|
2683
|
+
import { jsxDEV as jsxDEV9 } from "react/jsx-dev-runtime";
|
|
2409
2684
|
var VoiceTraceTimeline = ({
|
|
2410
2685
|
className,
|
|
2411
2686
|
path = "/api/voice-traces",
|
|
@@ -2413,49 +2688,49 @@ var VoiceTraceTimeline = ({
|
|
|
2413
2688
|
}) => {
|
|
2414
2689
|
const snapshot = useVoiceTraceTimeline(path, options);
|
|
2415
2690
|
const model = createVoiceTraceTimelineViewModel(snapshot, options);
|
|
2416
|
-
return /* @__PURE__ */
|
|
2691
|
+
return /* @__PURE__ */ jsxDEV9("section", {
|
|
2417
2692
|
className: [
|
|
2418
2693
|
"absolute-voice-trace-timeline",
|
|
2419
2694
|
`absolute-voice-trace-timeline--${model.status}`,
|
|
2420
2695
|
className
|
|
2421
2696
|
].filter(Boolean).join(" "),
|
|
2422
2697
|
children: [
|
|
2423
|
-
/* @__PURE__ */
|
|
2698
|
+
/* @__PURE__ */ jsxDEV9("header", {
|
|
2424
2699
|
className: "absolute-voice-trace-timeline__header",
|
|
2425
2700
|
children: [
|
|
2426
|
-
/* @__PURE__ */
|
|
2701
|
+
/* @__PURE__ */ jsxDEV9("span", {
|
|
2427
2702
|
className: "absolute-voice-trace-timeline__eyebrow",
|
|
2428
2703
|
children: model.title
|
|
2429
2704
|
}, undefined, false, undefined, this),
|
|
2430
|
-
/* @__PURE__ */
|
|
2705
|
+
/* @__PURE__ */ jsxDEV9("strong", {
|
|
2431
2706
|
className: "absolute-voice-trace-timeline__label",
|
|
2432
2707
|
children: model.label
|
|
2433
2708
|
}, undefined, false, undefined, this)
|
|
2434
2709
|
]
|
|
2435
2710
|
}, undefined, true, undefined, this),
|
|
2436
|
-
/* @__PURE__ */
|
|
2711
|
+
/* @__PURE__ */ jsxDEV9("p", {
|
|
2437
2712
|
className: "absolute-voice-trace-timeline__description",
|
|
2438
2713
|
children: model.description
|
|
2439
2714
|
}, undefined, false, undefined, this),
|
|
2440
|
-
model.sessions.length ? /* @__PURE__ */
|
|
2715
|
+
model.sessions.length ? /* @__PURE__ */ jsxDEV9("div", {
|
|
2441
2716
|
className: "absolute-voice-trace-timeline__sessions",
|
|
2442
|
-
children: model.sessions.map((session) => /* @__PURE__ */
|
|
2717
|
+
children: model.sessions.map((session) => /* @__PURE__ */ jsxDEV9("article", {
|
|
2443
2718
|
className: [
|
|
2444
2719
|
"absolute-voice-trace-timeline__session",
|
|
2445
2720
|
`absolute-voice-trace-timeline__session--${session.status}`
|
|
2446
2721
|
].join(" "),
|
|
2447
2722
|
children: [
|
|
2448
|
-
/* @__PURE__ */
|
|
2723
|
+
/* @__PURE__ */ jsxDEV9("header", {
|
|
2449
2724
|
children: [
|
|
2450
|
-
/* @__PURE__ */
|
|
2725
|
+
/* @__PURE__ */ jsxDEV9("strong", {
|
|
2451
2726
|
children: session.sessionId
|
|
2452
2727
|
}, undefined, false, undefined, this),
|
|
2453
|
-
/* @__PURE__ */
|
|
2728
|
+
/* @__PURE__ */ jsxDEV9("span", {
|
|
2454
2729
|
children: session.status
|
|
2455
2730
|
}, undefined, false, undefined, this)
|
|
2456
2731
|
]
|
|
2457
2732
|
}, undefined, true, undefined, this),
|
|
2458
|
-
/* @__PURE__ */
|
|
2733
|
+
/* @__PURE__ */ jsxDEV9("p", {
|
|
2459
2734
|
children: [
|
|
2460
2735
|
session.label,
|
|
2461
2736
|
" \xB7 ",
|
|
@@ -2465,17 +2740,17 @@ var VoiceTraceTimeline = ({
|
|
|
2465
2740
|
session.providerLabel
|
|
2466
2741
|
]
|
|
2467
2742
|
}, undefined, true, undefined, this),
|
|
2468
|
-
/* @__PURE__ */
|
|
2743
|
+
/* @__PURE__ */ jsxDEV9("a", {
|
|
2469
2744
|
href: session.detailHref,
|
|
2470
2745
|
children: "Open timeline"
|
|
2471
2746
|
}, undefined, false, undefined, this)
|
|
2472
2747
|
]
|
|
2473
2748
|
}, session.sessionId, true, undefined, this))
|
|
2474
|
-
}, undefined, false, undefined, this) : /* @__PURE__ */
|
|
2749
|
+
}, undefined, false, undefined, this) : /* @__PURE__ */ jsxDEV9("p", {
|
|
2475
2750
|
className: "absolute-voice-trace-timeline__empty",
|
|
2476
2751
|
children: "Run a voice session to see call timelines."
|
|
2477
2752
|
}, undefined, false, undefined, this),
|
|
2478
|
-
model.error ? /* @__PURE__ */
|
|
2753
|
+
model.error ? /* @__PURE__ */ jsxDEV9("p", {
|
|
2479
2754
|
className: "absolute-voice-trace-timeline__error",
|
|
2480
2755
|
children: model.error
|
|
2481
2756
|
}, undefined, false, undefined, this) : null
|
|
@@ -2483,7 +2758,7 @@ var VoiceTraceTimeline = ({
|
|
|
2483
2758
|
}, undefined, true, undefined, this);
|
|
2484
2759
|
};
|
|
2485
2760
|
// src/react/useVoiceTurnLatency.tsx
|
|
2486
|
-
import { useEffect as
|
|
2761
|
+
import { useEffect as useEffect10, useRef as useRef10, useSyncExternalStore as useSyncExternalStore10 } from "react";
|
|
2487
2762
|
|
|
2488
2763
|
// src/client/turnLatency.ts
|
|
2489
2764
|
var fetchVoiceTurnLatency = async (path = "/api/turn-latency", options = {}) => {
|
|
@@ -2590,27 +2865,27 @@ var createVoiceTurnLatencyStore = (path = "/api/turn-latency", options = {}) =>
|
|
|
2590
2865
|
|
|
2591
2866
|
// src/react/useVoiceTurnLatency.tsx
|
|
2592
2867
|
var useVoiceTurnLatency = (path = "/api/turn-latency", options = {}) => {
|
|
2593
|
-
const storeRef =
|
|
2868
|
+
const storeRef = useRef10(null);
|
|
2594
2869
|
if (!storeRef.current) {
|
|
2595
2870
|
storeRef.current = createVoiceTurnLatencyStore(path, options);
|
|
2596
2871
|
}
|
|
2597
2872
|
const store = storeRef.current;
|
|
2598
|
-
|
|
2873
|
+
useEffect10(() => {
|
|
2599
2874
|
store.refresh().catch(() => {});
|
|
2600
2875
|
return () => store.close();
|
|
2601
2876
|
}, [store]);
|
|
2602
2877
|
return {
|
|
2603
|
-
...
|
|
2878
|
+
...useSyncExternalStore10(store.subscribe, store.getSnapshot, store.getServerSnapshot),
|
|
2604
2879
|
refresh: store.refresh,
|
|
2605
2880
|
runProof: store.runProof
|
|
2606
2881
|
};
|
|
2607
2882
|
};
|
|
2608
2883
|
|
|
2609
2884
|
// src/client/turnLatencyWidget.ts
|
|
2610
|
-
var
|
|
2611
|
-
var
|
|
2885
|
+
var DEFAULT_TITLE9 = "Turn Latency";
|
|
2886
|
+
var DEFAULT_DESCRIPTION9 = "Per-turn timing from first transcript to commit and assistant response start.";
|
|
2612
2887
|
var DEFAULT_PROOF_LABEL = "Run latency proof";
|
|
2613
|
-
var
|
|
2888
|
+
var escapeHtml10 = (value) => value.replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">").replaceAll('"', """).replaceAll("'", "'");
|
|
2614
2889
|
var formatMs2 = (value) => typeof value === "number" ? `${Math.round(value)}ms` : "n/a";
|
|
2615
2890
|
var createVoiceTurnLatencyViewModel = (snapshot, options = {}) => {
|
|
2616
2891
|
const turns = (snapshot.report?.turns ?? []).map((turn) => ({
|
|
@@ -2624,39 +2899,39 @@ var createVoiceTurnLatencyViewModel = (snapshot, options = {}) => {
|
|
|
2624
2899
|
const warningCount = snapshot.report?.warnings ?? turns.filter((turn) => turn.status === "warn").length;
|
|
2625
2900
|
const failedCount = snapshot.report?.failed ?? turns.filter((turn) => turn.status === "fail").length;
|
|
2626
2901
|
return {
|
|
2627
|
-
description: options.description ??
|
|
2902
|
+
description: options.description ?? DEFAULT_DESCRIPTION9,
|
|
2628
2903
|
error: snapshot.error,
|
|
2629
2904
|
isLoading: snapshot.isLoading,
|
|
2630
2905
|
label: snapshot.error ? "Unavailable" : turns.length ? failedCount > 0 ? `${failedCount} slow` : warningCount > 0 ? `${warningCount} warnings` : `avg ${formatMs2(snapshot.report?.averageTotalMs)}` : snapshot.isLoading ? "Checking" : "No turns",
|
|
2631
2906
|
proofLabel: options.proofPath ? options.proofLabel ?? DEFAULT_PROOF_LABEL : undefined,
|
|
2632
2907
|
showProofAction: Boolean(options.proofPath),
|
|
2633
2908
|
status: snapshot.error ? "error" : turns.length ? failedCount > 0 || warningCount > 0 ? "warning" : "ready" : snapshot.isLoading ? "loading" : "empty",
|
|
2634
|
-
title: options.title ??
|
|
2909
|
+
title: options.title ?? DEFAULT_TITLE9,
|
|
2635
2910
|
turns,
|
|
2636
2911
|
updatedAt: snapshot.updatedAt
|
|
2637
2912
|
};
|
|
2638
2913
|
};
|
|
2639
2914
|
var renderVoiceTurnLatencyHTML = (snapshot, options = {}) => {
|
|
2640
2915
|
const model = createVoiceTurnLatencyViewModel(snapshot, options);
|
|
2641
|
-
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--${
|
|
2916
|
+
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)}">
|
|
2642
2917
|
<header>
|
|
2643
|
-
<strong>${
|
|
2644
|
-
<span>${
|
|
2918
|
+
<strong>${escapeHtml10(turn.label)}</strong>
|
|
2919
|
+
<span>${escapeHtml10(turn.status)}</span>
|
|
2645
2920
|
</header>
|
|
2646
2921
|
<dl>${turn.rows.map((row) => `<div>
|
|
2647
|
-
<dt>${
|
|
2648
|
-
<dd>${
|
|
2922
|
+
<dt>${escapeHtml10(row.label)}</dt>
|
|
2923
|
+
<dd>${escapeHtml10(row.value)}</dd>
|
|
2649
2924
|
</div>`).join("")}</dl>
|
|
2650
2925
|
</article>`).join("")}</div>` : '<p class="absolute-voice-turn-latency__empty">Complete a voice turn to see latency diagnostics.</p>';
|
|
2651
|
-
return `<section class="absolute-voice-turn-latency absolute-voice-turn-latency--${
|
|
2926
|
+
return `<section class="absolute-voice-turn-latency absolute-voice-turn-latency--${escapeHtml10(model.status)}">
|
|
2652
2927
|
<header class="absolute-voice-turn-latency__header">
|
|
2653
|
-
<span class="absolute-voice-turn-latency__eyebrow">${
|
|
2654
|
-
<strong class="absolute-voice-turn-latency__label">${
|
|
2928
|
+
<span class="absolute-voice-turn-latency__eyebrow">${escapeHtml10(model.title)}</span>
|
|
2929
|
+
<strong class="absolute-voice-turn-latency__label">${escapeHtml10(model.label)}</strong>
|
|
2655
2930
|
</header>
|
|
2656
|
-
<p class="absolute-voice-turn-latency__description">${
|
|
2657
|
-
${model.showProofAction ? `<button class="absolute-voice-turn-latency__proof" data-absolute-voice-turn-latency-proof type="button">${
|
|
2931
|
+
<p class="absolute-voice-turn-latency__description">${escapeHtml10(model.description)}</p>
|
|
2932
|
+
${model.showProofAction ? `<button class="absolute-voice-turn-latency__proof" data-absolute-voice-turn-latency-proof type="button">${escapeHtml10(model.proofLabel ?? DEFAULT_PROOF_LABEL)}</button>` : ""}
|
|
2658
2933
|
${turns}
|
|
2659
|
-
${model.error ? `<p class="absolute-voice-turn-latency__error">${
|
|
2934
|
+
${model.error ? `<p class="absolute-voice-turn-latency__error">${escapeHtml10(model.error)}</p>` : ""}
|
|
2660
2935
|
</section>`;
|
|
2661
2936
|
};
|
|
2662
2937
|
var mountVoiceTurnLatency = (element, path = "/api/turn-latency", options = {}) => {
|
|
@@ -2707,7 +2982,7 @@ var defineVoiceTurnLatencyElement = (tagName = "absolute-voice-turn-latency") =>
|
|
|
2707
2982
|
};
|
|
2708
2983
|
|
|
2709
2984
|
// src/react/VoiceTurnLatency.tsx
|
|
2710
|
-
import { jsxDEV as
|
|
2985
|
+
import { jsxDEV as jsxDEV10 } from "react/jsx-dev-runtime";
|
|
2711
2986
|
var VoiceTurnLatency = ({
|
|
2712
2987
|
className,
|
|
2713
2988
|
path = "/api/turn-latency",
|
|
@@ -2715,31 +2990,31 @@ var VoiceTurnLatency = ({
|
|
|
2715
2990
|
}) => {
|
|
2716
2991
|
const latency = useVoiceTurnLatency(path, options);
|
|
2717
2992
|
const model = createVoiceTurnLatencyViewModel(latency, options);
|
|
2718
|
-
return /* @__PURE__ */
|
|
2993
|
+
return /* @__PURE__ */ jsxDEV10("section", {
|
|
2719
2994
|
className: [
|
|
2720
2995
|
"absolute-voice-turn-latency",
|
|
2721
2996
|
`absolute-voice-turn-latency--${model.status}`,
|
|
2722
2997
|
className
|
|
2723
2998
|
].filter(Boolean).join(" "),
|
|
2724
2999
|
children: [
|
|
2725
|
-
/* @__PURE__ */
|
|
3000
|
+
/* @__PURE__ */ jsxDEV10("header", {
|
|
2726
3001
|
className: "absolute-voice-turn-latency__header",
|
|
2727
3002
|
children: [
|
|
2728
|
-
/* @__PURE__ */
|
|
3003
|
+
/* @__PURE__ */ jsxDEV10("span", {
|
|
2729
3004
|
className: "absolute-voice-turn-latency__eyebrow",
|
|
2730
3005
|
children: model.title
|
|
2731
3006
|
}, undefined, false, undefined, this),
|
|
2732
|
-
/* @__PURE__ */
|
|
3007
|
+
/* @__PURE__ */ jsxDEV10("strong", {
|
|
2733
3008
|
className: "absolute-voice-turn-latency__label",
|
|
2734
3009
|
children: model.label
|
|
2735
3010
|
}, undefined, false, undefined, this)
|
|
2736
3011
|
]
|
|
2737
3012
|
}, undefined, true, undefined, this),
|
|
2738
|
-
/* @__PURE__ */
|
|
3013
|
+
/* @__PURE__ */ jsxDEV10("p", {
|
|
2739
3014
|
className: "absolute-voice-turn-latency__description",
|
|
2740
3015
|
children: model.description
|
|
2741
3016
|
}, undefined, false, undefined, this),
|
|
2742
|
-
model.showProofAction ? /* @__PURE__ */
|
|
3017
|
+
model.showProofAction ? /* @__PURE__ */ jsxDEV10("button", {
|
|
2743
3018
|
className: "absolute-voice-turn-latency__proof",
|
|
2744
3019
|
onClick: () => {
|
|
2745
3020
|
latency.runProof().catch(() => {});
|
|
@@ -2747,31 +3022,31 @@ var VoiceTurnLatency = ({
|
|
|
2747
3022
|
type: "button",
|
|
2748
3023
|
children: model.proofLabel
|
|
2749
3024
|
}, undefined, false, undefined, this) : null,
|
|
2750
|
-
model.turns.length ? /* @__PURE__ */
|
|
3025
|
+
model.turns.length ? /* @__PURE__ */ jsxDEV10("div", {
|
|
2751
3026
|
className: "absolute-voice-turn-latency__turns",
|
|
2752
|
-
children: model.turns.map((turn) => /* @__PURE__ */
|
|
3027
|
+
children: model.turns.map((turn) => /* @__PURE__ */ jsxDEV10("article", {
|
|
2753
3028
|
className: [
|
|
2754
3029
|
"absolute-voice-turn-latency__turn",
|
|
2755
3030
|
`absolute-voice-turn-latency__turn--${turn.status}`
|
|
2756
3031
|
].join(" "),
|
|
2757
3032
|
children: [
|
|
2758
|
-
/* @__PURE__ */
|
|
3033
|
+
/* @__PURE__ */ jsxDEV10("header", {
|
|
2759
3034
|
children: [
|
|
2760
|
-
/* @__PURE__ */
|
|
3035
|
+
/* @__PURE__ */ jsxDEV10("strong", {
|
|
2761
3036
|
children: turn.label
|
|
2762
3037
|
}, undefined, false, undefined, this),
|
|
2763
|
-
/* @__PURE__ */
|
|
3038
|
+
/* @__PURE__ */ jsxDEV10("span", {
|
|
2764
3039
|
children: turn.status
|
|
2765
3040
|
}, undefined, false, undefined, this)
|
|
2766
3041
|
]
|
|
2767
3042
|
}, undefined, true, undefined, this),
|
|
2768
|
-
/* @__PURE__ */
|
|
2769
|
-
children: turn.rows.map((row) => /* @__PURE__ */
|
|
3043
|
+
/* @__PURE__ */ jsxDEV10("dl", {
|
|
3044
|
+
children: turn.rows.map((row) => /* @__PURE__ */ jsxDEV10("div", {
|
|
2770
3045
|
children: [
|
|
2771
|
-
/* @__PURE__ */
|
|
3046
|
+
/* @__PURE__ */ jsxDEV10("dt", {
|
|
2772
3047
|
children: row.label
|
|
2773
3048
|
}, undefined, false, undefined, this),
|
|
2774
|
-
/* @__PURE__ */
|
|
3049
|
+
/* @__PURE__ */ jsxDEV10("dd", {
|
|
2775
3050
|
children: row.value
|
|
2776
3051
|
}, undefined, false, undefined, this)
|
|
2777
3052
|
]
|
|
@@ -2779,11 +3054,11 @@ var VoiceTurnLatency = ({
|
|
|
2779
3054
|
}, undefined, false, undefined, this)
|
|
2780
3055
|
]
|
|
2781
3056
|
}, `${turn.sessionId}:${turn.turnId}`, true, undefined, this))
|
|
2782
|
-
}, undefined, false, undefined, this) : /* @__PURE__ */
|
|
3057
|
+
}, undefined, false, undefined, this) : /* @__PURE__ */ jsxDEV10("p", {
|
|
2783
3058
|
className: "absolute-voice-turn-latency__empty",
|
|
2784
3059
|
children: "Complete a voice turn to see latency diagnostics."
|
|
2785
3060
|
}, undefined, false, undefined, this),
|
|
2786
|
-
model.error ? /* @__PURE__ */
|
|
3061
|
+
model.error ? /* @__PURE__ */ jsxDEV10("p", {
|
|
2787
3062
|
className: "absolute-voice-turn-latency__error",
|
|
2788
3063
|
children: model.error
|
|
2789
3064
|
}, undefined, false, undefined, this) : null
|
|
@@ -2791,7 +3066,7 @@ var VoiceTurnLatency = ({
|
|
|
2791
3066
|
}, undefined, true, undefined, this);
|
|
2792
3067
|
};
|
|
2793
3068
|
// src/react/useVoiceTurnQuality.tsx
|
|
2794
|
-
import { useEffect as
|
|
3069
|
+
import { useEffect as useEffect11, useRef as useRef11, useSyncExternalStore as useSyncExternalStore11 } from "react";
|
|
2795
3070
|
|
|
2796
3071
|
// src/client/turnQuality.ts
|
|
2797
3072
|
var fetchVoiceTurnQuality = async (path = "/api/turn-quality", options = {}) => {
|
|
@@ -2874,25 +3149,25 @@ var createVoiceTurnQualityStore = (path = "/api/turn-quality", options = {}) =>
|
|
|
2874
3149
|
|
|
2875
3150
|
// src/react/useVoiceTurnQuality.tsx
|
|
2876
3151
|
var useVoiceTurnQuality = (path = "/api/turn-quality", options = {}) => {
|
|
2877
|
-
const storeRef =
|
|
3152
|
+
const storeRef = useRef11(null);
|
|
2878
3153
|
if (!storeRef.current) {
|
|
2879
3154
|
storeRef.current = createVoiceTurnQualityStore(path, options);
|
|
2880
3155
|
}
|
|
2881
3156
|
const store = storeRef.current;
|
|
2882
|
-
|
|
3157
|
+
useEffect11(() => {
|
|
2883
3158
|
store.refresh().catch(() => {});
|
|
2884
3159
|
return () => store.close();
|
|
2885
3160
|
}, [store]);
|
|
2886
3161
|
return {
|
|
2887
|
-
...
|
|
3162
|
+
...useSyncExternalStore11(store.subscribe, store.getSnapshot, store.getServerSnapshot),
|
|
2888
3163
|
refresh: store.refresh
|
|
2889
3164
|
};
|
|
2890
3165
|
};
|
|
2891
3166
|
|
|
2892
3167
|
// src/client/turnQualityWidget.ts
|
|
2893
|
-
var
|
|
2894
|
-
var
|
|
2895
|
-
var
|
|
3168
|
+
var DEFAULT_TITLE10 = "Turn Quality";
|
|
3169
|
+
var DEFAULT_DESCRIPTION10 = "Per-turn STT confidence, fallback selection, corrections, and transcript coverage.";
|
|
3170
|
+
var escapeHtml11 = (value) => value.replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">").replaceAll('"', """).replaceAll("'", "'");
|
|
2896
3171
|
var formatConfidence = (value) => typeof value === "number" ? `${Math.round(value * 100)}%` : "n/a";
|
|
2897
3172
|
var formatMaybe = (value) => value === undefined || value === "" ? "n/a" : String(value);
|
|
2898
3173
|
var getTurnDetail = (turn) => {
|
|
@@ -2930,37 +3205,37 @@ var createVoiceTurnQualityViewModel = (snapshot, options = {}) => {
|
|
|
2930
3205
|
const warningCount = snapshot.report?.warnings ?? turns.filter((turn) => turn.status === "warn").length;
|
|
2931
3206
|
const failedCount = snapshot.report?.failed ?? turns.filter((turn) => turn.status === "fail").length;
|
|
2932
3207
|
return {
|
|
2933
|
-
description: options.description ??
|
|
3208
|
+
description: options.description ?? DEFAULT_DESCRIPTION10,
|
|
2934
3209
|
error: snapshot.error,
|
|
2935
3210
|
isLoading: snapshot.isLoading,
|
|
2936
3211
|
label: snapshot.error ? "Unavailable" : turns.length ? failedCount > 0 ? `${failedCount} failed` : warningCount > 0 ? `${warningCount} warnings` : `${turns.length} healthy` : snapshot.isLoading ? "Checking" : "No turns",
|
|
2937
3212
|
status: snapshot.error ? "error" : turns.length ? failedCount > 0 || warningCount > 0 ? "warning" : "ready" : snapshot.isLoading ? "loading" : "empty",
|
|
2938
|
-
title: options.title ??
|
|
3213
|
+
title: options.title ?? DEFAULT_TITLE10,
|
|
2939
3214
|
turns,
|
|
2940
3215
|
updatedAt: snapshot.updatedAt
|
|
2941
3216
|
};
|
|
2942
3217
|
};
|
|
2943
3218
|
var renderVoiceTurnQualityHTML = (snapshot, options = {}) => {
|
|
2944
3219
|
const model = createVoiceTurnQualityViewModel(snapshot, options);
|
|
2945
|
-
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--${
|
|
3220
|
+
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)}">
|
|
2946
3221
|
<header>
|
|
2947
|
-
<strong>${
|
|
2948
|
-
<span>${
|
|
3222
|
+
<strong>${escapeHtml11(turn.label)}</strong>
|
|
3223
|
+
<span>${escapeHtml11(turn.status)}</span>
|
|
2949
3224
|
</header>
|
|
2950
|
-
<p>${
|
|
3225
|
+
<p>${escapeHtml11(turn.detail)}</p>
|
|
2951
3226
|
<dl>${turn.rows.map((row) => `<div>
|
|
2952
|
-
<dt>${
|
|
2953
|
-
<dd>${
|
|
3227
|
+
<dt>${escapeHtml11(row.label)}</dt>
|
|
3228
|
+
<dd>${escapeHtml11(row.value)}</dd>
|
|
2954
3229
|
</div>`).join("")}</dl>
|
|
2955
3230
|
</article>`).join("")}</div>` : '<p class="absolute-voice-turn-quality__empty">Complete a voice turn to see STT quality diagnostics.</p>';
|
|
2956
|
-
return `<section class="absolute-voice-turn-quality absolute-voice-turn-quality--${
|
|
3231
|
+
return `<section class="absolute-voice-turn-quality absolute-voice-turn-quality--${escapeHtml11(model.status)}">
|
|
2957
3232
|
<header class="absolute-voice-turn-quality__header">
|
|
2958
|
-
<span class="absolute-voice-turn-quality__eyebrow">${
|
|
2959
|
-
<strong class="absolute-voice-turn-quality__label">${
|
|
3233
|
+
<span class="absolute-voice-turn-quality__eyebrow">${escapeHtml11(model.title)}</span>
|
|
3234
|
+
<strong class="absolute-voice-turn-quality__label">${escapeHtml11(model.label)}</strong>
|
|
2960
3235
|
</header>
|
|
2961
|
-
<p class="absolute-voice-turn-quality__description">${
|
|
3236
|
+
<p class="absolute-voice-turn-quality__description">${escapeHtml11(model.description)}</p>
|
|
2962
3237
|
${turns}
|
|
2963
|
-
${model.error ? `<p class="absolute-voice-turn-quality__error">${
|
|
3238
|
+
${model.error ? `<p class="absolute-voice-turn-quality__error">${escapeHtml11(model.error)}</p>` : ""}
|
|
2964
3239
|
</section>`;
|
|
2965
3240
|
};
|
|
2966
3241
|
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}`;
|
|
@@ -3002,7 +3277,7 @@ var defineVoiceTurnQualityElement = (tagName = "absolute-voice-turn-quality") =>
|
|
|
3002
3277
|
};
|
|
3003
3278
|
|
|
3004
3279
|
// src/react/VoiceTurnQuality.tsx
|
|
3005
|
-
import { jsxDEV as
|
|
3280
|
+
import { jsxDEV as jsxDEV11 } from "react/jsx-dev-runtime";
|
|
3006
3281
|
var VoiceTurnQuality = ({
|
|
3007
3282
|
className,
|
|
3008
3283
|
path = "/api/turn-quality",
|
|
@@ -3010,58 +3285,58 @@ var VoiceTurnQuality = ({
|
|
|
3010
3285
|
}) => {
|
|
3011
3286
|
const snapshot = useVoiceTurnQuality(path, options);
|
|
3012
3287
|
const model = createVoiceTurnQualityViewModel(snapshot, options);
|
|
3013
|
-
return /* @__PURE__ */
|
|
3288
|
+
return /* @__PURE__ */ jsxDEV11("section", {
|
|
3014
3289
|
className: [
|
|
3015
3290
|
"absolute-voice-turn-quality",
|
|
3016
3291
|
`absolute-voice-turn-quality--${model.status}`,
|
|
3017
3292
|
className
|
|
3018
3293
|
].filter(Boolean).join(" "),
|
|
3019
3294
|
children: [
|
|
3020
|
-
/* @__PURE__ */
|
|
3295
|
+
/* @__PURE__ */ jsxDEV11("header", {
|
|
3021
3296
|
className: "absolute-voice-turn-quality__header",
|
|
3022
3297
|
children: [
|
|
3023
|
-
/* @__PURE__ */
|
|
3298
|
+
/* @__PURE__ */ jsxDEV11("span", {
|
|
3024
3299
|
className: "absolute-voice-turn-quality__eyebrow",
|
|
3025
3300
|
children: model.title
|
|
3026
3301
|
}, undefined, false, undefined, this),
|
|
3027
|
-
/* @__PURE__ */
|
|
3302
|
+
/* @__PURE__ */ jsxDEV11("strong", {
|
|
3028
3303
|
className: "absolute-voice-turn-quality__label",
|
|
3029
3304
|
children: model.label
|
|
3030
3305
|
}, undefined, false, undefined, this)
|
|
3031
3306
|
]
|
|
3032
3307
|
}, undefined, true, undefined, this),
|
|
3033
|
-
/* @__PURE__ */
|
|
3308
|
+
/* @__PURE__ */ jsxDEV11("p", {
|
|
3034
3309
|
className: "absolute-voice-turn-quality__description",
|
|
3035
3310
|
children: model.description
|
|
3036
3311
|
}, undefined, false, undefined, this),
|
|
3037
|
-
model.turns.length ? /* @__PURE__ */
|
|
3312
|
+
model.turns.length ? /* @__PURE__ */ jsxDEV11("div", {
|
|
3038
3313
|
className: "absolute-voice-turn-quality__turns",
|
|
3039
|
-
children: model.turns.map((turn) => /* @__PURE__ */
|
|
3314
|
+
children: model.turns.map((turn) => /* @__PURE__ */ jsxDEV11("article", {
|
|
3040
3315
|
className: [
|
|
3041
3316
|
"absolute-voice-turn-quality__turn",
|
|
3042
3317
|
`absolute-voice-turn-quality__turn--${turn.status}`
|
|
3043
3318
|
].join(" "),
|
|
3044
3319
|
children: [
|
|
3045
|
-
/* @__PURE__ */
|
|
3320
|
+
/* @__PURE__ */ jsxDEV11("header", {
|
|
3046
3321
|
children: [
|
|
3047
|
-
/* @__PURE__ */
|
|
3322
|
+
/* @__PURE__ */ jsxDEV11("strong", {
|
|
3048
3323
|
children: turn.label
|
|
3049
3324
|
}, undefined, false, undefined, this),
|
|
3050
|
-
/* @__PURE__ */
|
|
3325
|
+
/* @__PURE__ */ jsxDEV11("span", {
|
|
3051
3326
|
children: turn.status
|
|
3052
3327
|
}, undefined, false, undefined, this)
|
|
3053
3328
|
]
|
|
3054
3329
|
}, undefined, true, undefined, this),
|
|
3055
|
-
/* @__PURE__ */
|
|
3330
|
+
/* @__PURE__ */ jsxDEV11("p", {
|
|
3056
3331
|
children: turn.detail
|
|
3057
3332
|
}, undefined, false, undefined, this),
|
|
3058
|
-
/* @__PURE__ */
|
|
3059
|
-
children: turn.rows.map((row) => /* @__PURE__ */
|
|
3333
|
+
/* @__PURE__ */ jsxDEV11("dl", {
|
|
3334
|
+
children: turn.rows.map((row) => /* @__PURE__ */ jsxDEV11("div", {
|
|
3060
3335
|
children: [
|
|
3061
|
-
/* @__PURE__ */
|
|
3336
|
+
/* @__PURE__ */ jsxDEV11("dt", {
|
|
3062
3337
|
children: row.label
|
|
3063
3338
|
}, undefined, false, undefined, this),
|
|
3064
|
-
/* @__PURE__ */
|
|
3339
|
+
/* @__PURE__ */ jsxDEV11("dd", {
|
|
3065
3340
|
children: row.value
|
|
3066
3341
|
}, undefined, false, undefined, this)
|
|
3067
3342
|
]
|
|
@@ -3069,11 +3344,11 @@ var VoiceTurnQuality = ({
|
|
|
3069
3344
|
}, undefined, false, undefined, this)
|
|
3070
3345
|
]
|
|
3071
3346
|
}, `${turn.sessionId}:${turn.turnId}`, true, undefined, this))
|
|
3072
|
-
}, undefined, false, undefined, this) : /* @__PURE__ */
|
|
3347
|
+
}, undefined, false, undefined, this) : /* @__PURE__ */ jsxDEV11("p", {
|
|
3073
3348
|
className: "absolute-voice-turn-quality__empty",
|
|
3074
3349
|
children: "Complete a voice turn to see STT quality diagnostics."
|
|
3075
3350
|
}, undefined, false, undefined, this),
|
|
3076
|
-
model.error ? /* @__PURE__ */
|
|
3351
|
+
model.error ? /* @__PURE__ */ jsxDEV11("p", {
|
|
3077
3352
|
className: "absolute-voice-turn-quality__error",
|
|
3078
3353
|
children: model.error
|
|
3079
3354
|
}, undefined, false, undefined, this) : null
|
|
@@ -3081,7 +3356,7 @@ var VoiceTurnQuality = ({
|
|
|
3081
3356
|
}, undefined, true, undefined, this);
|
|
3082
3357
|
};
|
|
3083
3358
|
// src/react/useVoiceCampaignDialerProof.tsx
|
|
3084
|
-
import { useEffect as
|
|
3359
|
+
import { useEffect as useEffect12, useRef as useRef12, useSyncExternalStore as useSyncExternalStore12 } from "react";
|
|
3085
3360
|
|
|
3086
3361
|
// src/client/campaignDialerProof.ts
|
|
3087
3362
|
var fetchVoiceCampaignDialerProofStatus = async (path = "/api/voice/campaigns/dialer-proof", options = {}) => {
|
|
@@ -3203,23 +3478,23 @@ var createVoiceCampaignDialerProofStore = (path = "/api/voice/campaigns/dialer-p
|
|
|
3203
3478
|
|
|
3204
3479
|
// src/react/useVoiceCampaignDialerProof.tsx
|
|
3205
3480
|
var useVoiceCampaignDialerProof = (path = "/api/voice/campaigns/dialer-proof", options = {}) => {
|
|
3206
|
-
const storeRef =
|
|
3481
|
+
const storeRef = useRef12(null);
|
|
3207
3482
|
if (!storeRef.current) {
|
|
3208
3483
|
storeRef.current = createVoiceCampaignDialerProofStore(path, options);
|
|
3209
3484
|
}
|
|
3210
3485
|
const store = storeRef.current;
|
|
3211
|
-
|
|
3486
|
+
useEffect12(() => {
|
|
3212
3487
|
store.refresh().catch(() => {});
|
|
3213
3488
|
return () => store.close();
|
|
3214
3489
|
}, [store]);
|
|
3215
3490
|
return {
|
|
3216
|
-
...
|
|
3491
|
+
...useSyncExternalStore12(store.subscribe, store.getSnapshot, store.getServerSnapshot),
|
|
3217
3492
|
refresh: store.refresh,
|
|
3218
3493
|
runProof: store.runProof
|
|
3219
3494
|
};
|
|
3220
3495
|
};
|
|
3221
3496
|
// src/react/useVoiceStream.tsx
|
|
3222
|
-
import { useEffect as
|
|
3497
|
+
import { useEffect as useEffect13, useRef as useRef13, useSyncExternalStore as useSyncExternalStore13 } from "react";
|
|
3223
3498
|
|
|
3224
3499
|
// src/client/actions.ts
|
|
3225
3500
|
var normalizeErrorMessage = (value) => {
|
|
@@ -3879,13 +4154,13 @@ var EMPTY_SNAPSHOT = {
|
|
|
3879
4154
|
turns: []
|
|
3880
4155
|
};
|
|
3881
4156
|
var useVoiceStream = (path, options = {}) => {
|
|
3882
|
-
const streamRef =
|
|
4157
|
+
const streamRef = useRef13(null);
|
|
3883
4158
|
if (!streamRef.current) {
|
|
3884
4159
|
streamRef.current = createVoiceStream(path, options);
|
|
3885
4160
|
}
|
|
3886
4161
|
const stream = streamRef.current;
|
|
3887
|
-
|
|
3888
|
-
const snapshot =
|
|
4162
|
+
useEffect13(() => () => stream.close(), [stream]);
|
|
4163
|
+
const snapshot = useSyncExternalStore13(stream.subscribe, stream.getSnapshot, stream.getServerSnapshot) ?? EMPTY_SNAPSHOT;
|
|
3889
4164
|
return {
|
|
3890
4165
|
...snapshot,
|
|
3891
4166
|
callControl: (message) => stream.callControl(message),
|
|
@@ -3895,7 +4170,7 @@ var useVoiceStream = (path, options = {}) => {
|
|
|
3895
4170
|
};
|
|
3896
4171
|
};
|
|
3897
4172
|
// src/react/useVoiceController.tsx
|
|
3898
|
-
import { useEffect as
|
|
4173
|
+
import { useEffect as useEffect14, useRef as useRef14, useSyncExternalStore as useSyncExternalStore14 } from "react";
|
|
3899
4174
|
|
|
3900
4175
|
// src/client/htmx.ts
|
|
3901
4176
|
var DEFAULT_EVENT_NAME = "voice-refresh";
|
|
@@ -4558,13 +4833,13 @@ var EMPTY_SNAPSHOT2 = {
|
|
|
4558
4833
|
turns: []
|
|
4559
4834
|
};
|
|
4560
4835
|
var useVoiceController = (path, options = {}) => {
|
|
4561
|
-
const controllerRef =
|
|
4836
|
+
const controllerRef = useRef14(null);
|
|
4562
4837
|
if (!controllerRef.current) {
|
|
4563
4838
|
controllerRef.current = createVoiceController(path, options);
|
|
4564
4839
|
}
|
|
4565
4840
|
const controller = controllerRef.current;
|
|
4566
|
-
|
|
4567
|
-
const snapshot =
|
|
4841
|
+
useEffect14(() => () => controller.close(), [controller]);
|
|
4842
|
+
const snapshot = useSyncExternalStore14(controller.subscribe, controller.getSnapshot, controller.getServerSnapshot) ?? EMPTY_SNAPSHOT2;
|
|
4568
4843
|
return {
|
|
4569
4844
|
...snapshot,
|
|
4570
4845
|
bindHTMX: controller.bindHTMX,
|
|
@@ -4578,7 +4853,7 @@ var useVoiceController = (path, options = {}) => {
|
|
|
4578
4853
|
};
|
|
4579
4854
|
};
|
|
4580
4855
|
// src/react/useVoiceWorkflowStatus.tsx
|
|
4581
|
-
import { useEffect as
|
|
4856
|
+
import { useEffect as useEffect15, useRef as useRef15, useSyncExternalStore as useSyncExternalStore15 } from "react";
|
|
4582
4857
|
|
|
4583
4858
|
// src/client/workflowStatus.ts
|
|
4584
4859
|
var fetchVoiceWorkflowStatus = async (path = "/evals/scenarios/json", options = {}) => {
|
|
@@ -4661,17 +4936,17 @@ var createVoiceWorkflowStatusStore = (path = "/evals/scenarios/json", options =
|
|
|
4661
4936
|
|
|
4662
4937
|
// src/react/useVoiceWorkflowStatus.tsx
|
|
4663
4938
|
var useVoiceWorkflowStatus = (path = "/evals/scenarios/json", options = {}) => {
|
|
4664
|
-
const storeRef =
|
|
4939
|
+
const storeRef = useRef15(null);
|
|
4665
4940
|
if (!storeRef.current) {
|
|
4666
4941
|
storeRef.current = createVoiceWorkflowStatusStore(path, options);
|
|
4667
4942
|
}
|
|
4668
4943
|
const store = storeRef.current;
|
|
4669
|
-
|
|
4944
|
+
useEffect15(() => {
|
|
4670
4945
|
store.refresh().catch(() => {});
|
|
4671
4946
|
return () => store.close();
|
|
4672
4947
|
}, [store]);
|
|
4673
4948
|
return {
|
|
4674
|
-
...
|
|
4949
|
+
...useSyncExternalStore15(store.subscribe, store.getSnapshot, store.getServerSnapshot),
|
|
4675
4950
|
refresh: store.refresh
|
|
4676
4951
|
};
|
|
4677
4952
|
};
|
|
@@ -4684,6 +4959,7 @@ export {
|
|
|
4684
4959
|
useVoiceRoutingStatus,
|
|
4685
4960
|
useVoiceProviderStatus,
|
|
4686
4961
|
useVoiceProviderSimulationControls,
|
|
4962
|
+
useVoiceProviderContracts,
|
|
4687
4963
|
useVoiceProviderCapabilities,
|
|
4688
4964
|
useVoiceOpsStatus,
|
|
4689
4965
|
useVoiceOpsActionCenter,
|
|
@@ -4696,6 +4972,7 @@ export {
|
|
|
4696
4972
|
VoiceRoutingStatus,
|
|
4697
4973
|
VoiceProviderStatus,
|
|
4698
4974
|
VoiceProviderSimulationControls,
|
|
4975
|
+
VoiceProviderContracts,
|
|
4699
4976
|
VoiceProviderCapabilities,
|
|
4700
4977
|
VoiceOpsStatus,
|
|
4701
4978
|
VoiceOpsActionCenter,
|