@absolutejs/voice 0.0.22-beta.90 → 0.0.22-beta.91
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 +144 -20
- package/dist/angular/voice-trace-timeline.service.d.ts +12 -0
- package/dist/client/index.d.ts +4 -0
- package/dist/client/index.js +173 -0
- package/dist/client/traceTimeline.d.ts +19 -0
- package/dist/client/traceTimelineWidget.d.ts +32 -0
- package/dist/react/VoiceTraceTimeline.d.ts +6 -0
- package/dist/react/index.d.ts +2 -0
- package/dist/react/index.js +316 -50
- package/dist/react/useVoiceTraceTimeline.d.ts +8 -0
- package/dist/svelte/createVoiceTraceTimeline.d.ts +10 -0
- package/dist/svelte/index.d.ts +1 -0
- package/dist/svelte/index.js +194 -16
- package/dist/vue/index.d.ts +1 -0
- package/dist/vue/index.js +119 -6
- package/dist/vue/useVoiceTraceTimeline.d.ts +9 -0
- package/package.json +1 -1
package/dist/react/index.js
CHANGED
|
@@ -1495,8 +1495,272 @@ var VoiceRoutingStatus = ({
|
|
|
1495
1495
|
]
|
|
1496
1496
|
}, undefined, true, undefined, this);
|
|
1497
1497
|
};
|
|
1498
|
-
// src/
|
|
1498
|
+
// src/client/traceTimeline.ts
|
|
1499
|
+
var fetchVoiceTraceTimeline = async (path = "/api/voice-traces", options = {}) => {
|
|
1500
|
+
const fetchImpl = options.fetch ?? globalThis.fetch;
|
|
1501
|
+
const response = await fetchImpl(path);
|
|
1502
|
+
if (!response.ok) {
|
|
1503
|
+
throw new Error(`Voice trace timeline failed: HTTP ${response.status}`);
|
|
1504
|
+
}
|
|
1505
|
+
return await response.json();
|
|
1506
|
+
};
|
|
1507
|
+
var createVoiceTraceTimelineStore = (path = "/api/voice-traces", options = {}) => {
|
|
1508
|
+
const listeners = new Set;
|
|
1509
|
+
let closed = false;
|
|
1510
|
+
let timer;
|
|
1511
|
+
let snapshot = {
|
|
1512
|
+
error: null,
|
|
1513
|
+
isLoading: false,
|
|
1514
|
+
report: null
|
|
1515
|
+
};
|
|
1516
|
+
const emit = () => {
|
|
1517
|
+
for (const listener of listeners) {
|
|
1518
|
+
listener();
|
|
1519
|
+
}
|
|
1520
|
+
};
|
|
1521
|
+
const refresh = async () => {
|
|
1522
|
+
if (closed) {
|
|
1523
|
+
return snapshot.report;
|
|
1524
|
+
}
|
|
1525
|
+
snapshot = {
|
|
1526
|
+
...snapshot,
|
|
1527
|
+
error: null,
|
|
1528
|
+
isLoading: true
|
|
1529
|
+
};
|
|
1530
|
+
emit();
|
|
1531
|
+
try {
|
|
1532
|
+
const report = await fetchVoiceTraceTimeline(path, options);
|
|
1533
|
+
snapshot = {
|
|
1534
|
+
error: null,
|
|
1535
|
+
isLoading: false,
|
|
1536
|
+
report,
|
|
1537
|
+
updatedAt: Date.now()
|
|
1538
|
+
};
|
|
1539
|
+
emit();
|
|
1540
|
+
return report;
|
|
1541
|
+
} catch (error) {
|
|
1542
|
+
snapshot = {
|
|
1543
|
+
...snapshot,
|
|
1544
|
+
error: error instanceof Error ? error.message : String(error),
|
|
1545
|
+
isLoading: false
|
|
1546
|
+
};
|
|
1547
|
+
emit();
|
|
1548
|
+
throw error;
|
|
1549
|
+
}
|
|
1550
|
+
};
|
|
1551
|
+
const close = () => {
|
|
1552
|
+
closed = true;
|
|
1553
|
+
if (timer) {
|
|
1554
|
+
clearInterval(timer);
|
|
1555
|
+
timer = undefined;
|
|
1556
|
+
}
|
|
1557
|
+
listeners.clear();
|
|
1558
|
+
};
|
|
1559
|
+
if (options.intervalMs && options.intervalMs > 0) {
|
|
1560
|
+
timer = setInterval(() => {
|
|
1561
|
+
refresh().catch(() => {});
|
|
1562
|
+
}, options.intervalMs);
|
|
1563
|
+
}
|
|
1564
|
+
return {
|
|
1565
|
+
close,
|
|
1566
|
+
getServerSnapshot: () => snapshot,
|
|
1567
|
+
getSnapshot: () => snapshot,
|
|
1568
|
+
refresh,
|
|
1569
|
+
subscribe: (listener) => {
|
|
1570
|
+
listeners.add(listener);
|
|
1571
|
+
return () => {
|
|
1572
|
+
listeners.delete(listener);
|
|
1573
|
+
};
|
|
1574
|
+
}
|
|
1575
|
+
};
|
|
1576
|
+
};
|
|
1577
|
+
|
|
1578
|
+
// src/client/traceTimelineWidget.ts
|
|
1579
|
+
var DEFAULT_TITLE5 = "Voice Traces";
|
|
1580
|
+
var DEFAULT_DESCRIPTION5 = "Latest call timelines with provider latency, fallbacks, handoffs, and errors from your self-hosted trace store.";
|
|
1581
|
+
var escapeHtml6 = (value) => value.replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">").replaceAll('"', """).replaceAll("'", "'");
|
|
1582
|
+
var formatMs = (value) => typeof value === "number" ? `${value}ms` : "n/a";
|
|
1583
|
+
var formatProviders = (session) => session.providers.length ? session.providers.map((provider) => provider.provider).join(", ") : "No providers";
|
|
1584
|
+
var createVoiceTraceTimelineViewModel = (snapshot, options = {}) => {
|
|
1585
|
+
const sessions = (snapshot.report?.sessions ?? []).slice(0, options.limit ?? 3).map((session) => ({
|
|
1586
|
+
...session,
|
|
1587
|
+
detailHref: `${options.detailBasePath ?? "/traces"}/${encodeURIComponent(session.sessionId)}`,
|
|
1588
|
+
durationLabel: formatMs(session.summary.callDurationMs),
|
|
1589
|
+
label: `${session.summary.eventCount} events / ${session.summary.turnCount} turns`,
|
|
1590
|
+
providerLabel: formatProviders(session)
|
|
1591
|
+
}));
|
|
1592
|
+
const failed = sessions.filter((session) => session.status === "failed").length;
|
|
1593
|
+
const warnings = sessions.filter((session) => session.status === "warning").length;
|
|
1594
|
+
return {
|
|
1595
|
+
description: options.description ?? DEFAULT_DESCRIPTION5,
|
|
1596
|
+
error: snapshot.error,
|
|
1597
|
+
isLoading: snapshot.isLoading,
|
|
1598
|
+
label: snapshot.error ? "Unavailable" : failed > 0 ? `${failed} failed` : warnings > 0 ? `${warnings} warning` : sessions.length ? `${sessions.length} recent` : snapshot.isLoading ? "Checking" : "No traces yet",
|
|
1599
|
+
sessions,
|
|
1600
|
+
status: snapshot.error ? "error" : failed > 0 ? "failed" : warnings > 0 ? "warning" : sessions.length ? "ready" : snapshot.isLoading ? "loading" : "empty",
|
|
1601
|
+
title: options.title ?? DEFAULT_TITLE5,
|
|
1602
|
+
updatedAt: snapshot.updatedAt
|
|
1603
|
+
};
|
|
1604
|
+
};
|
|
1605
|
+
var renderVoiceTraceTimelineWidgetHTML = (snapshot, options = {}) => {
|
|
1606
|
+
const model = createVoiceTraceTimelineViewModel(snapshot, options);
|
|
1607
|
+
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--${escapeHtml6(session.status)}">
|
|
1608
|
+
<header>
|
|
1609
|
+
<strong>${escapeHtml6(session.sessionId)}</strong>
|
|
1610
|
+
<span>${escapeHtml6(session.status)}</span>
|
|
1611
|
+
</header>
|
|
1612
|
+
<p>${escapeHtml6(session.label)} \xB7 ${escapeHtml6(session.durationLabel)} \xB7 ${escapeHtml6(session.providerLabel)}</p>
|
|
1613
|
+
<a href="${escapeHtml6(session.detailHref)}">Open timeline</a>
|
|
1614
|
+
</article>`).join("")}</div>` : '<p class="absolute-voice-trace-timeline__empty">Run a voice session to see call timelines.</p>';
|
|
1615
|
+
return `<section class="absolute-voice-trace-timeline absolute-voice-trace-timeline--${escapeHtml6(model.status)}">
|
|
1616
|
+
<header class="absolute-voice-trace-timeline__header">
|
|
1617
|
+
<span class="absolute-voice-trace-timeline__eyebrow">${escapeHtml6(model.title)}</span>
|
|
1618
|
+
<strong class="absolute-voice-trace-timeline__label">${escapeHtml6(model.label)}</strong>
|
|
1619
|
+
</header>
|
|
1620
|
+
<p class="absolute-voice-trace-timeline__description">${escapeHtml6(model.description)}</p>
|
|
1621
|
+
${sessions}
|
|
1622
|
+
${model.error ? `<p class="absolute-voice-trace-timeline__error">${escapeHtml6(model.error)}</p>` : ""}
|
|
1623
|
+
</section>`;
|
|
1624
|
+
};
|
|
1625
|
+
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}`;
|
|
1626
|
+
var mountVoiceTraceTimeline = (element, path = "/api/voice-traces", options = {}) => {
|
|
1627
|
+
const store = createVoiceTraceTimelineStore(path, options);
|
|
1628
|
+
const render = () => {
|
|
1629
|
+
element.innerHTML = renderVoiceTraceTimelineWidgetHTML(store.getSnapshot(), options);
|
|
1630
|
+
};
|
|
1631
|
+
const unsubscribe = store.subscribe(render);
|
|
1632
|
+
render();
|
|
1633
|
+
store.refresh().catch(() => {});
|
|
1634
|
+
return {
|
|
1635
|
+
close: () => {
|
|
1636
|
+
unsubscribe();
|
|
1637
|
+
store.close();
|
|
1638
|
+
},
|
|
1639
|
+
refresh: store.refresh
|
|
1640
|
+
};
|
|
1641
|
+
};
|
|
1642
|
+
var defineVoiceTraceTimelineElement = (tagName = "absolute-voice-trace-timeline") => {
|
|
1643
|
+
if (typeof window === "undefined" || typeof customElements === "undefined" || customElements.get(tagName)) {
|
|
1644
|
+
return;
|
|
1645
|
+
}
|
|
1646
|
+
customElements.define(tagName, class AbsoluteVoiceTraceTimelineElement extends HTMLElement {
|
|
1647
|
+
mounted;
|
|
1648
|
+
connectedCallback() {
|
|
1649
|
+
const intervalMs = Number(this.getAttribute("interval-ms") ?? 5000);
|
|
1650
|
+
const limit = Number(this.getAttribute("limit") ?? 3);
|
|
1651
|
+
this.mounted = mountVoiceTraceTimeline(this, this.getAttribute("path") ?? "/api/voice-traces", {
|
|
1652
|
+
description: this.getAttribute("description") ?? undefined,
|
|
1653
|
+
detailBasePath: this.getAttribute("detail-base-path") ?? undefined,
|
|
1654
|
+
intervalMs: Number.isFinite(intervalMs) ? intervalMs : 5000,
|
|
1655
|
+
limit: Number.isFinite(limit) ? limit : 3,
|
|
1656
|
+
title: this.getAttribute("title") ?? undefined
|
|
1657
|
+
});
|
|
1658
|
+
}
|
|
1659
|
+
disconnectedCallback() {
|
|
1660
|
+
this.mounted?.close();
|
|
1661
|
+
this.mounted = undefined;
|
|
1662
|
+
}
|
|
1663
|
+
});
|
|
1664
|
+
};
|
|
1665
|
+
|
|
1666
|
+
// src/react/useVoiceTraceTimeline.tsx
|
|
1499
1667
|
import { useEffect as useEffect6, useRef as useRef6, useSyncExternalStore as useSyncExternalStore6 } from "react";
|
|
1668
|
+
var useVoiceTraceTimeline = (path = "/api/voice-traces", options = {}) => {
|
|
1669
|
+
const storeRef = useRef6(null);
|
|
1670
|
+
if (!storeRef.current) {
|
|
1671
|
+
storeRef.current = createVoiceTraceTimelineStore(path, options);
|
|
1672
|
+
}
|
|
1673
|
+
const store = storeRef.current;
|
|
1674
|
+
useEffect6(() => {
|
|
1675
|
+
store.refresh().catch(() => {});
|
|
1676
|
+
return () => store.close();
|
|
1677
|
+
}, [store]);
|
|
1678
|
+
return {
|
|
1679
|
+
...useSyncExternalStore6(store.subscribe, store.getSnapshot, store.getServerSnapshot),
|
|
1680
|
+
refresh: store.refresh
|
|
1681
|
+
};
|
|
1682
|
+
};
|
|
1683
|
+
|
|
1684
|
+
// src/react/VoiceTraceTimeline.tsx
|
|
1685
|
+
import { jsxDEV as jsxDEV6 } from "react/jsx-dev-runtime";
|
|
1686
|
+
var VoiceTraceTimeline = ({
|
|
1687
|
+
className,
|
|
1688
|
+
path = "/api/voice-traces",
|
|
1689
|
+
...options
|
|
1690
|
+
}) => {
|
|
1691
|
+
const snapshot = useVoiceTraceTimeline(path, options);
|
|
1692
|
+
const model = createVoiceTraceTimelineViewModel(snapshot, options);
|
|
1693
|
+
return /* @__PURE__ */ jsxDEV6("section", {
|
|
1694
|
+
className: [
|
|
1695
|
+
"absolute-voice-trace-timeline",
|
|
1696
|
+
`absolute-voice-trace-timeline--${model.status}`,
|
|
1697
|
+
className
|
|
1698
|
+
].filter(Boolean).join(" "),
|
|
1699
|
+
children: [
|
|
1700
|
+
/* @__PURE__ */ jsxDEV6("header", {
|
|
1701
|
+
className: "absolute-voice-trace-timeline__header",
|
|
1702
|
+
children: [
|
|
1703
|
+
/* @__PURE__ */ jsxDEV6("span", {
|
|
1704
|
+
className: "absolute-voice-trace-timeline__eyebrow",
|
|
1705
|
+
children: model.title
|
|
1706
|
+
}, undefined, false, undefined, this),
|
|
1707
|
+
/* @__PURE__ */ jsxDEV6("strong", {
|
|
1708
|
+
className: "absolute-voice-trace-timeline__label",
|
|
1709
|
+
children: model.label
|
|
1710
|
+
}, undefined, false, undefined, this)
|
|
1711
|
+
]
|
|
1712
|
+
}, undefined, true, undefined, this),
|
|
1713
|
+
/* @__PURE__ */ jsxDEV6("p", {
|
|
1714
|
+
className: "absolute-voice-trace-timeline__description",
|
|
1715
|
+
children: model.description
|
|
1716
|
+
}, undefined, false, undefined, this),
|
|
1717
|
+
model.sessions.length ? /* @__PURE__ */ jsxDEV6("div", {
|
|
1718
|
+
className: "absolute-voice-trace-timeline__sessions",
|
|
1719
|
+
children: model.sessions.map((session) => /* @__PURE__ */ jsxDEV6("article", {
|
|
1720
|
+
className: [
|
|
1721
|
+
"absolute-voice-trace-timeline__session",
|
|
1722
|
+
`absolute-voice-trace-timeline__session--${session.status}`
|
|
1723
|
+
].join(" "),
|
|
1724
|
+
children: [
|
|
1725
|
+
/* @__PURE__ */ jsxDEV6("header", {
|
|
1726
|
+
children: [
|
|
1727
|
+
/* @__PURE__ */ jsxDEV6("strong", {
|
|
1728
|
+
children: session.sessionId
|
|
1729
|
+
}, undefined, false, undefined, this),
|
|
1730
|
+
/* @__PURE__ */ jsxDEV6("span", {
|
|
1731
|
+
children: session.status
|
|
1732
|
+
}, undefined, false, undefined, this)
|
|
1733
|
+
]
|
|
1734
|
+
}, undefined, true, undefined, this),
|
|
1735
|
+
/* @__PURE__ */ jsxDEV6("p", {
|
|
1736
|
+
children: [
|
|
1737
|
+
session.label,
|
|
1738
|
+
" \xB7 ",
|
|
1739
|
+
session.durationLabel,
|
|
1740
|
+
" \xB7",
|
|
1741
|
+
" ",
|
|
1742
|
+
session.providerLabel
|
|
1743
|
+
]
|
|
1744
|
+
}, undefined, true, undefined, this),
|
|
1745
|
+
/* @__PURE__ */ jsxDEV6("a", {
|
|
1746
|
+
href: session.detailHref,
|
|
1747
|
+
children: "Open timeline"
|
|
1748
|
+
}, undefined, false, undefined, this)
|
|
1749
|
+
]
|
|
1750
|
+
}, session.sessionId, true, undefined, this))
|
|
1751
|
+
}, undefined, false, undefined, this) : /* @__PURE__ */ jsxDEV6("p", {
|
|
1752
|
+
className: "absolute-voice-trace-timeline__empty",
|
|
1753
|
+
children: "Run a voice session to see call timelines."
|
|
1754
|
+
}, undefined, false, undefined, this),
|
|
1755
|
+
model.error ? /* @__PURE__ */ jsxDEV6("p", {
|
|
1756
|
+
className: "absolute-voice-trace-timeline__error",
|
|
1757
|
+
children: model.error
|
|
1758
|
+
}, undefined, false, undefined, this) : null
|
|
1759
|
+
]
|
|
1760
|
+
}, undefined, true, undefined, this);
|
|
1761
|
+
};
|
|
1762
|
+
// src/react/useVoiceTurnQuality.tsx
|
|
1763
|
+
import { useEffect as useEffect7, useRef as useRef7, useSyncExternalStore as useSyncExternalStore7 } from "react";
|
|
1500
1764
|
|
|
1501
1765
|
// src/client/turnQuality.ts
|
|
1502
1766
|
var fetchVoiceTurnQuality = async (path = "/api/turn-quality", options = {}) => {
|
|
@@ -1579,25 +1843,25 @@ var createVoiceTurnQualityStore = (path = "/api/turn-quality", options = {}) =>
|
|
|
1579
1843
|
|
|
1580
1844
|
// src/react/useVoiceTurnQuality.tsx
|
|
1581
1845
|
var useVoiceTurnQuality = (path = "/api/turn-quality", options = {}) => {
|
|
1582
|
-
const storeRef =
|
|
1846
|
+
const storeRef = useRef7(null);
|
|
1583
1847
|
if (!storeRef.current) {
|
|
1584
1848
|
storeRef.current = createVoiceTurnQualityStore(path, options);
|
|
1585
1849
|
}
|
|
1586
1850
|
const store = storeRef.current;
|
|
1587
|
-
|
|
1851
|
+
useEffect7(() => {
|
|
1588
1852
|
store.refresh().catch(() => {});
|
|
1589
1853
|
return () => store.close();
|
|
1590
1854
|
}, [store]);
|
|
1591
1855
|
return {
|
|
1592
|
-
...
|
|
1856
|
+
...useSyncExternalStore7(store.subscribe, store.getSnapshot, store.getServerSnapshot),
|
|
1593
1857
|
refresh: store.refresh
|
|
1594
1858
|
};
|
|
1595
1859
|
};
|
|
1596
1860
|
|
|
1597
1861
|
// src/client/turnQualityWidget.ts
|
|
1598
|
-
var
|
|
1599
|
-
var
|
|
1600
|
-
var
|
|
1862
|
+
var DEFAULT_TITLE6 = "Turn Quality";
|
|
1863
|
+
var DEFAULT_DESCRIPTION6 = "Per-turn STT confidence, fallback selection, corrections, and transcript coverage.";
|
|
1864
|
+
var escapeHtml7 = (value) => value.replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">").replaceAll('"', """).replaceAll("'", "'");
|
|
1601
1865
|
var formatConfidence = (value) => typeof value === "number" ? `${Math.round(value * 100)}%` : "n/a";
|
|
1602
1866
|
var formatMaybe = (value) => value === undefined || value === "" ? "n/a" : String(value);
|
|
1603
1867
|
var getTurnDetail = (turn) => {
|
|
@@ -1635,37 +1899,37 @@ var createVoiceTurnQualityViewModel = (snapshot, options = {}) => {
|
|
|
1635
1899
|
const warningCount = snapshot.report?.warnings ?? turns.filter((turn) => turn.status === "warn").length;
|
|
1636
1900
|
const failedCount = snapshot.report?.failed ?? turns.filter((turn) => turn.status === "fail").length;
|
|
1637
1901
|
return {
|
|
1638
|
-
description: options.description ??
|
|
1902
|
+
description: options.description ?? DEFAULT_DESCRIPTION6,
|
|
1639
1903
|
error: snapshot.error,
|
|
1640
1904
|
isLoading: snapshot.isLoading,
|
|
1641
1905
|
label: snapshot.error ? "Unavailable" : turns.length ? failedCount > 0 ? `${failedCount} failed` : warningCount > 0 ? `${warningCount} warnings` : `${turns.length} healthy` : snapshot.isLoading ? "Checking" : "No turns",
|
|
1642
1906
|
status: snapshot.error ? "error" : turns.length ? failedCount > 0 || warningCount > 0 ? "warning" : "ready" : snapshot.isLoading ? "loading" : "empty",
|
|
1643
|
-
title: options.title ??
|
|
1907
|
+
title: options.title ?? DEFAULT_TITLE6,
|
|
1644
1908
|
turns,
|
|
1645
1909
|
updatedAt: snapshot.updatedAt
|
|
1646
1910
|
};
|
|
1647
1911
|
};
|
|
1648
1912
|
var renderVoiceTurnQualityHTML = (snapshot, options = {}) => {
|
|
1649
1913
|
const model = createVoiceTurnQualityViewModel(snapshot, options);
|
|
1650
|
-
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--${
|
|
1914
|
+
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)}">
|
|
1651
1915
|
<header>
|
|
1652
|
-
<strong>${
|
|
1653
|
-
<span>${
|
|
1916
|
+
<strong>${escapeHtml7(turn.label)}</strong>
|
|
1917
|
+
<span>${escapeHtml7(turn.status)}</span>
|
|
1654
1918
|
</header>
|
|
1655
|
-
<p>${
|
|
1919
|
+
<p>${escapeHtml7(turn.detail)}</p>
|
|
1656
1920
|
<dl>${turn.rows.map((row) => `<div>
|
|
1657
|
-
<dt>${
|
|
1658
|
-
<dd>${
|
|
1921
|
+
<dt>${escapeHtml7(row.label)}</dt>
|
|
1922
|
+
<dd>${escapeHtml7(row.value)}</dd>
|
|
1659
1923
|
</div>`).join("")}</dl>
|
|
1660
1924
|
</article>`).join("")}</div>` : '<p class="absolute-voice-turn-quality__empty">Complete a voice turn to see STT quality diagnostics.</p>';
|
|
1661
|
-
return `<section class="absolute-voice-turn-quality absolute-voice-turn-quality--${
|
|
1925
|
+
return `<section class="absolute-voice-turn-quality absolute-voice-turn-quality--${escapeHtml7(model.status)}">
|
|
1662
1926
|
<header class="absolute-voice-turn-quality__header">
|
|
1663
|
-
<span class="absolute-voice-turn-quality__eyebrow">${
|
|
1664
|
-
<strong class="absolute-voice-turn-quality__label">${
|
|
1927
|
+
<span class="absolute-voice-turn-quality__eyebrow">${escapeHtml7(model.title)}</span>
|
|
1928
|
+
<strong class="absolute-voice-turn-quality__label">${escapeHtml7(model.label)}</strong>
|
|
1665
1929
|
</header>
|
|
1666
|
-
<p class="absolute-voice-turn-quality__description">${
|
|
1930
|
+
<p class="absolute-voice-turn-quality__description">${escapeHtml7(model.description)}</p>
|
|
1667
1931
|
${turns}
|
|
1668
|
-
${model.error ? `<p class="absolute-voice-turn-quality__error">${
|
|
1932
|
+
${model.error ? `<p class="absolute-voice-turn-quality__error">${escapeHtml7(model.error)}</p>` : ""}
|
|
1669
1933
|
</section>`;
|
|
1670
1934
|
};
|
|
1671
1935
|
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}`;
|
|
@@ -1707,7 +1971,7 @@ var defineVoiceTurnQualityElement = (tagName = "absolute-voice-turn-quality") =>
|
|
|
1707
1971
|
};
|
|
1708
1972
|
|
|
1709
1973
|
// src/react/VoiceTurnQuality.tsx
|
|
1710
|
-
import { jsxDEV as
|
|
1974
|
+
import { jsxDEV as jsxDEV7 } from "react/jsx-dev-runtime";
|
|
1711
1975
|
var VoiceTurnQuality = ({
|
|
1712
1976
|
className,
|
|
1713
1977
|
path = "/api/turn-quality",
|
|
@@ -1715,58 +1979,58 @@ var VoiceTurnQuality = ({
|
|
|
1715
1979
|
}) => {
|
|
1716
1980
|
const snapshot = useVoiceTurnQuality(path, options);
|
|
1717
1981
|
const model = createVoiceTurnQualityViewModel(snapshot, options);
|
|
1718
|
-
return /* @__PURE__ */
|
|
1982
|
+
return /* @__PURE__ */ jsxDEV7("section", {
|
|
1719
1983
|
className: [
|
|
1720
1984
|
"absolute-voice-turn-quality",
|
|
1721
1985
|
`absolute-voice-turn-quality--${model.status}`,
|
|
1722
1986
|
className
|
|
1723
1987
|
].filter(Boolean).join(" "),
|
|
1724
1988
|
children: [
|
|
1725
|
-
/* @__PURE__ */
|
|
1989
|
+
/* @__PURE__ */ jsxDEV7("header", {
|
|
1726
1990
|
className: "absolute-voice-turn-quality__header",
|
|
1727
1991
|
children: [
|
|
1728
|
-
/* @__PURE__ */
|
|
1992
|
+
/* @__PURE__ */ jsxDEV7("span", {
|
|
1729
1993
|
className: "absolute-voice-turn-quality__eyebrow",
|
|
1730
1994
|
children: model.title
|
|
1731
1995
|
}, undefined, false, undefined, this),
|
|
1732
|
-
/* @__PURE__ */
|
|
1996
|
+
/* @__PURE__ */ jsxDEV7("strong", {
|
|
1733
1997
|
className: "absolute-voice-turn-quality__label",
|
|
1734
1998
|
children: model.label
|
|
1735
1999
|
}, undefined, false, undefined, this)
|
|
1736
2000
|
]
|
|
1737
2001
|
}, undefined, true, undefined, this),
|
|
1738
|
-
/* @__PURE__ */
|
|
2002
|
+
/* @__PURE__ */ jsxDEV7("p", {
|
|
1739
2003
|
className: "absolute-voice-turn-quality__description",
|
|
1740
2004
|
children: model.description
|
|
1741
2005
|
}, undefined, false, undefined, this),
|
|
1742
|
-
model.turns.length ? /* @__PURE__ */
|
|
2006
|
+
model.turns.length ? /* @__PURE__ */ jsxDEV7("div", {
|
|
1743
2007
|
className: "absolute-voice-turn-quality__turns",
|
|
1744
|
-
children: model.turns.map((turn) => /* @__PURE__ */
|
|
2008
|
+
children: model.turns.map((turn) => /* @__PURE__ */ jsxDEV7("article", {
|
|
1745
2009
|
className: [
|
|
1746
2010
|
"absolute-voice-turn-quality__turn",
|
|
1747
2011
|
`absolute-voice-turn-quality__turn--${turn.status}`
|
|
1748
2012
|
].join(" "),
|
|
1749
2013
|
children: [
|
|
1750
|
-
/* @__PURE__ */
|
|
2014
|
+
/* @__PURE__ */ jsxDEV7("header", {
|
|
1751
2015
|
children: [
|
|
1752
|
-
/* @__PURE__ */
|
|
2016
|
+
/* @__PURE__ */ jsxDEV7("strong", {
|
|
1753
2017
|
children: turn.label
|
|
1754
2018
|
}, undefined, false, undefined, this),
|
|
1755
|
-
/* @__PURE__ */
|
|
2019
|
+
/* @__PURE__ */ jsxDEV7("span", {
|
|
1756
2020
|
children: turn.status
|
|
1757
2021
|
}, undefined, false, undefined, this)
|
|
1758
2022
|
]
|
|
1759
2023
|
}, undefined, true, undefined, this),
|
|
1760
|
-
/* @__PURE__ */
|
|
2024
|
+
/* @__PURE__ */ jsxDEV7("p", {
|
|
1761
2025
|
children: turn.detail
|
|
1762
2026
|
}, undefined, false, undefined, this),
|
|
1763
|
-
/* @__PURE__ */
|
|
1764
|
-
children: turn.rows.map((row) => /* @__PURE__ */
|
|
2027
|
+
/* @__PURE__ */ jsxDEV7("dl", {
|
|
2028
|
+
children: turn.rows.map((row) => /* @__PURE__ */ jsxDEV7("div", {
|
|
1765
2029
|
children: [
|
|
1766
|
-
/* @__PURE__ */
|
|
2030
|
+
/* @__PURE__ */ jsxDEV7("dt", {
|
|
1767
2031
|
children: row.label
|
|
1768
2032
|
}, undefined, false, undefined, this),
|
|
1769
|
-
/* @__PURE__ */
|
|
2033
|
+
/* @__PURE__ */ jsxDEV7("dd", {
|
|
1770
2034
|
children: row.value
|
|
1771
2035
|
}, undefined, false, undefined, this)
|
|
1772
2036
|
]
|
|
@@ -1774,11 +2038,11 @@ var VoiceTurnQuality = ({
|
|
|
1774
2038
|
}, undefined, false, undefined, this)
|
|
1775
2039
|
]
|
|
1776
2040
|
}, `${turn.sessionId}:${turn.turnId}`, true, undefined, this))
|
|
1777
|
-
}, undefined, false, undefined, this) : /* @__PURE__ */
|
|
2041
|
+
}, undefined, false, undefined, this) : /* @__PURE__ */ jsxDEV7("p", {
|
|
1778
2042
|
className: "absolute-voice-turn-quality__empty",
|
|
1779
2043
|
children: "Complete a voice turn to see STT quality diagnostics."
|
|
1780
2044
|
}, undefined, false, undefined, this),
|
|
1781
|
-
model.error ? /* @__PURE__ */
|
|
2045
|
+
model.error ? /* @__PURE__ */ jsxDEV7("p", {
|
|
1782
2046
|
className: "absolute-voice-turn-quality__error",
|
|
1783
2047
|
children: model.error
|
|
1784
2048
|
}, undefined, false, undefined, this) : null
|
|
@@ -1786,7 +2050,7 @@ var VoiceTurnQuality = ({
|
|
|
1786
2050
|
}, undefined, true, undefined, this);
|
|
1787
2051
|
};
|
|
1788
2052
|
// src/react/useVoiceStream.tsx
|
|
1789
|
-
import { useEffect as
|
|
2053
|
+
import { useEffect as useEffect8, useRef as useRef8, useSyncExternalStore as useSyncExternalStore8 } from "react";
|
|
1790
2054
|
|
|
1791
2055
|
// src/client/actions.ts
|
|
1792
2056
|
var normalizeErrorMessage = (value) => {
|
|
@@ -2314,13 +2578,13 @@ var EMPTY_SNAPSHOT = {
|
|
|
2314
2578
|
turns: []
|
|
2315
2579
|
};
|
|
2316
2580
|
var useVoiceStream = (path, options = {}) => {
|
|
2317
|
-
const streamRef =
|
|
2581
|
+
const streamRef = useRef8(null);
|
|
2318
2582
|
if (!streamRef.current) {
|
|
2319
2583
|
streamRef.current = createVoiceStream(path, options);
|
|
2320
2584
|
}
|
|
2321
2585
|
const stream = streamRef.current;
|
|
2322
|
-
|
|
2323
|
-
const snapshot =
|
|
2586
|
+
useEffect8(() => () => stream.close(), [stream]);
|
|
2587
|
+
const snapshot = useSyncExternalStore8(stream.subscribe, stream.getSnapshot, stream.getServerSnapshot) ?? EMPTY_SNAPSHOT;
|
|
2324
2588
|
return {
|
|
2325
2589
|
...snapshot,
|
|
2326
2590
|
callControl: (message) => stream.callControl(message),
|
|
@@ -2330,7 +2594,7 @@ var useVoiceStream = (path, options = {}) => {
|
|
|
2330
2594
|
};
|
|
2331
2595
|
};
|
|
2332
2596
|
// src/react/useVoiceController.tsx
|
|
2333
|
-
import { useEffect as
|
|
2597
|
+
import { useEffect as useEffect9, useRef as useRef9, useSyncExternalStore as useSyncExternalStore9 } from "react";
|
|
2334
2598
|
|
|
2335
2599
|
// src/client/htmx.ts
|
|
2336
2600
|
var DEFAULT_EVENT_NAME = "voice-refresh";
|
|
@@ -2977,13 +3241,13 @@ var EMPTY_SNAPSHOT2 = {
|
|
|
2977
3241
|
turns: []
|
|
2978
3242
|
};
|
|
2979
3243
|
var useVoiceController = (path, options = {}) => {
|
|
2980
|
-
const controllerRef =
|
|
3244
|
+
const controllerRef = useRef9(null);
|
|
2981
3245
|
if (!controllerRef.current) {
|
|
2982
3246
|
controllerRef.current = createVoiceController(path, options);
|
|
2983
3247
|
}
|
|
2984
3248
|
const controller = controllerRef.current;
|
|
2985
|
-
|
|
2986
|
-
const snapshot =
|
|
3249
|
+
useEffect9(() => () => controller.close(), [controller]);
|
|
3250
|
+
const snapshot = useSyncExternalStore9(controller.subscribe, controller.getSnapshot, controller.getServerSnapshot) ?? EMPTY_SNAPSHOT2;
|
|
2987
3251
|
return {
|
|
2988
3252
|
...snapshot,
|
|
2989
3253
|
bindHTMX: controller.bindHTMX,
|
|
@@ -2997,7 +3261,7 @@ var useVoiceController = (path, options = {}) => {
|
|
|
2997
3261
|
};
|
|
2998
3262
|
};
|
|
2999
3263
|
// src/react/useVoiceWorkflowStatus.tsx
|
|
3000
|
-
import { useEffect as
|
|
3264
|
+
import { useEffect as useEffect10, useRef as useRef10, useSyncExternalStore as useSyncExternalStore10 } from "react";
|
|
3001
3265
|
|
|
3002
3266
|
// src/client/workflowStatus.ts
|
|
3003
3267
|
var fetchVoiceWorkflowStatus = async (path = "/evals/scenarios/json", options = {}) => {
|
|
@@ -3080,23 +3344,24 @@ var createVoiceWorkflowStatusStore = (path = "/evals/scenarios/json", options =
|
|
|
3080
3344
|
|
|
3081
3345
|
// src/react/useVoiceWorkflowStatus.tsx
|
|
3082
3346
|
var useVoiceWorkflowStatus = (path = "/evals/scenarios/json", options = {}) => {
|
|
3083
|
-
const storeRef =
|
|
3347
|
+
const storeRef = useRef10(null);
|
|
3084
3348
|
if (!storeRef.current) {
|
|
3085
3349
|
storeRef.current = createVoiceWorkflowStatusStore(path, options);
|
|
3086
3350
|
}
|
|
3087
3351
|
const store = storeRef.current;
|
|
3088
|
-
|
|
3352
|
+
useEffect10(() => {
|
|
3089
3353
|
store.refresh().catch(() => {});
|
|
3090
3354
|
return () => store.close();
|
|
3091
3355
|
}, [store]);
|
|
3092
3356
|
return {
|
|
3093
|
-
...
|
|
3357
|
+
...useSyncExternalStore10(store.subscribe, store.getSnapshot, store.getServerSnapshot),
|
|
3094
3358
|
refresh: store.refresh
|
|
3095
3359
|
};
|
|
3096
3360
|
};
|
|
3097
3361
|
export {
|
|
3098
3362
|
useVoiceWorkflowStatus,
|
|
3099
3363
|
useVoiceTurnQuality,
|
|
3364
|
+
useVoiceTraceTimeline,
|
|
3100
3365
|
useVoiceStream,
|
|
3101
3366
|
useVoiceRoutingStatus,
|
|
3102
3367
|
useVoiceProviderStatus,
|
|
@@ -3105,6 +3370,7 @@ export {
|
|
|
3105
3370
|
useVoiceController,
|
|
3106
3371
|
useVoiceAppKitStatus,
|
|
3107
3372
|
VoiceTurnQuality,
|
|
3373
|
+
VoiceTraceTimeline,
|
|
3108
3374
|
VoiceRoutingStatus,
|
|
3109
3375
|
VoiceProviderStatus,
|
|
3110
3376
|
VoiceProviderSimulationControls,
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { type VoiceTraceTimelineClientOptions } from '../client/traceTimeline';
|
|
2
|
+
export declare const useVoiceTraceTimeline: (path?: string, options?: VoiceTraceTimelineClientOptions) => {
|
|
3
|
+
refresh: () => Promise<import("..").VoiceTraceTimelineReport | null>;
|
|
4
|
+
error: string | null;
|
|
5
|
+
isLoading: boolean;
|
|
6
|
+
report: import("..").VoiceTraceTimelineReport | null;
|
|
7
|
+
updatedAt?: number;
|
|
8
|
+
};
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { type VoiceTraceTimelineWidgetOptions } from '../client/traceTimelineWidget';
|
|
2
|
+
export declare const createVoiceTraceTimeline: (path?: string, options?: VoiceTraceTimelineWidgetOptions) => {
|
|
3
|
+
getHTML: () => string;
|
|
4
|
+
getViewModel: () => import("../client").VoiceTraceTimelineViewModel;
|
|
5
|
+
close: () => void;
|
|
6
|
+
getServerSnapshot: () => import("../client").VoiceTraceTimelineSnapshot;
|
|
7
|
+
getSnapshot: () => import("../client").VoiceTraceTimelineSnapshot;
|
|
8
|
+
refresh: () => Promise<import("..").VoiceTraceTimelineReport | null>;
|
|
9
|
+
subscribe: (listener: () => void) => () => void;
|
|
10
|
+
};
|
package/dist/svelte/index.d.ts
CHANGED
|
@@ -5,6 +5,7 @@ export { createVoiceProviderCapabilities } from './createVoiceProviderCapabiliti
|
|
|
5
5
|
export { createVoiceStream } from './createVoiceStream';
|
|
6
6
|
export { createVoiceProviderStatus } from './createVoiceProviderStatus';
|
|
7
7
|
export { createVoiceRoutingStatus } from './createVoiceRoutingStatus';
|
|
8
|
+
export { createVoiceTraceTimeline } from './createVoiceTraceTimeline';
|
|
8
9
|
export { createVoiceTurnQuality } from './createVoiceTurnQuality';
|
|
9
10
|
export { createVoiceWorkflowStatus } from './createVoiceWorkflowStatus';
|
|
10
11
|
export { createVoiceController } from '../client/controller';
|