@absolutejs/voice 0.0.22-beta.150 → 0.0.22-beta.152

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/vue/index.js CHANGED
@@ -374,8 +374,279 @@ var VoiceOpsStatus = defineComponent({
374
374
  };
375
375
  }
376
376
  });
377
+ // src/vue/VoiceDeliveryRuntime.ts
378
+ import { defineComponent as defineComponent2, h as h2 } from "vue";
379
+
380
+ // src/client/deliveryRuntime.ts
381
+ var fetchVoiceDeliveryRuntime = async (path = "/api/voice-delivery-runtime", options = {}) => {
382
+ const fetchImpl = options.fetch ?? globalThis.fetch;
383
+ const response = await fetchImpl(path);
384
+ if (!response.ok) {
385
+ throw new Error(`Voice delivery runtime failed: HTTP ${response.status}`);
386
+ }
387
+ return await response.json();
388
+ };
389
+ var createVoiceDeliveryRuntimeStore = (path = "/api/voice-delivery-runtime", options = {}) => {
390
+ const listeners = new Set;
391
+ let closed = false;
392
+ let timer;
393
+ let snapshot = {
394
+ error: null,
395
+ isLoading: false
396
+ };
397
+ const emit = () => {
398
+ for (const listener of listeners) {
399
+ listener();
400
+ }
401
+ };
402
+ const refresh = async () => {
403
+ if (closed) {
404
+ return snapshot.report;
405
+ }
406
+ snapshot = {
407
+ ...snapshot,
408
+ error: null,
409
+ isLoading: true
410
+ };
411
+ emit();
412
+ try {
413
+ const report = await fetchVoiceDeliveryRuntime(path, options);
414
+ snapshot = {
415
+ error: null,
416
+ isLoading: false,
417
+ report,
418
+ updatedAt: Date.now()
419
+ };
420
+ emit();
421
+ return report;
422
+ } catch (error) {
423
+ snapshot = {
424
+ ...snapshot,
425
+ error: error instanceof Error ? error.message : String(error),
426
+ isLoading: false
427
+ };
428
+ emit();
429
+ throw error;
430
+ }
431
+ };
432
+ const close = () => {
433
+ closed = true;
434
+ if (timer) {
435
+ clearInterval(timer);
436
+ timer = undefined;
437
+ }
438
+ listeners.clear();
439
+ };
440
+ if (typeof window !== "undefined" && options.intervalMs && options.intervalMs > 0) {
441
+ timer = setInterval(() => {
442
+ refresh().catch(() => {});
443
+ }, options.intervalMs);
444
+ }
445
+ return {
446
+ close,
447
+ getServerSnapshot: () => snapshot,
448
+ getSnapshot: () => snapshot,
449
+ refresh,
450
+ subscribe: (listener) => {
451
+ listeners.add(listener);
452
+ return () => {
453
+ listeners.delete(listener);
454
+ };
455
+ }
456
+ };
457
+ };
458
+
459
+ // src/client/deliveryRuntimeWidget.ts
460
+ var DEFAULT_TITLE2 = "Voice Delivery Runtime";
461
+ var DEFAULT_DESCRIPTION2 = "Audit and trace delivery worker health from your AbsoluteJS voice app.";
462
+ var escapeHtml2 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
463
+ var createSurface = (id, summary) => {
464
+ if (!summary) {
465
+ return {
466
+ deadLettered: 0,
467
+ detail: "Worker disabled",
468
+ failed: 0,
469
+ id,
470
+ label: id === "audit" ? "Audit delivery" : "Trace delivery",
471
+ pending: 0,
472
+ status: "disabled",
473
+ total: 0
474
+ };
475
+ }
476
+ const blocked = summary.failed + summary.deadLettered;
477
+ return {
478
+ deadLettered: summary.deadLettered,
479
+ detail: `${summary.delivered}/${summary.total} delivered, ${summary.pending} pending`,
480
+ failed: summary.failed,
481
+ id,
482
+ label: id === "audit" ? "Audit delivery" : "Trace delivery",
483
+ pending: summary.pending,
484
+ status: blocked > 0 ? "warn" : "pass",
485
+ total: summary.total
486
+ };
487
+ };
488
+ var createVoiceDeliveryRuntimeViewModel = (snapshot, options = {}) => {
489
+ const report = snapshot.report;
490
+ const surfaces = [
491
+ createSurface("audit", report?.summary.audit),
492
+ createSurface("trace", report?.summary.trace)
493
+ ];
494
+ const hasWarnings = surfaces.some((surface) => surface.status === "warn");
495
+ return {
496
+ description: options.description ?? DEFAULT_DESCRIPTION2,
497
+ error: snapshot.error,
498
+ isLoading: snapshot.isLoading,
499
+ isRunning: Boolean(report?.isRunning),
500
+ label: snapshot.error ? "Unavailable" : report ? report.isRunning ? "Running" : "Stopped" : "Checking",
501
+ status: snapshot.error ? "error" : report ? hasWarnings ? "warn" : "pass" : "loading",
502
+ surfaces,
503
+ title: options.title ?? DEFAULT_TITLE2,
504
+ updatedAt: snapshot.updatedAt
505
+ };
506
+ };
507
+ var renderVoiceDeliveryRuntimeHTML = (snapshot, options = {}) => {
508
+ const model = createVoiceDeliveryRuntimeViewModel(snapshot, options);
509
+ const surfaces = model.surfaces.map((surface) => `<li class="absolute-voice-delivery-runtime__surface absolute-voice-delivery-runtime__surface--${escapeHtml2(surface.status)}">
510
+ <span>${escapeHtml2(surface.label)}</span>
511
+ <strong>${escapeHtml2(surface.detail)}</strong>
512
+ <small>${String(surface.failed)} failed &middot; ${String(surface.deadLettered)} dead-lettered</small>
513
+ </li>`).join("");
514
+ return `<section class="absolute-voice-delivery-runtime absolute-voice-delivery-runtime--${escapeHtml2(model.status)}">
515
+ <header class="absolute-voice-delivery-runtime__header">
516
+ <span class="absolute-voice-delivery-runtime__eyebrow">${escapeHtml2(model.title)}</span>
517
+ <strong class="absolute-voice-delivery-runtime__label">${escapeHtml2(model.label)}</strong>
518
+ </header>
519
+ <p class="absolute-voice-delivery-runtime__description">${escapeHtml2(model.description)}</p>
520
+ <ul class="absolute-voice-delivery-runtime__surfaces">${surfaces}</ul>
521
+ ${model.error ? `<p class="absolute-voice-delivery-runtime__error">${escapeHtml2(model.error)}</p>` : ""}
522
+ </section>`;
523
+ };
524
+ var getVoiceDeliveryRuntimeCSS = () => `.absolute-voice-delivery-runtime{border:1px solid #c9d8cf;border-radius:20px;background:#f6fff9;color:#0d1b12;padding:18px;box-shadow:0 18px 40px rgba(19,55,35,.12);font-family:inherit}.absolute-voice-delivery-runtime--warn,.absolute-voice-delivery-runtime--error{border-color:#f2b56b;background:#fff9ed}.absolute-voice-delivery-runtime__header{align-items:start;display:flex;gap:12px;justify-content:space-between}.absolute-voice-delivery-runtime__eyebrow{color:#4e6b59;font-size:12px;font-weight:800;letter-spacing:.08em;text-transform:uppercase}.absolute-voice-delivery-runtime__label{font-size:28px;line-height:1}.absolute-voice-delivery-runtime__description{color:#33483b;margin:12px 0 0}.absolute-voice-delivery-runtime__surfaces{display:grid;gap:8px;list-style:none;margin:16px 0 0;padding:0}.absolute-voice-delivery-runtime__surface{background:#fff;border:1px solid #d9eadf;border-radius:14px;display:grid;gap:4px;padding:10px 12px}.absolute-voice-delivery-runtime__surface--warn{border-color:#f2b56b}.absolute-voice-delivery-runtime__surface--disabled{opacity:.72}.absolute-voice-delivery-runtime__surface span,.absolute-voice-delivery-runtime__surface small{color:#587063}.absolute-voice-delivery-runtime__error{color:#9f1239;font-weight:700}`;
525
+ var mountVoiceDeliveryRuntime = (element, path = "/api/voice-delivery-runtime", options = {}) => {
526
+ const store = createVoiceDeliveryRuntimeStore(path, options);
527
+ const render = () => {
528
+ element.innerHTML = renderVoiceDeliveryRuntimeHTML(store.getSnapshot(), options);
529
+ };
530
+ const unsubscribe = store.subscribe(render);
531
+ render();
532
+ store.refresh().catch(() => {});
533
+ return {
534
+ close: () => {
535
+ unsubscribe();
536
+ store.close();
537
+ },
538
+ refresh: store.refresh
539
+ };
540
+ };
541
+ var defineVoiceDeliveryRuntimeElement = (tagName = "absolute-voice-delivery-runtime") => {
542
+ if (typeof window === "undefined" || typeof customElements === "undefined" || customElements.get(tagName)) {
543
+ return;
544
+ }
545
+ customElements.define(tagName, class AbsoluteVoiceDeliveryRuntimeElement extends HTMLElement {
546
+ mounted;
547
+ connectedCallback() {
548
+ const intervalMs = Number(this.getAttribute("interval-ms") ?? 5000);
549
+ this.mounted = mountVoiceDeliveryRuntime(this, this.getAttribute("path") ?? "/api/voice-delivery-runtime", {
550
+ description: this.getAttribute("description") ?? undefined,
551
+ intervalMs: Number.isFinite(intervalMs) ? intervalMs : 5000,
552
+ title: this.getAttribute("title") ?? undefined
553
+ });
554
+ }
555
+ disconnectedCallback() {
556
+ this.mounted?.close();
557
+ this.mounted = undefined;
558
+ }
559
+ });
560
+ };
561
+
562
+ // src/vue/useVoiceDeliveryRuntime.ts
563
+ import { onUnmounted as onUnmounted2, ref as ref2, shallowRef as shallowRef2 } from "vue";
564
+ function useVoiceDeliveryRuntime(path = "/api/voice-delivery-runtime", options = {}) {
565
+ const store = createVoiceDeliveryRuntimeStore(path, options);
566
+ const error = ref2(null);
567
+ const isLoading = ref2(false);
568
+ const report = shallowRef2(undefined);
569
+ const updatedAt = ref2(undefined);
570
+ const sync = () => {
571
+ const snapshot = store.getSnapshot();
572
+ error.value = snapshot.error;
573
+ isLoading.value = snapshot.isLoading;
574
+ report.value = snapshot.report;
575
+ updatedAt.value = snapshot.updatedAt;
576
+ };
577
+ const unsubscribe = store.subscribe(sync);
578
+ sync();
579
+ if (typeof window !== "undefined") {
580
+ store.refresh().catch(() => {});
581
+ }
582
+ onUnmounted2(() => {
583
+ unsubscribe();
584
+ store.close();
585
+ });
586
+ return {
587
+ error,
588
+ isLoading,
589
+ refresh: store.refresh,
590
+ report,
591
+ updatedAt
592
+ };
593
+ }
594
+
595
+ // src/vue/VoiceDeliveryRuntime.ts
596
+ var VoiceDeliveryRuntime = defineComponent2({
597
+ name: "VoiceDeliveryRuntime",
598
+ props: {
599
+ description: String,
600
+ intervalMs: Number,
601
+ path: {
602
+ default: "/api/voice-delivery-runtime",
603
+ type: String
604
+ },
605
+ title: String
606
+ },
607
+ setup(props) {
608
+ const options = {
609
+ description: props.description,
610
+ intervalMs: props.intervalMs,
611
+ title: props.title
612
+ };
613
+ const runtime = useVoiceDeliveryRuntime(props.path, options);
614
+ return () => {
615
+ const model = createVoiceDeliveryRuntimeViewModel({
616
+ error: runtime.error.value,
617
+ isLoading: runtime.isLoading.value,
618
+ report: runtime.report.value,
619
+ updatedAt: runtime.updatedAt.value
620
+ }, options);
621
+ return h2("section", {
622
+ class: [
623
+ "absolute-voice-delivery-runtime",
624
+ `absolute-voice-delivery-runtime--${model.status}`
625
+ ]
626
+ }, [
627
+ h2("header", { class: "absolute-voice-delivery-runtime__header" }, [
628
+ h2("span", { class: "absolute-voice-delivery-runtime__eyebrow" }, model.title),
629
+ h2("strong", { class: "absolute-voice-delivery-runtime__label" }, model.label)
630
+ ]),
631
+ h2("p", { class: "absolute-voice-delivery-runtime__description" }, model.description),
632
+ h2("ul", { class: "absolute-voice-delivery-runtime__surfaces" }, model.surfaces.map((surface) => h2("li", {
633
+ class: [
634
+ "absolute-voice-delivery-runtime__surface",
635
+ `absolute-voice-delivery-runtime__surface--${surface.status}`
636
+ ],
637
+ key: surface.id
638
+ }, [
639
+ h2("span", surface.label),
640
+ h2("strong", surface.detail),
641
+ h2("small", `${surface.failed} failed / ${surface.deadLettered} dead-lettered`)
642
+ ]))),
643
+ model.error ? h2("p", { class: "absolute-voice-delivery-runtime__error" }, model.error) : null
644
+ ]);
645
+ };
646
+ }
647
+ });
377
648
  // src/vue/VoiceProviderSimulationControls.ts
