@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.
@@ -656,9 +656,304 @@ var VoiceProviderSimulationControls = ({
656
656
  ]
657
657
  }, undefined, true, undefined, this);
658
658
  };
659
- // src/react/useVoiceProviderStatus.tsx
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("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
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 = useRef3(null);
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
- useEffect3(() => {
1044
+ useEffect4(() => {
750
1045
  store.refresh().catch(() => {});
751
1046
  return () => store.close();
752
1047
  }, [store]);
753
1048
  return {
754
- ...useSyncExternalStore3(store.subscribe, store.getSnapshot, store.getServerSnapshot),
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 DEFAULT_TITLE2 = "Voice Providers";
761
- var DEFAULT_DESCRIPTION2 = "Live provider health, fallback counts, latency, and suppression state from your self-hosted trace store.";
762
- var escapeHtml3 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
763
- var formatProvider = (provider) => provider.split(/[-_\s]+/).filter(Boolean).map((part) => `${part[0]?.toUpperCase() ?? ""}${part.slice(1)}`).join(" ") || provider;
764
- var formatStatus = (status) => status.split("-").map((part) => `${part[0]?.toUpperCase() ?? ""}${part.slice(1)}`).join(" ");
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("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
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 isWarningStatus = (status) => status === "degraded" || status === "rate-limited" || status === "recoverable" || status === "suppressed";
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: `${formatProvider(provider.provider)}${provider.recommended ? " recommended" : ""}`,
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) => isWarningStatus(provider.status)).length;
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 ?? DEFAULT_DESCRIPTION2,
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 ?? DEFAULT_TITLE2,
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--${escapeHtml3(provider.status)}">
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>${escapeHtml3(provider.label)}</strong>
821
- <span>${escapeHtml3(formatStatus(provider.status))}</span>
1115
+ <strong>${escapeHtml4(provider.label)}</strong>
1116
+ <span>${escapeHtml4(formatStatus2(provider.status))}</span>
822
1117
  </header>
823
- <p>${escapeHtml3(provider.detail)}</p>
1118
+ <p>${escapeHtml4(provider.detail)}</p>
824
1119
  <dl>${provider.rows.map((row) => `<div>
825
- <dt>${escapeHtml3(row.label)}</dt>
826
- <dd>${escapeHtml3(row.value)}</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--${escapeHtml3(model.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">${escapeHtml3(model.title)}</span>
832
- <strong class="absolute-voice-provider-status__label">${escapeHtml3(model.label)}</strong>
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">${escapeHtml3(model.description)}</p>
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">${escapeHtml3(model.error)}</p>` : ""}
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 jsxDEV3 } from "react/jsx-dev-runtime";
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__ */ jsxDEV3("section", {
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__ */ jsxDEV3("header", {
1188
+ /* @__PURE__ */ jsxDEV4("header", {
894
1189
  className: "absolute-voice-provider-status__header",
895
1190
  children: [
896
- /* @__PURE__ */ jsxDEV3("span", {
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__ */ jsxDEV3("strong", {
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__ */ jsxDEV3("p", {
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__ */ jsxDEV3("div", {
1205
+ model.providers.length ? /* @__PURE__ */ jsxDEV4("div", {
911
1206
  className: "absolute-voice-provider-status__providers",
912
- children: model.providers.map((provider) => /* @__PURE__ */ jsxDEV3("article", {
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__ */ jsxDEV3("header", {
1213
+ /* @__PURE__ */ jsxDEV4("header", {
919
1214
  children: [
920
- /* @__PURE__ */ jsxDEV3("strong", {
1215
+ /* @__PURE__ */ jsxDEV4("strong", {
921
1216
  children: provider.label
922
1217
  }, undefined, false, undefined, this),
923
- /* @__PURE__ */ jsxDEV3("span", {
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__ */ jsxDEV3("p", {
1223
+ /* @__PURE__ */ jsxDEV4("p", {
929
1224
  children: provider.detail
930
1225
  }, undefined, false, undefined, this),
931
- /* @__PURE__ */ jsxDEV3("dl", {
932
- children: provider.rows.map((row) => /* @__PURE__ */ jsxDEV3("div", {
1226
+ /* @__PURE__ */ jsxDEV4("dl", {
1227
+ children: provider.rows.map((row) => /* @__PURE__ */ jsxDEV4("div", {
933
1228
  children: [
934
- /* @__PURE__ */ jsxDEV3("dt", {
1229
+ /* @__PURE__ */ jsxDEV4("dt", {
935
1230
  children: row.label
936
1231
  }, undefined, false, undefined, this),
937
- /* @__PURE__ */ jsxDEV3("dd", {
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__ */ jsxDEV3("p", {
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__ */ jsxDEV3("p", {
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 useEffect4, useRef as useRef4, useSyncExternalStore as useSyncExternalStore4 } from "react";
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 = useRef4(null);
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
- useEffect4(() => {
1341
+ useEffect5(() => {
1047
1342
  store.refresh().catch(() => {});
1048
1343
  return () => store.close();
1049
1344
  }, [store]);
1050
1345
  return {
1051
- ...useSyncExternalStore4(store.subscribe, store.getSnapshot, store.getServerSnapshot),
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 DEFAULT_TITLE3 = "Voice Routing";
1058
- var DEFAULT_DESCRIPTION3 = "Latest provider routing decision from the self-hosted trace store.";
1059
- var escapeHtml4 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
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("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
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 ?? DEFAULT_DESCRIPTION3,
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 ?? DEFAULT_TITLE3,
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>${escapeHtml4(row.label)}</span>
1097
- <strong>${escapeHtml4(row.value)}</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--${escapeHtml4(model.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">${escapeHtml4(model.title)}</span>
1102
- <strong class="absolute-voice-routing-status__label">${escapeHtml4(model.label)}</strong>
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">${escapeHtml4(model.description)}</p>
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">${escapeHtml4(model.error)}</p>` : ""}
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 jsxDEV4 } from "react/jsx-dev-runtime";
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__ */ jsxDEV4("section", {
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__ */ jsxDEV4("header", {
1458
+ /* @__PURE__ */ jsxDEV5("header", {
1164
1459
  className: "absolute-voice-routing-status__header",
1165
1460
  children: [
1166
- /* @__PURE__ */ jsxDEV4("span", {
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__ */ jsxDEV4("strong", {
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__ */ jsxDEV4("p", {
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__ */ jsxDEV4("div", {
1475
+ model.rows.length ? /* @__PURE__ */ jsxDEV5("div", {
1181
1476
  className: "absolute-voice-routing-status__grid",
1182
- children: model.rows.map((row) => /* @__PURE__ */ jsxDEV4("div", {
1477
+ children: model.rows.map((row) => /* @__PURE__ */ jsxDEV5("div", {
1183
1478
  children: [
1184
- /* @__PURE__ */ jsxDEV4("span", {
1479
+ /* @__PURE__ */ jsxDEV5("span", {
1185
1480
  children: row.label
1186
1481
  }, undefined, false, undefined, this),
1187
- /* @__PURE__ */ jsxDEV4("strong", {
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__ */ jsxDEV4("p", {
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__ */ jsxDEV4("p", {
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 useEffect5, useRef as useRef5, useSyncExternalStore as useSyncExternalStore5 } from "react";
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 = useRef5(null);
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
- useEffect5(() => () => stream.close(), [stream]);
1738
- const snapshot = useSyncExternalStore5(stream.subscribe, stream.getSnapshot, stream.getServerSnapshot) ?? EMPTY_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 useEffect6, useRef as useRef6, useSyncExternalStore as useSyncExternalStore6 } from "react";
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 = useRef6(null);
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
- useEffect6(() => () => controller.close(), [controller]);
2401
- const snapshot = useSyncExternalStore6(controller.subscribe, controller.getSnapshot, controller.getServerSnapshot) ?? EMPTY_SNAPSHOT2;
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 useEffect7, useRef as useRef7, useSyncExternalStore as useSyncExternalStore7 } from "react";
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 = useRef7(null);
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
- useEffect7(() => {
2798
+ useEffect8(() => {
2504
2799
  store.refresh().catch(() => {});
2505
2800
  return () => store.close();
2506
2801
  }, [store]);
2507
2802
  return {
2508
- ...useSyncExternalStore7(store.subscribe, store.getSnapshot, store.getServerSnapshot),
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
  };