@absolutejs/voice 0.0.22-beta.153 → 0.0.22-beta.154

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,9 +374,348 @@ var VoiceOpsStatus = defineComponent({
374
374
  };
375
375
  }
376
376
  });
377
- // src/vue/VoiceDeliveryRuntime.ts
377
+ // src/vue/VoiceOpsActionCenter.ts
378
378
  import { defineComponent as defineComponent2, h as h2 } from "vue";
379
379
 
380
+ // src/client/opsActionCenter.ts
381
+ var createVoiceOpsActionCenterActions = (options = {}) => {
382
+ const deliveryRuntimePath = options.deliveryRuntimePath ?? "/api/voice-delivery-runtime";
383
+ const actions = [];
384
+ if (options.includeProductionReadiness !== false) {
385
+ actions.push({
386
+ description: "Refresh the production readiness report.",
387
+ id: "production-readiness",
388
+ label: "Refresh readiness",
389
+ method: "GET",
390
+ path: options.productionReadinessPath ?? "/api/production-readiness"
391
+ });
392
+ }
393
+ if (options.includeDeliveryRuntime !== false) {
394
+ actions.push({
395
+ description: "Drain pending and failed audit/trace deliveries.",
396
+ id: "delivery-runtime.tick",
397
+ label: "Tick delivery workers",
398
+ method: "POST",
399
+ path: `${deliveryRuntimePath.replace(/\/$/, "")}/tick`
400
+ }, {
401
+ description: "Move reviewed dead letters back to live delivery queues.",
402
+ id: "delivery-runtime.requeue-dead-letters",
403
+ label: "Requeue dead letters",
404
+ method: "POST",
405
+ path: `${deliveryRuntimePath.replace(/\/$/, "")}/requeue-dead-letters`
406
+ });
407
+ }
408
+ if (options.includeTurnLatencyProof !== false) {
409
+ actions.push({
410
+ description: "Run the synthetic turn latency proof.",
411
+ id: "turn-latency.proof",
412
+ label: "Run latency proof",
413
+ method: "POST",
414
+ path: options.turnLatencyProofPath ?? "/api/turn-latency/proof"
415
+ });
416
+ }
417
+ if (options.includeProviderSimulation !== false) {
418
+ const pathPrefix = options.providerSimulationPathPrefix ?? "/api/stt-simulate";
419
+ for (const provider of options.providers ?? []) {
420
+ actions.push({
421
+ description: `Simulate ${provider} provider failure.`,
422
+ id: `provider.${provider}.failure`,
423
+ label: `Simulate ${provider} failure`,
424
+ method: "POST",
425
+ path: `${pathPrefix}/failure?provider=${encodeURIComponent(provider)}`
426
+ }, {
427
+ description: `Mark ${provider} provider recovered.`,
428
+ id: `provider.${provider}.recovery`,
429
+ label: `Recover ${provider}`,
430
+ method: "POST",
431
+ path: `${pathPrefix}/recovery?provider=${encodeURIComponent(provider)}`
432
+ });
433
+ }
434
+ }
435
+ return actions;
436
+ };
437
+ var runVoiceOpsAction = async (action, options = {}) => {
438
+ const fetchImpl = options.fetch ?? globalThis.fetch;
439
+ const response = await fetchImpl(action.path, {
440
+ method: action.method ?? "POST"
441
+ });
442
+ const body = await response.json().catch(() => null);
443
+ if (!response.ok) {
444
+ const message = body && typeof body === "object" && "error" in body ? String(body.error) : `Voice ops action "${action.id}" failed: HTTP ${response.status}`;
445
+ throw new Error(message);
446
+ }
447
+ return {
448
+ actionId: action.id,
449
+ body,
450
+ ok: response.ok,
451
+ ranAt: Date.now(),
452
+ status: response.status
453
+ };
454
+ };
455
+ var createVoiceOpsActionCenterStore = (options = {}) => {
456
+ const listeners = new Set;
457
+ let closed = false;
458
+ let timer;
459
+ let snapshot = {
460
+ actions: options.actions ?? createVoiceOpsActionCenterActions(),
461
+ error: null,
462
+ isRunning: false
463
+ };
464
+ const emit = () => {
465
+ for (const listener of listeners) {
466
+ listener();
467
+ }
468
+ };
469
+ const setActions = (actions) => {
470
+ snapshot = { ...snapshot, actions, updatedAt: Date.now() };
471
+ emit();
472
+ };
473
+ const run = async (actionId) => {
474
+ if (closed) {
475
+ return snapshot.lastResult;
476
+ }
477
+ const action = snapshot.actions.find((item) => item.id === actionId);
478
+ if (!action) {
479
+ throw new Error(`Voice ops action "${actionId}" is not configured.`);
480
+ }
481
+ if (action.disabled) {
482
+ throw new Error(`Voice ops action "${actionId}" is disabled.`);
483
+ }
484
+ snapshot = {
485
+ ...snapshot,
486
+ error: null,
487
+ isRunning: true,
488
+ runningActionId: action.id
489
+ };
490
+ emit();
491
+ try {
492
+ const result = await runVoiceOpsAction(action, options);
493
+ snapshot = {
494
+ ...snapshot,
495
+ error: null,
496
+ isRunning: false,
497
+ lastResult: result,
498
+ runningActionId: undefined,
499
+ updatedAt: Date.now()
500
+ };
501
+ emit();
502
+ return result;
503
+ } catch (error) {
504
+ snapshot = {
505
+ ...snapshot,
506
+ error: error instanceof Error ? error.message : String(error),
507
+ isRunning: false,
508
+ runningActionId: undefined
509
+ };
510
+ emit();
511
+ throw error;
512
+ }
513
+ };
514
+ const close = () => {
515
+ closed = true;
516
+ if (timer) {
517
+ clearInterval(timer);
518
+ timer = undefined;
519
+ }
520
+ listeners.clear();
521
+ };
522
+ if (options.intervalMs && options.intervalMs > 0) {
523
+ timer = setInterval(() => {
524
+ emit();
525
+ }, options.intervalMs);
526
+ }
527
+ return {
528
+ close,
529
+ getServerSnapshot: () => snapshot,
530
+ getSnapshot: () => snapshot,
531
+ run,
532
+ setActions,
533
+ subscribe: (listener) => {
534
+ listeners.add(listener);
535
+ return () => {
536
+ listeners.delete(listener);
537
+ };
538
+ }
539
+ };
540
+ };
541
+
542
+ // src/client/opsActionCenterWidget.ts
543
+ var DEFAULT_TITLE2 = "Voice Ops Action Center";
544
+ var DEFAULT_DESCRIPTION2 = "Run production voice proofs and operator actions from one primitive panel.";
545
+ var escapeHtml2 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
546
+ var createVoiceOpsActionCenterViewModel = (snapshot, options = {}) => {
547
+ const status = snapshot.error ? "error" : snapshot.isRunning ? "running" : snapshot.lastResult ? "completed" : "ready";
548
+ return {
549
+ actions: snapshot.actions.map((action) => ({
550
+ description: action.description ?? "",
551
+ disabled: Boolean(action.disabled || snapshot.isRunning),
552
+ id: action.id,
553
+ isRunning: snapshot.runningActionId === action.id,
554
+ label: action.label
555
+ })),
556
+ description: options.description ?? DEFAULT_DESCRIPTION2,
557
+ error: snapshot.error,
558
+ isRunning: snapshot.isRunning,
559
+ label: status === "error" ? "Needs attention" : status === "running" ? "Running" : status === "completed" ? "Action completed" : "Ready",
560
+ lastResultLabel: snapshot.lastResult ? `${snapshot.lastResult.actionId} returned HTTP ${snapshot.lastResult.status}` : "No action has run yet.",
561
+ status,
562
+ title: options.title ?? DEFAULT_TITLE2
563
+ };
564
+ };
565
+ var renderVoiceOpsActionCenterHTML = (snapshot, options = {}) => {
566
+ const model = createVoiceOpsActionCenterViewModel(snapshot, options);
567
+ const actions = model.actions.map((action) => `<button type="button" data-absolute-voice-ops-action="${escapeHtml2(action.id)}"${action.disabled ? " disabled" : ""}>
568
+ ${escapeHtml2(action.isRunning ? "Working..." : action.label)}
569
+ </button>`).join("");
570
+ return `<section class="absolute-voice-ops-action-center absolute-voice-ops-action-center--${escapeHtml2(model.status)}">
571
+ <header class="absolute-voice-ops-action-center__header">
572
+ <span class="absolute-voice-ops-action-center__eyebrow">${escapeHtml2(model.title)}</span>
573
+ <strong class="absolute-voice-ops-action-center__label">${escapeHtml2(model.label)}</strong>
574
+ </header>
575
+ <p class="absolute-voice-ops-action-center__description">${escapeHtml2(model.description)}</p>
576
+ <div class="absolute-voice-ops-action-center__actions">${actions}</div>
577
+ <p class="absolute-voice-ops-action-center__result">${escapeHtml2(model.lastResultLabel)}</p>
578
+ ${model.error ? `<p class="absolute-voice-ops-action-center__error">${escapeHtml2(model.error)}</p>` : ""}
579
+ </section>`;
580
+ };
581
+ var getVoiceOpsActionCenterCSS = () => `.absolute-voice-ops-action-center{border:1px solid #d5cbb8;border-radius:20px;background:#fffaf1;color:#17130b;padding:18px;box-shadow:0 18px 40px rgba(58,42,16,.12);font-family:inherit}.absolute-voice-ops-action-center--error{border-color:#f2a7a7;background:#fff5f3}.absolute-voice-ops-action-center__header{align-items:start;display:flex;gap:12px;justify-content:space-between}.absolute-voice-ops-action-center__eyebrow{color:#725d37;font-size:12px;font-weight:800;letter-spacing:.08em;text-transform:uppercase}.absolute-voice-ops-action-center__label{font-size:28px;line-height:1}.absolute-voice-ops-action-center__description,.absolute-voice-ops-action-center__result{color:#5b4b2f;margin:12px 0 0}.absolute-voice-ops-action-center__actions{display:flex;flex-wrap:wrap;gap:8px;margin-top:14px}.absolute-voice-ops-action-center__actions button{background:#7c4a03;border:0;border-radius:999px;color:#fff8e8;cursor:pointer;font:inherit;font-weight:800;padding:8px 12px}.absolute-voice-ops-action-center__actions button:disabled{cursor:not-allowed;opacity:.5}.absolute-voice-ops-action-center__error{color:#9f1239;font-weight:700}`;
582
+ var mountVoiceOpsActionCenter = (element, options = {}) => {
583
+ const store = createVoiceOpsActionCenterStore(options);
584
+ const render = () => {
585
+ element.innerHTML = renderVoiceOpsActionCenterHTML(store.getSnapshot(), options);
586
+ };
587
+ const unsubscribe = store.subscribe(render);
588
+ const handleClick = (event) => {
589
+ const target = event.target;
590
+ if (!(target instanceof Element)) {
591
+ return;
592
+ }
593
+ const action = target.closest("[data-absolute-voice-ops-action]");
594
+ const actionId = action?.getAttribute("data-absolute-voice-ops-action");
595
+ if (actionId) {
596
+ store.run(actionId).catch(() => {});
597
+ }
598
+ };
599
+ element.addEventListener?.("click", handleClick);
600
+ render();
601
+ return {
602
+ close: () => {
603
+ element.removeEventListener?.("click", handleClick);
604
+ unsubscribe();
605
+ store.close();
606
+ },
607
+ run: store.run
608
+ };
609
+ };
610
+ var defineVoiceOpsActionCenterElement = (tagName = "absolute-voice-ops-action-center", options = {}) => {
611
+ if (typeof window === "undefined" || typeof customElements === "undefined" || customElements.get(tagName)) {
612
+ return;
613
+ }
614
+ customElements.define(tagName, class AbsoluteVoiceOpsActionCenterElement extends HTMLElement {
615
+ mounted;
616
+ connectedCallback() {
617
+ this.mounted = mountVoiceOpsActionCenter(this, {
618
+ ...options,
619
+ description: this.getAttribute("description") ?? options.description,
620
+ title: this.getAttribute("title") ?? options.title
621
+ });
622
+ }
623
+ disconnectedCallback() {
624
+ this.mounted?.close();
625
+ this.mounted = undefined;
626
+ }
627
+ });
628
+ };
629
+
630
+ // src/vue/useVoiceOpsActionCenter.ts
631
+ import { onUnmounted as onUnmounted2, ref as ref2, shallowRef as shallowRef2 } from "vue";
632
+ function useVoiceOpsActionCenter(options = {}) {
633
+ const store = createVoiceOpsActionCenterStore(options);
634
+ const actions = shallowRef2([]);
635
+ const error = ref2(null);
636
+ const isRunning = ref2(false);
637
+ const lastResult = shallowRef2(undefined);
638
+ const runningActionId = ref2(undefined);
639
+ const updatedAt = ref2(undefined);
640
+ const sync = () => {
641
+ const snapshot = store.getSnapshot();
642
+ actions.value = snapshot.actions;
643
+ error.value = snapshot.error;
644
+ isRunning.value = snapshot.isRunning;
645
+ lastResult.value = snapshot.lastResult;
646
+ runningActionId.value = snapshot.runningActionId;
647
+ updatedAt.value = snapshot.updatedAt;
648
+ };
649
+ const unsubscribe = store.subscribe(sync);
650
+ sync();
651
+ onUnmounted2(() => {
652
+ unsubscribe();
653
+ store.close();
654
+ });
655
+ return {
656
+ actions,
657
+ error,
658
+ isRunning,
659
+ lastResult,
660
+ run: store.run,
661
+ runningActionId,
662
+ setActions: store.setActions,
663
+ updatedAt
664
+ };
665
+ }
666
+
667
+ // src/vue/VoiceOpsActionCenter.ts
668
+ var VoiceOpsActionCenter = defineComponent2({
669
+ name: "VoiceOpsActionCenter",
670
+ props: {
671
+ actions: Array,
672
+ description: String,
673
+ title: String
674
+ },
675
+ setup(props) {
676
+ const options = {
677
+ actions: props.actions,
678
+ description: props.description,
679
+ title: props.title
680
+ };
681
+ const center = useVoiceOpsActionCenter(options);
682
+ return () => {
683
+ const model = createVoiceOpsActionCenterViewModel({
684
+ actions: center.actions.value,
685
+ error: center.error.value,
686
+ isRunning: center.isRunning.value,
687
+ lastResult: center.lastResult.value,
688
+ runningActionId: center.runningActionId.value,
689
+ updatedAt: center.updatedAt.value
690
+ }, options);
691
+ return h2("section", {
692
+ class: [
693
+ "absolute-voice-ops-action-center",
694
+ `absolute-voice-ops-action-center--${model.status}`
695
+ ]
696
+ }, [
697
+ h2("header", { class: "absolute-voice-ops-action-center__header" }, [
698
+ h2("span", { class: "absolute-voice-ops-action-center__eyebrow" }, model.title),
699
+ h2("strong", { class: "absolute-voice-ops-action-center__label" }, model.label)
700
+ ]),
701
+ h2("p", { class: "absolute-voice-ops-action-center__description" }, model.description),
702
+ h2("div", { class: "absolute-voice-ops-action-center__actions" }, model.actions.map((action) => h2("button", {
703
+ disabled: action.disabled,
704
+ key: action.id,
705
+ onClick: () => {
706
+ center.run(action.id).catch(() => {});
707
+ },
708
+ type: "button"
709
+ }, action.isRunning ? "Working..." : action.label))),
710
+ h2("p", { class: "absolute-voice-ops-action-center__result" }, model.lastResultLabel),
711
+ model.error ? h2("p", { class: "absolute-voice-ops-action-center__error" }, model.error) : null
712
+ ]);
713
+ };
714
+ }
715
+ });
716
+ // src/vue/VoiceDeliveryRuntime.ts
717
+ import { defineComponent as defineComponent3, h as h3 } from "vue";
718
+
380
719
  // src/client/deliveryRuntime.ts
