@absolutejs/voice 0.0.22-beta.65 → 0.0.22-beta.66
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 +149 -26
- package/dist/angular/voice-provider-capabilities.service.d.ts +12 -0
- package/dist/client/index.d.ts +4 -0
- package/dist/client/index.js +201 -0
- package/dist/client/providerCapabilities.d.ts +19 -0
- package/dist/client/providerCapabilitiesWidget.d.ts +32 -0
- package/dist/react/VoiceProviderCapabilities.d.ts +6 -0
- package/dist/react/index.d.ts +2 -0
- package/dist/react/index.js +380 -83
- package/dist/react/useVoiceProviderCapabilities.d.ts +8 -0
- package/dist/svelte/createVoiceProviderCapabilities.d.ts +10 -0
- package/dist/svelte/index.d.ts +1 -0
- package/dist/svelte/index.js +239 -33
- package/dist/vue/VoiceProviderCapabilities.d.ts +51 -0
- package/dist/vue/index.d.ts +2 -0
- package/dist/vue/index.js +387 -84
- package/dist/vue/useVoiceProviderCapabilities.d.ts +9 -0
- package/package.json +1 -1
package/dist/react/index.js
CHANGED
|
@@ -656,9 +656,304 @@ var VoiceProviderSimulationControls = ({
|
|
|
656
656
|
]
|
|
657
657
|
}, undefined, true, undefined, this);
|
|
658
658
|
};
|
|
659
|
-
// src/react/
|
|
659
|
+
// src/react/useVoiceProviderCapabilities.tsx
|
|
660
660
|
import { useEffect as useEffect3, useRef as useRef3, useSyncExternalStore as useSyncExternalStore3 } from "react";
|
|
661
661
|
|
|
662
|
+
// src/client/providerCapabilities.ts
|
|
663
|
+
var fetchVoiceProviderCapabilities = async (path = "/api/provider-capabilities", options = {}) => {
|
|
664
|
+
const fetchImpl = options.fetch ?? globalThis.fetch;
|
|
665
|
+
const response = await fetchImpl(path);
|
|
666
|
+
if (!response.ok) {
|
|
667
|
+
throw new Error(`Voice provider capabilities failed: HTTP ${response.status}`);
|
|
668
|
+
}
|
|
669
|
+
return await response.json();
|
|
670
|
+
};
|
|
671
|
+
var createVoiceProviderCapabilitiesStore = (path = "/api/provider-capabilities", options = {}) => {
|
|
672
|
+
const listeners = new Set;
|
|
673
|
+
let closed = false;
|
|
674
|
+
let timer;
|
|
675
|
+
let snapshot = {
|
|
676
|
+
error: null,
|
|
677
|
+
isLoading: false
|
|
678
|
+
};
|
|
679
|
+
const emit = () => {
|
|
680
|
+
for (const listener of listeners) {
|
|
681
|
+
listener();
|
|
682
|
+
}
|
|
683
|
+
};
|
|
684
|
+
const refresh = async () => {
|
|
685
|
+
if (closed) {
|
|
686
|
+
return snapshot.report;
|
|
687
|
+
}
|
|
688
|
+
snapshot = {
|
|
689
|
+
...snapshot,
|
|
690
|
+
error: null,
|
|
691
|
+
isLoading: true
|
|
692
|
+
};
|
|
693
|
+
emit();
|
|
694
|
+
try {
|
|
695
|
+
const report = await fetchVoiceProviderCapabilities(path, options);
|
|
696
|
+
snapshot = {
|
|
697
|
+
error: null,
|
|
698
|
+
isLoading: false,
|
|
699
|
+
report,
|
|
700
|
+
updatedAt: Date.now()
|
|
701
|
+
};
|
|
702
|
+
emit();
|
|
703
|
+
return report;
|
|
704
|
+
} catch (error) {
|
|
705
|
+
snapshot = {
|
|
706
|
+
...snapshot,
|
|
707
|
+
error: error instanceof Error ? error.message : String(error),
|
|
708
|
+
isLoading: false
|
|
709
|
+
};
|
|
710
|
+
emit();
|
|
711
|
+
throw error;
|
|
712
|
+
}
|
|
713
|
+
};
|
|
714
|
+
const close = () => {
|
|
715
|
+
closed = true;
|
|
716
|
+
if (timer) {
|
|
717
|
+
clearInterval(timer);
|
|
718
|
+
timer = undefined;
|
|
719
|
+
}
|
|
720
|
+
listeners.clear();
|
|
721
|
+
};
|
|
722
|
+
if (options.intervalMs && options.intervalMs > 0) {
|
|
723
|
+
timer = setInterval(() => {
|
|
724
|
+
refresh().catch(() => {});
|
|
725
|
+
}, options.intervalMs);
|
|
726
|
+
}
|
|
727
|
+
return {
|
|
728
|
+
close,
|
|
729
|
+
getServerSnapshot: () => snapshot,
|
|
730
|
+
getSnapshot: () => snapshot,
|
|
731
|
+
refresh,
|
|
732
|
+
subscribe: (listener) => {
|
|
733
|
+
listeners.add(listener);
|
|
734
|
+
return () => {
|
|
735
|
+
listeners.delete(listener);
|
|
736
|
+
};
|
|
737
|
+
}
|
|
738
|
+
};
|
|
739
|
+
};
|
|
740
|
+
|
|
741
|
+
// src/react/useVoiceProviderCapabilities.tsx
|
|
742
|
+
var useVoiceProviderCapabilities = (path = "/api/provider-capabilities", options = {}) => {
|
|
743
|
+
const storeRef = useRef3(null);
|
|
744
|
+
if (!storeRef.current) {
|
|
745
|
+
storeRef.current = createVoiceProviderCapabilitiesStore(path, options);
|
|
746
|
+
}
|
|
747
|
+
const store = storeRef.current;
|
|
748
|
+
useEffect3(() => {
|
|
749
|
+
store.refresh().catch(() => {});
|
|
750
|
+
return () => store.close();
|
|
751
|
+
}, [store]);
|
|
752
|
+
return {
|
|
753
|
+
...useSyncExternalStore3(store.subscribe, store.getSnapshot, store.getServerSnapshot),
|
|
754
|
+
refresh: store.refresh
|
|
755
|
+
};
|
|
756
|
+
};
|
|
757
|
+
|
|
758
|
+
// src/client/providerCapabilitiesWidget.ts
|
|
759
|
+
var DEFAULT_TITLE2 = "Provider Capabilities";
|
|
760
|
+
var DEFAULT_DESCRIPTION2 = "Configured, selected, and healthy voice providers for this deployment.";
|
|
761
|
+
var escapeHtml3 = (value) => value.replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">").replaceAll('"', """).replaceAll("'", "'");
|
|
762
|
+
var formatProvider = (provider) => provider.split(/[-_\s]+/).filter(Boolean).map((part) => `${part[0]?.toUpperCase() ?? ""}${part.slice(1)}`).join(" ") || provider;
|
|
763
|
+
var formatKind2 = (kind) => kind.toUpperCase();
|
|
764
|
+
var formatStatus = (status) => status.split("-").map((part) => `${part[0]?.toUpperCase() ?? ""}${part.slice(1)}`).join(" ");
|
|
765
|
+
var getCapabilityDetail = (capability) => {
|
|
766
|
+
if (!capability.configured) {
|
|
767
|
+
return "Not configured in this deployment.";
|
|
768
|
+
}
|
|
769
|
+
if (capability.selected) {
|
|
770
|
+
return `Selected ${capability.kind.toUpperCase()} provider for new sessions.`;
|
|
771
|
+
}
|
|
772
|
+
if (capability.health?.status === "healthy") {
|
|
773
|
+
return "Configured and healthy fallback candidate.";
|
|
774
|
+
}
|
|
775
|
+
if (capability.health?.status === "idle") {
|
|
776
|
+
return "Configured; no traffic observed yet.";
|
|
777
|
+
}
|
|
778
|
+
if (capability.health?.lastError) {
|
|
779
|
+
return capability.health.lastError;
|
|
780
|
+
}
|
|
781
|
+
return "Configured and available.";
|
|
782
|
+
};
|
|
783
|
+
var isWarningStatus = (status) => status === "degraded" || status === "rate-limited" || status === "suppressed" || status === "unconfigured";
|
|
784
|
+
var createVoiceProviderCapabilitiesViewModel = (snapshot, options = {}) => {
|
|
785
|
+
const capabilities = (snapshot.report?.capabilities ?? []).map((capability) => ({
|
|
786
|
+
...capability,
|
|
787
|
+
detail: getCapabilityDetail(capability),
|
|
788
|
+
label: `${formatProvider(capability.provider)} ${formatKind2(capability.kind)}`,
|
|
789
|
+
rows: [
|
|
790
|
+
{ label: "Status", value: formatStatus(capability.status) },
|
|
791
|
+
{ label: "Selected", value: capability.selected ? "Yes" : "No" },
|
|
792
|
+
{ label: "Model", value: capability.model ?? "Default" },
|
|
793
|
+
{
|
|
794
|
+
label: "Features",
|
|
795
|
+
value: capability.features?.join(", ") || "Not specified"
|
|
796
|
+
},
|
|
797
|
+
{ label: "Runs", value: String(capability.health?.runCount ?? 0) },
|
|
798
|
+
{ label: "Errors", value: String(capability.health?.errorCount ?? 0) }
|
|
799
|
+
]
|
|
800
|
+
}));
|
|
801
|
+
const warningCount = capabilities.filter((capability) => isWarningStatus(capability.status)).length;
|
|
802
|
+
const selectedCount = snapshot.report?.selected ?? capabilities.filter((capability) => capability.selected).length;
|
|
803
|
+
return {
|
|
804
|
+
capabilities,
|
|
805
|
+
description: options.description ?? DEFAULT_DESCRIPTION2,
|
|
806
|
+
error: snapshot.error,
|
|
807
|
+
isLoading: snapshot.isLoading,
|
|
808
|
+
label: snapshot.error ? "Unavailable" : capabilities.length ? warningCount > 0 ? `${warningCount} needs attention` : `${selectedCount} selected` : snapshot.isLoading ? "Checking" : "No capabilities",
|
|
809
|
+
status: snapshot.error ? "error" : capabilities.length ? warningCount > 0 ? "warning" : "ready" : snapshot.isLoading ? "loading" : "empty",
|
|
810
|
+
title: options.title ?? DEFAULT_TITLE2,
|
|
811
|
+
updatedAt: snapshot.updatedAt
|
|
812
|
+
};
|
|
813
|
+
};
|
|
814
|
+
var renderVoiceProviderCapabilitiesHTML = (snapshot, options = {}) => {
|
|
815
|
+
const model = createVoiceProviderCapabilitiesViewModel(snapshot, options);
|
|
816
|
+
const capabilities = model.capabilities.length ? `<div class="absolute-voice-provider-capabilities__providers">${model.capabilities.map((capability) => `<article class="absolute-voice-provider-capabilities__provider absolute-voice-provider-capabilities__provider--${escapeHtml3(capability.status)}">
|
|
817
|
+
<header>
|
|
818
|
+
<strong>${escapeHtml3(capability.label)}</strong>
|
|
819
|
+
<span>${escapeHtml3(formatStatus(capability.status))}</span>
|
|
820
|
+
</header>
|
|
821
|
+
<p>${escapeHtml3(capability.detail)}</p>
|
|
822
|
+
<dl>${capability.rows.map((row) => `<div>
|
|
823
|
+
<dt>${escapeHtml3(row.label)}</dt>
|
|
824
|
+
<dd>${escapeHtml3(row.value)}</dd>
|
|
825
|
+
</div>`).join("")}</dl>
|
|
826
|
+
</article>`).join("")}</div>` : '<p class="absolute-voice-provider-capabilities__empty">Configure provider capabilities to see deployment coverage.</p>';
|
|
827
|
+
return `<section class="absolute-voice-provider-capabilities absolute-voice-provider-capabilities--${escapeHtml3(model.status)}">
|
|
828
|
+
<header class="absolute-voice-provider-capabilities__header">
|
|
829
|
+
<span class="absolute-voice-provider-capabilities__eyebrow">${escapeHtml3(model.title)}</span>
|
|
830
|
+
<strong class="absolute-voice-provider-capabilities__label">${escapeHtml3(model.label)}</strong>
|
|
831
|
+
</header>
|
|
832
|
+
<p class="absolute-voice-provider-capabilities__description">${escapeHtml3(model.description)}</p>
|
|
833
|
+
${capabilities}
|
|
834
|
+
${model.error ? `<p class="absolute-voice-provider-capabilities__error">${escapeHtml3(model.error)}</p>` : ""}
|
|
835
|
+
</section>`;
|
|
836
|
+
};
|
|
837
|
+
var getVoiceProviderCapabilitiesCSS = () => `.absolute-voice-provider-capabilities{border:1px solid #bfd7ea;border-radius:20px;background:#f6fbff;color:#08131f;padding:18px;box-shadow:0 18px 40px rgba(14,51,78,.12);font-family:inherit}.absolute-voice-provider-capabilities--error,.absolute-voice-provider-capabilities--warning{border-color:#f2a7a7;background:#fff5f3}.absolute-voice-provider-capabilities__header,.absolute-voice-provider-capabilities__provider header{align-items:start;display:flex;gap:12px;justify-content:space-between}.absolute-voice-provider-capabilities__eyebrow{color:#255f85;font-size:12px;font-weight:800;letter-spacing:.08em;text-transform:uppercase}.absolute-voice-provider-capabilities__label{font-size:24px;line-height:1}.absolute-voice-provider-capabilities__description,.absolute-voice-provider-capabilities__provider p,.absolute-voice-provider-capabilities__provider dt,.absolute-voice-provider-capabilities__empty{color:#405467}.absolute-voice-provider-capabilities__providers{display:grid;gap:12px;margin-top:14px}.absolute-voice-provider-capabilities__provider{background:#fff;border:1px solid #d7e7f3;border-radius:16px;padding:14px}.absolute-voice-provider-capabilities__provider--selected,.absolute-voice-provider-capabilities__provider--healthy{border-color:#86efac}.absolute-voice-provider-capabilities__provider--degraded,.absolute-voice-provider-capabilities__provider--rate-limited,.absolute-voice-provider-capabilities__provider--suppressed,.absolute-voice-provider-capabilities__provider--unconfigured{border-color:#f2a7a7}.absolute-voice-provider-capabilities__provider p{margin:10px 0}.absolute-voice-provider-capabilities__provider dl{display:grid;gap:8px;grid-template-columns:repeat(2,minmax(0,1fr));margin:0}.absolute-voice-provider-capabilities__provider div{background:#f6fbff;border:1px solid #d7e7f3;border-radius:12px;padding:8px}.absolute-voice-provider-capabilities__provider dt{font-size:12px}.absolute-voice-provider-capabilities__provider dd{font-weight:800;margin:4px 0 0}.absolute-voice-provider-capabilities__empty{margin:14px 0 0}.absolute-voice-provider-capabilities__error{color:#9f1239;font-weight:700}`;
|
|
838
|
+
var mountVoiceProviderCapabilities = (element, path = "/api/provider-capabilities", options = {}) => {
|
|
839
|
+
const store = createVoiceProviderCapabilitiesStore(path, options);
|
|
840
|
+
const render = () => {
|
|
841
|
+
element.innerHTML = renderVoiceProviderCapabilitiesHTML(store.getSnapshot(), options);
|
|
842
|
+
};
|
|
843
|
+
const unsubscribe = store.subscribe(render);
|
|
844
|
+
render();
|
|
845
|
+
store.refresh().catch(() => {});
|
|
846
|
+
return {
|
|
847
|
+
close: () => {
|
|
848
|
+
unsubscribe();
|
|
849
|
+
store.close();
|
|
850
|
+
},
|
|
851
|
+
refresh: store.refresh
|
|
852
|
+
};
|
|
853
|
+
};
|
|
854
|
+
var defineVoiceProviderCapabilitiesElement = (tagName = "absolute-voice-provider-capabilities") => {
|
|
855
|
+
if (typeof window === "undefined" || typeof customElements === "undefined" || customElements.get(tagName)) {
|
|
856
|
+
return;
|
|
857
|
+
}
|
|
858
|
+
customElements.define(tagName, class AbsoluteVoiceProviderCapabilitiesElement extends HTMLElement {
|
|
859
|
+
mounted;
|
|
860
|
+
connectedCallback() {
|
|
861
|
+
const intervalMs = Number(this.getAttribute("interval-ms") ?? 5000);
|
|
862
|
+
this.mounted = mountVoiceProviderCapabilities(this, this.getAttribute("path") ?? "/api/provider-capabilities", {
|
|
863
|
+
description: this.getAttribute("description") ?? undefined,
|
|
864
|
+
intervalMs: Number.isFinite(intervalMs) ? intervalMs : 5000,
|
|
865
|
+
title: this.getAttribute("title") ?? undefined
|
|
866
|
+
});
|
|
867
|
+
}
|
|
868
|
+
disconnectedCallback() {
|
|
869
|
+
this.mounted?.close();
|
|
870
|
+
this.mounted = undefined;
|
|
871
|
+
}
|
|
872
|
+
});
|
|
873
|
+
};
|
|
874
|
+
|
|
875
|
+
// src/react/VoiceProviderCapabilities.tsx
|
|
876
|
+
import { jsxDEV as jsxDEV3 } from "react/jsx-dev-runtime";
|
|
877
|
+
var VoiceProviderCapabilities = ({
|
|
878
|
+
className,
|
|
879
|
+
path = "/api/provider-capabilities",
|
|
880
|
+
...options
|
|
881
|
+
}) => {
|
|
882
|
+
const snapshot = useVoiceProviderCapabilities(path, options);
|
|
883
|
+
const model = createVoiceProviderCapabilitiesViewModel(snapshot, options);
|
|
884
|
+
return /* @__PURE__ */ jsxDEV3("section", {
|
|
885
|
+
className: [
|
|
886
|
+
"absolute-voice-provider-capabilities",
|
|
887
|
+
`absolute-voice-provider-capabilities--${model.status}`,
|
|
888
|
+
className
|
|
889
|
+
].filter(Boolean).join(" "),
|
|
890
|
+
children: [
|
|
891
|
+
/* @__PURE__ */ jsxDEV3("header", {
|
|
892
|
+
className: "absolute-voice-provider-capabilities__header",
|
|
893
|
+
children: [
|
|
894
|
+
/* @__PURE__ */ jsxDEV3("span", {
|
|
895
|
+
className: "absolute-voice-provider-capabilities__eyebrow",
|
|
896
|
+
children: model.title
|
|
897
|
+
}, undefined, false, undefined, this),
|
|
898
|
+
/* @__PURE__ */ jsxDEV3("strong", {
|
|
899
|
+
className: "absolute-voice-provider-capabilities__label",
|
|
900
|
+
children: model.label
|
|
901
|
+
}, undefined, false, undefined, this)
|
|
902
|
+
]
|
|
903
|
+
}, undefined, true, undefined, this),
|
|
904
|
+
/* @__PURE__ */ jsxDEV3("p", {
|
|
905
|
+
className: "absolute-voice-provider-capabilities__description",
|
|
906
|
+
children: model.description
|
|
907
|
+
}, undefined, false, undefined, this),
|
|
908
|
+
model.capabilities.length ? /* @__PURE__ */ jsxDEV3("div", {
|
|
909
|
+
className: "absolute-voice-provider-capabilities__providers",
|
|
910
|
+
children: model.capabilities.map((capability) => /* @__PURE__ */ jsxDEV3("article", {
|
|
911
|
+
className: [
|
|
912
|
+
"absolute-voice-provider-capabilities__provider",
|
|
913
|
+
`absolute-voice-provider-capabilities__provider--${capability.status}`
|
|
914
|
+
].join(" "),
|
|
915
|
+
children: [
|
|
916
|
+
/* @__PURE__ */ jsxDEV3("header", {
|
|
917
|
+
children: [
|
|
918
|
+
/* @__PURE__ */ jsxDEV3("strong", {
|
|
919
|
+
children: capability.label
|
|
920
|
+
}, undefined, false, undefined, this),
|
|
921
|
+
/* @__PURE__ */ jsxDEV3("span", {
|
|
922
|
+
children: capability.status
|
|
923
|
+
}, undefined, false, undefined, this)
|
|
924
|
+
]
|
|
925
|
+
}, undefined, true, undefined, this),
|
|
926
|
+
/* @__PURE__ */ jsxDEV3("p", {
|
|
927
|
+
children: capability.detail
|
|
928
|
+
}, undefined, false, undefined, this),
|
|
929
|
+
/* @__PURE__ */ jsxDEV3("dl", {
|
|
930
|
+
children: capability.rows.map((row) => /* @__PURE__ */ jsxDEV3("div", {
|
|
931
|
+
children: [
|
|
932
|
+
/* @__PURE__ */ jsxDEV3("dt", {
|
|
933
|
+
children: row.label
|
|
934
|
+
}, undefined, false, undefined, this),
|
|
935
|
+
/* @__PURE__ */ jsxDEV3("dd", {
|
|
936
|
+
children: row.value
|
|
937
|
+
}, undefined, false, undefined, this)
|
|
938
|
+
]
|
|
939
|
+
}, row.label, true, undefined, this))
|
|
940
|
+
}, undefined, false, undefined, this)
|
|
941
|
+
]
|
|
942
|
+
}, `${capability.kind}:${capability.provider}`, true, undefined, this))
|
|
943
|
+
}, undefined, false, undefined, this) : /* @__PURE__ */ jsxDEV3("p", {
|
|
944
|
+
className: "absolute-voice-provider-capabilities__empty",
|
|
945
|
+
children: "Configure provider capabilities to see deployment coverage."
|
|
946
|
+
}, undefined, false, undefined, this),
|
|
947
|
+
model.error ? /* @__PURE__ */ jsxDEV3("p", {
|
|
948
|
+
className: "absolute-voice-provider-capabilities__error",
|
|
949
|
+
children: model.error
|
|
950
|
+
}, undefined, false, undefined, this) : null
|
|
951
|
+
]
|
|
952
|
+
}, undefined, true, undefined, this);
|
|
953
|
+
};
|
|
954
|
+
// src/react/useVoiceProviderStatus.tsx
|
|
955
|
+
import { useEffect as useEffect4, useRef as useRef4, useSyncExternalStore as useSyncExternalStore4 } from "react";
|
|
956
|
+
|
|
662
957
|
// src/client/providerStatus.ts
|
|
663
958
|
var fetchVoiceProviderStatus = async (path = "/api/provider-status", options = {}) => {
|
|
664
959
|
const fetchImpl = options.fetch ?? globalThis.fetch;
|
|
@@ -741,27 +1036,27 @@ var createVoiceProviderStatusStore = (path = "/api/provider-status", options = {
|
|
|
741
1036
|
|
|
742
1037
|
// src/react/useVoiceProviderStatus.tsx
|
|
743
1038
|
var useVoiceProviderStatus = (path = "/api/provider-status", options = {}) => {
|
|
744
|
-
const storeRef =
|
|
1039
|
+
const storeRef = useRef4(null);
|
|
745
1040
|
if (!storeRef.current) {
|
|
746
1041
|
storeRef.current = createVoiceProviderStatusStore(path, options);
|
|
747
1042
|
}
|
|
748
1043
|
const store = storeRef.current;
|
|
749
|
-
|
|
1044
|
+
useEffect4(() => {
|
|
750
1045
|
store.refresh().catch(() => {});
|
|
751
1046
|
return () => store.close();
|
|
752
1047
|
}, [store]);
|
|
753
1048
|
return {
|
|
754
|
-
...
|
|
1049
|
+
...useSyncExternalStore4(store.subscribe, store.getSnapshot, store.getServerSnapshot),
|
|
755
1050
|
refresh: store.refresh
|
|
756
1051
|
};
|
|
757
1052
|
};
|
|
758
1053
|
|
|
759
1054
|
// src/client/providerStatusWidget.ts
|
|
760
|
-
var
|
|
761
|
-
var
|
|
762
|
-
var
|
|
763
|
-
var
|
|
764
|
-
var
|
|
1055
|
+
var DEFAULT_TITLE3 = "Voice Providers";
|
|
1056
|
+
var DEFAULT_DESCRIPTION3 = "Live provider health, fallback counts, latency, and suppression state from your self-hosted trace store.";
|
|
1057
|
+
var escapeHtml4 = (value) => value.replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">").replaceAll('"', """).replaceAll("'", "'");
|
|
1058
|
+
var formatProvider2 = (provider) => provider.split(/[-_\s]+/).filter(Boolean).map((part) => `${part[0]?.toUpperCase() ?? ""}${part.slice(1)}`).join(" ") || provider;
|
|
1059
|
+
var formatStatus2 = (status) => status.split("-").map((part) => `${part[0]?.toUpperCase() ?? ""}${part.slice(1)}`).join(" ");
|
|
765
1060
|
var formatLatency = (value) => typeof value === "number" ? `${value}ms` : "No samples";
|
|
766
1061
|
var formatSuppression = (value) => typeof value === "number" ? `${Math.ceil(value / 1000)}s` : "None";
|
|
767
1062
|
var getProviderDetail = (provider) => {
|
|
@@ -782,12 +1077,12 @@ var getProviderDetail = (provider) => {
|
|
|
782
1077
|
}
|
|
783
1078
|
return "No provider traffic observed yet.";
|
|
784
1079
|
};
|
|
785
|
-
var
|
|
1080
|
+
var isWarningStatus2 = (status) => status === "degraded" || status === "rate-limited" || status === "recoverable" || status === "suppressed";
|
|
786
1081
|
var createVoiceProviderStatusViewModel = (snapshot, options = {}) => {
|
|
787
1082
|
const providers = snapshot.providers.map((provider) => ({
|
|
788
1083
|
...provider,
|
|
789
1084
|
detail: getProviderDetail(provider),
|
|
790
|
-
label: `${
|
|
1085
|
+
label: `${formatProvider2(provider.provider)}${provider.recommended ? " recommended" : ""}`,
|
|
791
1086
|
rows: [
|
|
792
1087
|
{ label: "Runs", value: String(provider.runCount) },
|
|
793
1088
|
{ label: "Avg latency", value: formatLatency(provider.averageElapsedMs) },
|
|
@@ -800,40 +1095,40 @@ var createVoiceProviderStatusViewModel = (snapshot, options = {}) => {
|
|
|
800
1095
|
}
|
|
801
1096
|
]
|
|
802
1097
|
}));
|
|
803
|
-
const warningCount = providers.filter((provider) =>
|
|
1098
|
+
const warningCount = providers.filter((provider) => isWarningStatus2(provider.status)).length;
|
|
804
1099
|
const healthyCount = providers.filter((provider) => provider.status === "healthy").length;
|
|
805
1100
|
return {
|
|
806
|
-
description: options.description ??
|
|
1101
|
+
description: options.description ?? DEFAULT_DESCRIPTION3,
|
|
807
1102
|
error: snapshot.error,
|
|
808
1103
|
isLoading: snapshot.isLoading,
|
|
809
1104
|
label: snapshot.error ? "Unavailable" : providers.length ? warningCount > 0 ? `${warningCount} needs attention` : `${healthyCount} healthy` : snapshot.isLoading ? "Checking" : "No provider traffic",
|
|
810
1105
|
providers,
|
|
811
1106
|
status: snapshot.error ? "error" : providers.length ? warningCount > 0 ? "warning" : "ready" : snapshot.isLoading ? "loading" : "empty",
|
|
812
|
-
title: options.title ??
|
|
1107
|
+
title: options.title ?? DEFAULT_TITLE3,
|
|
813
1108
|
updatedAt: snapshot.updatedAt
|
|
814
1109
|
};
|
|
815
1110
|
};
|
|
816
1111
|
var renderVoiceProviderStatusHTML = (snapshot, options = {}) => {
|
|
817
1112
|
const model = createVoiceProviderStatusViewModel(snapshot, options);
|
|
818
|
-
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--${
|
|
1113
|
+
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--${escapeHtml4(provider.status)}">
|
|
819
1114
|
<header>
|
|
820
|
-
<strong>${
|
|
821
|
-
<span>${
|
|
1115
|
+
<strong>${escapeHtml4(provider.label)}</strong>
|
|
1116
|
+
<span>${escapeHtml4(formatStatus2(provider.status))}</span>
|
|
822
1117
|
</header>
|
|
823
|
-
<p>${
|
|
1118
|
+
<p>${escapeHtml4(provider.detail)}</p>
|
|
824
1119
|
<dl>${provider.rows.map((row) => `<div>
|
|
825
|
-
<dt>${
|
|
826
|
-
<dd>${
|
|
1120
|
+
<dt>${escapeHtml4(row.label)}</dt>
|
|
1121
|
+
<dd>${escapeHtml4(row.value)}</dd>
|
|
827
1122
|
</div>`).join("")}</dl>
|
|
828
1123
|
</article>`).join("")}</div>` : '<p class="absolute-voice-provider-status__empty">Run voice traffic to see provider health.</p>';
|
|
829
|
-
return `<section class="absolute-voice-provider-status absolute-voice-provider-status--${
|
|
1124
|
+
return `<section class="absolute-voice-provider-status absolute-voice-provider-status--${escapeHtml4(model.status)}">
|
|
830
1125
|
<header class="absolute-voice-provider-status__header">
|
|
831
|
-
<span class="absolute-voice-provider-status__eyebrow">${
|
|
832
|
-
<strong class="absolute-voice-provider-status__label">${
|
|
1126
|
+
<span class="absolute-voice-provider-status__eyebrow">${escapeHtml4(model.title)}</span>
|
|
1127
|
+
<strong class="absolute-voice-provider-status__label">${escapeHtml4(model.label)}</strong>
|
|
833
1128
|
</header>
|
|
834
|
-
<p class="absolute-voice-provider-status__description">${
|
|
1129
|
+
<p class="absolute-voice-provider-status__description">${escapeHtml4(model.description)}</p>
|
|
835
1130
|
${providers}
|
|
836
|
-
${model.error ? `<p class="absolute-voice-provider-status__error">${
|
|
1131
|
+
${model.error ? `<p class="absolute-voice-provider-status__error">${escapeHtml4(model.error)}</p>` : ""}
|
|
837
1132
|
</section>`;
|
|
838
1133
|
};
|
|
839
1134
|
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}`;
|
|
@@ -875,7 +1170,7 @@ var defineVoiceProviderStatusElement = (tagName = "absolute-voice-provider-statu
|
|
|
875
1170
|
};
|
|
876
1171
|
|
|
877
1172
|
// src/react/VoiceProviderStatus.tsx
|
|
878
|
-
import { jsxDEV as
|
|
1173
|
+
import { jsxDEV as jsxDEV4 } from "react/jsx-dev-runtime";
|
|
879
1174
|
var VoiceProviderStatus = ({
|
|
880
1175
|
className,
|
|
881
1176
|
path = "/api/provider-status",
|
|
@@ -883,58 +1178,58 @@ var VoiceProviderStatus = ({
|
|
|
883
1178
|
}) => {
|
|
884
1179
|
const snapshot = useVoiceProviderStatus(path, options);
|
|
885
1180
|
const model = createVoiceProviderStatusViewModel(snapshot, options);
|
|
886
|
-
return /* @__PURE__ */
|
|
1181
|
+
return /* @__PURE__ */ jsxDEV4("section", {
|
|
887
1182
|
className: [
|
|
888
1183
|
"absolute-voice-provider-status",
|
|
889
1184
|
`absolute-voice-provider-status--${model.status}`,
|
|
890
1185
|
className
|
|
891
1186
|
].filter(Boolean).join(" "),
|
|
892
1187
|
children: [
|
|
893
|
-
/* @__PURE__ */
|
|
1188
|
+
/* @__PURE__ */ jsxDEV4("header", {
|
|
894
1189
|
className: "absolute-voice-provider-status__header",
|
|
895
1190
|
children: [
|
|
896
|
-
/* @__PURE__ */
|
|
1191
|
+
/* @__PURE__ */ jsxDEV4("span", {
|
|
897
1192
|
className: "absolute-voice-provider-status__eyebrow",
|
|
898
1193
|
children: model.title
|
|
899
1194
|
}, undefined, false, undefined, this),
|
|
900
|
-
/* @__PURE__ */
|
|
1195
|
+
/* @__PURE__ */ jsxDEV4("strong", {
|
|
901
1196
|
className: "absolute-voice-provider-status__label",
|
|
902
1197
|
children: model.label
|
|
903
1198
|
}, undefined, false, undefined, this)
|
|
904
1199
|
]
|
|
905
1200
|
}, undefined, true, undefined, this),
|
|
906
|
-
/* @__PURE__ */
|
|
1201
|
+
/* @__PURE__ */ jsxDEV4("p", {
|
|
907
1202
|
className: "absolute-voice-provider-status__description",
|
|
908
1203
|
children: model.description
|
|
909
1204
|
}, undefined, false, undefined, this),
|
|
910
|
-
model.providers.length ? /* @__PURE__ */
|
|
1205
|
+
model.providers.length ? /* @__PURE__ */ jsxDEV4("div", {
|
|
911
1206
|
className: "absolute-voice-provider-status__providers",
|
|
912
|
-
children: model.providers.map((provider) => /* @__PURE__ */
|
|
1207
|
+
children: model.providers.map((provider) => /* @__PURE__ */ jsxDEV4("article", {
|
|
913
1208
|
className: [
|
|
914
1209
|
"absolute-voice-provider-status__provider",
|
|
915
1210
|
`absolute-voice-provider-status__provider--${provider.status}`
|
|
916
1211
|
].join(" "),
|
|
917
1212
|
children: [
|
|
918
|
-
/* @__PURE__ */
|
|
1213
|
+
/* @__PURE__ */ jsxDEV4("header", {
|
|
919
1214
|
children: [
|
|
920
|
-
/* @__PURE__ */
|
|
1215
|
+
/* @__PURE__ */ jsxDEV4("strong", {
|
|
921
1216
|
children: provider.label
|
|
922
1217
|
}, undefined, false, undefined, this),
|
|
923
|
-
/* @__PURE__ */
|
|
1218
|
+
/* @__PURE__ */ jsxDEV4("span", {
|
|
924
1219
|
children: provider.status
|
|
925
1220
|
}, undefined, false, undefined, this)
|
|
926
1221
|
]
|
|
927
1222
|
}, undefined, true, undefined, this),
|
|
928
|
-
/* @__PURE__ */
|
|
1223
|
+
/* @__PURE__ */ jsxDEV4("p", {
|
|
929
1224
|
children: provider.detail
|
|
930
1225
|
}, undefined, false, undefined, this),
|
|
931
|
-
/* @__PURE__ */
|
|
932
|
-
children: provider.rows.map((row) => /* @__PURE__ */
|
|
1226
|
+
/* @__PURE__ */ jsxDEV4("dl", {
|
|
1227
|
+
children: provider.rows.map((row) => /* @__PURE__ */ jsxDEV4("div", {
|
|
933
1228
|
children: [
|
|
934
|
-
/* @__PURE__ */
|
|
1229
|
+
/* @__PURE__ */ jsxDEV4("dt", {
|
|
935
1230
|
children: row.label
|
|
936
1231
|
}, undefined, false, undefined, this),
|
|
937
|
-
/* @__PURE__ */
|
|
1232
|
+
/* @__PURE__ */ jsxDEV4("dd", {
|
|
938
1233
|
children: row.value
|
|
939
1234
|
}, undefined, false, undefined, this)
|
|
940
1235
|
]
|
|
@@ -942,11 +1237,11 @@ var VoiceProviderStatus = ({
|
|
|
942
1237
|
}, undefined, false, undefined, this)
|
|
943
1238
|
]
|
|
944
1239
|
}, provider.provider, true, undefined, this))
|
|
945
|
-
}, undefined, false, undefined, this) : /* @__PURE__ */
|
|
1240
|
+
}, undefined, false, undefined, this) : /* @__PURE__ */ jsxDEV4("p", {
|
|
946
1241
|
className: "absolute-voice-provider-status__empty",
|
|
947
1242
|
children: "Run voice traffic to see provider health."
|
|
948
1243
|
}, undefined, false, undefined, this),
|
|
949
|
-
model.error ? /* @__PURE__ */
|
|
1244
|
+
model.error ? /* @__PURE__ */ jsxDEV4("p", {
|
|
950
1245
|
className: "absolute-voice-provider-status__error",
|
|
951
1246
|
children: model.error
|
|
952
1247
|
}, undefined, false, undefined, this) : null
|
|
@@ -954,7 +1249,7 @@ var VoiceProviderStatus = ({
|
|
|
954
1249
|
}, undefined, true, undefined, this);
|
|
955
1250
|
};
|
|
956
1251
|
// src/react/useVoiceRoutingStatus.tsx
|
|
957
|
-
import { useEffect as
|
|
1252
|
+
import { useEffect as useEffect5, useRef as useRef5, useSyncExternalStore as useSyncExternalStore5 } from "react";
|
|
958
1253
|
|
|
959
1254
|
// src/client/routingStatus.ts
|
|
960
1255
|
var fetchVoiceRoutingStatus = async (path = "/api/routing/latest", options = {}) => {
|
|
@@ -1038,25 +1333,25 @@ var createVoiceRoutingStatusStore = (path = "/api/routing/latest", options = {})
|
|
|
1038
1333
|
|
|
1039
1334
|
// src/react/useVoiceRoutingStatus.tsx
|
|
1040
1335
|
var useVoiceRoutingStatus = (path = "/api/routing/latest", options = {}) => {
|
|
1041
|
-
const storeRef =
|
|
1336
|
+
const storeRef = useRef5(null);
|
|
1042
1337
|
if (!storeRef.current) {
|
|
1043
1338
|
storeRef.current = createVoiceRoutingStatusStore(path, options);
|
|
1044
1339
|
}
|
|
1045
1340
|
const store = storeRef.current;
|
|
1046
|
-
|
|
1341
|
+
useEffect5(() => {
|
|
1047
1342
|
store.refresh().catch(() => {});
|
|
1048
1343
|
return () => store.close();
|
|
1049
1344
|
}, [store]);
|
|
1050
1345
|
return {
|
|
1051
|
-
...
|
|
1346
|
+
...useSyncExternalStore5(store.subscribe, store.getSnapshot, store.getServerSnapshot),
|
|
1052
1347
|
refresh: store.refresh
|
|
1053
1348
|
};
|
|
1054
1349
|
};
|
|
1055
1350
|
|
|
1056
1351
|
// src/client/routingStatusWidget.ts
|
|
1057
|
-
var
|
|
1058
|
-
var
|
|
1059
|
-
var
|
|
1352
|
+
var DEFAULT_TITLE4 = "Voice Routing";
|
|
1353
|
+
var DEFAULT_DESCRIPTION4 = "Latest provider routing decision from the self-hosted trace store.";
|
|
1354
|
+
var escapeHtml5 = (value) => value.replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">").replaceAll('"', """).replaceAll("'", "'");
|
|
1060
1355
|
var formatValue = (value, fallback = "None") => typeof value === "string" && value.trim() ? value : typeof value === "number" && Number.isFinite(value) ? String(value) : fallback;
|
|
1061
1356
|
var createVoiceRoutingStatusViewModel = (snapshot, options = {}) => {
|
|
1062
1357
|
const decision = snapshot.decision;
|
|
@@ -1080,30 +1375,30 @@ var createVoiceRoutingStatusViewModel = (snapshot, options = {}) => {
|
|
|
1080
1375
|
] : [];
|
|
1081
1376
|
return {
|
|
1082
1377
|
decision,
|
|
1083
|
-
description: options.description ??
|
|
1378
|
+
description: options.description ?? DEFAULT_DESCRIPTION4,
|
|
1084
1379
|
error: snapshot.error,
|
|
1085
1380
|
isLoading: snapshot.isLoading,
|
|
1086
1381
|
label: snapshot.error ? "Unavailable" : decision ? `${formatValue(decision.kind).toUpperCase()} ${formatValue(decision.status, "unknown")}` : snapshot.isLoading ? "Checking" : "No routing yet",
|
|
1087
1382
|
rows,
|
|
1088
1383
|
status: snapshot.error ? "error" : decision ? "ready" : snapshot.isLoading ? "loading" : "empty",
|
|
1089
|
-
title: options.title ??
|
|
1384
|
+
title: options.title ?? DEFAULT_TITLE4,
|
|
1090
1385
|
updatedAt: snapshot.updatedAt
|
|
1091
1386
|
};
|
|
1092
1387
|
};
|
|
1093
1388
|
var renderVoiceRoutingStatusHTML = (snapshot, options = {}) => {
|
|
1094
1389
|
const model = createVoiceRoutingStatusViewModel(snapshot, options);
|
|
1095
1390
|
const rows = model.rows.length ? `<div class="absolute-voice-routing-status__grid">${model.rows.map((row) => `<div>
|
|
1096
|
-
<span>${
|
|
1097
|
-
<strong>${
|
|
1391
|
+
<span>${escapeHtml5(row.label)}</span>
|
|
1392
|
+
<strong>${escapeHtml5(row.value)}</strong>
|
|
1098
1393
|
</div>`).join("")}</div>` : '<p class="absolute-voice-routing-status__empty">Start a voice session to see the selected provider.</p>';
|
|
1099
|
-
return `<section class="absolute-voice-routing-status absolute-voice-routing-status--${
|
|
1394
|
+
return `<section class="absolute-voice-routing-status absolute-voice-routing-status--${escapeHtml5(model.status)}">
|
|
1100
1395
|
<header class="absolute-voice-routing-status__header">
|
|
1101
|
-
<span class="absolute-voice-routing-status__eyebrow">${
|
|
1102
|
-
<strong class="absolute-voice-routing-status__label">${
|
|
1396
|
+
<span class="absolute-voice-routing-status__eyebrow">${escapeHtml5(model.title)}</span>
|
|
1397
|
+
<strong class="absolute-voice-routing-status__label">${escapeHtml5(model.label)}</strong>
|
|
1103
1398
|
</header>
|
|
1104
|
-
<p class="absolute-voice-routing-status__description">${
|
|
1399
|
+
<p class="absolute-voice-routing-status__description">${escapeHtml5(model.description)}</p>
|
|
1105
1400
|
${rows}
|
|
1106
|
-
${model.error ? `<p class="absolute-voice-routing-status__error">${
|
|
1401
|
+
${model.error ? `<p class="absolute-voice-routing-status__error">${escapeHtml5(model.error)}</p>` : ""}
|
|
1107
1402
|
</section>`;
|
|
1108
1403
|
};
|
|
1109
1404
|
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}`;
|
|
@@ -1145,7 +1440,7 @@ var defineVoiceRoutingStatusElement = (tagName = "absolute-voice-routing-status"
|
|
|
1145
1440
|
};
|
|
1146
1441
|
|
|
1147
1442
|
// src/react/VoiceRoutingStatus.tsx
|
|
1148
|
-
import { jsxDEV as
|
|
1443
|
+
import { jsxDEV as jsxDEV5 } from "react/jsx-dev-runtime";
|
|
1149
1444
|
var VoiceRoutingStatus = ({
|
|
1150
1445
|
className,
|
|
1151
1446
|
path = "/api/routing/latest",
|
|
@@ -1153,47 +1448,47 @@ var VoiceRoutingStatus = ({
|
|
|
1153
1448
|
}) => {
|
|
1154
1449
|
const snapshot = useVoiceRoutingStatus(path, options);
|
|
1155
1450
|
const model = createVoiceRoutingStatusViewModel(snapshot, options);
|
|
1156
|
-
return /* @__PURE__ */
|
|
1451
|
+
return /* @__PURE__ */ jsxDEV5("section", {
|
|
1157
1452
|
className: [
|
|
1158
1453
|
"absolute-voice-routing-status",
|
|
1159
1454
|
`absolute-voice-routing-status--${model.status}`,
|
|
1160
1455
|
className
|
|
1161
1456
|
].filter(Boolean).join(" "),
|
|
1162
1457
|
children: [
|
|
1163
|
-
/* @__PURE__ */
|
|
1458
|
+
/* @__PURE__ */ jsxDEV5("header", {
|
|
1164
1459
|
className: "absolute-voice-routing-status__header",
|
|
1165
1460
|
children: [
|
|
1166
|
-
/* @__PURE__ */
|
|
1461
|
+
/* @__PURE__ */ jsxDEV5("span", {
|
|
1167
1462
|
className: "absolute-voice-routing-status__eyebrow",
|
|
1168
1463
|
children: model.title
|
|
1169
1464
|
}, undefined, false, undefined, this),
|
|
1170
|
-
/* @__PURE__ */
|
|
1465
|
+
/* @__PURE__ */ jsxDEV5("strong", {
|
|
1171
1466
|
className: "absolute-voice-routing-status__label",
|
|
1172
1467
|
children: model.label
|
|
1173
1468
|
}, undefined, false, undefined, this)
|
|
1174
1469
|
]
|
|
1175
1470
|
}, undefined, true, undefined, this),
|
|
1176
|
-
/* @__PURE__ */
|
|
1471
|
+
/* @__PURE__ */ jsxDEV5("p", {
|
|
1177
1472
|
className: "absolute-voice-routing-status__description",
|
|
1178
1473
|
children: model.description
|
|
1179
1474
|
}, undefined, false, undefined, this),
|
|
1180
|
-
model.rows.length ? /* @__PURE__ */
|
|
1475
|
+
model.rows.length ? /* @__PURE__ */ jsxDEV5("div", {
|
|
1181
1476
|
className: "absolute-voice-routing-status__grid",
|
|
1182
|
-
children: model.rows.map((row) => /* @__PURE__ */
|
|
1477
|
+
children: model.rows.map((row) => /* @__PURE__ */ jsxDEV5("div", {
|
|
1183
1478
|
children: [
|
|
1184
|
-
/* @__PURE__ */
|
|
1479
|
+
/* @__PURE__ */ jsxDEV5("span", {
|
|
1185
1480
|
children: row.label
|
|
1186
1481
|
}, undefined, false, undefined, this),
|
|
1187
|
-
/* @__PURE__ */
|
|
1482
|
+
/* @__PURE__ */ jsxDEV5("strong", {
|
|
1188
1483
|
children: row.value
|
|
1189
1484
|
}, undefined, false, undefined, this)
|
|
1190
1485
|
]
|
|
1191
1486
|
}, row.label, true, undefined, this))
|
|
1192
|
-
}, undefined, false, undefined, this) : /* @__PURE__ */
|
|
1487
|
+
}, undefined, false, undefined, this) : /* @__PURE__ */ jsxDEV5("p", {
|
|
1193
1488
|
className: "absolute-voice-routing-status__empty",
|
|
1194
1489
|
children: "Start a voice session to see the selected provider."
|
|
1195
1490
|
}, undefined, false, undefined, this),
|
|
1196
|
-
model.error ? /* @__PURE__ */
|
|
1491
|
+
model.error ? /* @__PURE__ */ jsxDEV5("p", {
|
|
1197
1492
|
className: "absolute-voice-routing-status__error",
|
|
1198
1493
|
children: model.error
|
|
1199
1494
|
}, undefined, false, undefined, this) : null
|
|
@@ -1201,7 +1496,7 @@ var VoiceRoutingStatus = ({
|
|
|
1201
1496
|
}, undefined, true, undefined, this);
|
|
1202
1497
|
};
|
|
1203
1498
|
// src/react/useVoiceStream.tsx
|
|
1204
|
-
import { useEffect as
|
|
1499
|
+
import { useEffect as useEffect6, useRef as useRef6, useSyncExternalStore as useSyncExternalStore6 } from "react";
|
|
1205
1500
|
|
|
1206
1501
|
// src/client/actions.ts
|
|
1207
1502
|
var normalizeErrorMessage = (value) => {
|
|
@@ -1729,13 +2024,13 @@ var EMPTY_SNAPSHOT = {
|
|
|
1729
2024
|
turns: []
|
|
1730
2025
|
};
|
|
1731
2026
|
var useVoiceStream = (path, options = {}) => {
|
|
1732
|
-
const streamRef =
|
|
2027
|
+
const streamRef = useRef6(null);
|
|
1733
2028
|
if (!streamRef.current) {
|
|
1734
2029
|
streamRef.current = createVoiceStream(path, options);
|
|
1735
2030
|
}
|
|
1736
2031
|
const stream = streamRef.current;
|
|
1737
|
-
|
|
1738
|
-
const snapshot =
|
|
2032
|
+
useEffect6(() => () => stream.close(), [stream]);
|
|
2033
|
+
const snapshot = useSyncExternalStore6(stream.subscribe, stream.getSnapshot, stream.getServerSnapshot) ?? EMPTY_SNAPSHOT;
|
|
1739
2034
|
return {
|
|
1740
2035
|
...snapshot,
|
|
1741
2036
|
callControl: (message) => stream.callControl(message),
|
|
@@ -1745,7 +2040,7 @@ var useVoiceStream = (path, options = {}) => {
|
|
|
1745
2040
|
};
|
|
1746
2041
|
};
|
|
1747
2042
|
// src/react/useVoiceController.tsx
|
|
1748
|
-
import { useEffect as
|
|
2043
|
+
import { useEffect as useEffect7, useRef as useRef7, useSyncExternalStore as useSyncExternalStore7 } from "react";
|
|
1749
2044
|
|
|
1750
2045
|
// src/client/htmx.ts
|
|
1751
2046
|
var DEFAULT_EVENT_NAME = "voice-refresh";
|
|
@@ -2392,13 +2687,13 @@ var EMPTY_SNAPSHOT2 = {
|
|
|
2392
2687
|
turns: []
|
|
2393
2688
|
};
|
|
2394
2689
|
var useVoiceController = (path, options = {}) => {
|
|
2395
|
-
const controllerRef =
|
|
2690
|
+
const controllerRef = useRef7(null);
|
|
2396
2691
|
if (!controllerRef.current) {
|
|
2397
2692
|
controllerRef.current = createVoiceController(path, options);
|
|
2398
2693
|
}
|
|
2399
2694
|
const controller = controllerRef.current;
|
|
2400
|
-
|
|
2401
|
-
const snapshot =
|
|
2695
|
+
useEffect7(() => () => controller.close(), [controller]);
|
|
2696
|
+
const snapshot = useSyncExternalStore7(controller.subscribe, controller.getSnapshot, controller.getServerSnapshot) ?? EMPTY_SNAPSHOT2;
|
|
2402
2697
|
return {
|
|
2403
2698
|
...snapshot,
|
|
2404
2699
|
bindHTMX: controller.bindHTMX,
|
|
@@ -2412,7 +2707,7 @@ var useVoiceController = (path, options = {}) => {
|
|
|
2412
2707
|
};
|
|
2413
2708
|
};
|
|
2414
2709
|
// src/react/useVoiceWorkflowStatus.tsx
|
|
2415
|
-
import { useEffect as
|
|
2710
|
+
import { useEffect as useEffect8, useRef as useRef8, useSyncExternalStore as useSyncExternalStore8 } from "react";
|
|
2416
2711
|
|
|
2417
2712
|
// src/client/workflowStatus.ts
|
|
2418
2713
|
var fetchVoiceWorkflowStatus = async (path = "/evals/scenarios/json", options = {}) => {
|
|
@@ -2495,17 +2790,17 @@ var createVoiceWorkflowStatusStore = (path = "/evals/scenarios/json", options =
|
|
|
2495
2790
|
|
|
2496
2791
|
// src/react/useVoiceWorkflowStatus.tsx
|
|
2497
2792
|
var useVoiceWorkflowStatus = (path = "/evals/scenarios/json", options = {}) => {
|
|
2498
|
-
const storeRef =
|
|
2793
|
+
const storeRef = useRef8(null);
|
|
2499
2794
|
if (!storeRef.current) {
|
|
2500
2795
|
storeRef.current = createVoiceWorkflowStatusStore(path, options);
|
|
2501
2796
|
}
|
|
2502
2797
|
const store = storeRef.current;
|
|
2503
|
-
|
|
2798
|
+
useEffect8(() => {
|
|
2504
2799
|
store.refresh().catch(() => {});
|
|
2505
2800
|
return () => store.close();
|
|
2506
2801
|
}, [store]);
|
|
2507
2802
|
return {
|
|
2508
|
-
...
|
|
2803
|
+
...useSyncExternalStore8(store.subscribe, store.getSnapshot, store.getServerSnapshot),
|
|
2509
2804
|
refresh: store.refresh
|
|
2510
2805
|
};
|
|
2511
2806
|
};
|
|
@@ -2515,10 +2810,12 @@ export {
|
|
|
2515
2810
|
useVoiceRoutingStatus,
|
|
2516
2811
|
useVoiceProviderStatus,
|
|
2517
2812
|
useVoiceProviderSimulationControls,
|
|
2813
|
+
useVoiceProviderCapabilities,
|
|
2518
2814
|
useVoiceController,
|
|
2519
2815
|
useVoiceAppKitStatus,
|
|
2520
2816
|
VoiceRoutingStatus,
|
|
2521
2817
|
VoiceProviderStatus,
|
|
2522
2818
|
VoiceProviderSimulationControls,
|
|
2819
|
+
VoiceProviderCapabilities,
|
|
2523
2820
|
VoiceOpsStatus
|
|
2524
2821
|
};
|