378
- import { computed, defineComponent as defineComponent2, h as h2 } from "vue";
649
+ import { computed, defineComponent as defineComponent3, h as h3 } from "vue";
379
650
 
380
651
  // src/client/providerSimulationControls.ts
381
652
  var postSimulation = async (pathPrefix, mode, provider, fetchImpl) => {
@@ -457,7 +728,7 @@ var createVoiceProviderSimulationControlsStore = (options) => {
457
728
  };
458
729
 
459
730
  // src/client/providerSimulationControlsWidget.ts
460
- var escapeHtml2 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
731
+ var escapeHtml3 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
461
732
  var formatKind = (kind) => (kind ?? "stt").toUpperCase();
462
733
  var createVoiceProviderSimulationControlsViewModel = (snapshot, options) => {
463
734
  const configuredProviders = options.providers.filter((provider) => provider.configured !== false);
@@ -477,18 +748,18 @@ var createVoiceProviderSimulationControlsViewModel = (snapshot, options) => {
477
748
  };
478
749
  var renderVoiceProviderSimulationControlsHTML = (snapshot, options) => {
479
750
  const model = createVoiceProviderSimulationControlsViewModel(snapshot, options);
480
- const failureButtons = model.failureProviders.map((provider) => `<button type="button" data-voice-provider-fail="${escapeHtml2(provider.provider)}"${!model.canSimulateFailure || snapshot.isRunning ? " disabled" : ""}>Simulate ${escapeHtml2(provider.provider)} ${escapeHtml2(formatKind(options.kind))} failure</button>`).join("");
481
- const recoveryButtons = model.providers.map((provider) => `<button type="button" data-voice-provider-recover="${escapeHtml2(provider.provider)}"${snapshot.isRunning ? " disabled" : ""}>Mark ${escapeHtml2(provider.provider)} recovered</button>`).join("");
751
+ const failureButtons = model.failureProviders.map((provider) => `<button type="button" data-voice-provider-fail="${escapeHtml3(provider.provider)}"${!model.canSimulateFailure || snapshot.isRunning ? " disabled" : ""}>Simulate ${escapeHtml3(provider.provider)} ${escapeHtml3(formatKind(options.kind))} failure</button>`).join("");
752
+ const recoveryButtons = model.providers.map((provider) => `<button type="button" data-voice-provider-recover="${escapeHtml3(provider.provider)}"${snapshot.isRunning ? " disabled" : ""}>Mark ${escapeHtml3(provider.provider)} recovered</button>`).join("");
482
753
  return `<section class="absolute-voice-provider-simulation absolute-voice-provider-simulation--${snapshot.error ? "error" : snapshot.isRunning ? "running" : "ready"}">
483
754
  <header class="absolute-voice-provider-simulation__header">
484
- <span class="absolute-voice-provider-simulation__eyebrow">${escapeHtml2(model.title)}</span>
485
- <strong class="absolute-voice-provider-simulation__label">${escapeHtml2(model.label)}</strong>
755
+ <span class="absolute-voice-provider-simulation__eyebrow">${escapeHtml3(model.title)}</span>
756
+ <strong class="absolute-voice-provider-simulation__label">${escapeHtml3(model.label)}</strong>
486
757
  </header>
487
- <p class="absolute-voice-provider-simulation__description">${escapeHtml2(model.description)}</p>
488
- ${model.canSimulateFailure ? "" : `<p class="absolute-voice-provider-simulation__empty">${escapeHtml2(options.fallbackRequiredMessage ?? "Configure fallback providers before simulating failure.")}</p>`}
758
+ <p class="absolute-voice-provider-simulation__description">${escapeHtml3(model.description)}</p>
759
+ ${model.canSimulateFailure ? "" : `<p class="absolute-voice-provider-simulation__empty">${escapeHtml3(options.fallbackRequiredMessage ?? "Configure fallback providers before simulating failure.")}</p>`}
489
760
  <div class="absolute-voice-provider-simulation__actions">${failureButtons}${recoveryButtons}</div>
490
- ${snapshot.error ? `<p class="absolute-voice-provider-simulation__error">${escapeHtml2(snapshot.error)}</p>` : ""}
491
- ${model.resultText ? `<pre class="absolute-voice-provider-simulation__result">${escapeHtml2(model.resultText)}</pre>` : ""}
761
+ ${snapshot.error ? `<p class="absolute-voice-provider-simulation__error">${escapeHtml3(snapshot.error)}</p>` : ""}
762
+ ${model.resultText ? `<pre class="absolute-voice-provider-simulation__result">${escapeHtml3(model.resultText)}</pre>` : ""}
492
763
  </section>`;
493
764
  };
494
765
  var bindVoiceProviderSimulationControls = (element, store) => {
@@ -554,15 +825,15 @@ var defineVoiceProviderSimulationControlsElement = (tagName = "absolute-voice-pr
554
825
  };
555
826
 
556
827
  // src/vue/useVoiceProviderSimulationControls.ts
557
- import { onUnmounted as onUnmounted2, ref as ref2 } from "vue";
828
+ import { onUnmounted as onUnmounted3, ref as ref3 } from "vue";
558
829
  function useVoiceProviderSimulationControls(options) {
559
830
  const store = createVoiceProviderSimulationControlsStore(options);
560
- const error = ref2(null);
561
- const isRunning = ref2(false);
562
- const lastResult = ref2(null);
563
- const mode = ref2(null);
564
- const provider = ref2(null);
565
- const updatedAt = ref2(undefined);
831
+ const error = ref3(null);
832
+ const isRunning = ref3(false);
833
+ const lastResult = ref3(null);
834
+ const mode = ref3(null);
835
+ const provider = ref3(null);
836
+ const updatedAt = ref3(undefined);
566
837
  const sync = () => {
567
838
  const snapshot = store.getSnapshot();
568
839
  error.value = snapshot.error;
@@ -574,7 +845,7 @@ function useVoiceProviderSimulationControls(options) {
574
845
  };
575
846
  const unsubscribe = store.subscribe(sync);
576
847
  sync();
577
- onUnmounted2(() => {
848
+ onUnmounted3(() => {
578
849
  unsubscribe();
579
850
  store.close();
580
851
  });
@@ -590,7 +861,7 @@ function useVoiceProviderSimulationControls(options) {
590
861
  }
591
862
 
592
863
  // src/vue/VoiceProviderSimulationControls.ts
593
- var VoiceProviderSimulationControls = defineComponent2({
864
+ var VoiceProviderSimulationControls = defineComponent3({
594
865
  name: "VoiceProviderSimulationControls",
595
866
  props: {
596
867
  class: { default: "", type: String },
@@ -632,40 +903,40 @@ var VoiceProviderSimulationControls = defineComponent2({
632
903
  const run = (provider, mode) => {
633
904
  controls.run(provider, mode).catch(() => {});
634
905
  };
635
- return () => h2("section", {
906
+ return () => h3("section", {
636
907
  class: [
637
908
  "absolute-voice-provider-simulation",
638
909
  `absolute-voice-provider-simulation--${controls.error.value ? "error" : controls.isRunning.value ? "running" : "ready"}`,
639
910
  props.class
640
911
  ]
641
912
  }, [
642
- h2("header", { class: "absolute-voice-provider-simulation__header" }, [
643
- h2("span", { class: "absolute-voice-provider-simulation__eyebrow" }, model.value.title),
644
- h2("strong", { class: "absolute-voice-provider-simulation__label" }, model.value.label)
913
+ h3("header", { class: "absolute-voice-provider-simulation__header" }, [
914
+ h3("span", { class: "absolute-voice-provider-simulation__eyebrow" }, model.value.title),
915
+ h3("strong", { class: "absolute-voice-provider-simulation__label" }, model.value.label)
645
916
  ]),
646
- h2("p", { class: "absolute-voice-provider-simulation__description" }, model.value.description),
647
- model.value.canSimulateFailure ? null : h2("p", { class: "absolute-voice-provider-simulation__empty" }, props.fallbackRequiredMessage ?? "Configure fallback providers before simulating failure."),
648
- h2("div", { class: "absolute-voice-provider-simulation__actions" }, [
649
- ...model.value.failureProviders.map((provider) => h2("button", {
917
+ h3("p", { class: "absolute-voice-provider-simulation__description" }, model.value.description),
918
+ model.value.canSimulateFailure ? null : h3("p", { class: "absolute-voice-provider-simulation__empty" }, props.fallbackRequiredMessage ?? "Configure fallback providers before simulating failure."),
919
+ h3("div", { class: "absolute-voice-provider-simulation__actions" }, [
920
+ ...model.value.failureProviders.map((provider) => h3("button", {
650
921
  disabled: !model.value.canSimulateFailure || controls.isRunning.value,
651
922
  key: `fail-${provider.provider}`,
652
923
  onClick: () => run(provider.provider, "failure"),
653
924
  type: "button"
654
925
  }, `Simulate ${provider.provider} ${props.kind.toUpperCase()} failure`)),
655
- ...model.value.providers.map((provider) => h2("button", {
926
+ ...model.value.providers.map((provider) => h3("button", {
656
927
  disabled: controls.isRunning.value,
657
928
  key: `recover-${provider.provider}`,
658
929
  onClick: () => run(provider.provider, "recovery"),
659
930
  type: "button"
660
931
  }, `Mark ${provider.provider} recovered`))
661
932
  ]),
662
- controls.error.value ? h2("p", { class: "absolute-voice-provider-simulation__error" }, controls.error.value) : null,
663
- model.value.resultText ? h2("pre", { class: "absolute-voice-provider-simulation__result" }, model.value.resultText) : null
933
+ controls.error.value ? h3("p", { class: "absolute-voice-provider-simulation__error" }, controls.error.value) : null,
934
+ model.value.resultText ? h3("pre", { class: "absolute-voice-provider-simulation__result" }, model.value.resultText) : null
664
935
  ]);
665
936
  }
666
937
  });
667
938
  // src/vue/VoiceProviderCapabilities.ts
668
- import { computed as computed2, defineComponent as defineComponent3, h as h3 } from "vue";
939
+ import { computed as computed2, defineComponent as defineComponent4, h as h4 } from "vue";
669
940
 
670
941
  // src/client/providerCapabilities.ts
671
942
  var fetchVoiceProviderCapabilities = async (path = "/api/provider-capabilities", options = {}) => {
@@ -747,9 +1018,9 @@ var createVoiceProviderCapabilitiesStore = (path = "/api/provider-capabilities",
747
1018
  };
748
1019
 
749
1020
  // src/client/providerCapabilitiesWidget.ts
750
- var DEFAULT_TITLE2 = "Provider Capabilities";
751
- var DEFAULT_DESCRIPTION2 = "Configured, selected, and healthy voice providers for this deployment.";
752
- var escapeHtml3 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
1021
+ var DEFAULT_TITLE3 = "Provider Capabilities";
1022
+ var DEFAULT_DESCRIPTION3 = "Configured, selected, and healthy voice providers for this deployment.";
1023
+ var escapeHtml4 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
753
1024
  var formatProvider = (provider) => provider.split(/[-_\s]+/).filter(Boolean).map((part) => `${part[0]?.toUpperCase() ?? ""}${part.slice(1)}`).join(" ") || provider;
754
1025
  var formatKind2 = (kind) => kind.toUpperCase();
755
1026
  var formatStatus = (status) => status.split("-").map((part) => `${part[0]?.toUpperCase() ?? ""}${part.slice(1)}`).join(" ");
@@ -793,36 +1064,36 @@ var createVoiceProviderCapabilitiesViewModel = (snapshot, options = {}) => {
793
1064
  const selectedCount = snapshot.report?.selected ?? capabilities.filter((capability) => capability.selected).length;
794
1065
  return {
795
1066
  capabilities,
796
- description: options.description ?? DEFAULT_DESCRIPTION2,
1067
+ description: options.description ?? DEFAULT_DESCRIPTION3,
797
1068
  error: snapshot.error,
798
1069
  isLoading: snapshot.isLoading,
799
1070
  label: snapshot.error ? "Unavailable" : capabilities.length ? warningCount > 0 ? `${warningCount} needs attention` : `${selectedCount} selected` : snapshot.isLoading ? "Checking" : "No capabilities",
800
1071
  status: snapshot.error ? "error" : capabilities.length ? warningCount > 0 ? "warning" : "ready" : snapshot.isLoading ? "loading" : "empty",
801
- title: options.title ?? DEFAULT_TITLE2,
1072
+ title: options.title ?? DEFAULT_TITLE3,
802
1073
  updatedAt: snapshot.updatedAt
803
1074
  };
804
1075
  };
805
1076
  var renderVoiceProviderCapabilitiesHTML = (snapshot, options = {}) => {
806
1077
  const model = createVoiceProviderCapabilitiesViewModel(snapshot, options);
807
- 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)}">
1078
+ 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--${escapeHtml4(capability.status)}">
808
1079
  <header>
809
- <strong>${escapeHtml3(capability.label)}</strong>
810
- <span>${escapeHtml3(formatStatus(capability.status))}</span>
1080
+ <strong>${escapeHtml4(capability.label)}</strong>
1081
+ <span>${escapeHtml4(formatStatus(capability.status))}</span>
811
1082
  </header>
812
- <p>${escapeHtml3(capability.detail)}</p>
1083
+ <p>${escapeHtml4(capability.detail)}</p>
813
1084
  <dl>${capability.rows.map((row) => `<div>
814
- <dt>${escapeHtml3(row.label)}</dt>
815
- <dd>${escapeHtml3(row.value)}</dd>
1085
+ <dt>${escapeHtml4(row.label)}</dt>
1086
+ <dd>${escapeHtml4(row.value)}</dd>
816
1087
  </div>`).join("")}</dl>
817
1088
  </article>`).join("")}</div>` : '<p class="absolute-voice-provider-capabilities__empty">Configure provider capabilities to see deployment coverage.</p>';
818
- return `<section class="absolute-voice-provider-capabilities absolute-voice-provider-capabilities--${escapeHtml3(model.status)}">
1089
+ return `<section class="absolute-voice-provider-capabilities absolute-voice-provider-capabilities--${escapeHtml4(model.status)}">
819
1090
  <header class="absolute-voice-provider-capabilities__header">
820
- <span class="absolute-voice-provider-capabilities__eyebrow">${escapeHtml3(model.title)}</span>
821
- <strong class="absolute-voice-provider-capabilities__label">${escapeHtml3(model.label)}</strong>
1091
+ <span class="absolute-voice-provider-capabilities__eyebrow">${escapeHtml4(model.title)}</span>
1092
+ <strong class="absolute-voice-provider-capabilities__label">${escapeHtml4(model.label)}</strong>
822
1093
  </header>
823
- <p class="absolute-voice-provider-capabilities__description">${escapeHtml3(model.description)}</p>
1094
+ <p class="absolute-voice-provider-capabilities__description">${escapeHtml4(model.description)}</p>
824
1095
  ${capabilities}
825
- ${model.error ? `<p class="absolute-voice-provider-capabilities__error">${escapeHtml3(model.error)}</p>` : ""}
1096
+ ${model.error ? `<p class="absolute-voice-provider-capabilities__error">${escapeHtml4(model.error)}</p>` : ""}
826
1097
  </section>`;
827
1098
  };
828
1099
  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}`;
@@ -864,13 +1135,13 @@ var defineVoiceProviderCapabilitiesElement = (tagName = "absolute-voice-provider
864
1135
  };
865
1136
 
866
1137
  // src/vue/useVoiceProviderCapabilities.ts
867
- import { onUnmounted as onUnmounted3, shallowRef as shallowRef2 } from "vue";
1138
+ import { onUnmounted as onUnmounted4, shallowRef as shallowRef3 } from "vue";
868
1139
  function useVoiceProviderCapabilities(path = "/api/provider-capabilities", options = {}) {
869
1140
  const store = createVoiceProviderCapabilitiesStore(path, options);
870
- const error = shallowRef2(null);
871
- const isLoading = shallowRef2(false);
872
- const report = shallowRef2();
873
- const updatedAt = shallowRef2(undefined);
1141
+ const error = shallowRef3(null);
1142
+ const isLoading = shallowRef3(false);
1143
+ const report = shallowRef3();
1144
+ const updatedAt = shallowRef3(undefined);
874
1145
  const sync = () => {
875
1146
  const snapshot = store.getSnapshot();
876
1147
  error.value = snapshot.error;
@@ -881,7 +1152,7 @@ function useVoiceProviderCapabilities(path = "/api/provider-capabilities", optio
881
1152
  const unsubscribe = store.subscribe(sync);
882
1153
  sync();
883
1154
  store.refresh().catch(() => {});
884
- onUnmounted3(() => {
1155
+ onUnmounted4(() => {
885
1156
  unsubscribe();
886
1157
  store.close();
887
1158
  });
@@ -895,7 +1166,7 @@ function useVoiceProviderCapabilities(path = "/api/provider-capabilities", optio
895
1166
  }
896
1167
 
897
1168
  // src/vue/VoiceProviderCapabilities.ts
898
- var VoiceProviderCapabilities = defineComponent3({
1169
+ var VoiceProviderCapabilities = defineComponent4({
899
1170
  name: "VoiceProviderCapabilities",
900
1171
  props: {
901
1172
  class: {
@@ -932,41 +1203,41 @@ var VoiceProviderCapabilities = defineComponent3({
932
1203
  report: capabilities.report.value,
933
1204
  updatedAt: capabilities.updatedAt.value
934
1205
  }, options));
935
- return () => h3("section", {
1206
+ return () => h4("section", {
936
1207
  class: [
937
1208
  "absolute-voice-provider-capabilities",
938
1209
  `absolute-voice-provider-capabilities--${model.value.status}`,
939
1210
  props.class
940
1211
  ]
941
1212
  }, [
942
- h3("header", { class: "absolute-voice-provider-capabilities__header" }, [
943
- h3("span", { class: "absolute-voice-provider-capabilities__eyebrow" }, model.value.title),
944
- h3("strong", { class: "absolute-voice-provider-capabilities__label" }, model.value.label)
1213
+ h4("header", { class: "absolute-voice-provider-capabilities__header" }, [
1214
+ h4("span", { class: "absolute-voice-provider-capabilities__eyebrow" }, model.value.title),
1215
+ h4("strong", { class: "absolute-voice-provider-capabilities__label" }, model.value.label)
945
1216
  ]),
946
- h3("p", { class: "absolute-voice-provider-capabilities__description" }, model.value.description),
947
- model.value.capabilities.length ? h3("div", { class: "absolute-voice-provider-capabilities__providers" }, model.value.capabilities.map((capability) => h3("article", {
1217
+ h4("p", { class: "absolute-voice-provider-capabilities__description" }, model.value.description),
1218
+ model.value.capabilities.length ? h4("div", { class: "absolute-voice-provider-capabilities__providers" }, model.value.capabilities.map((capability) => h4("article", {
948
1219
  class: [
949
1220
  "absolute-voice-provider-capabilities__provider",
950
1221
  `absolute-voice-provider-capabilities__provider--${capability.status}`
951
1222
  ],
952
1223
  key: `${capability.kind}:${capability.provider}`
953
1224
  }, [
954
- h3("header", [
955
- h3("strong", capability.label),
956
- h3("span", capability.status)
1225
+ h4("header", [
1226
+ h4("strong", capability.label),
1227
+ h4("span", capability.status)
957
1228
  ]),
958
- h3("p", capability.detail),
959
- h3("dl", capability.rows.map((row) => h3("div", { key: row.label }, [
960
- h3("dt", row.label),
961
- h3("dd", row.value)
1229
+ h4("p", capability.detail),
1230
+ h4("dl", capability.rows.map((row) => h4("div", { key: row.label }, [
1231
+ h4("dt", row.label),
1232
+ h4("dd", row.value)
962
1233
  ])))
963
- ]))) : h3("p", { class: "absolute-voice-provider-capabilities__empty" }, "Configure provider capabilities to see deployment coverage."),
964
- model.value.error ? h3("p", { class: "absolute-voice-provider-capabilities__error" }, model.value.error) : null
1234
+ ]))) : h4("p", { class: "absolute-voice-provider-capabilities__empty" }, "Configure provider capabilities to see deployment coverage."),
1235
+ model.value.error ? h4("p", { class: "absolute-voice-provider-capabilities__error" }, model.value.error) : null
965
1236
  ]);
966
1237
  }
967
1238
  });
968
1239
  // src/vue/VoiceProviderStatus.ts
969
- import { computed as computed3, defineComponent as defineComponent4, h as h4 } from "vue";
1240
+ import { computed as computed3, defineComponent as defineComponent5, h as h5 } from "vue";
970
1241
 
971
1242
  // src/client/providerStatus.ts
972
1243
  var fetchVoiceProviderStatus = async (path = "/api/provider-status", options = {}) => {
@@ -1049,9 +1320,9 @@ var createVoiceProviderStatusStore = (path = "/api/provider-status", options = {
1049
1320
  };
1050
1321
 
1051
1322
  // src/client/providerStatusWidget.ts
1052
- var DEFAULT_TITLE3 = "Voice Providers";
1053
- var DEFAULT_DESCRIPTION3 = "Live provider health, fallback counts, latency, and suppression state from your self-hosted trace store.";
1054
- var escapeHtml4 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
1323
+ var DEFAULT_TITLE4 = "Voice Providers";
1324
+ var DEFAULT_DESCRIPTION4 = "Live provider health, fallback counts, latency, and suppression state from your self-hosted trace store.";
1325
+ var escapeHtml5 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
1055
1326
  var formatProvider2 = (provider) => provider.split(/[-_\s]+/).filter(Boolean).map((part) => `${part[0]?.toUpperCase() ?? ""}${part.slice(1)}`).join(" ") || provider;
1056
1327
  var formatStatus2 = (status) => status.split("-").map((part) => `${part[0]?.toUpperCase() ?? ""}${part.slice(1)}`).join(" ");
1057
1328
  var formatLatency = (value) => typeof value === "number" ? `${value}ms` : "No samples";
@@ -1095,37 +1366,37 @@ var createVoiceProviderStatusViewModel = (snapshot, options = {}) => {
1095
1366
  const warningCount = providers.filter((provider) => isWarningStatus2(provider.status)).length;
1096
1367
  const healthyCount = providers.filter((provider) => provider.status === "healthy").length;
1097
1368
  return {
1098
- description: options.description ?? DEFAULT_DESCRIPTION3,
1369
+ description: options.description ?? DEFAULT_DESCRIPTION4,
1099
1370
  error: snapshot.error,
1100
1371
  isLoading: snapshot.isLoading,
1101
1372
  label: snapshot.error ? "Unavailable" : providers.length ? warningCount > 0 ? `${warningCount} needs attention` : `${healthyCount} healthy` : snapshot.isLoading ? "Checking" : "No provider traffic",
1102
1373
  providers,
1103
1374
  status: snapshot.error ? "error" : providers.length ? warningCount > 0 ? "warning" : "ready" : snapshot.isLoading ? "loading" : "empty",
1104
- title: options.title ?? DEFAULT_TITLE3,
1375
+ title: options.title ?? DEFAULT_TITLE4,
1105
1376
  updatedAt: snapshot.updatedAt
1106
1377
  };
1107
1378
  };
1108
1379
  var renderVoiceProviderStatusHTML = (snapshot, options = {}) => {
1109
1380
  const model = createVoiceProviderStatusViewModel(snapshot, options);
1110
- 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)}">
1381
+ 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--${escapeHtml5(provider.status)}">
1111
1382
  <header>
1112
- <strong>${escapeHtml4(provider.label)}</strong>
1113
- <span>${escapeHtml4(formatStatus2(provider.status))}</span>
1383
+ <strong>${escapeHtml5(provider.label)}</strong>
1384
+ <span>${escapeHtml5(formatStatus2(provider.status))}</span>
1114
1385
  </header>
1115
- <p>${escapeHtml4(provider.detail)}</p>
1386
+ <p>${escapeHtml5(provider.detail)}</p>
1116
1387
  <dl>${provider.rows.map((row) => `<div>
1117
- <dt>${escapeHtml4(row.label)}</dt>
1118
- <dd>${escapeHtml4(row.value)}</dd>
1388
+ <dt>${escapeHtml5(row.label)}</dt>
1389
+ <dd>${escapeHtml5(row.value)}</dd>
1119
1390
  </div>`).join("")}</dl>
1120
1391
  </article>`).join("")}</div>` : '<p class="absolute-voice-provider-status__empty">Run voice traffic to see provider health.</p>';
1121
- return `<section class="absolute-voice-provider-status absolute-voice-provider-status--${escapeHtml4(model.status)}">
1392
+ return `<section class="absolute-voice-provider-status absolute-voice-provider-status--${escapeHtml5(model.status)}">
1122
1393
  <header class="absolute-voice-provider-status__header">
1123
- <span class="absolute-voice-provider-status__eyebrow">${escapeHtml4(model.title)}</span>
1124
- <strong class="absolute-voice-provider-status__label">${escapeHtml4(model.label)}</strong>
1394
+ <span class="absolute-voice-provider-status__eyebrow">${escapeHtml5(model.title)}</span>
1395
+ <strong class="absolute-voice-provider-status__label">${escapeHtml5(model.label)}</strong>
1125
1396
  </header>
1126
- <p class="absolute-voice-provider-status__description">${escapeHtml4(model.description)}</p>
1397
+ <p class="absolute-voice-provider-status__description">${escapeHtml5(model.description)}</p>
1127
1398
  ${providers}
1128
- ${model.error ? `<p class="absolute-voice-provider-status__error">${escapeHtml4(model.error)}</p>` : ""}
1399
+ ${model.error ? `<p class="absolute-voice-provider-status__error">${escapeHtml5(model.error)}</p>` : ""}
1129
1400
  </section>`;
1130
1401
  };
1131
1402
  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}`;
@@ -1167,13 +1438,13 @@ var defineVoiceProviderStatusElement = (tagName = "absolute-voice-provider-statu
1167
1438
  };
1168
1439
 
1169
1440
  // src/vue/useVoiceProviderStatus.ts
1170
- import { onUnmounted as onUnmounted4, ref as ref3, shallowRef as shallowRef3 } from "vue";
1441
+ import { onUnmounted as onUnmounted5, ref as ref4, shallowRef as shallowRef4 } from "vue";
1171
1442
  function useVoiceProviderStatus(path = "/api/provider-status", options = {}) {
1172
1443
  const store = createVoiceProviderStatusStore(path, options);
1173
- const error = ref3(null);
1174
- const isLoading = ref3(false);
1175
- const providers = shallowRef3([]);
1176
- const updatedAt = ref3(undefined);
1444
+ const error = ref4(null);
1445
+ const isLoading = ref4(false);
1446
+ const providers = shallowRef4([]);
1447
+ const updatedAt = ref4(undefined);
1177
1448
  const sync = () => {
1178
1449
  const snapshot = store.getSnapshot();
1179
1450
  error.value = snapshot.error;
@@ -1184,7 +1455,7 @@ function useVoiceProviderStatus(path = "/api/provider-status", options = {}) {
1184
1455
  const unsubscribe = store.subscribe(sync);
1185
1456
  sync();
1186
1457
  store.refresh().catch(() => {});
1187
- onUnmounted4(() => {
1458
+ onUnmounted5(() => {
1188
1459
  unsubscribe();
1189
1460
  store.close();
1190
1461
  });
@@ -1198,7 +1469,7 @@ function useVoiceProviderStatus(path = "/api/provider-status", options = {}) {
1198
1469
  }
1199
1470
 
1200
1471
  // src/vue/VoiceProviderStatus.ts
1201
- var VoiceProviderStatus = defineComponent4({
1472
+ var VoiceProviderStatus = defineComponent5({
1202
1473
  name: "VoiceProviderStatus",
1203
1474
  props: {
1204
1475
  class: {
@@ -1235,41 +1506,41 @@ var VoiceProviderStatus = defineComponent4({
1235
1506
  providers: status.providers.value,
1236
1507
  updatedAt: status.updatedAt.value
1237
1508
  }, options));
1238
- return () => h4("section", {
1509
+ return () => h5("section", {
1239
1510
  class: [
1240
1511
  "absolute-voice-provider-status",
1241
1512
  `absolute-voice-provider-status--${model.value.status}`,
1242
1513
  props.class
1243
1514
  ]
1244
1515
  }, [
1245
- h4("header", { class: "absolute-voice-provider-status__header" }, [
1246
- h4("span", { class: "absolute-voice-provider-status__eyebrow" }, model.value.title),
1247
- h4("strong", { class: "absolute-voice-provider-status__label" }, model.value.label)
1516
+ h5("header", { class: "absolute-voice-provider-status__header" }, [
1517
+ h5("span", { class: "absolute-voice-provider-status__eyebrow" }, model.value.title),
1518
+ h5("strong", { class: "absolute-voice-provider-status__label" }, model.value.label)
1248
1519
  ]),
1249
- h4("p", { class: "absolute-voice-provider-status__description" }, model.value.description),
1250
- model.value.providers.length ? h4("div", { class: "absolute-voice-provider-status__providers" }, model.value.providers.map((provider) => h4("article", {
1520
+ h5("p", { class: "absolute-voice-provider-status__description" }, model.value.description),
1521
+ model.value.providers.length ? h5("div", { class: "absolute-voice-provider-status__providers" }, model.value.providers.map((provider) => h5("article", {
1251
1522
  class: [
1252
1523
  "absolute-voice-provider-status__provider",
1253
1524
  `absolute-voice-provider-status__provider--${provider.status}`
1254
1525
  ],
1255
1526
  key: provider.provider
1256
1527
  }, [
1257
- h4("header", [
1258
- h4("strong", provider.label),
1259
- h4("span", provider.status)
1528
+ h5("header", [
1529
+ h5("strong", provider.label),
1530
+ h5("span", provider.status)
1260
1531
  ]),
1261
- h4("p", provider.detail),
1262
- h4("dl", provider.rows.map((row) => h4("div", { key: row.label }, [
1263
- h4("dt", row.label),
1264
- h4("dd", row.value)
1532
+ h5("p", provider.detail),
1533
+ h5("dl", provider.rows.map((row) => h5("div", { key: row.label }, [
1534
+ h5("dt", row.label),
1535
+ h5("dd", row.value)
1265
1536
  ])))
1266
- ]))) : h4("p", { class: "absolute-voice-provider-status__empty" }, "Run voice traffic to see provider health."),
1267
- model.value.error ? h4("p", { class: "absolute-voice-provider-status__error" }, model.value.error) : null
1537
+ ]))) : h5("p", { class: "absolute-voice-provider-status__empty" }, "Run voice traffic to see provider health."),
1538
+ model.value.error ? h5("p", { class: "absolute-voice-provider-status__error" }, model.value.error) : null
1268
1539
  ]);
1269
1540
  }
1270
1541
  });
1271
1542
  // src/vue/VoiceRoutingStatus.ts
1272
- import { computed as computed4, defineComponent as defineComponent5, h as h5 } from "vue";
1543
+ import { computed as computed4, defineComponent as defineComponent6, h as h6 } from "vue";
1273
1544
 
1274
1545
  // src/client/routingStatus.ts
1275
1546
  var fetchVoiceRoutingStatus = async (path = "/api/routing/latest", options = {}) => {
@@ -1352,9 +1623,9 @@ var createVoiceRoutingStatusStore = (path = "/api/routing/latest", options = {})
1352
1623
  };
1353
1624
 
1354
1625
  // src/client/routingStatusWidget.ts
1355
- var DEFAULT_TITLE4 = "Voice Routing";
1356
- var DEFAULT_DESCRIPTION4 = "Latest provider routing decision from the self-hosted trace store.";
1357
- var escapeHtml5 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
1626
+ var DEFAULT_TITLE5 = "Voice Routing";
1627
+ var DEFAULT_DESCRIPTION5 = "Latest provider routing decision from the self-hosted trace store.";
1628
+ var escapeHtml6 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
1358
1629
  var formatValue = (value, fallback = "None") => typeof value === "string" && value.trim() ? value : typeof value === "number" && Number.isFinite(value) ? String(value) : fallback;
1359
1630
  var createVoiceRoutingStatusViewModel = (snapshot, options = {}) => {
1360
1631
  const decision = snapshot.decision;
@@ -1378,30 +1649,30 @@ var createVoiceRoutingStatusViewModel = (snapshot, options = {}) => {
1378
1649
  ] : [];
1379
1650
  return {
1380
1651
  decision,
1381
- description: options.description ?? DEFAULT_DESCRIPTION4,
1652
+ description: options.description ?? DEFAULT_DESCRIPTION5,
1382
1653
  error: snapshot.error,
1383
1654
  isLoading: snapshot.isLoading,
1384
1655
  label: snapshot.error ? "Unavailable" : decision ? `${formatValue(decision.kind).toUpperCase()} ${formatValue(decision.status, "unknown")}` : snapshot.isLoading ? "Checking" : "No routing yet",
1385
1656
  rows,
1386
1657
  status: snapshot.error ? "error" : decision ? "ready" : snapshot.isLoading ? "loading" : "empty",
1387
- title: options.title ?? DEFAULT_TITLE4,
1658
+ title: options.title ?? DEFAULT_TITLE5,
1388
1659
  updatedAt: snapshot.updatedAt
1389
1660
  };
1390
1661
  };
1391
1662
  var renderVoiceRoutingStatusHTML = (snapshot, options = {}) => {
1392
1663
  const model = createVoiceRoutingStatusViewModel(snapshot, options);
1393
1664
  const rows = model.rows.length ? `<div class="absolute-voice-routing-status__grid">${model.rows.map((row) => `<div>
1394
- <span>${escapeHtml5(row.label)}</span>
1395
- <strong>${escapeHtml5(row.value)}</strong>
1665
+ <span>${escapeHtml6(row.label)}</span>
1666
+ <strong>${escapeHtml6(row.value)}</strong>
1396
1667
  </div>`).join("")}</div>` : '<p class="absolute-voice-routing-status__empty">Start a voice session to see the selected provider.</p>';
1397
- return `<section class="absolute-voice-routing-status absolute-voice-routing-status--${escapeHtml5(model.status)}">
1668
+ return `<section class="absolute-voice-routing-status absolute-voice-routing-status--${escapeHtml6(model.status)}">
1398
1669
  <header class="absolute-voice-routing-status__header">
1399
- <span class="absolute-voice-routing-status__eyebrow">${escapeHtml5(model.title)}</span>
1400
- <strong class="absolute-voice-routing-status__label">${escapeHtml5(model.label)}</strong>
1670
+ <span class="absolute-voice-routing-status__eyebrow">${escapeHtml6(model.title)}</span>
1671
+ <strong class="absolute-voice-routing-status__label">${escapeHtml6(model.label)}</strong>
1401
1672
  </header>
1402
- <p class="absolute-voice-routing-status__description">${escapeHtml5(model.description)}</p>
1673
+ <p class="absolute-voice-routing-status__description">${escapeHtml6(model.description)}</p>
1403
1674
  ${rows}
1404
- ${model.error ? `<p class="absolute-voice-routing-status__error">${escapeHtml5(model.error)}</p>` : ""}
1675
+ ${model.error ? `<p class="absolute-voice-routing-status__error">${escapeHtml6(model.error)}</p>` : ""}
1405
1676
  </section>`;
1406
1677
  };
1407
1678
  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}`;
@@ -1443,13 +1714,13 @@ var defineVoiceRoutingStatusElement = (tagName = "absolute-voice-routing-status"
1443
1714
  };
1444
1715
 
1445
1716
  // src/vue/useVoiceRoutingStatus.ts
1446
- import { onUnmounted as onUnmounted5, ref as ref4, shallowRef as shallowRef4 } from "vue";
1717
+ import { onUnmounted as onUnmounted6, ref as ref5, shallowRef as shallowRef5 } from "vue";
1447
1718
  function useVoiceRoutingStatus(path = "/api/routing/latest", options = {}) {
1448
1719
  const store = createVoiceRoutingStatusStore(path, options);
1449
- const decision = shallowRef4(null);
1450
- const error = ref4(null);
1451
- const isLoading = ref4(false);
1452
- const updatedAt = ref4(undefined);
1720
+ const decision = shallowRef5(null);
1721
+ const error = ref5(null);
1722
+ const isLoading = ref5(false);
1723
+ const updatedAt = ref5(undefined);
1453
1724
  const sync = () => {
1454
1725
  const snapshot = store.getSnapshot();
1455
1726
  decision.value = snapshot.decision;
@@ -1460,7 +1731,7 @@ function useVoiceRoutingStatus(path = "/api/routing/latest", options = {}) {
1460
1731
  const unsubscribe = store.subscribe(sync);
1461
1732
  sync();
1462
1733
  store.refresh().catch(() => {});
1463
- onUnmounted5(() => {
1734
+ onUnmounted6(() => {
1464
1735
  unsubscribe();
1465
1736
  store.close();
1466
1737
  });
@@ -1474,7 +1745,7 @@ function useVoiceRoutingStatus(path = "/api/routing/latest", options = {}) {
1474
1745
  }
1475
1746
 
1476
1747
  // src/vue/VoiceRoutingStatus.ts
1477
- var VoiceRoutingStatus = defineComponent5({
1748
+ var VoiceRoutingStatus = defineComponent6({
1478
1749
  name: "VoiceRoutingStatus",
1479
1750
  props: {
1480
1751
  class: {
@@ -1511,28 +1782,28 @@ var VoiceRoutingStatus = defineComponent5({
1511
1782
  isLoading: status.isLoading.value,
1512
1783
  updatedAt: status.updatedAt.value
1513
1784
  }, options));
1514
- return () => h5("section", {
1785
+ return () => h6("section", {
1515
1786
  class: [
1516
1787
  "absolute-voice-routing-status",
1517
1788
  `absolute-voice-routing-status--${model.value.status}`,
1518
1789
  props.class
1519
1790
  ]
1520
1791
  }, [
1521
- h5("header", { class: "absolute-voice-routing-status__header" }, [
1522
- h5("span", { class: "absolute-voice-routing-status__eyebrow" }, model.value.title),
1523
- h5("strong", { class: "absolute-voice-routing-status__label" }, model.value.label)
1792
+ h6("header", { class: "absolute-voice-routing-status__header" }, [
1793
+ h6("span", { class: "absolute-voice-routing-status__eyebrow" }, model.value.title),
1794
+ h6("strong", { class: "absolute-voice-routing-status__label" }, model.value.label)
1524
1795
  ]),
1525
- h5("p", { class: "absolute-voice-routing-status__description" }, model.value.description),
1526
- model.value.rows.length ? h5("div", { class: "absolute-voice-routing-status__grid" }, model.value.rows.map((row) => h5("div", { key: row.label }, [
1527
- h5("span", row.label),
1528
- h5("strong", row.value)
1529
- ]))) : h5("p", { class: "absolute-voice-routing-status__empty" }, "Start a voice session to see the selected provider."),
1530
- model.value.error ? h5("p", { class: "absolute-voice-routing-status__error" }, model.value.error) : null
1796
+ h6("p", { class: "absolute-voice-routing-status__description" }, model.value.description),
1797
+ model.value.rows.length ? h6("div", { class: "absolute-voice-routing-status__grid" }, model.value.rows.map((row) => h6("div", { key: row.label }, [
1798
+ h6("span", row.label),
1799
+ h6("strong", row.value)
1800
+ ]))) : h6("p", { class: "absolute-voice-routing-status__empty" }, "Start a voice session to see the selected provider."),
1801
+ model.value.error ? h6("p", { class: "absolute-voice-routing-status__error" }, model.value.error) : null
1531
1802
  ]);
1532
1803
  }
1533
1804
  });
1534
1805
  // src/vue/VoiceTurnLatency.ts
1535
- import { computed as computed5, defineComponent as defineComponent6, h as h6 } from "vue";
1806
+ import { computed as computed5, defineComponent as defineComponent7, h as h7 } from "vue";
1536
1807
 
1537
1808
  // src/client/turnLatency.ts
1538
1809
  var fetchVoiceTurnLatency = async (path = "/api/turn-latency", options = {}) => {
@@ -1638,10 +1909,10 @@ var createVoiceTurnLatencyStore = (path = "/api/turn-latency", options = {}) =>
1638
1909
  };
1639
1910
 
1640
1911
  // src/client/turnLatencyWidget.ts
1641
- var DEFAULT_TITLE5 = "Turn Latency";
1642
- var DEFAULT_DESCRIPTION5 = "Per-turn timing from first transcript to commit and assistant response start.";
1912
+ var DEFAULT_TITLE6 = "Turn Latency";
1913
+ var DEFAULT_DESCRIPTION6 = "Per-turn timing from first transcript to commit and assistant response start.";
1643
1914
  var DEFAULT_PROOF_LABEL = "Run latency proof";
1644
- var escapeHtml6 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
1915
+ var escapeHtml7 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
1645
1916
  var formatMs = (value) => typeof value === "number" ? `${Math.round(value)}ms` : "n/a";
1646
1917
  var createVoiceTurnLatencyViewModel = (snapshot, options = {}) => {
1647
1918
  const turns = (snapshot.report?.turns ?? []).map((turn) => ({
@@ -1655,39 +1926,39 @@ var createVoiceTurnLatencyViewModel = (snapshot, options = {}) => {
1655
1926
  const warningCount = snapshot.report?.warnings ?? turns.filter((turn) => turn.status === "warn").length;
1656
1927
  const failedCount = snapshot.report?.failed ?? turns.filter((turn) => turn.status === "fail").length;
1657
1928
  return {
1658
- description: options.description ?? DEFAULT_DESCRIPTION5,
1929
+ description: options.description ?? DEFAULT_DESCRIPTION6,
1659
1930
  error: snapshot.error,
1660
1931
  isLoading: snapshot.isLoading,
1661
1932
  label: snapshot.error ? "Unavailable" : turns.length ? failedCount > 0 ? `${failedCount} slow` : warningCount > 0 ? `${warningCount} warnings` : `avg ${formatMs(snapshot.report?.averageTotalMs)}` : snapshot.isLoading ? "Checking" : "No turns",
1662
1933
  proofLabel: options.proofPath ? options.proofLabel ?? DEFAULT_PROOF_LABEL : undefined,
1663
1934
  showProofAction: Boolean(options.proofPath),
1664
1935
  status: snapshot.error ? "error" : turns.length ? failedCount > 0 || warningCount > 0 ? "warning" : "ready" : snapshot.isLoading ? "loading" : "empty",
1665
- title: options.title ?? DEFAULT_TITLE5,
1936
+ title: options.title ?? DEFAULT_TITLE6,
1666
1937
  turns,
1667
1938
  updatedAt: snapshot.updatedAt
1668
1939
  };
1669
1940
  };
1670
1941
  var renderVoiceTurnLatencyHTML = (snapshot, options = {}) => {
1671
1942
  const model = createVoiceTurnLatencyViewModel(snapshot, options);
1672
- const turns = model.turns.length ? `<div class="absolute-voice-turn-latency__turns">${model.turns.map((turn) => `<article class="absolute-voice-turn-latency__turn absolute-voice-turn-latency__turn--${escapeHtml6(turn.status)}">
1943
+ const turns = model.turns.length ? `<div class="absolute-voice-turn-latency__turns">${model.turns.map((turn) => `<article class="absolute-voice-turn-latency__turn absolute-voice-turn-latency__turn--${escapeHtml7(turn.status)}">
1673
1944
  <header>
1674
- <strong>${escapeHtml6(turn.label)}</strong>
1675
- <span>${escapeHtml6(turn.status)}</span>
1945
+ <strong>${escapeHtml7(turn.label)}</strong>
1946
+ <span>${escapeHtml7(turn.status)}</span>
1676
1947
  </header>
1677
1948
  <dl>${turn.rows.map((row) => `<div>
1678
- <dt>${escapeHtml6(row.label)}</dt>
1679
- <dd>${escapeHtml6(row.value)}</dd>
1949
+ <dt>${escapeHtml7(row.label)}</dt>
1950
+ <dd>${escapeHtml7(row.value)}</dd>
1680
1951
  </div>`).join("")}</dl>
1681
1952
  </article>`).join("")}</div>` : '<p class="absolute-voice-turn-latency__empty">Complete a voice turn to see latency diagnostics.</p>';
1682
- return `<section class="absolute-voice-turn-latency absolute-voice-turn-latency--${escapeHtml6(model.status)}">
1953
+ return `<section class="absolute-voice-turn-latency absolute-voice-turn-latency--${escapeHtml7(model.status)}">
1683
1954
  <header class="absolute-voice-turn-latency__header">
1684
- <span class="absolute-voice-turn-latency__eyebrow">${escapeHtml6(model.title)}</span>
1685
- <strong class="absolute-voice-turn-latency__label">${escapeHtml6(model.label)}</strong>
1955
+ <span class="absolute-voice-turn-latency__eyebrow">${escapeHtml7(model.title)}</span>
1956
+ <strong class="absolute-voice-turn-latency__label">${escapeHtml7(model.label)}</strong>
1686
1957
  </header>
1687
- <p class="absolute-voice-turn-latency__description">${escapeHtml6(model.description)}</p>
1688
- ${model.showProofAction ? `<button class="absolute-voice-turn-latency__proof" data-absolute-voice-turn-latency-proof type="button">${escapeHtml6(model.proofLabel ?? DEFAULT_PROOF_LABEL)}</button>` : ""}
1958
+ <p class="absolute-voice-turn-latency__description">${escapeHtml7(model.description)}</p>
1959
+ ${model.showProofAction ? `<button class="absolute-voice-turn-latency__proof" data-absolute-voice-turn-latency-proof type="button">${escapeHtml7(model.proofLabel ?? DEFAULT_PROOF_LABEL)}</button>` : ""}
1689
1960
  ${turns}
1690
- ${model.error ? `<p class="absolute-voice-turn-latency__error">${escapeHtml6(model.error)}</p>` : ""}
1961
+ ${model.error ? `<p class="absolute-voice-turn-latency__error">${escapeHtml7(model.error)}</p>` : ""}
1691
1962
  </section>`;
1692
1963
  };
1693
1964
  var mountVoiceTurnLatency = (element, path = "/api/turn-latency", options = {}) => {
@@ -1738,13 +2009,13 @@ var defineVoiceTurnLatencyElement = (tagName = "absolute-voice-turn-latency") =>
1738
2009
  };
1739
2010
 
1740
2011
  // src/vue/useVoiceTurnLatency.ts
1741
- import { onUnmounted as onUnmounted6, shallowRef as shallowRef5 } from "vue";
2012
+ import { onUnmounted as onUnmounted7, shallowRef as shallowRef6 } from "vue";
1742
2013
  function useVoiceTurnLatency(path = "/api/turn-latency", options = {}) {
1743
2014
  const store = createVoiceTurnLatencyStore(path, options);
1744
- const error = shallowRef5(null);
1745
- const isLoading = shallowRef5(false);
1746
- const report = shallowRef5();
1747
- const updatedAt = shallowRef5(undefined);
2015
+ const error = shallowRef6(null);
2016
+ const isLoading = shallowRef6(false);
2017
+ const report = shallowRef6();
2018
+ const updatedAt = shallowRef6(undefined);
1748
2019
  const sync = () => {
1749
2020
  const snapshot = store.getSnapshot();
1750
2021
  error.value = snapshot.error;
@@ -1755,7 +2026,7 @@ function useVoiceTurnLatency(path = "/api/turn-latency", options = {}) {
1755
2026
  const unsubscribe = store.subscribe(sync);
1756
2027
  sync();
1757
2028
  store.refresh().catch(() => {});
1758
- onUnmounted6(() => {
2029
+ onUnmounted7(() => {
1759
2030
  unsubscribe();
1760
2031
  store.close();
1761
2032
  });
@@ -1770,7 +2041,7 @@ function useVoiceTurnLatency(path = "/api/turn-latency", options = {}) {
1770
2041
  }
1771
2042
 
1772
2043
  // src/vue/VoiceTurnLatency.ts
1773
- var VoiceTurnLatency = defineComponent6({
2044
+ var VoiceTurnLatency = defineComponent7({
1774
2045
  name: "VoiceTurnLatency",
1775
2046
  props: {
1776
2047
  class: { default: "", type: String },
@@ -1796,47 +2067,47 @@ var VoiceTurnLatency = defineComponent6({
1796
2067
  report: latency.report.value,
1797
2068
  updatedAt: latency.updatedAt.value
1798
2069
  }, options));
1799
- return () => h6("section", {
2070
+ return () => h7("section", {
1800
2071
  class: [
1801
2072
  "absolute-voice-turn-latency",
1802
2073
  `absolute-voice-turn-latency--${model.value.status}`,
1803
2074
  props.class
1804
2075
  ]
1805
2076
  }, [
1806
- h6("header", { class: "absolute-voice-turn-latency__header" }, [
1807
- h6("span", { class: "absolute-voice-turn-latency__eyebrow" }, model.value.title),
1808
- h6("strong", { class: "absolute-voice-turn-latency__label" }, model.value.label)
2077
+ h7("header", { class: "absolute-voice-turn-latency__header" }, [
2078
+ h7("span", { class: "absolute-voice-turn-latency__eyebrow" }, model.value.title),
2079
+ h7("strong", { class: "absolute-voice-turn-latency__label" }, model.value.label)
1809
2080
  ]),
1810
- h6("p", { class: "absolute-voice-turn-latency__description" }, model.value.description),
1811
- model.value.showProofAction ? h6("button", {
2081
+ h7("p", { class: "absolute-voice-turn-latency__description" }, model.value.description),
2082
+ model.value.showProofAction ? h7("button", {
1812
2083
  class: "absolute-voice-turn-latency__proof",
1813
2084
  onClick: () => {
1814
2085
  latency.runProof().catch(() => {});
1815
2086
  },
1816
2087
  type: "button"
1817
2088
  }, model.value.proofLabel) : null,
1818
- model.value.turns.length ? h6("div", { class: "absolute-voice-turn-latency__turns" }, model.value.turns.map((turn) => h6("article", {
2089
+ model.value.turns.length ? h7("div", { class: "absolute-voice-turn-latency__turns" }, model.value.turns.map((turn) => h7("article", {
1819
2090
  class: [
1820
2091
  "absolute-voice-turn-latency__turn",
1821
2092
  `absolute-voice-turn-latency__turn--${turn.status}`
1822
2093
  ],
1823
2094
  key: `${turn.sessionId}:${turn.turnId}`
1824
2095
  }, [
1825
- h6("header", [
1826
- h6("strong", turn.label),
1827
- h6("span", turn.status)
2096
+ h7("header", [
2097
+ h7("strong", turn.label),
2098
+ h7("span", turn.status)
1828
2099
  ]),
1829
- h6("dl", turn.rows.map((row) => h6("div", { key: row.label }, [
1830
- h6("dt", row.label),
1831
- h6("dd", row.value)
2100
+ h7("dl", turn.rows.map((row) => h7("div", { key: row.label }, [
2101
+ h7("dt", row.label),
2102
+ h7("dd", row.value)
1832
2103
  ])))
1833
- ]))) : h6("p", { class: "absolute-voice-turn-latency__empty" }, "Complete a voice turn to see latency diagnostics."),
1834
- model.value.error ? h6("p", { class: "absolute-voice-turn-latency__error" }, model.value.error) : null
2104
+ ]))) : h7("p", { class: "absolute-voice-turn-latency__empty" }, "Complete a voice turn to see latency diagnostics."),
2105
+ model.value.error ? h7("p", { class: "absolute-voice-turn-latency__error" }, model.value.error) : null
1835
2106
  ]);
1836
2107
  }
1837
2108
  });
1838
2109
  // src/vue/VoiceTurnQuality.ts
1839
- import { computed as computed6, defineComponent as defineComponent7, h as h7 } from "vue";
2110
+ import { computed as computed6, defineComponent as defineComponent8, h as h8 } from "vue";
1840
2111
 
1841
2112
  // src/client/turnQuality.ts
1842
2113
  var fetchVoiceTurnQuality = async (path = "/api/turn-quality", options = {}) => {
@@ -1918,9 +2189,9 @@ var createVoiceTurnQualityStore = (path = "/api/turn-quality", options = {}) =>
1918
2189
  };
1919
2190
 
1920
2191
  // src/client/turnQualityWidget.ts
1921
- var DEFAULT_TITLE6 = "Turn Quality";
1922
- var DEFAULT_DESCRIPTION6 = "Per-turn STT confidence, fallback selection, corrections, and transcript coverage.";
1923
- var escapeHtml7 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
2192
+ var DEFAULT_TITLE7 = "Turn Quality";
2193
+ var DEFAULT_DESCRIPTION7 = "Per-turn STT confidence, fallback selection, corrections, and transcript coverage.";
2194
+ var escapeHtml8 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
1924
2195
  var formatConfidence = (value) => typeof value === "number" ? `${Math.round(value * 100)}%` : "n/a";
1925
2196
  var formatMaybe = (value) => value === undefined || value === "" ? "n/a" : String(value);
1926
2197
  var getTurnDetail = (turn) => {
@@ -1958,37 +2229,37 @@ var createVoiceTurnQualityViewModel = (snapshot, options = {}) => {
1958
2229
  const warningCount = snapshot.report?.warnings ?? turns.filter((turn) => turn.status === "warn").length;
1959
2230
  const failedCount = snapshot.report?.failed ?? turns.filter((turn) => turn.status === "fail").length;
1960
2231
  return {
1961
- description: options.description ?? DEFAULT_DESCRIPTION6,
2232
+ description: options.description ?? DEFAULT_DESCRIPTION7,
1962
2233
  error: snapshot.error,
1963
2234
  isLoading: snapshot.isLoading,
1964
2235
  label: snapshot.error ? "Unavailable" : turns.length ? failedCount > 0 ? `${failedCount} failed` : warningCount > 0 ? `${warningCount} warnings` : `${turns.length} healthy` : snapshot.isLoading ? "Checking" : "No turns",
1965
2236
  status: snapshot.error ? "error" : turns.length ? failedCount > 0 || warningCount > 0 ? "warning" : "ready" : snapshot.isLoading ? "loading" : "empty",
1966
- title: options.title ?? DEFAULT_TITLE6,
2237
+ title: options.title ?? DEFAULT_TITLE7,
1967
2238
  turns,
1968
2239
  updatedAt: snapshot.updatedAt
1969
2240
  };
1970
2241
  };
1971
2242
  var renderVoiceTurnQualityHTML = (snapshot, options = {}) => {
1972
2243
  const model = createVoiceTurnQualityViewModel(snapshot, options);
1973
- 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)}">
2244
+ 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--${escapeHtml8(turn.status)}">
1974
2245
  <header>
1975
- <strong>${escapeHtml7(turn.label)}</strong>
1976
- <span>${escapeHtml7(turn.status)}</span>
2246
+ <strong>${escapeHtml8(turn.label)}</strong>
2247
+ <span>${escapeHtml8(turn.status)}</span>
1977
2248
  </header>
1978
- <p>${escapeHtml7(turn.detail)}</p>
2249
+ <p>${escapeHtml8(turn.detail)}</p>
1979
2250
  <dl>${turn.rows.map((row) => `<div>
1980
- <dt>${escapeHtml7(row.label)}</dt>
1981
- <dd>${escapeHtml7(row.value)}</dd>
2251
+ <dt>${escapeHtml8(row.label)}</dt>
2252
+ <dd>${escapeHtml8(row.value)}</dd>
1982
2253
  </div>`).join("")}</dl>
1983
2254
  </article>`).join("")}</div>` : '<p class="absolute-voice-turn-quality__empty">Complete a voice turn to see STT quality diagnostics.</p>';
1984
- return `<section class="absolute-voice-turn-quality absolute-voice-turn-quality--${escapeHtml7(model.status)}">
2255
+ return `<section class="absolute-voice-turn-quality absolute-voice-turn-quality--${escapeHtml8(model.status)}">
1985
2256
  <header class="absolute-voice-turn-quality__header">
1986
- <span class="absolute-voice-turn-quality__eyebrow">${escapeHtml7(model.title)}</span>
1987
- <strong class="absolute-voice-turn-quality__label">${escapeHtml7(model.label)}</strong>
2257
+ <span class="absolute-voice-turn-quality__eyebrow">${escapeHtml8(model.title)}</span>
2258
+ <strong class="absolute-voice-turn-quality__label">${escapeHtml8(model.label)}</strong>
1988
2259
  </header>
1989
- <p class="absolute-voice-turn-quality__description">${escapeHtml7(model.description)}</p>
2260
+ <p class="absolute-voice-turn-quality__description">${escapeHtml8(model.description)}</p>
1990
2261
  ${turns}
1991
- ${model.error ? `<p class="absolute-voice-turn-quality__error">${escapeHtml7(model.error)}</p>` : ""}
2262
+ ${model.error ? `<p class="absolute-voice-turn-quality__error">${escapeHtml8(model.error)}</p>` : ""}
1992
2263
  </section>`;
1993
2264
  };
1994
2265
  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}`;
@@ -2030,13 +2301,13 @@ var defineVoiceTurnQualityElement = (tagName = "absolute-voice-turn-quality") =>
2030
2301
  };
2031
2302
 
2032
2303
  // src/vue/useVoiceTurnQuality.ts
2033
- import { onUnmounted as onUnmounted7, shallowRef as shallowRef6 } from "vue";
2304
+ import { onUnmounted as onUnmounted8, shallowRef as shallowRef7 } from "vue";
2034
2305
  function useVoiceTurnQuality(path = "/api/turn-quality", options = {}) {
2035
2306
  const store = createVoiceTurnQualityStore(path, options);
2036
- const error = shallowRef6(null);
2037
- const isLoading = shallowRef6(false);
2038
- const report = shallowRef6();
2039
- const updatedAt = shallowRef6(undefined);
2307
+ const error = shallowRef7(null);
2308
+ const isLoading = shallowRef7(false);
2309
+ const report = shallowRef7();
2310
+ const updatedAt = shallowRef7(undefined);
2040
2311
  const sync = () => {
2041
2312
  const snapshot = store.getSnapshot();
2042
2313
  error.value = snapshot.error;
@@ -2047,7 +2318,7 @@ function useVoiceTurnQuality(path = "/api/turn-quality", options = {}) {
2047
2318
  const unsubscribe = store.subscribe(sync);
2048
2319
  sync();
2049
2320
  store.refresh().catch(() => {});
2050
- onUnmounted7(() => {
2321
+ onUnmounted8(() => {
2051
2322
  unsubscribe();
2052
2323
  store.close();
2053
2324
  });
@@ -2055,7 +2326,7 @@ function useVoiceTurnQuality(path = "/api/turn-quality", options = {}) {
2055
2326
  }
2056
2327
 
2057
2328
  // src/vue/VoiceTurnQuality.ts
2058
- var VoiceTurnQuality = defineComponent7({
2329
+ var VoiceTurnQuality = defineComponent8({
2059
2330
  name: "VoiceTurnQuality",
2060
2331
  props: {
2061
2332
  class: { default: "", type: String },
@@ -2077,41 +2348,41 @@ var VoiceTurnQuality = defineComponent7({
2077
2348
  report: quality.report.value,
2078
2349
  updatedAt: quality.updatedAt.value
2079
2350
  }, options));
2080
- return () => h7("section", {
2351
+ return () => h8("section", {
2081
2352
  class: [
2082
2353
  "absolute-voice-turn-quality",
2083
2354
  `absolute-voice-turn-quality--${model.value.status}`,
2084
2355
  props.class
2085
2356
  ]
2086
2357
  }, [
2087
- h7("header", { class: "absolute-voice-turn-quality__header" }, [
2088
- h7("span", { class: "absolute-voice-turn-quality__eyebrow" }, model.value.title),
2089
- h7("strong", { class: "absolute-voice-turn-quality__label" }, model.value.label)
2358
+ h8("header", { class: "absolute-voice-turn-quality__header" }, [
2359
+ h8("span", { class: "absolute-voice-turn-quality__eyebrow" }, model.value.title),
2360
+ h8("strong", { class: "absolute-voice-turn-quality__label" }, model.value.label)
2090
2361
  ]),
2091
- h7("p", { class: "absolute-voice-turn-quality__description" }, model.value.description),
2092
- model.value.turns.length ? h7("div", { class: "absolute-voice-turn-quality__turns" }, model.value.turns.map((turn) => h7("article", {
2362
+ h8("p", { class: "absolute-voice-turn-quality__description" }, model.value.description),
2363
+ model.value.turns.length ? h8("div", { class: "absolute-voice-turn-quality__turns" }, model.value.turns.map((turn) => h8("article", {
2093
2364
  class: [
2094
2365
  "absolute-voice-turn-quality__turn",
2095
2366
  `absolute-voice-turn-quality__turn--${turn.status}`
2096
2367
  ],
2097
2368
  key: `${turn.sessionId}:${turn.turnId}`
2098
2369
  }, [
2099
- h7("header", [
2100
- h7("strong", turn.label),
2101
- h7("span", turn.status)
2370
+ h8("header", [
2371
+ h8("strong", turn.label),
2372
+ h8("span", turn.status)
2102
2373
  ]),
2103
- h7("p", turn.detail),
2104
- h7("dl", turn.rows.map((row) => h7("div", { key: row.label }, [
2105
- h7("dt", row.label),
2106
- h7("dd", row.value)
2374
+ h8("p", turn.detail),
2375
+ h8("dl", turn.rows.map((row) => h8("div", { key: row.label }, [
2376
+ h8("dt", row.label),
2377
+ h8("dd", row.value)
2107
2378
  ])))
2108
- ]))) : h7("p", { class: "absolute-voice-turn-quality__empty" }, "Complete a voice turn to see STT quality diagnostics."),
2109
- model.value.error ? h7("p", { class: "absolute-voice-turn-quality__error" }, model.value.error) : null
2379
+ ]))) : h8("p", { class: "absolute-voice-turn-quality__empty" }, "Complete a voice turn to see STT quality diagnostics."),
2380
+ model.value.error ? h8("p", { class: "absolute-voice-turn-quality__error" }, model.value.error) : null
2110
2381
  ]);
2111
2382
  }
2112
2383
  });
2113
2384
  // src/vue/useVoiceCampaignDialerProof.ts
2114
- import { onUnmounted as onUnmounted8, shallowRef as shallowRef7 } from "vue";
2385
+ import { onUnmounted as onUnmounted9, shallowRef as shallowRef8 } from "vue";
2115
2386
 
2116
2387
  // src/client/campaignDialerProof.ts
2117
2388
  var fetchVoiceCampaignDialerProofStatus = async (path = "/api/voice/campaigns/dialer-proof", options = {}) => {
@@ -2234,11 +2505,11 @@ var createVoiceCampaignDialerProofStore = (path = "/api/voice/campaigns/dialer-p
2234
2505
  // src/vue/useVoiceCampaignDialerProof.ts
2235
2506
  function useVoiceCampaignDialerProof(path = "/api/voice/campaigns/dialer-proof", options = {}) {
2236
2507
  const store = createVoiceCampaignDialerProofStore(path, options);
2237
- const error = shallowRef7(null);
2238
- const isLoading = shallowRef7(false);
2239
- const report = shallowRef7();
2240
- const status = shallowRef7();
2241
- const updatedAt = shallowRef7(undefined);
2508
+ const error = shallowRef8(null);
2509
+ const isLoading = shallowRef8(false);
2510
+ const report = shallowRef8();
2511
+ const status = shallowRef8();
2512
+ const updatedAt = shallowRef8(undefined);
2242
2513
  const sync = () => {
2243
2514
  const snapshot = store.getSnapshot();
2244
2515
  error.value = snapshot.error;
@@ -2252,7 +2523,7 @@ function useVoiceCampaignDialerProof(path = "/api/voice/campaigns/dialer-proof",
2252
2523
  if (typeof window !== "undefined") {
2253
2524
  store.refresh().catch(() => {});
2254
2525
  }
2255
- onUnmounted8(() => {
2526
+ onUnmounted9(() => {
2256
2527
  unsubscribe();
2257
2528
  store.close();
2258
2529
  });
@@ -2267,7 +2538,7 @@ function useVoiceCampaignDialerProof(path = "/api/voice/campaigns/dialer-proof",
2267
2538
  };
2268
2539
  }
2269
2540
  // src/vue/useVoiceStream.ts
2270
- import { onUnmounted as onUnmounted9, ref as ref5, shallowRef as shallowRef8 } from "vue";
2541
+ import { onUnmounted as onUnmounted10, ref as ref6, shallowRef as shallowRef9 } from "vue";
2271
2542
 
2272
2543
  // src/client/actions.ts
2273
2544
  var normalizeErrorMessage = (value) => {
@@ -2912,16 +3183,16 @@ var createVoiceStream = (path, options = {}) => {
2912
3183
  // src/vue/useVoiceStream.ts
2913
3184
  function useVoiceStream(path, options = {}) {
2914
3185
  const stream = createVoiceStream(path, options);
2915
- const assistantAudio = shallowRef8([]);
2916
- const assistantTexts = shallowRef8([]);
2917
- const call = shallowRef8(null);
2918
- const error = ref5(null);
2919
- const isConnected = ref5(false);
2920
- const partial = ref5("");
2921
- const reconnect = shallowRef8(stream.reconnect);
2922
- const sessionId = ref5(stream.sessionId);
2923
- const status = ref5(stream.status);
2924
- const turns = shallowRef8([]);
3186
+ const assistantAudio = shallowRef9([]);
3187
+ const assistantTexts = shallowRef9([]);
3188
+ const call = shallowRef9(null);
3189
+ const error = ref6(null);
3190
+ const isConnected = ref6(false);
3191
+ const partial = ref6("");
3192
+ const reconnect = shallowRef9(stream.reconnect);
3193
+ const sessionId = ref6(stream.sessionId);
3194
+ const status = ref6(stream.status);
3195
+ const turns = shallowRef9([]);
2925
3196
  const sync = () => {
2926
3197
  assistantAudio.value = [...stream.assistantAudio];
2927
3198
  assistantTexts.value = [...stream.assistantTexts];
@@ -2940,7 +3211,7 @@ function useVoiceStream(path, options = {}) {
2940
3211
  unsubscribe();
2941
3212
  stream.close();
2942
3213
  };
2943
- onUnmounted9(destroy);
3214
+ onUnmounted10(destroy);
2944
3215
  return {
2945
3216
  assistantAudio,
2946
3217
  assistantTexts,
@@ -2959,7 +3230,7 @@ function useVoiceStream(path, options = {}) {
2959
3230
  };
2960
3231
  }
2961
3232
  // src/vue/useVoiceController.ts
2962
- import { onUnmounted as onUnmounted10, ref as ref6, shallowRef as shallowRef9 } from "vue";
3233
+ import { onUnmounted as onUnmounted11, ref as ref7, shallowRef as shallowRef10 } from "vue";
2963
3234
 
2964
3235
  // src/client/htmx.ts
2965
3236
  var DEFAULT_EVENT_NAME = "voice-refresh";
@@ -3605,17 +3876,17 @@ var createVoiceController = (path, options = {}) => {
3605
3876
  // src/vue/useVoiceController.ts
3606
3877
  function useVoiceController(path, options = {}) {
3607
3878
  const controller = createVoiceController(path, options);
3608
- const assistantAudio = shallowRef9([]);
3609
- const assistantTexts = shallowRef9([]);
3610
- const error = ref6(null);
3611
- const isConnected = ref6(false);
3612
- const isRecording = ref6(false);
3613
- const partial = ref6("");
3614
- const reconnect = shallowRef9(controller.reconnect);
3615
- const recordingError = ref6(null);
3616
- const sessionId = ref6(controller.sessionId);
3617
- const status = ref6(controller.status);
3618
- const turns = shallowRef9([]);
3879
+ const assistantAudio = shallowRef10([]);
3880
+ const assistantTexts = shallowRef10([]);
3881
+ const error = ref7(null);
3882
+ const isConnected = ref7(false);
3883
+ const isRecording = ref7(false);
3884
+ const partial = ref7("");
3885
+ const reconnect = shallowRef10(controller.reconnect);
3886
+ const recordingError = ref7(null);
3887
+ const sessionId = ref7(controller.sessionId);
3888
+ const status = ref7(controller.status);
3889
+ const turns = shallowRef10([]);
3619
3890
  const sync = () => {
3620
3891
  assistantAudio.value = [...controller.assistantAudio];
3621
3892
  assistantTexts.value = [...controller.assistantTexts];
@@ -3635,7 +3906,7 @@ function useVoiceController(path, options = {}) {
3635
3906
  unsubscribe();
3636
3907
  controller.close();
3637
3908
  };
3638
- onUnmounted10(destroy);
3909
+ onUnmounted11(destroy);
3639
3910
  return {
3640
3911
  assistantAudio,
3641
3912
  assistantTexts,
@@ -3658,7 +3929,7 @@ function useVoiceController(path, options = {}) {
3658
3929
  };
3659
3930
  }
3660
3931
  // src/vue/useVoiceTraceTimeline.ts
3661
- import { onUnmounted as onUnmounted11, ref as ref7, shallowRef as shallowRef10 } from "vue";
3932
+ import { onUnmounted as onUnmounted12, ref as ref8, shallowRef as shallowRef11 } from "vue";
3662
3933
 
3663
3934
  // src/client/traceTimeline.ts
3664
3935
  var fetchVoiceTraceTimeline = async (path = "/api/voice-traces", options = {}) => {
@@ -3743,10 +4014,10 @@ var createVoiceTraceTimelineStore = (path = "/api/voice-traces", options = {}) =
3743
4014
  // src/vue/useVoiceTraceTimeline.ts
3744
4015
  function useVoiceTraceTimeline(path = "/api/voice-traces", options = {}) {
3745
4016
  const store = createVoiceTraceTimelineStore(path, options);
3746
- const error = ref7(null);
3747
- const isLoading = ref7(false);
3748
- const report = shallowRef10(null);
3749
- const updatedAt = ref7(undefined);
4017
+ const error = ref8(null);
4018
+ const isLoading = ref8(false);
4019
+ const report = shallowRef11(null);
4020
+ const updatedAt = ref8(undefined);
3750
4021
  const sync = () => {
3751
4022
  const snapshot = store.getSnapshot();
3752
4023
  error.value = snapshot.error;
@@ -3757,7 +4028,7 @@ function useVoiceTraceTimeline(path = "/api/voice-traces", options = {}) {
3757
4028
  const unsubscribe = store.subscribe(sync);
3758
4029
  sync();
3759
4030
  store.refresh().catch(() => {});
3760
- onUnmounted11(() => {
4031
+ onUnmounted12(() => {
3761
4032
  unsubscribe();
3762
4033
  store.close();
3763
4034
  });
@@ -3770,7 +4041,7 @@ function useVoiceTraceTimeline(path = "/api/voice-traces", options = {}) {
3770
4041
  };
3771
4042
  }
3772
4043
  // src/vue/useVoiceWorkflowStatus.ts
3773
- import { onUnmounted as onUnmounted12, ref as ref8, shallowRef as shallowRef11 } from "vue";
4044
+ import { onUnmounted as onUnmounted13, ref as ref9, shallowRef as shallowRef12 } from "vue";
3774
4045
 
3775
4046
  // src/client/workflowStatus.ts
3776
4047
  var fetchVoiceWorkflowStatus = async (path = "/evals/scenarios/json", options = {}) => {
@@ -3854,10 +4125,10 @@ var createVoiceWorkflowStatusStore = (path = "/evals/scenarios/json", options =
3854
4125
  // src/vue/useVoiceWorkflowStatus.ts
3855
4126
  function useVoiceWorkflowStatus(path = "/evals/scenarios/json", options = {}) {
3856
4127
  const store = createVoiceWorkflowStatusStore(path, options);
3857
- const error = ref8(null);
3858
- const isLoading = ref8(false);
3859
- const report = shallowRef11(undefined);
3860
- const updatedAt = ref8(undefined);
4128
+ const error = ref9(null);
4129
+ const isLoading = ref9(false);
4130
+ const report = shallowRef12(undefined);
4131
+ const updatedAt = ref9(undefined);
3861
4132
  const sync = () => {
3862
4133
  const snapshot = store.getSnapshot();
3863
4134
  error.value = snapshot.error;
@@ -3870,7 +4141,7 @@ function useVoiceWorkflowStatus(path = "/evals/scenarios/json", options = {}) {
3870
4141
  if (typeof window !== "undefined") {
3871
4142
  store.refresh().catch(() => {});
3872
4143
  }
3873
- onUnmounted12(() => {
4144
+ onUnmounted13(() => {
3874
4145
  unsubscribe();
3875
4146
  store.close();
3876
4147
  });
@@ -3893,6 +4164,7 @@ export {
3893
4164
  useVoiceProviderSimulationControls,
3894
4165
  useVoiceProviderCapabilities,
3895
4166
  useVoiceOpsStatus,
4167
+ useVoiceDeliveryRuntime,
3896
4168
  useVoiceController,
3897
4169
  useVoiceCampaignDialerProof,
3898
4170
  VoiceTurnQuality,
@@ -3901,5 +4173,6 @@ export {
3901
4173
  VoiceProviderStatus,
3902
4174
  VoiceProviderSimulationControls,
3903
4175
  VoiceProviderCapabilities,
3904
- VoiceOpsStatus
4176
+ VoiceOpsStatus,
4177
+ VoiceDeliveryRuntime
3905
4178
  };