381
720
  var getDefaultActionPath = (path, action, options) => {
382
721
  if (action === "tick") {
@@ -515,9 +854,9 @@ var createVoiceDeliveryRuntimeStore = (path = "/api/voice-delivery-runtime", opt
515
854
  };
516
855
 
517
856
  // src/client/deliveryRuntimeWidget.ts
518
- var DEFAULT_TITLE2 = "Voice Delivery Runtime";
519
- var DEFAULT_DESCRIPTION2 = "Audit and trace delivery worker health from your AbsoluteJS voice app.";
520
- var escapeHtml2 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
857
+ var DEFAULT_TITLE3 = "Voice Delivery Runtime";
858
+ var DEFAULT_DESCRIPTION3 = "Audit and trace delivery worker health from your AbsoluteJS voice app.";
859
+ var escapeHtml3 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
521
860
  var createSurface = (id, summary) => {
522
861
  if (!summary) {
523
862
  return {
@@ -551,7 +890,7 @@ var createVoiceDeliveryRuntimeViewModel = (snapshot, options = {}) => {
551
890
  ];
552
891
  const hasWarnings = surfaces.some((surface) => surface.status === "warn");
553
892
  return {
554
- description: options.description ?? DEFAULT_DESCRIPTION2,
893
+ description: options.description ?? DEFAULT_DESCRIPTION3,
555
894
  error: snapshot.error,
556
895
  actionError: snapshot.actionError,
557
896
  actionStatus: snapshot.actionStatus,
@@ -560,32 +899,32 @@ var createVoiceDeliveryRuntimeViewModel = (snapshot, options = {}) => {
560
899
  label: snapshot.error ? "Unavailable" : report ? report.isRunning ? "Running" : "Stopped" : "Checking",
561
900
  status: snapshot.error ? "error" : report ? hasWarnings ? "warn" : "pass" : "loading",
562
901
  surfaces,
563
- title: options.title ?? DEFAULT_TITLE2,
902
+ title: options.title ?? DEFAULT_TITLE3,
564
903
  updatedAt: snapshot.updatedAt
565
904
  };
566
905
  };
567
906
  var renderVoiceDeliveryRuntimeHTML = (snapshot, options = {}) => {
568
907
  const model = createVoiceDeliveryRuntimeViewModel(snapshot, options);
569
- const surfaces = model.surfaces.map((surface) => `<li class="absolute-voice-delivery-runtime__surface absolute-voice-delivery-runtime__surface--${escapeHtml2(surface.status)}">
570
- <span>${escapeHtml2(surface.label)}</span>
571
- <strong>${escapeHtml2(surface.detail)}</strong>
908
+ const surfaces = model.surfaces.map((surface) => `<li class="absolute-voice-delivery-runtime__surface absolute-voice-delivery-runtime__surface--${escapeHtml3(surface.status)}">
909
+ <span>${escapeHtml3(surface.label)}</span>
910
+ <strong>${escapeHtml3(surface.detail)}</strong>
572
911
  <small>${String(surface.failed)} failed &middot; ${String(surface.deadLettered)} dead-lettered</small>
573
912
  </li>`).join("");
574
913
  const actions = options.includeActions === false ? "" : `<div class="absolute-voice-delivery-runtime__actions">
575
914
  <button type="button" data-absolute-voice-delivery-runtime-action="tick">${model.actionStatus === "running" ? "Working..." : "Tick workers"}</button>
576
915
  <button type="button" data-absolute-voice-delivery-runtime-action="requeue-dead-letters"${model.surfaces.some((surface) => surface.deadLettered > 0) ? "" : " disabled"}>Requeue dead letters</button>
577
916
  </div>`;
578
- const actionError = model.actionError ? `<p class="absolute-voice-delivery-runtime__error">${escapeHtml2(model.actionError)}</p>` : "";
579
- return `<section class="absolute-voice-delivery-runtime absolute-voice-delivery-runtime--${escapeHtml2(model.status)}">
917
+ const actionError = model.actionError ? `<p class="absolute-voice-delivery-runtime__error">${escapeHtml3(model.actionError)}</p>` : "";
918
+ return `<section class="absolute-voice-delivery-runtime absolute-voice-delivery-runtime--${escapeHtml3(model.status)}">
580
919
  <header class="absolute-voice-delivery-runtime__header">
581
- <span class="absolute-voice-delivery-runtime__eyebrow">${escapeHtml2(model.title)}</span>
582
- <strong class="absolute-voice-delivery-runtime__label">${escapeHtml2(model.label)}</strong>
920
+ <span class="absolute-voice-delivery-runtime__eyebrow">${escapeHtml3(model.title)}</span>
921
+ <strong class="absolute-voice-delivery-runtime__label">${escapeHtml3(model.label)}</strong>
583
922
  </header>
584
- <p class="absolute-voice-delivery-runtime__description">${escapeHtml2(model.description)}</p>
923
+ <p class="absolute-voice-delivery-runtime__description">${escapeHtml3(model.description)}</p>
585
924
  <ul class="absolute-voice-delivery-runtime__surfaces">${surfaces}</ul>
586
925
  ${actions}
587
926
  ${actionError}
588
- ${model.error ? `<p class="absolute-voice-delivery-runtime__error">${escapeHtml2(model.error)}</p>` : ""}
927
+ ${model.error ? `<p class="absolute-voice-delivery-runtime__error">${escapeHtml3(model.error)}</p>` : ""}
589
928
  </section>`;
590
929
  };
591
930
  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__actions{display:flex;flex-wrap:wrap;gap:8px;margin-top:14px}.absolute-voice-delivery-runtime__actions button{background:#134e2d;border:0;border-radius:999px;color:#f6fff9;cursor:pointer;font:inherit;font-weight:800;padding:8px 12px}.absolute-voice-delivery-runtime__actions button:disabled{cursor:not-allowed;opacity:.48}.absolute-voice-delivery-runtime__error{color:#9f1239;font-weight:700}`;
@@ -643,15 +982,15 @@ var defineVoiceDeliveryRuntimeElement = (tagName = "absolute-voice-delivery-runt
643
982
  };
644
983
 
645
984
  // src/vue/useVoiceDeliveryRuntime.ts
646
- import { onUnmounted as onUnmounted2, ref as ref2, shallowRef as shallowRef2 } from "vue";
985
+ import { onUnmounted as onUnmounted3, ref as ref3, shallowRef as shallowRef3 } from "vue";
647
986
  function useVoiceDeliveryRuntime(path = "/api/voice-delivery-runtime", options = {}) {
648
987
  const store = createVoiceDeliveryRuntimeStore(path, options);
649
- const actionError = ref2(null);
650
- const actionStatus = ref2("idle");
651
- const error = ref2(null);
652
- const isLoading = ref2(false);
653
- const report = shallowRef2(undefined);
654
- const updatedAt = ref2(undefined);
988
+ const actionError = ref3(null);
989
+ const actionStatus = ref3("idle");
990
+ const error = ref3(null);
991
+ const isLoading = ref3(false);
992
+ const report = shallowRef3(undefined);
993
+ const updatedAt = ref3(undefined);
655
994
  const sync = () => {
656
995
  const snapshot = store.getSnapshot();
657
996
  actionError.value = snapshot.actionError;
@@ -666,7 +1005,7 @@ function useVoiceDeliveryRuntime(path = "/api/voice-delivery-runtime", options =
666
1005
  if (typeof window !== "undefined") {
667
1006
  store.refresh().catch(() => {});
668
1007
  }
669
- onUnmounted2(() => {
1008
+ onUnmounted3(() => {
670
1009
  unsubscribe();
671
1010
  store.close();
672
1011
  });
@@ -684,7 +1023,7 @@ function useVoiceDeliveryRuntime(path = "/api/voice-delivery-runtime", options =
684
1023
  }
685
1024
 
686
1025
  // src/vue/VoiceDeliveryRuntime.ts
687
- var VoiceDeliveryRuntime = defineComponent2({
1026
+ var VoiceDeliveryRuntime = defineComponent3({
688
1027
  name: "VoiceDeliveryRuntime",
689
1028
  props: {
690
1029
  description: String,
@@ -716,37 +1055,37 @@ var VoiceDeliveryRuntime = defineComponent2({
716
1055
  updatedAt: runtime.updatedAt.value
717
1056
  }, options);
718
1057
  const hasDeadLetters = model.surfaces.some((surface) => surface.deadLettered > 0);
719
- return h2("section", {
1058
+ return h3("section", {
720
1059
  class: [
721
1060
  "absolute-voice-delivery-runtime",
722
1061
  `absolute-voice-delivery-runtime--${model.status}`
723
1062
  ]
724
1063
  }, [
725
- h2("header", { class: "absolute-voice-delivery-runtime__header" }, [
726
- h2("span", { class: "absolute-voice-delivery-runtime__eyebrow" }, model.title),
727
- h2("strong", { class: "absolute-voice-delivery-runtime__label" }, model.label)
1064
+ h3("header", { class: "absolute-voice-delivery-runtime__header" }, [
1065
+ h3("span", { class: "absolute-voice-delivery-runtime__eyebrow" }, model.title),
1066
+ h3("strong", { class: "absolute-voice-delivery-runtime__label" }, model.label)
728
1067
  ]),
729
- h2("p", { class: "absolute-voice-delivery-runtime__description" }, model.description),
730
- h2("ul", { class: "absolute-voice-delivery-runtime__surfaces" }, model.surfaces.map((surface) => h2("li", {
1068
+ h3("p", { class: "absolute-voice-delivery-runtime__description" }, model.description),
1069
+ h3("ul", { class: "absolute-voice-delivery-runtime__surfaces" }, model.surfaces.map((surface) => h3("li", {
731
1070
  class: [
732
1071
  "absolute-voice-delivery-runtime__surface",
733
1072
  `absolute-voice-delivery-runtime__surface--${surface.status}`
734
1073
  ],
735
1074
  key: surface.id
736
1075
  }, [
737
- h2("span", surface.label),
738
- h2("strong", surface.detail),
739
- h2("small", `${surface.failed} failed / ${surface.deadLettered} dead-lettered`)
1076
+ h3("span", surface.label),
1077
+ h3("strong", surface.detail),
1078
+ h3("small", `${surface.failed} failed / ${surface.deadLettered} dead-lettered`)
740
1079
  ]))),
741
- props.includeActions ? h2("div", { class: "absolute-voice-delivery-runtime__actions" }, [
742
- h2("button", {
1080
+ props.includeActions ? h3("div", { class: "absolute-voice-delivery-runtime__actions" }, [
1081
+ h3("button", {
743
1082
  disabled: model.actionStatus === "running",
744
1083
  onClick: () => {
745
1084
  runtime.tick().catch(() => {});
746
1085
  },
747
1086
  type: "button"
748
1087
  }, model.actionStatus === "running" ? "Working..." : "Tick workers"),
749
- h2("button", {
1088
+ h3("button", {
750
1089
  disabled: model.actionStatus === "running" || !hasDeadLetters,
751
1090
  onClick: () => {
752
1091
  runtime.requeueDeadLetters().catch(() => {});
@@ -754,14 +1093,14 @@ var VoiceDeliveryRuntime = defineComponent2({
754
1093
  type: "button"
755
1094
  }, "Requeue dead letters")
756
1095
  ]) : null,
757
- model.actionError ? h2("p", { class: "absolute-voice-delivery-runtime__error" }, model.actionError) : null,
758
- model.error ? h2("p", { class: "absolute-voice-delivery-runtime__error" }, model.error) : null
1096
+ model.actionError ? h3("p", { class: "absolute-voice-delivery-runtime__error" }, model.actionError) : null,
1097
+ model.error ? h3("p", { class: "absolute-voice-delivery-runtime__error" }, model.error) : null
759
1098
  ]);
760
1099
  };
761
1100
  }
762
1101
  });
763
1102
  // src/vue/VoiceProviderSimulationControls.ts
764
- import { computed, defineComponent as defineComponent3, h as h3 } from "vue";
1103
+ import { computed, defineComponent as defineComponent4, h as h4 } from "vue";
765
1104
 
766
1105
  // src/client/providerSimulationControls.ts
767
1106
  var postSimulation = async (pathPrefix, mode, provider, fetchImpl) => {
@@ -843,7 +1182,7 @@ var createVoiceProviderSimulationControlsStore = (options) => {
843
1182
  };
844
1183
 
845
1184
  // src/client/providerSimulationControlsWidget.ts
846
- var escapeHtml3 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
1185
+ var escapeHtml4 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
847
1186
  var formatKind = (kind) => (kind ?? "stt").toUpperCase();
848
1187
  var createVoiceProviderSimulationControlsViewModel = (snapshot, options) => {
849
1188
  const configuredProviders = options.providers.filter((provider) => provider.configured !== false);
@@ -863,18 +1202,18 @@ var createVoiceProviderSimulationControlsViewModel = (snapshot, options) => {
863
1202
  };
864
1203
  var renderVoiceProviderSimulationControlsHTML = (snapshot, options) => {
865
1204
  const model = createVoiceProviderSimulationControlsViewModel(snapshot, options);
866
- 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("");
867
- 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("");
1205
+ const failureButtons = model.failureProviders.map((provider) => `<button type="button" data-voice-provider-fail="${escapeHtml4(provider.provider)}"${!model.canSimulateFailure || snapshot.isRunning ? " disabled" : ""}>Simulate ${escapeHtml4(provider.provider)} ${escapeHtml4(formatKind(options.kind))} failure</button>`).join("");
1206
+ const recoveryButtons = model.providers.map((provider) => `<button type="button" data-voice-provider-recover="${escapeHtml4(provider.provider)}"${snapshot.isRunning ? " disabled" : ""}>Mark ${escapeHtml4(provider.provider)} recovered</button>`).join("");
868
1207
  return `<section class="absolute-voice-provider-simulation absolute-voice-provider-simulation--${snapshot.error ? "error" : snapshot.isRunning ? "running" : "ready"}">
869
1208
  <header class="absolute-voice-provider-simulation__header">
870
- <span class="absolute-voice-provider-simulation__eyebrow">${escapeHtml3(model.title)}</span>
871
- <strong class="absolute-voice-provider-simulation__label">${escapeHtml3(model.label)}</strong>
1209
+ <span class="absolute-voice-provider-simulation__eyebrow">${escapeHtml4(model.title)}</span>
1210
+ <strong class="absolute-voice-provider-simulation__label">${escapeHtml4(model.label)}</strong>
872
1211
  </header>
873
- <p class="absolute-voice-provider-simulation__description">${escapeHtml3(model.description)}</p>
874
- ${model.canSimulateFailure ? "" : `<p class="absolute-voice-provider-simulation__empty">${escapeHtml3(options.fallbackRequiredMessage ?? "Configure fallback providers before simulating failure.")}</p>`}
1212
+ <p class="absolute-voice-provider-simulation__description">${escapeHtml4(model.description)}</p>
1213
+ ${model.canSimulateFailure ? "" : `<p class="absolute-voice-provider-simulation__empty">${escapeHtml4(options.fallbackRequiredMessage ?? "Configure fallback providers before simulating failure.")}</p>`}
875
1214
  <div class="absolute-voice-provider-simulation__actions">${failureButtons}${recoveryButtons}</div>
876
- ${snapshot.error ? `<p class="absolute-voice-provider-simulation__error">${escapeHtml3(snapshot.error)}</p>` : ""}
877
- ${model.resultText ? `<pre class="absolute-voice-provider-simulation__result">${escapeHtml3(model.resultText)}</pre>` : ""}
1215
+ ${snapshot.error ? `<p class="absolute-voice-provider-simulation__error">${escapeHtml4(snapshot.error)}</p>` : ""}
1216
+ ${model.resultText ? `<pre class="absolute-voice-provider-simulation__result">${escapeHtml4(model.resultText)}</pre>` : ""}
878
1217
  </section>`;
879
1218
  };
880
1219
  var bindVoiceProviderSimulationControls = (element, store) => {
@@ -940,15 +1279,15 @@ var defineVoiceProviderSimulationControlsElement = (tagName = "absolute-voice-pr
940
1279
  };
941
1280
 
942
1281
  // src/vue/useVoiceProviderSimulationControls.ts
943
- import { onUnmounted as onUnmounted3, ref as ref3 } from "vue";
1282
+ import { onUnmounted as onUnmounted4, ref as ref4 } from "vue";
944
1283
  function useVoiceProviderSimulationControls(options) {
945
1284
  const store = createVoiceProviderSimulationControlsStore(options);
946
- const error = ref3(null);
947
- const isRunning = ref3(false);
948
- const lastResult = ref3(null);
949
- const mode = ref3(null);
950
- const provider = ref3(null);
951
- const updatedAt = ref3(undefined);
1285
+ const error = ref4(null);
1286
+ const isRunning = ref4(false);
1287
+ const lastResult = ref4(null);
1288
+ const mode = ref4(null);
1289
+ const provider = ref4(null);
1290
+ const updatedAt = ref4(undefined);
952
1291
  const sync = () => {
953
1292
  const snapshot = store.getSnapshot();
954
1293
  error.value = snapshot.error;
@@ -960,7 +1299,7 @@ function useVoiceProviderSimulationControls(options) {
960
1299
  };
961
1300
  const unsubscribe = store.subscribe(sync);
962
1301
  sync();
963
- onUnmounted3(() => {
1302
+ onUnmounted4(() => {
964
1303
  unsubscribe();
965
1304
  store.close();
966
1305
  });
@@ -976,7 +1315,7 @@ function useVoiceProviderSimulationControls(options) {
976
1315
  }
977
1316
 
978
1317
  // src/vue/VoiceProviderSimulationControls.ts
979
- var VoiceProviderSimulationControls = defineComponent3({
1318
+ var VoiceProviderSimulationControls = defineComponent4({
980
1319
  name: "VoiceProviderSimulationControls",
981
1320
  props: {
982
1321
  class: { default: "", type: String },
@@ -1018,40 +1357,40 @@ var VoiceProviderSimulationControls = defineComponent3({
1018
1357
  const run = (provider, mode) => {
1019
1358
  controls.run(provider, mode).catch(() => {});
1020
1359
  };
1021
- return () => h3("section", {
1360
+ return () => h4("section", {
1022
1361
  class: [
1023
1362
  "absolute-voice-provider-simulation",
1024
1363
  `absolute-voice-provider-simulation--${controls.error.value ? "error" : controls.isRunning.value ? "running" : "ready"}`,
1025
1364
  props.class
1026
1365
  ]
1027
1366
  }, [
1028
- h3("header", { class: "absolute-voice-provider-simulation__header" }, [
1029
- h3("span", { class: "absolute-voice-provider-simulation__eyebrow" }, model.value.title),
1030
- h3("strong", { class: "absolute-voice-provider-simulation__label" }, model.value.label)
1367
+ h4("header", { class: "absolute-voice-provider-simulation__header" }, [
1368
+ h4("span", { class: "absolute-voice-provider-simulation__eyebrow" }, model.value.title),
1369
+ h4("strong", { class: "absolute-voice-provider-simulation__label" }, model.value.label)
1031
1370
  ]),
1032
- h3("p", { class: "absolute-voice-provider-simulation__description" }, model.value.description),
1033
- model.value.canSimulateFailure ? null : h3("p", { class: "absolute-voice-provider-simulation__empty" }, props.fallbackRequiredMessage ?? "Configure fallback providers before simulating failure."),
1034
- h3("div", { class: "absolute-voice-provider-simulation__actions" }, [
1035
- ...model.value.failureProviders.map((provider) => h3("button", {
1371
+ h4("p", { class: "absolute-voice-provider-simulation__description" }, model.value.description),
1372
+ model.value.canSimulateFailure ? null : h4("p", { class: "absolute-voice-provider-simulation__empty" }, props.fallbackRequiredMessage ?? "Configure fallback providers before simulating failure."),
1373
+ h4("div", { class: "absolute-voice-provider-simulation__actions" }, [
1374
+ ...model.value.failureProviders.map((provider) => h4("button", {
1036
1375
  disabled: !model.value.canSimulateFailure || controls.isRunning.value,
1037
1376
  key: `fail-${provider.provider}`,
1038
1377
  onClick: () => run(provider.provider, "failure"),
1039
1378
  type: "button"
1040
1379
  }, `Simulate ${provider.provider} ${props.kind.toUpperCase()} failure`)),
1041
- ...model.value.providers.map((provider) => h3("button", {
1380
+ ...model.value.providers.map((provider) => h4("button", {
1042
1381
  disabled: controls.isRunning.value,
1043
1382
  key: `recover-${provider.provider}`,
1044
1383
  onClick: () => run(provider.provider, "recovery"),
1045
1384
  type: "button"
1046
1385
  }, `Mark ${provider.provider} recovered`))
1047
1386
  ]),
1048
- controls.error.value ? h3("p", { class: "absolute-voice-provider-simulation__error" }, controls.error.value) : null,
1049
- model.value.resultText ? h3("pre", { class: "absolute-voice-provider-simulation__result" }, model.value.resultText) : null
1387
+ controls.error.value ? h4("p", { class: "absolute-voice-provider-simulation__error" }, controls.error.value) : null,
1388
+ model.value.resultText ? h4("pre", { class: "absolute-voice-provider-simulation__result" }, model.value.resultText) : null
1050
1389
  ]);
1051
1390
  }
1052
1391
  });
1053
1392
  // src/vue/VoiceProviderCapabilities.ts
1054
- import { computed as computed2, defineComponent as defineComponent4, h as h4 } from "vue";
1393
+ import { computed as computed2, defineComponent as defineComponent5, h as h5 } from "vue";
1055
1394
 
1056
1395
  // src/client/providerCapabilities.ts
1057
1396
  var fetchVoiceProviderCapabilities = async (path = "/api/provider-capabilities", options = {}) => {
@@ -1133,9 +1472,9 @@ var createVoiceProviderCapabilitiesStore = (path = "/api/provider-capabilities",
1133
1472
  };
1134
1473
 
1135
1474
  // src/client/providerCapabilitiesWidget.ts
1136
- var DEFAULT_TITLE3 = "Provider Capabilities";
1137
- var DEFAULT_DESCRIPTION3 = "Configured, selected, and healthy voice providers for this deployment.";
1138
- var escapeHtml4 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
1475
+ var DEFAULT_TITLE4 = "Provider Capabilities";
1476
+ var DEFAULT_DESCRIPTION4 = "Configured, selected, and healthy voice providers for this deployment.";
1477
+ var escapeHtml5 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
1139
1478
  var formatProvider = (provider) => provider.split(/[-_\s]+/).filter(Boolean).map((part) => `${part[0]?.toUpperCase() ?? ""}${part.slice(1)}`).join(" ") || provider;
1140
1479
  var formatKind2 = (kind) => kind.toUpperCase();
1141
1480
  var formatStatus = (status) => status.split("-").map((part) => `${part[0]?.toUpperCase() ?? ""}${part.slice(1)}`).join(" ");
@@ -1179,36 +1518,36 @@ var createVoiceProviderCapabilitiesViewModel = (snapshot, options = {}) => {
1179
1518
  const selectedCount = snapshot.report?.selected ?? capabilities.filter((capability) => capability.selected).length;
1180
1519
  return {
1181
1520
  capabilities,
1182
- description: options.description ?? DEFAULT_DESCRIPTION3,
1521
+ description: options.description ?? DEFAULT_DESCRIPTION4,
1183
1522
  error: snapshot.error,
1184
1523
  isLoading: snapshot.isLoading,
1185
1524
  label: snapshot.error ? "Unavailable" : capabilities.length ? warningCount > 0 ? `${warningCount} needs attention` : `${selectedCount} selected` : snapshot.isLoading ? "Checking" : "No capabilities",
1186
1525
  status: snapshot.error ? "error" : capabilities.length ? warningCount > 0 ? "warning" : "ready" : snapshot.isLoading ? "loading" : "empty",
1187
- title: options.title ?? DEFAULT_TITLE3,
1526
+ title: options.title ?? DEFAULT_TITLE4,
1188
1527
  updatedAt: snapshot.updatedAt
1189
1528
  };
1190
1529
  };
1191
1530
  var renderVoiceProviderCapabilitiesHTML = (snapshot, options = {}) => {
1192
1531
  const model = createVoiceProviderCapabilitiesViewModel(snapshot, options);
1193
- 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)}">
1532
+ 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--${escapeHtml5(capability.status)}">
1194
1533
  <header>
1195
- <strong>${escapeHtml4(capability.label)}</strong>
1196
- <span>${escapeHtml4(formatStatus(capability.status))}</span>
1534
+ <strong>${escapeHtml5(capability.label)}</strong>
1535
+ <span>${escapeHtml5(formatStatus(capability.status))}</span>
1197
1536
  </header>
1198
- <p>${escapeHtml4(capability.detail)}</p>
1537
+ <p>${escapeHtml5(capability.detail)}</p>
1199
1538
  <dl>${capability.rows.map((row) => `<div>
1200
- <dt>${escapeHtml4(row.label)}</dt>
1201
- <dd>${escapeHtml4(row.value)}</dd>
1539
+ <dt>${escapeHtml5(row.label)}</dt>
1540
+ <dd>${escapeHtml5(row.value)}</dd>
1202
1541
  </div>`).join("")}</dl>
1203
1542
  </article>`).join("")}</div>` : '<p class="absolute-voice-provider-capabilities__empty">Configure provider capabilities to see deployment coverage.</p>';
1204
- return `<section class="absolute-voice-provider-capabilities absolute-voice-provider-capabilities--${escapeHtml4(model.status)}">
1543
+ return `<section class="absolute-voice-provider-capabilities absolute-voice-provider-capabilities--${escapeHtml5(model.status)}">
1205
1544
  <header class="absolute-voice-provider-capabilities__header">
1206
- <span class="absolute-voice-provider-capabilities__eyebrow">${escapeHtml4(model.title)}</span>
1207
- <strong class="absolute-voice-provider-capabilities__label">${escapeHtml4(model.label)}</strong>
1545
+ <span class="absolute-voice-provider-capabilities__eyebrow">${escapeHtml5(model.title)}</span>
1546
+ <strong class="absolute-voice-provider-capabilities__label">${escapeHtml5(model.label)}</strong>
1208
1547
  </header>
1209
- <p class="absolute-voice-provider-capabilities__description">${escapeHtml4(model.description)}</p>
1548
+ <p class="absolute-voice-provider-capabilities__description">${escapeHtml5(model.description)}</p>
1210
1549
  ${capabilities}
1211
- ${model.error ? `<p class="absolute-voice-provider-capabilities__error">${escapeHtml4(model.error)}</p>` : ""}
1550
+ ${model.error ? `<p class="absolute-voice-provider-capabilities__error">${escapeHtml5(model.error)}</p>` : ""}
1212
1551
  </section>`;
1213
1552
  };
1214
1553
  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}`;
@@ -1250,13 +1589,13 @@ var defineVoiceProviderCapabilitiesElement = (tagName = "absolute-voice-provider
1250
1589
  };
1251
1590
 
1252
1591
  // src/vue/useVoiceProviderCapabilities.ts
1253
- import { onUnmounted as onUnmounted4, shallowRef as shallowRef3 } from "vue";
1592
+ import { onUnmounted as onUnmounted5, shallowRef as shallowRef4 } from "vue";
1254
1593
  function useVoiceProviderCapabilities(path = "/api/provider-capabilities", options = {}) {
1255
1594
  const store = createVoiceProviderCapabilitiesStore(path, options);
1256
- const error = shallowRef3(null);
1257
- const isLoading = shallowRef3(false);
1258
- const report = shallowRef3();
1259
- const updatedAt = shallowRef3(undefined);
1595
+ const error = shallowRef4(null);
1596
+ const isLoading = shallowRef4(false);
1597
+ const report = shallowRef4();
1598
+ const updatedAt = shallowRef4(undefined);
1260
1599
  const sync = () => {
1261
1600
  const snapshot = store.getSnapshot();
1262
1601
  error.value = snapshot.error;
@@ -1267,7 +1606,7 @@ function useVoiceProviderCapabilities(path = "/api/provider-capabilities", optio
1267
1606
  const unsubscribe = store.subscribe(sync);
1268
1607
  sync();
1269
1608
  store.refresh().catch(() => {});
1270
- onUnmounted4(() => {
1609
+ onUnmounted5(() => {
1271
1610
  unsubscribe();
1272
1611
  store.close();
1273
1612
  });
@@ -1281,7 +1620,7 @@ function useVoiceProviderCapabilities(path = "/api/provider-capabilities", optio
1281
1620
  }
1282
1621
 
1283
1622
  // src/vue/VoiceProviderCapabilities.ts
1284
- var VoiceProviderCapabilities = defineComponent4({
1623
+ var VoiceProviderCapabilities = defineComponent5({
1285
1624
  name: "VoiceProviderCapabilities",
1286
1625
  props: {
1287
1626
  class: {
@@ -1318,41 +1657,41 @@ var VoiceProviderCapabilities = defineComponent4({
1318
1657
  report: capabilities.report.value,
1319
1658
  updatedAt: capabilities.updatedAt.value
1320
1659
  }, options));
1321
- return () => h4("section", {
1660
+ return () => h5("section", {
1322
1661
  class: [
1323
1662
  "absolute-voice-provider-capabilities",
1324
1663
  `absolute-voice-provider-capabilities--${model.value.status}`,
1325
1664
  props.class
1326
1665
  ]
1327
1666
  }, [
1328
- h4("header", { class: "absolute-voice-provider-capabilities__header" }, [
1329
- h4("span", { class: "absolute-voice-provider-capabilities__eyebrow" }, model.value.title),
1330
- h4("strong", { class: "absolute-voice-provider-capabilities__label" }, model.value.label)
1667
+ h5("header", { class: "absolute-voice-provider-capabilities__header" }, [
1668
+ h5("span", { class: "absolute-voice-provider-capabilities__eyebrow" }, model.value.title),
1669
+ h5("strong", { class: "absolute-voice-provider-capabilities__label" }, model.value.label)
1331
1670
  ]),
1332
- h4("p", { class: "absolute-voice-provider-capabilities__description" }, model.value.description),
1333
- model.value.capabilities.length ? h4("div", { class: "absolute-voice-provider-capabilities__providers" }, model.value.capabilities.map((capability) => h4("article", {
1671
+ h5("p", { class: "absolute-voice-provider-capabilities__description" }, model.value.description),
1672
+ model.value.capabilities.length ? h5("div", { class: "absolute-voice-provider-capabilities__providers" }, model.value.capabilities.map((capability) => h5("article", {
1334
1673
  class: [
1335
1674
  "absolute-voice-provider-capabilities__provider",
1336
1675
  `absolute-voice-provider-capabilities__provider--${capability.status}`
1337
1676
  ],
1338
1677
  key: `${capability.kind}:${capability.provider}`
1339
1678
  }, [
1340
- h4("header", [
1341
- h4("strong", capability.label),
1342
- h4("span", capability.status)
1679
+ h5("header", [
1680
+ h5("strong", capability.label),
1681
+ h5("span", capability.status)
1343
1682
  ]),
1344
- h4("p", capability.detail),
1345
- h4("dl", capability.rows.map((row) => h4("div", { key: row.label }, [
1346
- h4("dt", row.label),
1347
- h4("dd", row.value)
1683
+ h5("p", capability.detail),
1684
+ h5("dl", capability.rows.map((row) => h5("div", { key: row.label }, [
1685
+ h5("dt", row.label),
1686
+ h5("dd", row.value)
1348
1687
  ])))
1349
- ]))) : h4("p", { class: "absolute-voice-provider-capabilities__empty" }, "Configure provider capabilities to see deployment coverage."),
1350
- model.value.error ? h4("p", { class: "absolute-voice-provider-capabilities__error" }, model.value.error) : null
1688
+ ]))) : h5("p", { class: "absolute-voice-provider-capabilities__empty" }, "Configure provider capabilities to see deployment coverage."),
1689
+ model.value.error ? h5("p", { class: "absolute-voice-provider-capabilities__error" }, model.value.error) : null
1351
1690
  ]);
1352
1691
  }
1353
1692
  });
1354
1693
  // src/vue/VoiceProviderStatus.ts
1355
- import { computed as computed3, defineComponent as defineComponent5, h as h5 } from "vue";
1694
+ import { computed as computed3, defineComponent as defineComponent6, h as h6 } from "vue";
1356
1695
 
1357
1696
  // src/client/providerStatus.ts
1358
1697
  var fetchVoiceProviderStatus = async (path = "/api/provider-status", options = {}) => {
@@ -1435,9 +1774,9 @@ var createVoiceProviderStatusStore = (path = "/api/provider-status", options = {
1435
1774
  };
1436
1775
 
1437
1776
  // src/client/providerStatusWidget.ts
1438
- var DEFAULT_TITLE4 = "Voice Providers";
1439
- var DEFAULT_DESCRIPTION4 = "Live provider health, fallback counts, latency, and suppression state from your self-hosted trace store.";
1440
- var escapeHtml5 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
1777
+ var DEFAULT_TITLE5 = "Voice Providers";
1778
+ var DEFAULT_DESCRIPTION5 = "Live provider health, fallback counts, latency, and suppression state from your self-hosted trace store.";
1779
+ var escapeHtml6 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
1441
1780
  var formatProvider2 = (provider) => provider.split(/[-_\s]+/).filter(Boolean).map((part) => `${part[0]?.toUpperCase() ?? ""}${part.slice(1)}`).join(" ") || provider;
1442
1781
  var formatStatus2 = (status) => status.split("-").map((part) => `${part[0]?.toUpperCase() ?? ""}${part.slice(1)}`).join(" ");
1443
1782
  var formatLatency = (value) => typeof value === "number" ? `${value}ms` : "No samples";
@@ -1481,37 +1820,37 @@ var createVoiceProviderStatusViewModel = (snapshot, options = {}) => {
1481
1820
  const warningCount = providers.filter((provider) => isWarningStatus2(provider.status)).length;
1482
1821
  const healthyCount = providers.filter((provider) => provider.status === "healthy").length;
1483
1822
  return {
1484
- description: options.description ?? DEFAULT_DESCRIPTION4,
1823
+ description: options.description ?? DEFAULT_DESCRIPTION5,
1485
1824
  error: snapshot.error,
1486
1825
  isLoading: snapshot.isLoading,
1487
1826
  label: snapshot.error ? "Unavailable" : providers.length ? warningCount > 0 ? `${warningCount} needs attention` : `${healthyCount} healthy` : snapshot.isLoading ? "Checking" : "No provider traffic",
1488
1827
  providers,
1489
1828
  status: snapshot.error ? "error" : providers.length ? warningCount > 0 ? "warning" : "ready" : snapshot.isLoading ? "loading" : "empty",
1490
- title: options.title ?? DEFAULT_TITLE4,
1829
+ title: options.title ?? DEFAULT_TITLE5,
1491
1830
  updatedAt: snapshot.updatedAt
1492
1831
  };
1493
1832
  };
1494
1833
  var renderVoiceProviderStatusHTML = (snapshot, options = {}) => {
1495
1834
  const model = createVoiceProviderStatusViewModel(snapshot, options);
1496
- 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)}">
1835
+ 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--${escapeHtml6(provider.status)}">
1497
1836
  <header>
1498
- <strong>${escapeHtml5(provider.label)}</strong>
1499
- <span>${escapeHtml5(formatStatus2(provider.status))}</span>
1837
+ <strong>${escapeHtml6(provider.label)}</strong>
1838
+ <span>${escapeHtml6(formatStatus2(provider.status))}</span>
1500
1839
  </header>
1501
- <p>${escapeHtml5(provider.detail)}</p>
1840
+ <p>${escapeHtml6(provider.detail)}</p>
1502
1841
  <dl>${provider.rows.map((row) => `<div>
1503
- <dt>${escapeHtml5(row.label)}</dt>
1504
- <dd>${escapeHtml5(row.value)}</dd>
1842
+ <dt>${escapeHtml6(row.label)}</dt>
1843
+ <dd>${escapeHtml6(row.value)}</dd>
1505
1844
  </div>`).join("")}</dl>
1506
1845
  </article>`).join("")}</div>` : '<p class="absolute-voice-provider-status__empty">Run voice traffic to see provider health.</p>';
1507
- return `<section class="absolute-voice-provider-status absolute-voice-provider-status--${escapeHtml5(model.status)}">
1846
+ return `<section class="absolute-voice-provider-status absolute-voice-provider-status--${escapeHtml6(model.status)}">
1508
1847
  <header class="absolute-voice-provider-status__header">
1509
- <span class="absolute-voice-provider-status__eyebrow">${escapeHtml5(model.title)}</span>
1510
- <strong class="absolute-voice-provider-status__label">${escapeHtml5(model.label)}</strong>
1848
+ <span class="absolute-voice-provider-status__eyebrow">${escapeHtml6(model.title)}</span>
1849
+ <strong class="absolute-voice-provider-status__label">${escapeHtml6(model.label)}</strong>
1511
1850
  </header>
1512
- <p class="absolute-voice-provider-status__description">${escapeHtml5(model.description)}</p>
1851
+ <p class="absolute-voice-provider-status__description">${escapeHtml6(model.description)}</p>
1513
1852
  ${providers}
1514
- ${model.error ? `<p class="absolute-voice-provider-status__error">${escapeHtml5(model.error)}</p>` : ""}
1853
+ ${model.error ? `<p class="absolute-voice-provider-status__error">${escapeHtml6(model.error)}</p>` : ""}
1515
1854
  </section>`;
1516
1855
  };
1517
1856
  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}`;
@@ -1553,13 +1892,13 @@ var defineVoiceProviderStatusElement = (tagName = "absolute-voice-provider-statu
1553
1892
  };
1554
1893
 
1555
1894
  // src/vue/useVoiceProviderStatus.ts
1556
- import { onUnmounted as onUnmounted5, ref as ref4, shallowRef as shallowRef4 } from "vue";
1895
+ import { onUnmounted as onUnmounted6, ref as ref5, shallowRef as shallowRef5 } from "vue";
1557
1896
  function useVoiceProviderStatus(path = "/api/provider-status", options = {}) {
1558
1897
  const store = createVoiceProviderStatusStore(path, options);
1559
- const error = ref4(null);
1560
- const isLoading = ref4(false);
1561
- const providers = shallowRef4([]);
1562
- const updatedAt = ref4(undefined);
1898
+ const error = ref5(null);
1899
+ const isLoading = ref5(false);
1900
+ const providers = shallowRef5([]);
1901
+ const updatedAt = ref5(undefined);
1563
1902
  const sync = () => {
1564
1903
  const snapshot = store.getSnapshot();
1565
1904
  error.value = snapshot.error;
@@ -1570,7 +1909,7 @@ function useVoiceProviderStatus(path = "/api/provider-status", options = {}) {
1570
1909
  const unsubscribe = store.subscribe(sync);
1571
1910
  sync();
1572
1911
  store.refresh().catch(() => {});
1573
- onUnmounted5(() => {
1912
+ onUnmounted6(() => {
1574
1913
  unsubscribe();
1575
1914
  store.close();
1576
1915
  });
@@ -1584,7 +1923,7 @@ function useVoiceProviderStatus(path = "/api/provider-status", options = {}) {
1584
1923
  }
1585
1924
 
1586
1925
  // src/vue/VoiceProviderStatus.ts
1587
- var VoiceProviderStatus = defineComponent5({
1926
+ var VoiceProviderStatus = defineComponent6({
1588
1927
  name: "VoiceProviderStatus",
1589
1928
  props: {
1590
1929
  class: {
@@ -1621,41 +1960,41 @@ var VoiceProviderStatus = defineComponent5({
1621
1960
  providers: status.providers.value,
1622
1961
  updatedAt: status.updatedAt.value
1623
1962
  }, options));
1624
- return () => h5("section", {
1963
+ return () => h6("section", {
1625
1964
  class: [
1626
1965
  "absolute-voice-provider-status",
1627
1966
  `absolute-voice-provider-status--${model.value.status}`,
1628
1967
  props.class
1629
1968
  ]
1630
1969
  }, [
1631
- h5("header", { class: "absolute-voice-provider-status__header" }, [
1632
- h5("span", { class: "absolute-voice-provider-status__eyebrow" }, model.value.title),
1633
- h5("strong", { class: "absolute-voice-provider-status__label" }, model.value.label)
1970
+ h6("header", { class: "absolute-voice-provider-status__header" }, [
1971
+ h6("span", { class: "absolute-voice-provider-status__eyebrow" }, model.value.title),
1972
+ h6("strong", { class: "absolute-voice-provider-status__label" }, model.value.label)
1634
1973
  ]),
1635
- h5("p", { class: "absolute-voice-provider-status__description" }, model.value.description),
1636
- model.value.providers.length ? h5("div", { class: "absolute-voice-provider-status__providers" }, model.value.providers.map((provider) => h5("article", {
1974
+ h6("p", { class: "absolute-voice-provider-status__description" }, model.value.description),
1975
+ model.value.providers.length ? h6("div", { class: "absolute-voice-provider-status__providers" }, model.value.providers.map((provider) => h6("article", {
1637
1976
  class: [
1638
1977
  "absolute-voice-provider-status__provider",
1639
1978
  `absolute-voice-provider-status__provider--${provider.status}`
1640
1979
  ],
1641
1980
  key: provider.provider
1642
1981
  }, [
1643
- h5("header", [
1644
- h5("strong", provider.label),
1645
- h5("span", provider.status)
1982
+ h6("header", [
1983
+ h6("strong", provider.label),
1984
+ h6("span", provider.status)
1646
1985
  ]),
1647
- h5("p", provider.detail),
1648
- h5("dl", provider.rows.map((row) => h5("div", { key: row.label }, [
1649
- h5("dt", row.label),
1650
- h5("dd", row.value)
1986
+ h6("p", provider.detail),
1987
+ h6("dl", provider.rows.map((row) => h6("div", { key: row.label }, [
1988
+ h6("dt", row.label),
1989
+ h6("dd", row.value)
1651
1990
  ])))
1652
- ]))) : h5("p", { class: "absolute-voice-provider-status__empty" }, "Run voice traffic to see provider health."),
1653
- model.value.error ? h5("p", { class: "absolute-voice-provider-status__error" }, model.value.error) : null
1991
+ ]))) : h6("p", { class: "absolute-voice-provider-status__empty" }, "Run voice traffic to see provider health."),
1992
+ model.value.error ? h6("p", { class: "absolute-voice-provider-status__error" }, model.value.error) : null
1654
1993
  ]);
1655
1994
  }
1656
1995
  });
1657
1996
  // src/vue/VoiceRoutingStatus.ts
1658
- import { computed as computed4, defineComponent as defineComponent6, h as h6 } from "vue";
1997
+ import { computed as computed4, defineComponent as defineComponent7, h as h7 } from "vue";
1659
1998
 
1660
1999
  // src/client/routingStatus.ts
1661
2000
  var fetchVoiceRoutingStatus = async (path = "/api/routing/latest", options = {}) => {
@@ -1738,9 +2077,9 @@ var createVoiceRoutingStatusStore = (path = "/api/routing/latest", options = {})
1738
2077
  };
1739
2078
 
1740
2079
  // src/client/routingStatusWidget.ts
1741
- var DEFAULT_TITLE5 = "Voice Routing";
1742
- var DEFAULT_DESCRIPTION5 = "Latest provider routing decision from the self-hosted trace store.";
1743
- var escapeHtml6 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
2080
+ var DEFAULT_TITLE6 = "Voice Routing";
2081
+ var DEFAULT_DESCRIPTION6 = "Latest provider routing decision from the self-hosted trace store.";
2082
+ var escapeHtml7 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
1744
2083
  var formatValue = (value, fallback = "None") => typeof value === "string" && value.trim() ? value : typeof value === "number" && Number.isFinite(value) ? String(value) : fallback;
1745
2084
  var createVoiceRoutingStatusViewModel = (snapshot, options = {}) => {
1746
2085
  const decision = snapshot.decision;
@@ -1764,30 +2103,30 @@ var createVoiceRoutingStatusViewModel = (snapshot, options = {}) => {
1764
2103
  ] : [];
1765
2104
  return {
1766
2105
  decision,
1767
- description: options.description ?? DEFAULT_DESCRIPTION5,
2106
+ description: options.description ?? DEFAULT_DESCRIPTION6,
1768
2107
  error: snapshot.error,
1769
2108
  isLoading: snapshot.isLoading,
1770
2109
  label: snapshot.error ? "Unavailable" : decision ? `${formatValue(decision.kind).toUpperCase()} ${formatValue(decision.status, "unknown")}` : snapshot.isLoading ? "Checking" : "No routing yet",
1771
2110
  rows,
1772
2111
  status: snapshot.error ? "error" : decision ? "ready" : snapshot.isLoading ? "loading" : "empty",
1773
- title: options.title ?? DEFAULT_TITLE5,
2112
+ title: options.title ?? DEFAULT_TITLE6,
1774
2113
  updatedAt: snapshot.updatedAt
1775
2114
  };
1776
2115
  };
1777
2116
  var renderVoiceRoutingStatusHTML = (snapshot, options = {}) => {
1778
2117
  const model = createVoiceRoutingStatusViewModel(snapshot, options);
1779
2118
  const rows = model.rows.length ? `<div class="absolute-voice-routing-status__grid">${model.rows.map((row) => `<div>
1780
- <span>${escapeHtml6(row.label)}</span>
1781
- <strong>${escapeHtml6(row.value)}</strong>
2119
+ <span>${escapeHtml7(row.label)}</span>
2120
+ <strong>${escapeHtml7(row.value)}</strong>
1782
2121
  </div>`).join("")}</div>` : '<p class="absolute-voice-routing-status__empty">Start a voice session to see the selected provider.</p>';
1783
- return `<section class="absolute-voice-routing-status absolute-voice-routing-status--${escapeHtml6(model.status)}">
2122
+ return `<section class="absolute-voice-routing-status absolute-voice-routing-status--${escapeHtml7(model.status)}">
1784
2123
  <header class="absolute-voice-routing-status__header">
1785
- <span class="absolute-voice-routing-status__eyebrow">${escapeHtml6(model.title)}</span>
1786
- <strong class="absolute-voice-routing-status__label">${escapeHtml6(model.label)}</strong>
2124
+ <span class="absolute-voice-routing-status__eyebrow">${escapeHtml7(model.title)}</span>
2125
+ <strong class="absolute-voice-routing-status__label">${escapeHtml7(model.label)}</strong>
1787
2126
  </header>
1788
- <p class="absolute-voice-routing-status__description">${escapeHtml6(model.description)}</p>
2127
+ <p class="absolute-voice-routing-status__description">${escapeHtml7(model.description)}</p>
1789
2128
  ${rows}
1790
- ${model.error ? `<p class="absolute-voice-routing-status__error">${escapeHtml6(model.error)}</p>` : ""}
2129
+ ${model.error ? `<p class="absolute-voice-routing-status__error">${escapeHtml7(model.error)}</p>` : ""}
1791
2130
  </section>`;
1792
2131
  };
1793
2132
  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}`;
@@ -1829,13 +2168,13 @@ var defineVoiceRoutingStatusElement = (tagName = "absolute-voice-routing-status"
1829
2168
  };
1830
2169
 
1831
2170
  // src/vue/useVoiceRoutingStatus.ts
1832
- import { onUnmounted as onUnmounted6, ref as ref5, shallowRef as shallowRef5 } from "vue";
2171
+ import { onUnmounted as onUnmounted7, ref as ref6, shallowRef as shallowRef6 } from "vue";
1833
2172
  function useVoiceRoutingStatus(path = "/api/routing/latest", options = {}) {
1834
2173
  const store = createVoiceRoutingStatusStore(path, options);
1835
- const decision = shallowRef5(null);
1836
- const error = ref5(null);
1837
- const isLoading = ref5(false);
1838
- const updatedAt = ref5(undefined);
2174
+ const decision = shallowRef6(null);
2175
+ const error = ref6(null);
2176
+ const isLoading = ref6(false);
2177
+ const updatedAt = ref6(undefined);
1839
2178
  const sync = () => {
1840
2179
  const snapshot = store.getSnapshot();
1841
2180
  decision.value = snapshot.decision;
@@ -1846,7 +2185,7 @@ function useVoiceRoutingStatus(path = "/api/routing/latest", options = {}) {
1846
2185
  const unsubscribe = store.subscribe(sync);
1847
2186
  sync();
1848
2187
  store.refresh().catch(() => {});
1849
- onUnmounted6(() => {
2188
+ onUnmounted7(() => {
1850
2189
  unsubscribe();
1851
2190
  store.close();
1852
2191
  });
@@ -1860,7 +2199,7 @@ function useVoiceRoutingStatus(path = "/api/routing/latest", options = {}) {
1860
2199
  }
1861
2200
 
1862
2201
  // src/vue/VoiceRoutingStatus.ts
1863
- var VoiceRoutingStatus = defineComponent6({
2202
+ var VoiceRoutingStatus = defineComponent7({
1864
2203
  name: "VoiceRoutingStatus",
1865
2204
  props: {
1866
2205
  class: {
@@ -1897,28 +2236,28 @@ var VoiceRoutingStatus = defineComponent6({
1897
2236
  isLoading: status.isLoading.value,
1898
2237
  updatedAt: status.updatedAt.value
1899
2238
  }, options));
1900
- return () => h6("section", {
2239
+ return () => h7("section", {
1901
2240
  class: [
1902
2241
  "absolute-voice-routing-status",
1903
2242
  `absolute-voice-routing-status--${model.value.status}`,
1904
2243
  props.class
1905
2244
  ]
1906
2245
  }, [
1907
- h6("header", { class: "absolute-voice-routing-status__header" }, [
1908
- h6("span", { class: "absolute-voice-routing-status__eyebrow" }, model.value.title),
1909
- h6("strong", { class: "absolute-voice-routing-status__label" }, model.value.label)
2246
+ h7("header", { class: "absolute-voice-routing-status__header" }, [
2247
+ h7("span", { class: "absolute-voice-routing-status__eyebrow" }, model.value.title),
2248
+ h7("strong", { class: "absolute-voice-routing-status__label" }, model.value.label)
1910
2249
  ]),
1911
- h6("p", { class: "absolute-voice-routing-status__description" }, model.value.description),
1912
- model.value.rows.length ? h6("div", { class: "absolute-voice-routing-status__grid" }, model.value.rows.map((row) => h6("div", { key: row.label }, [
1913
- h6("span", row.label),
1914
- h6("strong", row.value)
1915
- ]))) : h6("p", { class: "absolute-voice-routing-status__empty" }, "Start a voice session to see the selected provider."),
1916
- model.value.error ? h6("p", { class: "absolute-voice-routing-status__error" }, model.value.error) : null
2250
+ h7("p", { class: "absolute-voice-routing-status__description" }, model.value.description),
2251
+ model.value.rows.length ? h7("div", { class: "absolute-voice-routing-status__grid" }, model.value.rows.map((row) => h7("div", { key: row.label }, [
2252
+ h7("span", row.label),
2253
+ h7("strong", row.value)
2254
+ ]))) : h7("p", { class: "absolute-voice-routing-status__empty" }, "Start a voice session to see the selected provider."),
2255
+ model.value.error ? h7("p", { class: "absolute-voice-routing-status__error" }, model.value.error) : null
1917
2256
  ]);
1918
2257
  }
1919
2258
  });
1920
2259
  // src/vue/VoiceTurnLatency.ts
1921
- import { computed as computed5, defineComponent as defineComponent7, h as h7 } from "vue";
2260
+ import { computed as computed5, defineComponent as defineComponent8, h as h8 } from "vue";
1922
2261
 
1923
2262
  // src/client/turnLatency.ts
1924
2263
  var fetchVoiceTurnLatency = async (path = "/api/turn-latency", options = {}) => {
@@ -2024,10 +2363,10 @@ var createVoiceTurnLatencyStore = (path = "/api/turn-latency", options = {}) =>
2024
2363
  };
2025
2364
 
2026
2365
  // src/client/turnLatencyWidget.ts
2027
- var DEFAULT_TITLE6 = "Turn Latency";
2028
- var DEFAULT_DESCRIPTION6 = "Per-turn timing from first transcript to commit and assistant response start.";
2366
+ var DEFAULT_TITLE7 = "Turn Latency";
2367
+ var DEFAULT_DESCRIPTION7 = "Per-turn timing from first transcript to commit and assistant response start.";
2029
2368
  var DEFAULT_PROOF_LABEL = "Run latency proof";
2030
- var escapeHtml7 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
2369
+ var escapeHtml8 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
2031
2370
  var formatMs = (value) => typeof value === "number" ? `${Math.round(value)}ms` : "n/a";
2032
2371
  var createVoiceTurnLatencyViewModel = (snapshot, options = {}) => {
2033
2372
  const turns = (snapshot.report?.turns ?? []).map((turn) => ({
@@ -2041,39 +2380,39 @@ var createVoiceTurnLatencyViewModel = (snapshot, options = {}) => {
2041
2380
  const warningCount = snapshot.report?.warnings ?? turns.filter((turn) => turn.status === "warn").length;
2042
2381
  const failedCount = snapshot.report?.failed ?? turns.filter((turn) => turn.status === "fail").length;
2043
2382
  return {
2044
- description: options.description ?? DEFAULT_DESCRIPTION6,
2383
+ description: options.description ?? DEFAULT_DESCRIPTION7,
2045
2384
  error: snapshot.error,
2046
2385
  isLoading: snapshot.isLoading,
2047
2386
  label: snapshot.error ? "Unavailable" : turns.length ? failedCount > 0 ? `${failedCount} slow` : warningCount > 0 ? `${warningCount} warnings` : `avg ${formatMs(snapshot.report?.averageTotalMs)}` : snapshot.isLoading ? "Checking" : "No turns",
2048
2387
  proofLabel: options.proofPath ? options.proofLabel ?? DEFAULT_PROOF_LABEL : undefined,
2049
2388
  showProofAction: Boolean(options.proofPath),
2050
2389
  status: snapshot.error ? "error" : turns.length ? failedCount > 0 || warningCount > 0 ? "warning" : "ready" : snapshot.isLoading ? "loading" : "empty",
2051
- title: options.title ?? DEFAULT_TITLE6,
2390
+ title: options.title ?? DEFAULT_TITLE7,
2052
2391
  turns,
2053
2392
  updatedAt: snapshot.updatedAt
2054
2393
  };
2055
2394
  };
2056
2395
  var renderVoiceTurnLatencyHTML = (snapshot, options = {}) => {
2057
2396
  const model = createVoiceTurnLatencyViewModel(snapshot, options);
2058
- 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)}">
2397
+ 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--${escapeHtml8(turn.status)}">
2059
2398
  <header>
2060
- <strong>${escapeHtml7(turn.label)}</strong>
2061
- <span>${escapeHtml7(turn.status)}</span>
2399
+ <strong>${escapeHtml8(turn.label)}</strong>
2400
+ <span>${escapeHtml8(turn.status)}</span>
2062
2401
  </header>
2063
2402
  <dl>${turn.rows.map((row) => `<div>
2064
- <dt>${escapeHtml7(row.label)}</dt>
2065
- <dd>${escapeHtml7(row.value)}</dd>
2403
+ <dt>${escapeHtml8(row.label)}</dt>
2404
+ <dd>${escapeHtml8(row.value)}</dd>
2066
2405
  </div>`).join("")}</dl>
2067
2406
  </article>`).join("")}</div>` : '<p class="absolute-voice-turn-latency__empty">Complete a voice turn to see latency diagnostics.</p>';
2068
- return `<section class="absolute-voice-turn-latency absolute-voice-turn-latency--${escapeHtml7(model.status)}">
2407
+ return `<section class="absolute-voice-turn-latency absolute-voice-turn-latency--${escapeHtml8(model.status)}">
2069
2408
  <header class="absolute-voice-turn-latency__header">
2070
- <span class="absolute-voice-turn-latency__eyebrow">${escapeHtml7(model.title)}</span>
2071
- <strong class="absolute-voice-turn-latency__label">${escapeHtml7(model.label)}</strong>
2409
+ <span class="absolute-voice-turn-latency__eyebrow">${escapeHtml8(model.title)}</span>
2410
+ <strong class="absolute-voice-turn-latency__label">${escapeHtml8(model.label)}</strong>
2072
2411
  </header>
2073
- <p class="absolute-voice-turn-latency__description">${escapeHtml7(model.description)}</p>
2074
- ${model.showProofAction ? `<button class="absolute-voice-turn-latency__proof" data-absolute-voice-turn-latency-proof type="button">${escapeHtml7(model.proofLabel ?? DEFAULT_PROOF_LABEL)}</button>` : ""}
2412
+ <p class="absolute-voice-turn-latency__description">${escapeHtml8(model.description)}</p>
2413
+ ${model.showProofAction ? `<button class="absolute-voice-turn-latency__proof" data-absolute-voice-turn-latency-proof type="button">${escapeHtml8(model.proofLabel ?? DEFAULT_PROOF_LABEL)}</button>` : ""}
2075
2414
  ${turns}
2076
- ${model.error ? `<p class="absolute-voice-turn-latency__error">${escapeHtml7(model.error)}</p>` : ""}
2415
+ ${model.error ? `<p class="absolute-voice-turn-latency__error">${escapeHtml8(model.error)}</p>` : ""}
2077
2416
  </section>`;
2078
2417
  };
2079
2418
  var mountVoiceTurnLatency = (element, path = "/api/turn-latency", options = {}) => {
@@ -2124,13 +2463,13 @@ var defineVoiceTurnLatencyElement = (tagName = "absolute-voice-turn-latency") =>
2124
2463
  };
2125
2464
 
2126
2465
  // src/vue/useVoiceTurnLatency.ts
2127
- import { onUnmounted as onUnmounted7, shallowRef as shallowRef6 } from "vue";
2466
+ import { onUnmounted as onUnmounted8, shallowRef as shallowRef7 } from "vue";
2128
2467
  function useVoiceTurnLatency(path = "/api/turn-latency", options = {}) {
2129
2468
  const store = createVoiceTurnLatencyStore(path, options);
2130
- const error = shallowRef6(null);
2131
- const isLoading = shallowRef6(false);
2132
- const report = shallowRef6();
2133
- const updatedAt = shallowRef6(undefined);
2469
+ const error = shallowRef7(null);
2470
+ const isLoading = shallowRef7(false);
2471
+ const report = shallowRef7();
2472
+ const updatedAt = shallowRef7(undefined);
2134
2473
  const sync = () => {
2135
2474
  const snapshot = store.getSnapshot();
2136
2475
  error.value = snapshot.error;
@@ -2141,7 +2480,7 @@ function useVoiceTurnLatency(path = "/api/turn-latency", options = {}) {
2141
2480
  const unsubscribe = store.subscribe(sync);
2142
2481
  sync();
2143
2482
  store.refresh().catch(() => {});
2144
- onUnmounted7(() => {
2483
+ onUnmounted8(() => {
2145
2484
  unsubscribe();
2146
2485
  store.close();
2147
2486
  });
@@ -2156,7 +2495,7 @@ function useVoiceTurnLatency(path = "/api/turn-latency", options = {}) {
2156
2495
  }
2157
2496
 
2158
2497
  // src/vue/VoiceTurnLatency.ts
2159
- var VoiceTurnLatency = defineComponent7({
2498
+ var VoiceTurnLatency = defineComponent8({
2160
2499
  name: "VoiceTurnLatency",
2161
2500
  props: {
2162
2501
  class: { default: "", type: String },
@@ -2182,47 +2521,47 @@ var VoiceTurnLatency = defineComponent7({
2182
2521
  report: latency.report.value,
2183
2522
  updatedAt: latency.updatedAt.value
2184
2523
  }, options));
2185
- return () => h7("section", {
2524
+ return () => h8("section", {
2186
2525
  class: [
2187
2526
  "absolute-voice-turn-latency",
2188
2527
  `absolute-voice-turn-latency--${model.value.status}`,
2189
2528
  props.class
2190
2529
  ]
2191
2530
  }, [
2192
- h7("header", { class: "absolute-voice-turn-latency__header" }, [
2193
- h7("span", { class: "absolute-voice-turn-latency__eyebrow" }, model.value.title),
2194
- h7("strong", { class: "absolute-voice-turn-latency__label" }, model.value.label)
2531
+ h8("header", { class: "absolute-voice-turn-latency__header" }, [
2532
+ h8("span", { class: "absolute-voice-turn-latency__eyebrow" }, model.value.title),
2533
+ h8("strong", { class: "absolute-voice-turn-latency__label" }, model.value.label)
2195
2534
  ]),
2196
- h7("p", { class: "absolute-voice-turn-latency__description" }, model.value.description),
2197
- model.value.showProofAction ? h7("button", {
2535
+ h8("p", { class: "absolute-voice-turn-latency__description" }, model.value.description),
2536
+ model.value.showProofAction ? h8("button", {
2198
2537
  class: "absolute-voice-turn-latency__proof",
2199
2538
  onClick: () => {
2200
2539
  latency.runProof().catch(() => {});
2201
2540
  },
2202
2541
  type: "button"
2203
2542
  }, model.value.proofLabel) : null,
2204
- model.value.turns.length ? h7("div", { class: "absolute-voice-turn-latency__turns" }, model.value.turns.map((turn) => h7("article", {
2543
+ model.value.turns.length ? h8("div", { class: "absolute-voice-turn-latency__turns" }, model.value.turns.map((turn) => h8("article", {
2205
2544
  class: [
2206
2545
  "absolute-voice-turn-latency__turn",
2207
2546
  `absolute-voice-turn-latency__turn--${turn.status}`
2208
2547
  ],
2209
2548
  key: `${turn.sessionId}:${turn.turnId}`
2210
2549
  }, [
2211
- h7("header", [
2212
- h7("strong", turn.label),
2213
- h7("span", turn.status)
2550
+ h8("header", [
2551
+ h8("strong", turn.label),
2552
+ h8("span", turn.status)
2214
2553
  ]),
2215
- h7("dl", turn.rows.map((row) => h7("div", { key: row.label }, [
2216
- h7("dt", row.label),
2217
- h7("dd", row.value)
2554
+ h8("dl", turn.rows.map((row) => h8("div", { key: row.label }, [
2555
+ h8("dt", row.label),
2556
+ h8("dd", row.value)
2218
2557
  ])))
2219
- ]))) : h7("p", { class: "absolute-voice-turn-latency__empty" }, "Complete a voice turn to see latency diagnostics."),
2220
- model.value.error ? h7("p", { class: "absolute-voice-turn-latency__error" }, model.value.error) : null
2558
+ ]))) : h8("p", { class: "absolute-voice-turn-latency__empty" }, "Complete a voice turn to see latency diagnostics."),
2559
+ model.value.error ? h8("p", { class: "absolute-voice-turn-latency__error" }, model.value.error) : null
2221
2560
  ]);
2222
2561
  }
2223
2562
  });
2224
2563
  // src/vue/VoiceTurnQuality.ts
2225
- import { computed as computed6, defineComponent as defineComponent8, h as h8 } from "vue";
2564
+ import { computed as computed6, defineComponent as defineComponent9, h as h9 } from "vue";
2226
2565
 
2227
2566
  // src/client/turnQuality.ts
2228
2567
  var fetchVoiceTurnQuality = async (path = "/api/turn-quality", options = {}) => {
@@ -2304,9 +2643,9 @@ var createVoiceTurnQualityStore = (path = "/api/turn-quality", options = {}) =>
2304
2643
  };
2305
2644
 
2306
2645
  // src/client/turnQualityWidget.ts
2307
- var DEFAULT_TITLE7 = "Turn Quality";
2308
- var DEFAULT_DESCRIPTION7 = "Per-turn STT confidence, fallback selection, corrections, and transcript coverage.";
2309
- var escapeHtml8 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
2646
+ var DEFAULT_TITLE8 = "Turn Quality";
2647
+ var DEFAULT_DESCRIPTION8 = "Per-turn STT confidence, fallback selection, corrections, and transcript coverage.";
2648
+ var escapeHtml9 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
2310
2649
  var formatConfidence = (value) => typeof value === "number" ? `${Math.round(value * 100)}%` : "n/a";
2311
2650
  var formatMaybe = (value) => value === undefined || value === "" ? "n/a" : String(value);
2312
2651
  var getTurnDetail = (turn) => {
@@ -2344,37 +2683,37 @@ var createVoiceTurnQualityViewModel = (snapshot, options = {}) => {
2344
2683
  const warningCount = snapshot.report?.warnings ?? turns.filter((turn) => turn.status === "warn").length;
2345
2684
  const failedCount = snapshot.report?.failed ?? turns.filter((turn) => turn.status === "fail").length;
2346
2685
  return {
2347
- description: options.description ?? DEFAULT_DESCRIPTION7,
2686
+ description: options.description ?? DEFAULT_DESCRIPTION8,
2348
2687
  error: snapshot.error,
2349
2688
  isLoading: snapshot.isLoading,
2350
2689
  label: snapshot.error ? "Unavailable" : turns.length ? failedCount > 0 ? `${failedCount} failed` : warningCount > 0 ? `${warningCount} warnings` : `${turns.length} healthy` : snapshot.isLoading ? "Checking" : "No turns",
2351
2690
  status: snapshot.error ? "error" : turns.length ? failedCount > 0 || warningCount > 0 ? "warning" : "ready" : snapshot.isLoading ? "loading" : "empty",
2352
- title: options.title ?? DEFAULT_TITLE7,
2691
+ title: options.title ?? DEFAULT_TITLE8,
2353
2692
  turns,
2354
2693
  updatedAt: snapshot.updatedAt
2355
2694
  };
2356
2695
  };
2357
2696
  var renderVoiceTurnQualityHTML = (snapshot, options = {}) => {
2358
2697
  const model = createVoiceTurnQualityViewModel(snapshot, options);
2359
- 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)}">
2698
+ 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--${escapeHtml9(turn.status)}">
2360
2699
  <header>
2361
- <strong>${escapeHtml8(turn.label)}</strong>
2362
- <span>${escapeHtml8(turn.status)}</span>
2700
+ <strong>${escapeHtml9(turn.label)}</strong>
2701
+ <span>${escapeHtml9(turn.status)}</span>
2363
2702
  </header>
2364
- <p>${escapeHtml8(turn.detail)}</p>
2703
+ <p>${escapeHtml9(turn.detail)}</p>
2365
2704
  <dl>${turn.rows.map((row) => `<div>
2366
- <dt>${escapeHtml8(row.label)}</dt>
2367
- <dd>${escapeHtml8(row.value)}</dd>
2705
+ <dt>${escapeHtml9(row.label)}</dt>
2706
+ <dd>${escapeHtml9(row.value)}</dd>
2368
2707
  </div>`).join("")}</dl>
2369
2708
  </article>`).join("")}</div>` : '<p class="absolute-voice-turn-quality__empty">Complete a voice turn to see STT quality diagnostics.</p>';
2370
- return `<section class="absolute-voice-turn-quality absolute-voice-turn-quality--${escapeHtml8(model.status)}">
2709
+ return `<section class="absolute-voice-turn-quality absolute-voice-turn-quality--${escapeHtml9(model.status)}">
2371
2710
  <header class="absolute-voice-turn-quality__header">
2372
- <span class="absolute-voice-turn-quality__eyebrow">${escapeHtml8(model.title)}</span>
2373
- <strong class="absolute-voice-turn-quality__label">${escapeHtml8(model.label)}</strong>
2711
+ <span class="absolute-voice-turn-quality__eyebrow">${escapeHtml9(model.title)}</span>
2712
+ <strong class="absolute-voice-turn-quality__label">${escapeHtml9(model.label)}</strong>
2374
2713
  </header>
2375
- <p class="absolute-voice-turn-quality__description">${escapeHtml8(model.description)}</p>
2714
+ <p class="absolute-voice-turn-quality__description">${escapeHtml9(model.description)}</p>
2376
2715
  ${turns}
2377
- ${model.error ? `<p class="absolute-voice-turn-quality__error">${escapeHtml8(model.error)}</p>` : ""}
2716
+ ${model.error ? `<p class="absolute-voice-turn-quality__error">${escapeHtml9(model.error)}</p>` : ""}
2378
2717
  </section>`;
2379
2718
  };
2380
2719
  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}`;
@@ -2416,13 +2755,13 @@ var defineVoiceTurnQualityElement = (tagName = "absolute-voice-turn-quality") =>
2416
2755
  };
2417
2756
 
2418
2757
  // src/vue/useVoiceTurnQuality.ts
2419
- import { onUnmounted as onUnmounted8, shallowRef as shallowRef7 } from "vue";
2758
+ import { onUnmounted as onUnmounted9, shallowRef as shallowRef8 } from "vue";
2420
2759
  function useVoiceTurnQuality(path = "/api/turn-quality", options = {}) {
2421
2760
  const store = createVoiceTurnQualityStore(path, options);
2422
- const error = shallowRef7(null);
2423
- const isLoading = shallowRef7(false);
2424
- const report = shallowRef7();
2425
- const updatedAt = shallowRef7(undefined);
2761
+ const error = shallowRef8(null);
2762
+ const isLoading = shallowRef8(false);
2763
+ const report = shallowRef8();
2764
+ const updatedAt = shallowRef8(undefined);
2426
2765
  const sync = () => {
2427
2766
  const snapshot = store.getSnapshot();
2428
2767
  error.value = snapshot.error;
@@ -2433,7 +2772,7 @@ function useVoiceTurnQuality(path = "/api/turn-quality", options = {}) {
2433
2772
  const unsubscribe = store.subscribe(sync);
2434
2773
  sync();
2435
2774
  store.refresh().catch(() => {});
2436
- onUnmounted8(() => {
2775
+ onUnmounted9(() => {
2437
2776
  unsubscribe();
2438
2777
  store.close();
2439
2778
  });
@@ -2441,7 +2780,7 @@ function useVoiceTurnQuality(path = "/api/turn-quality", options = {}) {
2441
2780
  }
2442
2781
 
2443
2782
  // src/vue/VoiceTurnQuality.ts
2444
- var VoiceTurnQuality = defineComponent8({
2783
+ var VoiceTurnQuality = defineComponent9({
2445
2784
  name: "VoiceTurnQuality",
2446
2785
  props: {
2447
2786
  class: { default: "", type: String },
@@ -2463,41 +2802,41 @@ var VoiceTurnQuality = defineComponent8({
2463
2802
  report: quality.report.value,
2464
2803
  updatedAt: quality.updatedAt.value
2465
2804
  }, options));
2466
- return () => h8("section", {
2805
+ return () => h9("section", {
2467
2806
  class: [
2468
2807
  "absolute-voice-turn-quality",
2469
2808
  `absolute-voice-turn-quality--${model.value.status}`,
2470
2809
  props.class
2471
2810
  ]
2472
2811
  }, [
2473
- h8("header", { class: "absolute-voice-turn-quality__header" }, [
2474
- h8("span", { class: "absolute-voice-turn-quality__eyebrow" }, model.value.title),
2475
- h8("strong", { class: "absolute-voice-turn-quality__label" }, model.value.label)
2812
+ h9("header", { class: "absolute-voice-turn-quality__header" }, [
2813
+ h9("span", { class: "absolute-voice-turn-quality__eyebrow" }, model.value.title),
2814
+ h9("strong", { class: "absolute-voice-turn-quality__label" }, model.value.label)
2476
2815
  ]),
2477
- h8("p", { class: "absolute-voice-turn-quality__description" }, model.value.description),
2478
- model.value.turns.length ? h8("div", { class: "absolute-voice-turn-quality__turns" }, model.value.turns.map((turn) => h8("article", {
2816
+ h9("p", { class: "absolute-voice-turn-quality__description" }, model.value.description),
2817
+ model.value.turns.length ? h9("div", { class: "absolute-voice-turn-quality__turns" }, model.value.turns.map((turn) => h9("article", {
2479
2818
  class: [
2480
2819
  "absolute-voice-turn-quality__turn",
2481
2820
  `absolute-voice-turn-quality__turn--${turn.status}`
2482
2821
  ],
2483
2822
  key: `${turn.sessionId}:${turn.turnId}`
2484
2823
  }, [
2485
- h8("header", [
2486
- h8("strong", turn.label),
2487
- h8("span", turn.status)
2824
+ h9("header", [
2825
+ h9("strong", turn.label),
2826
+ h9("span", turn.status)
2488
2827
  ]),
2489
- h8("p", turn.detail),
2490
- h8("dl", turn.rows.map((row) => h8("div", { key: row.label }, [
2491
- h8("dt", row.label),
2492
- h8("dd", row.value)
2828
+ h9("p", turn.detail),
2829
+ h9("dl", turn.rows.map((row) => h9("div", { key: row.label }, [
2830
+ h9("dt", row.label),
2831
+ h9("dd", row.value)
2493
2832
  ])))
2494
- ]))) : h8("p", { class: "absolute-voice-turn-quality__empty" }, "Complete a voice turn to see STT quality diagnostics."),
2495
- model.value.error ? h8("p", { class: "absolute-voice-turn-quality__error" }, model.value.error) : null
2833
+ ]))) : h9("p", { class: "absolute-voice-turn-quality__empty" }, "Complete a voice turn to see STT quality diagnostics."),
2834
+ model.value.error ? h9("p", { class: "absolute-voice-turn-quality__error" }, model.value.error) : null
2496
2835
  ]);
2497
2836
  }
2498
2837
  });
2499
2838
  // src/vue/useVoiceCampaignDialerProof.ts
2500
- import { onUnmounted as onUnmounted9, shallowRef as shallowRef8 } from "vue";
2839
+ import { onUnmounted as onUnmounted10, shallowRef as shallowRef9 } from "vue";
2501
2840
 
2502
2841
  // src/client/campaignDialerProof.ts
2503
2842
  var fetchVoiceCampaignDialerProofStatus = async (path = "/api/voice/campaigns/dialer-proof", options = {}) => {
@@ -2620,11 +2959,11 @@ var createVoiceCampaignDialerProofStore = (path = "/api/voice/campaigns/dialer-p
2620
2959
  // src/vue/useVoiceCampaignDialerProof.ts
2621
2960
  function useVoiceCampaignDialerProof(path = "/api/voice/campaigns/dialer-proof", options = {}) {
2622
2961
  const store = createVoiceCampaignDialerProofStore(path, options);
2623
- const error = shallowRef8(null);
2624
- const isLoading = shallowRef8(false);
2625
- const report = shallowRef8();
2626
- const status = shallowRef8();
2627
- const updatedAt = shallowRef8(undefined);
2962
+ const error = shallowRef9(null);
2963
+ const isLoading = shallowRef9(false);
2964
+ const report = shallowRef9();
2965
+ const status = shallowRef9();
2966
+ const updatedAt = shallowRef9(undefined);
2628
2967
  const sync = () => {
2629
2968
  const snapshot = store.getSnapshot();
2630
2969
  error.value = snapshot.error;
@@ -2638,7 +2977,7 @@ function useVoiceCampaignDialerProof(path = "/api/voice/campaigns/dialer-proof",
2638
2977
  if (typeof window !== "undefined") {
2639
2978
  store.refresh().catch(() => {});
2640
2979
  }
2641
- onUnmounted9(() => {
2980
+ onUnmounted10(() => {
2642
2981
  unsubscribe();
2643
2982
  store.close();
2644
2983
  });
@@ -2653,7 +2992,7 @@ function useVoiceCampaignDialerProof(path = "/api/voice/campaigns/dialer-proof",
2653
2992
  };
2654
2993
  }
2655
2994
  // src/vue/useVoiceStream.ts
2656
- import { onUnmounted as onUnmounted10, ref as ref6, shallowRef as shallowRef9 } from "vue";
2995
+ import { onUnmounted as onUnmounted11, ref as ref7, shallowRef as shallowRef10 } from "vue";
2657
2996
 
2658
2997
  // src/client/actions.ts
2659
2998
  var normalizeErrorMessage = (value) => {
@@ -3298,16 +3637,16 @@ var createVoiceStream = (path, options = {}) => {
3298
3637
  // src/vue/useVoiceStream.ts
3299
3638
  function useVoiceStream(path, options = {}) {
3300
3639
  const stream = createVoiceStream(path, options);
3301
- const assistantAudio = shallowRef9([]);
3302
- const assistantTexts = shallowRef9([]);
3303
- const call = shallowRef9(null);
3304
- const error = ref6(null);
3305
- const isConnected = ref6(false);
3306
- const partial = ref6("");
3307
- const reconnect = shallowRef9(stream.reconnect);
3308
- const sessionId = ref6(stream.sessionId);
3309
- const status = ref6(stream.status);
3310
- const turns = shallowRef9([]);
3640
+ const assistantAudio = shallowRef10([]);
3641
+ const assistantTexts = shallowRef10([]);
3642
+ const call = shallowRef10(null);
3643
+ const error = ref7(null);
3644
+ const isConnected = ref7(false);
3645
+ const partial = ref7("");
3646
+ const reconnect = shallowRef10(stream.reconnect);
3647
+ const sessionId = ref7(stream.sessionId);
3648
+ const status = ref7(stream.status);
3649
+ const turns = shallowRef10([]);
3311
3650
  const sync = () => {
3312
3651
  assistantAudio.value = [...stream.assistantAudio];
3313
3652
  assistantTexts.value = [...stream.assistantTexts];
@@ -3326,7 +3665,7 @@ function useVoiceStream(path, options = {}) {
3326
3665
  unsubscribe();
3327
3666
  stream.close();
3328
3667
  };
3329
- onUnmounted10(destroy);
3668
+ onUnmounted11(destroy);
3330
3669
  return {
3331
3670
  assistantAudio,
3332
3671
  assistantTexts,
@@ -3345,7 +3684,7 @@ function useVoiceStream(path, options = {}) {
3345
3684
  };
3346
3685
  }
3347
3686
  // src/vue/useVoiceController.ts
3348
- import { onUnmounted as onUnmounted11, ref as ref7, shallowRef as shallowRef10 } from "vue";
3687
+ import { onUnmounted as onUnmounted12, ref as ref8, shallowRef as shallowRef11 } from "vue";
3349
3688
 
3350
3689
  // src/client/htmx.ts
3351
3690
  var DEFAULT_EVENT_NAME = "voice-refresh";
@@ -3991,17 +4330,17 @@ var createVoiceController = (path, options = {}) => {
3991
4330
  // src/vue/useVoiceController.ts
3992
4331
  function useVoiceController(path, options = {}) {
3993
4332
  const controller = createVoiceController(path, options);
3994
- const assistantAudio = shallowRef10([]);
3995
- const assistantTexts = shallowRef10([]);
3996
- const error = ref7(null);
3997
- const isConnected = ref7(false);
3998
- const isRecording = ref7(false);
3999
- const partial = ref7("");
4000
- const reconnect = shallowRef10(controller.reconnect);
4001
- const recordingError = ref7(null);
4002
- const sessionId = ref7(controller.sessionId);
4003
- const status = ref7(controller.status);
4004
- const turns = shallowRef10([]);
4333
+ const assistantAudio = shallowRef11([]);
4334
+ const assistantTexts = shallowRef11([]);
4335
+ const error = ref8(null);
4336
+ const isConnected = ref8(false);
4337
+ const isRecording = ref8(false);
4338
+ const partial = ref8("");
4339
+ const reconnect = shallowRef11(controller.reconnect);
4340
+ const recordingError = ref8(null);
4341
+ const sessionId = ref8(controller.sessionId);
4342
+ const status = ref8(controller.status);
4343
+ const turns = shallowRef11([]);
4005
4344
  const sync = () => {
4006
4345
  assistantAudio.value = [...controller.assistantAudio];
4007
4346
  assistantTexts.value = [...controller.assistantTexts];
@@ -4021,7 +4360,7 @@ function useVoiceController(path, options = {}) {
4021
4360
  unsubscribe();
4022
4361
  controller.close();
4023
4362
  };
4024
- onUnmounted11(destroy);
4363
+ onUnmounted12(destroy);
4025
4364
  return {
4026
4365
  assistantAudio,
4027
4366
  assistantTexts,
@@ -4044,7 +4383,7 @@ function useVoiceController(path, options = {}) {
4044
4383
  };
4045
4384
  }
4046
4385
  // src/vue/useVoiceTraceTimeline.ts
4047
- import { onUnmounted as onUnmounted12, ref as ref8, shallowRef as shallowRef11 } from "vue";
4386
+ import { onUnmounted as onUnmounted13, ref as ref9, shallowRef as shallowRef12 } from "vue";
4048
4387
 
4049
4388
  // src/client/traceTimeline.ts
4050
4389
  var fetchVoiceTraceTimeline = async (path = "/api/voice-traces", options = {}) => {
@@ -4129,10 +4468,10 @@ var createVoiceTraceTimelineStore = (path = "/api/voice-traces", options = {}) =
4129
4468
  // src/vue/useVoiceTraceTimeline.ts
4130
4469
  function useVoiceTraceTimeline(path = "/api/voice-traces", options = {}) {
4131
4470
  const store = createVoiceTraceTimelineStore(path, options);
4132
- const error = ref8(null);
4133
- const isLoading = ref8(false);
4134
- const report = shallowRef11(null);
4135
- const updatedAt = ref8(undefined);
4471
+ const error = ref9(null);
4472
+ const isLoading = ref9(false);
4473
+ const report = shallowRef12(null);
4474
+ const updatedAt = ref9(undefined);
4136
4475
  const sync = () => {
4137
4476
  const snapshot = store.getSnapshot();
4138
4477
  error.value = snapshot.error;
@@ -4143,7 +4482,7 @@ function useVoiceTraceTimeline(path = "/api/voice-traces", options = {}) {
4143
4482
  const unsubscribe = store.subscribe(sync);
4144
4483
  sync();
4145
4484
  store.refresh().catch(() => {});
4146
- onUnmounted12(() => {
4485
+ onUnmounted13(() => {
4147
4486
  unsubscribe();
4148
4487
  store.close();
4149
4488
  });
@@ -4156,7 +4495,7 @@ function useVoiceTraceTimeline(path = "/api/voice-traces", options = {}) {
4156
4495
  };
4157
4496
  }
4158
4497
  // src/vue/useVoiceWorkflowStatus.ts
4159
- import { onUnmounted as onUnmounted13, ref as ref9, shallowRef as shallowRef12 } from "vue";
4498
+ import { onUnmounted as onUnmounted14, ref as ref10, shallowRef as shallowRef13 } from "vue";
4160
4499
 
4161
4500
  // src/client/workflowStatus.ts
4162
4501
  var fetchVoiceWorkflowStatus = async (path = "/evals/scenarios/json", options = {}) => {
@@ -4240,10 +4579,10 @@ var createVoiceWorkflowStatusStore = (path = "/evals/scenarios/json", options =
4240
4579
  // src/vue/useVoiceWorkflowStatus.ts
4241
4580
  function useVoiceWorkflowStatus(path = "/evals/scenarios/json", options = {}) {
4242
4581
  const store = createVoiceWorkflowStatusStore(path, options);
4243
- const error = ref9(null);
4244
- const isLoading = ref9(false);
4245
- const report = shallowRef12(undefined);
4246
- const updatedAt = ref9(undefined);
4582
+ const error = ref10(null);
4583
+ const isLoading = ref10(false);
4584
+ const report = shallowRef13(undefined);
4585
+ const updatedAt = ref10(undefined);
4247
4586
  const sync = () => {
4248
4587
  const snapshot = store.getSnapshot();
4249
4588
  error.value = snapshot.error;
@@ -4256,7 +4595,7 @@ function useVoiceWorkflowStatus(path = "/evals/scenarios/json", options = {}) {
4256
4595
  if (typeof window !== "undefined") {
4257
4596
  store.refresh().catch(() => {});
4258
4597
  }
4259
- onUnmounted13(() => {
4598
+ onUnmounted14(() => {
4260
4599
  unsubscribe();
4261
4600
  store.close();
4262
4601
  });
@@ -4279,6 +4618,7 @@ export {
4279
4618
  useVoiceProviderSimulationControls,
4280
4619
  useVoiceProviderCapabilities,
4281
4620
  useVoiceOpsStatus,
4621
+ useVoiceOpsActionCenter,
4282
4622
  useVoiceDeliveryRuntime,
4283
4623
  useVoiceController,
4284
4624
  useVoiceCampaignDialerProof,
@@ -4289,5 +4629,6 @@ export {
4289
4629
  VoiceProviderSimulationControls,
4290
4630
  VoiceProviderCapabilities,
4291
4631
  VoiceOpsStatus,
4632
+ VoiceOpsActionCenter,
4292
4633
  VoiceDeliveryRuntime
4293
4634
  };