@absolutejs/voice 0.0.22-beta.94 → 0.0.22-beta.96
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 +139 -20
- package/dist/angular/voice-turn-latency.service.d.ts +12 -0
- package/dist/client/index.d.ts +4 -0
- package/dist/client/index.js +182 -17
- package/dist/client/turnLatency.d.ts +19 -0
- package/dist/client/turnLatencyWidget.d.ts +30 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +278 -68
- package/dist/react/VoiceTurnLatency.d.ts +6 -0
- package/dist/react/index.d.ts +2 -0
- package/dist/react/index.js +309 -50
- package/dist/react/useVoiceTurnLatency.d.ts +8 -0
- package/dist/svelte/createVoiceTurnLatency.d.ts +10 -0
- package/dist/svelte/index.d.ts +1 -0
- package/dist/svelte/index.js +187 -16
- package/dist/testing/index.js +57 -1
- package/dist/trace.d.ts +1 -1
- package/dist/turnLatency.d.ts +95 -0
- package/dist/vue/VoiceTurnLatency.d.ts +51 -0
- package/dist/vue/index.d.ts +2 -0
- package/dist/vue/index.js +303 -57
- package/dist/vue/useVoiceTurnLatency.d.ts +9 -0
- package/package.json +1 -1
package/dist/vue/index.js
CHANGED
|
@@ -1531,9 +1531,253 @@ var VoiceRoutingStatus = defineComponent5({
|
|
|
1531
1531
|
]);
|
|
1532
1532
|
}
|
|
1533
1533
|
});
|
|
1534
|
-
// src/vue/
|
|
1534
|
+
// src/vue/VoiceTurnLatency.ts
|
|
1535
1535
|
import { computed as computed5, defineComponent as defineComponent6, h as h6 } from "vue";
|
|
1536
1536
|
|
|
1537
|
+
// src/client/turnLatency.ts
|
|
1538
|
+
var fetchVoiceTurnLatency = async (path = "/api/turn-latency", options = {}) => {
|
|
1539
|
+
const fetchImpl = options.fetch ?? globalThis.fetch;
|
|
1540
|
+
const response = await fetchImpl(path);
|
|
1541
|
+
if (!response.ok) {
|
|
1542
|
+
throw new Error(`Voice turn latency failed: HTTP ${response.status}`);
|
|
1543
|
+
}
|
|
1544
|
+
return await response.json();
|
|
1545
|
+
};
|
|
1546
|
+
var createVoiceTurnLatencyStore = (path = "/api/turn-latency", options = {}) => {
|
|
1547
|
+
const listeners = new Set;
|
|
1548
|
+
let closed = false;
|
|
1549
|
+
let timer;
|
|
1550
|
+
let snapshot = {
|
|
1551
|
+
error: null,
|
|
1552
|
+
isLoading: false
|
|
1553
|
+
};
|
|
1554
|
+
const emit = () => {
|
|
1555
|
+
for (const listener of listeners) {
|
|
1556
|
+
listener();
|
|
1557
|
+
}
|
|
1558
|
+
};
|
|
1559
|
+
const refresh = async () => {
|
|
1560
|
+
if (closed) {
|
|
1561
|
+
return snapshot.report;
|
|
1562
|
+
}
|
|
1563
|
+
snapshot = { ...snapshot, error: null, isLoading: true };
|
|
1564
|
+
emit();
|
|
1565
|
+
try {
|
|
1566
|
+
const report = await fetchVoiceTurnLatency(path, options);
|
|
1567
|
+
snapshot = {
|
|
1568
|
+
error: null,
|
|
1569
|
+
isLoading: false,
|
|
1570
|
+
report,
|
|
1571
|
+
updatedAt: Date.now()
|
|
1572
|
+
};
|
|
1573
|
+
emit();
|
|
1574
|
+
return report;
|
|
1575
|
+
} catch (error) {
|
|
1576
|
+
snapshot = {
|
|
1577
|
+
...snapshot,
|
|
1578
|
+
error: error instanceof Error ? error.message : String(error),
|
|
1579
|
+
isLoading: false
|
|
1580
|
+
};
|
|
1581
|
+
emit();
|
|
1582
|
+
throw error;
|
|
1583
|
+
}
|
|
1584
|
+
};
|
|
1585
|
+
const close = () => {
|
|
1586
|
+
closed = true;
|
|
1587
|
+
if (timer) {
|
|
1588
|
+
clearInterval(timer);
|
|
1589
|
+
timer = undefined;
|
|
1590
|
+
}
|
|
1591
|
+
listeners.clear();
|
|
1592
|
+
};
|
|
1593
|
+
if (options.intervalMs && options.intervalMs > 0) {
|
|
1594
|
+
timer = setInterval(() => {
|
|
1595
|
+
refresh().catch(() => {});
|
|
1596
|
+
}, options.intervalMs);
|
|
1597
|
+
}
|
|
1598
|
+
return {
|
|
1599
|
+
close,
|
|
1600
|
+
getServerSnapshot: () => snapshot,
|
|
1601
|
+
getSnapshot: () => snapshot,
|
|
1602
|
+
refresh,
|
|
1603
|
+
subscribe: (listener) => {
|
|
1604
|
+
listeners.add(listener);
|
|
1605
|
+
return () => {
|
|
1606
|
+
listeners.delete(listener);
|
|
1607
|
+
};
|
|
1608
|
+
}
|
|
1609
|
+
};
|
|
1610
|
+
};
|
|
1611
|
+
|
|
1612
|
+
// src/client/turnLatencyWidget.ts
|
|
1613
|
+
var DEFAULT_TITLE5 = "Turn Latency";
|
|
1614
|
+
var DEFAULT_DESCRIPTION5 = "Per-turn timing from first transcript to commit and assistant response start.";
|
|
1615
|
+
var escapeHtml6 = (value) => value.replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">").replaceAll('"', """).replaceAll("'", "'");
|
|
1616
|
+
var formatMs = (value) => typeof value === "number" ? `${Math.round(value)}ms` : "n/a";
|
|
1617
|
+
var createVoiceTurnLatencyViewModel = (snapshot, options = {}) => {
|
|
1618
|
+
const turns = (snapshot.report?.turns ?? []).map((turn) => ({
|
|
1619
|
+
...turn,
|
|
1620
|
+
label: turn.text || "Empty turn",
|
|
1621
|
+
rows: turn.stages.map((stage) => ({
|
|
1622
|
+
label: stage.label,
|
|
1623
|
+
value: formatMs(stage.valueMs)
|
|
1624
|
+
}))
|
|
1625
|
+
}));
|
|
1626
|
+
const warningCount = snapshot.report?.warnings ?? turns.filter((turn) => turn.status === "warn").length;
|
|
1627
|
+
const failedCount = snapshot.report?.failed ?? turns.filter((turn) => turn.status === "fail").length;
|
|
1628
|
+
return {
|
|
1629
|
+
description: options.description ?? DEFAULT_DESCRIPTION5,
|
|
1630
|
+
error: snapshot.error,
|
|
1631
|
+
isLoading: snapshot.isLoading,
|
|
1632
|
+
label: snapshot.error ? "Unavailable" : turns.length ? failedCount > 0 ? `${failedCount} slow` : warningCount > 0 ? `${warningCount} warnings` : `avg ${formatMs(snapshot.report?.averageTotalMs)}` : snapshot.isLoading ? "Checking" : "No turns",
|
|
1633
|
+
status: snapshot.error ? "error" : turns.length ? failedCount > 0 || warningCount > 0 ? "warning" : "ready" : snapshot.isLoading ? "loading" : "empty",
|
|
1634
|
+
title: options.title ?? DEFAULT_TITLE5,
|
|
1635
|
+
turns,
|
|
1636
|
+
updatedAt: snapshot.updatedAt
|
|
1637
|
+
};
|
|
1638
|
+
};
|
|
1639
|
+
var renderVoiceTurnLatencyHTML = (snapshot, options = {}) => {
|
|
1640
|
+
const model = createVoiceTurnLatencyViewModel(snapshot, options);
|
|
1641
|
+
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--${escapeHtml6(turn.status)}">
|
|
1642
|
+
<header>
|
|
1643
|
+
<strong>${escapeHtml6(turn.label)}</strong>
|
|
1644
|
+
<span>${escapeHtml6(turn.status)}</span>
|
|
1645
|
+
</header>
|
|
1646
|
+
<dl>${turn.rows.map((row) => `<div>
|
|
1647
|
+
<dt>${escapeHtml6(row.label)}</dt>
|
|
1648
|
+
<dd>${escapeHtml6(row.value)}</dd>
|
|
1649
|
+
</div>`).join("")}</dl>
|
|
1650
|
+
</article>`).join("")}</div>` : '<p class="absolute-voice-turn-latency__empty">Complete a voice turn to see latency diagnostics.</p>';
|
|
1651
|
+
return `<section class="absolute-voice-turn-latency absolute-voice-turn-latency--${escapeHtml6(model.status)}">
|
|
1652
|
+
<header class="absolute-voice-turn-latency__header">
|
|
1653
|
+
<span class="absolute-voice-turn-latency__eyebrow">${escapeHtml6(model.title)}</span>
|
|
1654
|
+
<strong class="absolute-voice-turn-latency__label">${escapeHtml6(model.label)}</strong>
|
|
1655
|
+
</header>
|
|
1656
|
+
<p class="absolute-voice-turn-latency__description">${escapeHtml6(model.description)}</p>
|
|
1657
|
+
${turns}
|
|
1658
|
+
${model.error ? `<p class="absolute-voice-turn-latency__error">${escapeHtml6(model.error)}</p>` : ""}
|
|
1659
|
+
</section>`;
|
|
1660
|
+
};
|
|
1661
|
+
var mountVoiceTurnLatency = (element, path = "/api/turn-latency", options = {}) => {
|
|
1662
|
+
const store = createVoiceTurnLatencyStore(path, options);
|
|
1663
|
+
const render = () => {
|
|
1664
|
+
element.innerHTML = renderVoiceTurnLatencyHTML(store.getSnapshot(), options);
|
|
1665
|
+
};
|
|
1666
|
+
const unsubscribe = store.subscribe(render);
|
|
1667
|
+
render();
|
|
1668
|
+
store.refresh().catch(() => {});
|
|
1669
|
+
return {
|
|
1670
|
+
close: () => {
|
|
1671
|
+
unsubscribe();
|
|
1672
|
+
store.close();
|
|
1673
|
+
},
|
|
1674
|
+
refresh: store.refresh
|
|
1675
|
+
};
|
|
1676
|
+
};
|
|
1677
|
+
var defineVoiceTurnLatencyElement = (tagName = "absolute-voice-turn-latency") => {
|
|
1678
|
+
if (typeof window === "undefined" || typeof customElements === "undefined" || customElements.get(tagName)) {
|
|
1679
|
+
return;
|
|
1680
|
+
}
|
|
1681
|
+
customElements.define(tagName, class AbsoluteVoiceTurnLatencyElement extends HTMLElement {
|
|
1682
|
+
mounted;
|
|
1683
|
+
connectedCallback() {
|
|
1684
|
+
const intervalMs = Number(this.getAttribute("interval-ms") ?? 5000);
|
|
1685
|
+
this.mounted = mountVoiceTurnLatency(this, this.getAttribute("path") ?? "/api/turn-latency", {
|
|
1686
|
+
description: this.getAttribute("description") ?? undefined,
|
|
1687
|
+
intervalMs: Number.isFinite(intervalMs) ? intervalMs : 5000,
|
|
1688
|
+
title: this.getAttribute("title") ?? undefined
|
|
1689
|
+
});
|
|
1690
|
+
}
|
|
1691
|
+
disconnectedCallback() {
|
|
1692
|
+
this.mounted?.close();
|
|
1693
|
+
this.mounted = undefined;
|
|
1694
|
+
}
|
|
1695
|
+
});
|
|
1696
|
+
};
|
|
1697
|
+
|
|
1698
|
+
// src/vue/useVoiceTurnLatency.ts
|
|
1699
|
+
import { onUnmounted as onUnmounted6, shallowRef as shallowRef5 } from "vue";
|
|
1700
|
+
var useVoiceTurnLatency = (path = "/api/turn-latency", options = {}) => {
|
|
1701
|
+
const store = createVoiceTurnLatencyStore(path, options);
|
|
1702
|
+
const error = shallowRef5(null);
|
|
1703
|
+
const isLoading = shallowRef5(false);
|
|
1704
|
+
const report = shallowRef5();
|
|
1705
|
+
const updatedAt = shallowRef5(undefined);
|
|
1706
|
+
const sync = () => {
|
|
1707
|
+
const snapshot = store.getSnapshot();
|
|
1708
|
+
error.value = snapshot.error;
|
|
1709
|
+
isLoading.value = snapshot.isLoading;
|
|
1710
|
+
report.value = snapshot.report;
|
|
1711
|
+
updatedAt.value = snapshot.updatedAt;
|
|
1712
|
+
};
|
|
1713
|
+
const unsubscribe = store.subscribe(sync);
|
|
1714
|
+
sync();
|
|
1715
|
+
store.refresh().catch(() => {});
|
|
1716
|
+
onUnmounted6(() => {
|
|
1717
|
+
unsubscribe();
|
|
1718
|
+
store.close();
|
|
1719
|
+
});
|
|
1720
|
+
return { error, isLoading, refresh: store.refresh, report, updatedAt };
|
|
1721
|
+
};
|
|
1722
|
+
|
|
1723
|
+
// src/vue/VoiceTurnLatency.ts
|
|
1724
|
+
var VoiceTurnLatency = defineComponent6({
|
|
1725
|
+
name: "VoiceTurnLatency",
|
|
1726
|
+
props: {
|
|
1727
|
+
class: { default: "", type: String },
|
|
1728
|
+
description: { default: undefined, type: String },
|
|
1729
|
+
intervalMs: { default: 5000, type: Number },
|
|
1730
|
+
path: { default: "/api/turn-latency", type: String },
|
|
1731
|
+
title: { default: undefined, type: String }
|
|
1732
|
+
},
|
|
1733
|
+
setup(props) {
|
|
1734
|
+
const options = {
|
|
1735
|
+
description: props.description,
|
|
1736
|
+
intervalMs: props.intervalMs,
|
|
1737
|
+
title: props.title
|
|
1738
|
+
};
|
|
1739
|
+
const latency = useVoiceTurnLatency(props.path, options);
|
|
1740
|
+
const model = computed5(() => createVoiceTurnLatencyViewModel({
|
|
1741
|
+
error: latency.error.value,
|
|
1742
|
+
isLoading: latency.isLoading.value,
|
|
1743
|
+
report: latency.report.value,
|
|
1744
|
+
updatedAt: latency.updatedAt.value
|
|
1745
|
+
}, options));
|
|
1746
|
+
return () => h6("section", {
|
|
1747
|
+
class: [
|
|
1748
|
+
"absolute-voice-turn-latency",
|
|
1749
|
+
`absolute-voice-turn-latency--${model.value.status}`,
|
|
1750
|
+
props.class
|
|
1751
|
+
]
|
|
1752
|
+
}, [
|
|
1753
|
+
h6("header", { class: "absolute-voice-turn-latency__header" }, [
|
|
1754
|
+
h6("span", { class: "absolute-voice-turn-latency__eyebrow" }, model.value.title),
|
|
1755
|
+
h6("strong", { class: "absolute-voice-turn-latency__label" }, model.value.label)
|
|
1756
|
+
]),
|
|
1757
|
+
h6("p", { class: "absolute-voice-turn-latency__description" }, model.value.description),
|
|
1758
|
+
model.value.turns.length ? h6("div", { class: "absolute-voice-turn-latency__turns" }, model.value.turns.map((turn) => h6("article", {
|
|
1759
|
+
class: [
|
|
1760
|
+
"absolute-voice-turn-latency__turn",
|
|
1761
|
+
`absolute-voice-turn-latency__turn--${turn.status}`
|
|
1762
|
+
],
|
|
1763
|
+
key: `${turn.sessionId}:${turn.turnId}`
|
|
1764
|
+
}, [
|
|
1765
|
+
h6("header", [
|
|
1766
|
+
h6("strong", turn.label),
|
|
1767
|
+
h6("span", turn.status)
|
|
1768
|
+
]),
|
|
1769
|
+
h6("dl", turn.rows.map((row) => h6("div", { key: row.label }, [
|
|
1770
|
+
h6("dt", row.label),
|
|
1771
|
+
h6("dd", row.value)
|
|
1772
|
+
])))
|
|
1773
|
+
]))) : h6("p", { class: "absolute-voice-turn-latency__empty" }, "Complete a voice turn to see latency diagnostics."),
|
|
1774
|
+
model.value.error ? h6("p", { class: "absolute-voice-turn-latency__error" }, model.value.error) : null
|
|
1775
|
+
]);
|
|
1776
|
+
}
|
|
1777
|
+
});
|
|
1778
|
+
// src/vue/VoiceTurnQuality.ts
|
|
1779
|
+
import { computed as computed6, defineComponent as defineComponent7, h as h7 } from "vue";
|
|
1780
|
+
|
|
1537
1781
|
// src/client/turnQuality.ts
|
|
1538
1782
|
var fetchVoiceTurnQuality = async (path = "/api/turn-quality", options = {}) => {
|
|
1539
1783
|
const fetchImpl = options.fetch ?? globalThis.fetch;
|
|
@@ -1614,9 +1858,9 @@ var createVoiceTurnQualityStore = (path = "/api/turn-quality", options = {}) =>
|
|
|
1614
1858
|
};
|
|
1615
1859
|
|
|
1616
1860
|
// src/client/turnQualityWidget.ts
|
|
1617
|
-
var
|
|
1618
|
-
var
|
|
1619
|
-
var
|
|
1861
|
+
var DEFAULT_TITLE6 = "Turn Quality";
|
|
1862
|
+
var DEFAULT_DESCRIPTION6 = "Per-turn STT confidence, fallback selection, corrections, and transcript coverage.";
|
|
1863
|
+
var escapeHtml7 = (value) => value.replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">").replaceAll('"', """).replaceAll("'", "'");
|
|
1620
1864
|
var formatConfidence = (value) => typeof value === "number" ? `${Math.round(value * 100)}%` : "n/a";
|
|
1621
1865
|
var formatMaybe = (value) => value === undefined || value === "" ? "n/a" : String(value);
|
|
1622
1866
|
var getTurnDetail = (turn) => {
|
|
@@ -1654,37 +1898,37 @@ var createVoiceTurnQualityViewModel = (snapshot, options = {}) => {
|
|
|
1654
1898
|
const warningCount = snapshot.report?.warnings ?? turns.filter((turn) => turn.status === "warn").length;
|
|
1655
1899
|
const failedCount = snapshot.report?.failed ?? turns.filter((turn) => turn.status === "fail").length;
|
|
1656
1900
|
return {
|
|
1657
|
-
description: options.description ??
|
|
1901
|
+
description: options.description ?? DEFAULT_DESCRIPTION6,
|
|
1658
1902
|
error: snapshot.error,
|
|
1659
1903
|
isLoading: snapshot.isLoading,
|
|
1660
1904
|
label: snapshot.error ? "Unavailable" : turns.length ? failedCount > 0 ? `${failedCount} failed` : warningCount > 0 ? `${warningCount} warnings` : `${turns.length} healthy` : snapshot.isLoading ? "Checking" : "No turns",
|
|
1661
1905
|
status: snapshot.error ? "error" : turns.length ? failedCount > 0 || warningCount > 0 ? "warning" : "ready" : snapshot.isLoading ? "loading" : "empty",
|
|
1662
|
-
title: options.title ??
|
|
1906
|
+
title: options.title ?? DEFAULT_TITLE6,
|
|
1663
1907
|
turns,
|
|
1664
1908
|
updatedAt: snapshot.updatedAt
|
|
1665
1909
|
};
|
|
1666
1910
|
};
|
|
1667
1911
|
var renderVoiceTurnQualityHTML = (snapshot, options = {}) => {
|
|
1668
1912
|
const model = createVoiceTurnQualityViewModel(snapshot, options);
|
|
1669
|
-
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--${
|
|
1913
|
+
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--${escapeHtml7(turn.status)}">
|
|
1670
1914
|
<header>
|
|
1671
|
-
<strong>${
|
|
1672
|
-
<span>${
|
|
1915
|
+
<strong>${escapeHtml7(turn.label)}</strong>
|
|
1916
|
+
<span>${escapeHtml7(turn.status)}</span>
|
|
1673
1917
|
</header>
|
|
1674
|
-
<p>${
|
|
1918
|
+
<p>${escapeHtml7(turn.detail)}</p>
|
|
1675
1919
|
<dl>${turn.rows.map((row) => `<div>
|
|
1676
|
-
<dt>${
|
|
1677
|
-
<dd>${
|
|
1920
|
+
<dt>${escapeHtml7(row.label)}</dt>
|
|
1921
|
+
<dd>${escapeHtml7(row.value)}</dd>
|
|
1678
1922
|
</div>`).join("")}</dl>
|
|
1679
1923
|
</article>`).join("")}</div>` : '<p class="absolute-voice-turn-quality__empty">Complete a voice turn to see STT quality diagnostics.</p>';
|
|
1680
|
-
return `<section class="absolute-voice-turn-quality absolute-voice-turn-quality--${
|
|
1924
|
+
return `<section class="absolute-voice-turn-quality absolute-voice-turn-quality--${escapeHtml7(model.status)}">
|
|
1681
1925
|
<header class="absolute-voice-turn-quality__header">
|
|
1682
|
-
<span class="absolute-voice-turn-quality__eyebrow">${
|
|
1683
|
-
<strong class="absolute-voice-turn-quality__label">${
|
|
1926
|
+
<span class="absolute-voice-turn-quality__eyebrow">${escapeHtml7(model.title)}</span>
|
|
1927
|
+
<strong class="absolute-voice-turn-quality__label">${escapeHtml7(model.label)}</strong>
|
|
1684
1928
|
</header>
|
|
1685
|
-
<p class="absolute-voice-turn-quality__description">${
|
|
1929
|
+
<p class="absolute-voice-turn-quality__description">${escapeHtml7(model.description)}</p>
|
|
1686
1930
|
${turns}
|
|
1687
|
-
${model.error ? `<p class="absolute-voice-turn-quality__error">${
|
|
1931
|
+
${model.error ? `<p class="absolute-voice-turn-quality__error">${escapeHtml7(model.error)}</p>` : ""}
|
|
1688
1932
|
</section>`;
|
|
1689
1933
|
};
|
|
1690
1934
|
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}`;
|
|
@@ -1726,13 +1970,13 @@ var defineVoiceTurnQualityElement = (tagName = "absolute-voice-turn-quality") =>
|
|
|
1726
1970
|
};
|
|
1727
1971
|
|
|
1728
1972
|
// src/vue/useVoiceTurnQuality.ts
|
|
1729
|
-
import { onUnmounted as
|
|
1973
|
+
import { onUnmounted as onUnmounted7, shallowRef as shallowRef6 } from "vue";
|
|
1730
1974
|
var useVoiceTurnQuality = (path = "/api/turn-quality", options = {}) => {
|
|
1731
1975
|
const store = createVoiceTurnQualityStore(path, options);
|
|
1732
|
-
const error =
|
|
1733
|
-
const isLoading =
|
|
1734
|
-
const report =
|
|
1735
|
-
const updatedAt =
|
|
1976
|
+
const error = shallowRef6(null);
|
|
1977
|
+
const isLoading = shallowRef6(false);
|
|
1978
|
+
const report = shallowRef6();
|
|
1979
|
+
const updatedAt = shallowRef6(undefined);
|
|
1736
1980
|
const sync = () => {
|
|
1737
1981
|
const snapshot = store.getSnapshot();
|
|
1738
1982
|
error.value = snapshot.error;
|
|
@@ -1743,7 +1987,7 @@ var useVoiceTurnQuality = (path = "/api/turn-quality", options = {}) => {
|
|
|
1743
1987
|
const unsubscribe = store.subscribe(sync);
|
|
1744
1988
|
sync();
|
|
1745
1989
|
store.refresh().catch(() => {});
|
|
1746
|
-
|
|
1990
|
+
onUnmounted7(() => {
|
|
1747
1991
|
unsubscribe();
|
|
1748
1992
|
store.close();
|
|
1749
1993
|
});
|
|
@@ -1751,7 +1995,7 @@ var useVoiceTurnQuality = (path = "/api/turn-quality", options = {}) => {
|
|
|
1751
1995
|
};
|
|
1752
1996
|
|
|
1753
1997
|
// src/vue/VoiceTurnQuality.ts
|
|
1754
|
-
var VoiceTurnQuality =
|
|
1998
|
+
var VoiceTurnQuality = defineComponent7({
|
|
1755
1999
|
name: "VoiceTurnQuality",
|
|
1756
2000
|
props: {
|
|
1757
2001
|
class: { default: "", type: String },
|
|
@@ -1767,47 +2011,47 @@ var VoiceTurnQuality = defineComponent6({
|
|
|
1767
2011
|
title: props.title
|
|
1768
2012
|
};
|
|
1769
2013
|
const quality = useVoiceTurnQuality(props.path, options);
|
|
1770
|
-
const model =
|
|
2014
|
+
const model = computed6(() => createVoiceTurnQualityViewModel({
|
|
1771
2015
|
error: quality.error.value,
|
|
1772
2016
|
isLoading: quality.isLoading.value,
|
|
1773
2017
|
report: quality.report.value,
|
|
1774
2018
|
updatedAt: quality.updatedAt.value
|
|
1775
2019
|
}, options));
|
|
1776
|
-
return () =>
|
|
2020
|
+
return () => h7("section", {
|
|
1777
2021
|
class: [
|
|
1778
2022
|
"absolute-voice-turn-quality",
|
|
1779
2023
|
`absolute-voice-turn-quality--${model.value.status}`,
|
|
1780
2024
|
props.class
|
|
1781
2025
|
]
|
|
1782
2026
|
}, [
|
|
1783
|
-
|
|
1784
|
-
|
|
1785
|
-
|
|
2027
|
+
h7("header", { class: "absolute-voice-turn-quality__header" }, [
|
|
2028
|
+
h7("span", { class: "absolute-voice-turn-quality__eyebrow" }, model.value.title),
|
|
2029
|
+
h7("strong", { class: "absolute-voice-turn-quality__label" }, model.value.label)
|
|
1786
2030
|
]),
|
|
1787
|
-
|
|
1788
|
-
model.value.turns.length ?
|
|
2031
|
+
h7("p", { class: "absolute-voice-turn-quality__description" }, model.value.description),
|
|
2032
|
+
model.value.turns.length ? h7("div", { class: "absolute-voice-turn-quality__turns" }, model.value.turns.map((turn) => h7("article", {
|
|
1789
2033
|
class: [
|
|
1790
2034
|
"absolute-voice-turn-quality__turn",
|
|
1791
2035
|
`absolute-voice-turn-quality__turn--${turn.status}`
|
|
1792
2036
|
],
|
|
1793
2037
|
key: `${turn.sessionId}:${turn.turnId}`
|
|
1794
2038
|
}, [
|
|
1795
|
-
|
|
1796
|
-
|
|
1797
|
-
|
|
2039
|
+
h7("header", [
|
|
2040
|
+
h7("strong", turn.label),
|
|
2041
|
+
h7("span", turn.status)
|
|
1798
2042
|
]),
|
|
1799
|
-
|
|
1800
|
-
|
|
1801
|
-
|
|
1802
|
-
|
|
2043
|
+
h7("p", turn.detail),
|
|
2044
|
+
h7("dl", turn.rows.map((row) => h7("div", { key: row.label }, [
|
|
2045
|
+
h7("dt", row.label),
|
|
2046
|
+
h7("dd", row.value)
|
|
1803
2047
|
])))
|
|
1804
|
-
]))) :
|
|
1805
|
-
model.value.error ?
|
|
2048
|
+
]))) : h7("p", { class: "absolute-voice-turn-quality__empty" }, "Complete a voice turn to see STT quality diagnostics."),
|
|
2049
|
+
model.value.error ? h7("p", { class: "absolute-voice-turn-quality__error" }, model.value.error) : null
|
|
1806
2050
|
]);
|
|
1807
2051
|
}
|
|
1808
2052
|
});
|
|
1809
2053
|
// src/vue/useVoiceStream.ts
|
|
1810
|
-
import { onUnmounted as
|
|
2054
|
+
import { onUnmounted as onUnmounted8, ref as ref5, shallowRef as shallowRef7 } from "vue";
|
|
1811
2055
|
|
|
1812
2056
|
// src/client/actions.ts
|
|
1813
2057
|
var normalizeErrorMessage = (value) => {
|
|
@@ -2325,15 +2569,15 @@ var createVoiceStream = (path, options = {}) => {
|
|
|
2325
2569
|
// src/vue/useVoiceStream.ts
|
|
2326
2570
|
var useVoiceStream = (path, options = {}) => {
|
|
2327
2571
|
const stream = createVoiceStream(path, options);
|
|
2328
|
-
const assistantAudio =
|
|
2329
|
-
const assistantTexts =
|
|
2330
|
-
const call =
|
|
2572
|
+
const assistantAudio = shallowRef7([]);
|
|
2573
|
+
const assistantTexts = shallowRef7([]);
|
|
2574
|
+
const call = shallowRef7(null);
|
|
2331
2575
|
const error = ref5(null);
|
|
2332
2576
|
const isConnected = ref5(false);
|
|
2333
2577
|
const partial = ref5("");
|
|
2334
2578
|
const sessionId = ref5(stream.sessionId);
|
|
2335
2579
|
const status = ref5(stream.status);
|
|
2336
|
-
const turns =
|
|
2580
|
+
const turns = shallowRef7([]);
|
|
2337
2581
|
const sync = () => {
|
|
2338
2582
|
assistantAudio.value = [...stream.assistantAudio];
|
|
2339
2583
|
assistantTexts.value = [...stream.assistantTexts];
|
|
@@ -2351,7 +2595,7 @@ var useVoiceStream = (path, options = {}) => {
|
|
|
2351
2595
|
unsubscribe();
|
|
2352
2596
|
stream.close();
|
|
2353
2597
|
};
|
|
2354
|
-
|
|
2598
|
+
onUnmounted8(destroy);
|
|
2355
2599
|
return {
|
|
2356
2600
|
assistantAudio,
|
|
2357
2601
|
assistantTexts,
|
|
@@ -2369,7 +2613,7 @@ var useVoiceStream = (path, options = {}) => {
|
|
|
2369
2613
|
};
|
|
2370
2614
|
};
|
|
2371
2615
|
// src/vue/useVoiceController.ts
|
|
2372
|
-
import { onUnmounted as
|
|
2616
|
+
import { onUnmounted as onUnmounted9, ref as ref6, shallowRef as shallowRef8 } from "vue";
|
|
2373
2617
|
|
|
2374
2618
|
// src/client/htmx.ts
|
|
2375
2619
|
var DEFAULT_EVENT_NAME = "voice-refresh";
|
|
@@ -3010,8 +3254,8 @@ var createVoiceController = (path, options = {}) => {
|
|
|
3010
3254
|
// src/vue/useVoiceController.ts
|
|
3011
3255
|
var useVoiceController = (path, options = {}) => {
|
|
3012
3256
|
const controller = createVoiceController(path, options);
|
|
3013
|
-
const assistantAudio =
|
|
3014
|
-
const assistantTexts =
|
|
3257
|
+
const assistantAudio = shallowRef8([]);
|
|
3258
|
+
const assistantTexts = shallowRef8([]);
|
|
3015
3259
|
const error = ref6(null);
|
|
3016
3260
|
const isConnected = ref6(false);
|
|
3017
3261
|
const isRecording = ref6(false);
|
|
@@ -3019,7 +3263,7 @@ var useVoiceController = (path, options = {}) => {
|
|
|
3019
3263
|
const recordingError = ref6(null);
|
|
3020
3264
|
const sessionId = ref6(controller.sessionId);
|
|
3021
3265
|
const status = ref6(controller.status);
|
|
3022
|
-
const turns =
|
|
3266
|
+
const turns = shallowRef8([]);
|
|
3023
3267
|
const sync = () => {
|
|
3024
3268
|
assistantAudio.value = [...controller.assistantAudio];
|
|
3025
3269
|
assistantTexts.value = [...controller.assistantTexts];
|
|
@@ -3038,7 +3282,7 @@ var useVoiceController = (path, options = {}) => {
|
|
|
3038
3282
|
unsubscribe();
|
|
3039
3283
|
controller.close();
|
|
3040
3284
|
};
|
|
3041
|
-
|
|
3285
|
+
onUnmounted9(destroy);
|
|
3042
3286
|
return {
|
|
3043
3287
|
assistantAudio,
|
|
3044
3288
|
assistantTexts,
|
|
@@ -3060,7 +3304,7 @@ var useVoiceController = (path, options = {}) => {
|
|
|
3060
3304
|
};
|
|
3061
3305
|
};
|
|
3062
3306
|
// src/vue/useVoiceTraceTimeline.ts
|
|
3063
|
-
import { onUnmounted as
|
|
3307
|
+
import { onUnmounted as onUnmounted10, ref as ref7, shallowRef as shallowRef9 } from "vue";
|
|
3064
3308
|
|
|
3065
3309
|
// src/client/traceTimeline.ts
|
|
3066
3310
|
var fetchVoiceTraceTimeline = async (path = "/api/voice-traces", options = {}) => {
|
|
@@ -3147,7 +3391,7 @@ var useVoiceTraceTimeline = (path = "/api/voice-traces", options = {}) => {
|
|
|
3147
3391
|
const store = createVoiceTraceTimelineStore(path, options);
|
|
3148
3392
|
const error = ref7(null);
|
|
3149
3393
|
const isLoading = ref7(false);
|
|
3150
|
-
const report =
|
|
3394
|
+
const report = shallowRef9(null);
|
|
3151
3395
|
const updatedAt = ref7(undefined);
|
|
3152
3396
|
const sync = () => {
|
|
3153
3397
|
const snapshot = store.getSnapshot();
|
|
@@ -3159,7 +3403,7 @@ var useVoiceTraceTimeline = (path = "/api/voice-traces", options = {}) => {
|
|
|
3159
3403
|
const unsubscribe = store.subscribe(sync);
|
|
3160
3404
|
sync();
|
|
3161
3405
|
store.refresh().catch(() => {});
|
|
3162
|
-
|
|
3406
|
+
onUnmounted10(() => {
|
|
3163
3407
|
unsubscribe();
|
|
3164
3408
|
store.close();
|
|
3165
3409
|
});
|
|
@@ -3172,7 +3416,7 @@ var useVoiceTraceTimeline = (path = "/api/voice-traces", options = {}) => {
|
|
|
3172
3416
|
};
|
|
3173
3417
|
};
|
|
3174
3418
|
// src/vue/useVoiceWorkflowStatus.ts
|
|
3175
|
-
import { onUnmounted as
|
|
3419
|
+
import { onUnmounted as onUnmounted11, ref as ref8, shallowRef as shallowRef10 } from "vue";
|
|
3176
3420
|
|
|
3177
3421
|
// src/client/workflowStatus.ts
|
|
3178
3422
|
var fetchVoiceWorkflowStatus = async (path = "/evals/scenarios/json", options = {}) => {
|
|
@@ -3258,7 +3502,7 @@ var useVoiceWorkflowStatus = (path = "/evals/scenarios/json", options = {}) => {
|
|
|
3258
3502
|
const store = createVoiceWorkflowStatusStore(path, options);
|
|
3259
3503
|
const error = ref8(null);
|
|
3260
3504
|
const isLoading = ref8(false);
|
|
3261
|
-
const report =
|
|
3505
|
+
const report = shallowRef10(undefined);
|
|
3262
3506
|
const updatedAt = ref8(undefined);
|
|
3263
3507
|
const sync = () => {
|
|
3264
3508
|
const snapshot = store.getSnapshot();
|
|
@@ -3272,7 +3516,7 @@ var useVoiceWorkflowStatus = (path = "/evals/scenarios/json", options = {}) => {
|
|
|
3272
3516
|
if (typeof window !== "undefined") {
|
|
3273
3517
|
store.refresh().catch(() => {});
|
|
3274
3518
|
}
|
|
3275
|
-
|
|
3519
|
+
onUnmounted11(() => {
|
|
3276
3520
|
unsubscribe();
|
|
3277
3521
|
store.close();
|
|
3278
3522
|
});
|
|
@@ -3287,6 +3531,7 @@ var useVoiceWorkflowStatus = (path = "/evals/scenarios/json", options = {}) => {
|
|
|
3287
3531
|
export {
|
|
3288
3532
|
useVoiceWorkflowStatus,
|
|
3289
3533
|
useVoiceTurnQuality,
|
|
3534
|
+
useVoiceTurnLatency,
|
|
3290
3535
|
useVoiceTraceTimeline,
|
|
3291
3536
|
useVoiceStream,
|
|
3292
3537
|
useVoiceRoutingStatus,
|
|
@@ -3296,6 +3541,7 @@ export {
|
|
|
3296
3541
|
useVoiceController,
|
|
3297
3542
|
useVoiceAppKitStatus,
|
|
3298
3543
|
VoiceTurnQuality,
|
|
3544
|
+
VoiceTurnLatency,
|
|
3299
3545
|
VoiceRoutingStatus,
|
|
3300
3546
|
VoiceProviderStatus,
|
|
3301
3547
|
VoiceProviderSimulationControls,
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { type VoiceTurnLatencyClientOptions } from '../client/turnLatency';
|
|
2
|
+
import type { VoiceTurnLatencyReport } from '../turnLatency';
|
|
3
|
+
export declare const useVoiceTurnLatency: (path?: string, options?: VoiceTurnLatencyClientOptions) => {
|
|
4
|
+
error: import("vue").ShallowRef<string | null, string | null>;
|
|
5
|
+
isLoading: import("vue").ShallowRef<boolean, boolean>;
|
|
6
|
+
refresh: () => Promise<VoiceTurnLatencyReport | undefined>;
|
|
7
|
+
report: import("vue").ShallowRef<VoiceTurnLatencyReport | undefined, VoiceTurnLatencyReport | undefined>;
|
|
8
|
+
updatedAt: import("vue").ShallowRef<number | undefined, number | undefined>;
|
|
9
|
+
};
|