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

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,377 @@ 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 recordVoiceOpsActionResult = async (result, options = {}) => {
382
+ if (options.auditPath === false) {
383
+ return;
384
+ }
385
+ const path = options.auditPath ?? "/api/voice/ops-actions/audit";
386
+ const fetchImpl = options.fetch ?? globalThis.fetch;
387
+ const response = await fetchImpl(path, {
388
+ body: JSON.stringify(result),
389
+ headers: {
390
+ "Content-Type": "application/json"
391
+ },
392
+ method: "POST"
393
+ });
394
+ if (!response.ok) {
395
+ throw new Error(`Voice ops action audit failed: HTTP ${response.status}`);
396
+ }
397
+ };
398
+ var createVoiceOpsActionCenterActions = (options = {}) => {
399
+ const deliveryRuntimePath = options.deliveryRuntimePath ?? "/api/voice-delivery-runtime";
400
+ const actions = [];
401
+ if (options.includeProductionReadiness !== false) {
402
+ actions.push({
403
+ description: "Refresh the production readiness report.",
404
+ id: "production-readiness",
405
+ label: "Refresh readiness",
406
+ method: "GET",
407
+ path: options.productionReadinessPath ?? "/api/production-readiness"
408
+ });
409
+ }
410
+ if (options.includeDeliveryRuntime !== false) {
411
+ actions.push({
412
+ description: "Drain pending and failed audit/trace deliveries.",
413
+ id: "delivery-runtime.tick",
414
+ label: "Tick delivery workers",
415
+ method: "POST",
416
+ path: `${deliveryRuntimePath.replace(/\/$/, "")}/tick`
417
+ }, {
418
+ description: "Move reviewed dead letters back to live delivery queues.",
419
+ id: "delivery-runtime.requeue-dead-letters",
420
+ label: "Requeue dead letters",
421
+ method: "POST",
422
+ path: `${deliveryRuntimePath.replace(/\/$/, "")}/requeue-dead-letters`
423
+ });
424
+ }
425
+ if (options.includeTurnLatencyProof !== false) {
426
+ actions.push({
427
+ description: "Run the synthetic turn latency proof.",
428
+ id: "turn-latency.proof",
429
+ label: "Run latency proof",
430
+ method: "POST",
431
+ path: options.turnLatencyProofPath ?? "/api/turn-latency/proof"
432
+ });
433
+ }
434
+ if (options.includeProviderSimulation !== false) {
435
+ const pathPrefix = options.providerSimulationPathPrefix ?? "/api/stt-simulate";
436
+ for (const provider of options.providers ?? []) {
437
+ actions.push({
438
+ description: `Simulate ${provider} provider failure.`,
439
+ id: `provider.${provider}.failure`,
440
+ label: `Simulate ${provider} failure`,
441
+ method: "POST",
442
+ path: `${pathPrefix}/failure?provider=${encodeURIComponent(provider)}`
443
+ }, {
444
+ description: `Mark ${provider} provider recovered.`,
445
+ id: `provider.${provider}.recovery`,
446
+ label: `Recover ${provider}`,
447
+ method: "POST",
448
+ path: `${pathPrefix}/recovery?provider=${encodeURIComponent(provider)}`
449
+ });
450
+ }
451
+ }
452
+ return actions;
453
+ };
454
+ var runVoiceOpsAction = async (action, options = {}) => {
455
+ const fetchImpl = options.fetch ?? globalThis.fetch;
456
+ const response = await fetchImpl(action.path, {
457
+ method: action.method ?? "POST"
458
+ });
459
+ const body = await response.json().catch(() => null);
460
+ if (!response.ok) {
461
+ const message = body && typeof body === "object" && "error" in body ? String(body.error) : `Voice ops action "${action.id}" failed: HTTP ${response.status}`;
462
+ throw new Error(message);
463
+ }
464
+ return {
465
+ actionId: action.id,
466
+ body,
467
+ ok: response.ok,
468
+ ranAt: Date.now(),
469
+ status: response.status
470
+ };
471
+ };
472
+ var createVoiceOpsActionCenterStore = (options = {}) => {
473
+ const listeners = new Set;
474
+ let closed = false;
475
+ let timer;
476
+ let snapshot = {
477
+ actions: options.actions ?? createVoiceOpsActionCenterActions(),
478
+ error: null,
479
+ isRunning: false
480
+ };
481
+ const emit = () => {
482
+ for (const listener of listeners) {
483
+ listener();
484
+ }
485
+ };
486
+ const setActions = (actions) => {
487
+ snapshot = { ...snapshot, actions, updatedAt: Date.now() };
488
+ emit();
489
+ };
490
+ const run = async (actionId) => {
491
+ if (closed) {
492
+ return snapshot.lastResult;
493
+ }
494
+ const action = snapshot.actions.find((item) => item.id === actionId);
495
+ if (!action) {
496
+ throw new Error(`Voice ops action "${actionId}" is not configured.`);
497
+ }
498
+ if (action.disabled) {
499
+ throw new Error(`Voice ops action "${actionId}" is disabled.`);
500
+ }
501
+ snapshot = {
502
+ ...snapshot,
503
+ error: null,
504
+ isRunning: true,
505
+ runningActionId: action.id
506
+ };
507
+ emit();
508
+ try {
509
+ const result = await runVoiceOpsAction(action, options);
510
+ await options.onActionResult?.(result);
511
+ await recordVoiceOpsActionResult(result, options);
512
+ snapshot = {
513
+ ...snapshot,
514
+ error: null,
515
+ isRunning: false,
516
+ lastResult: result,
517
+ runningActionId: undefined,
518
+ updatedAt: Date.now()
519
+ };
520
+ emit();
521
+ return result;
522
+ } catch (error) {
523
+ const result = {
524
+ actionId: action.id,
525
+ body: null,
526
+ error: error instanceof Error ? error.message : String(error),
527
+ ok: false,
528
+ ranAt: Date.now(),
529
+ status: 0
530
+ };
531
+ await options.onActionResult?.(result);
532
+ await recordVoiceOpsActionResult(result, options).catch(() => {});
533
+ snapshot = {
534
+ ...snapshot,
535
+ error: error instanceof Error ? error.message : String(error),
536
+ isRunning: false,
537
+ runningActionId: undefined
538
+ };
539
+ emit();
540
+ throw error;
541
+ }
542
+ };
543
+ const close = () => {
544
+ closed = true;
545
+ if (timer) {
546
+ clearInterval(timer);
547
+ timer = undefined;
548
+ }
549
+ listeners.clear();
550
+ };
551
+ if (options.intervalMs && options.intervalMs > 0) {
552
+ timer = setInterval(() => {
553
+ emit();
554
+ }, options.intervalMs);
555
+ }
556
+ return {
557
+ close,
558
+ getServerSnapshot: () => snapshot,
559
+ getSnapshot: () => snapshot,
560
+ run,
561
+ setActions,
562
+ subscribe: (listener) => {
563
+ listeners.add(listener);
564
+ return () => {
565
+ listeners.delete(listener);
566
+ };
567
+ }
568
+ };
569
+ };
570
+
571
+ // src/client/opsActionCenterWidget.ts
572
+ var DEFAULT_TITLE2 = "Voice Ops Action Center";
573
+ var DEFAULT_DESCRIPTION2 = "Run production voice proofs and operator actions from one primitive panel.";
574
+ var escapeHtml2 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
575
+ var createVoiceOpsActionCenterViewModel = (snapshot, options = {}) => {
576
+ const status = snapshot.error ? "error" : snapshot.isRunning ? "running" : snapshot.lastResult ? "completed" : "ready";
577
+ return {
578
+ actions: snapshot.actions.map((action) => ({
579
+ description: action.description ?? "",
580
+ disabled: Boolean(action.disabled || snapshot.isRunning),
581
+ id: action.id,
582
+ isRunning: snapshot.runningActionId === action.id,
583
+ label: action.label
584
+ })),
585
+ description: options.description ?? DEFAULT_DESCRIPTION2,
586
+ error: snapshot.error,
587
+ isRunning: snapshot.isRunning,
588
+ label: status === "error" ? "Needs attention" : status === "running" ? "Running" : status === "completed" ? "Action completed" : "Ready",
589
+ lastResultLabel: snapshot.lastResult ? `${snapshot.lastResult.actionId} returned HTTP ${snapshot.lastResult.status}` : "No action has run yet.",
590
+ status,
591
+ title: options.title ?? DEFAULT_TITLE2
592
+ };
593
+ };
594
+ var renderVoiceOpsActionCenterHTML = (snapshot, options = {}) => {
595
+ const model = createVoiceOpsActionCenterViewModel(snapshot, options);
596
+ const actions = model.actions.map((action) => `<button type="button" data-absolute-voice-ops-action="${escapeHtml2(action.id)}"${action.disabled ? " disabled" : ""}>
597
+ ${escapeHtml2(action.isRunning ? "Working..." : action.label)}
598
+ </button>`).join("");
599
+ return `<section class="absolute-voice-ops-action-center absolute-voice-ops-action-center--${escapeHtml2(model.status)}">
600
+ <header class="absolute-voice-ops-action-center__header">
601
+ <span class="absolute-voice-ops-action-center__eyebrow">${escapeHtml2(model.title)}</span>
602
+ <strong class="absolute-voice-ops-action-center__label">${escapeHtml2(model.label)}</strong>
603
+ </header>
604
+ <p class="absolute-voice-ops-action-center__description">${escapeHtml2(model.description)}</p>
605
+ <div class="absolute-voice-ops-action-center__actions">${actions}</div>
606
+ <p class="absolute-voice-ops-action-center__result">${escapeHtml2(model.lastResultLabel)}</p>
607
+ ${model.error ? `<p class="absolute-voice-ops-action-center__error">${escapeHtml2(model.error)}</p>` : ""}
608
+ </section>`;
609
+ };
610
+ 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}`;
611
+ var mountVoiceOpsActionCenter = (element, options = {}) => {
612
+ const store = createVoiceOpsActionCenterStore(options);
613
+ const render = () => {
614
+ element.innerHTML = renderVoiceOpsActionCenterHTML(store.getSnapshot(), options);
615
+ };
616
+ const unsubscribe = store.subscribe(render);
617
+ const handleClick = (event) => {
618
+ const target = event.target;
619
+ if (!(target instanceof Element)) {
620
+ return;
621
+ }
622
+ const action = target.closest("[data-absolute-voice-ops-action]");
623
+ const actionId = action?.getAttribute("data-absolute-voice-ops-action");
624
+ if (actionId) {
625
+ store.run(actionId).catch(() => {});
626
+ }
627
+ };
628
+ element.addEventListener?.("click", handleClick);
629
+ render();
630
+ return {
631
+ close: () => {
632
+ element.removeEventListener?.("click", handleClick);
633
+ unsubscribe();
634
+ store.close();
635
+ },
636
+ run: store.run
637
+ };
638
+ };
639
+ var defineVoiceOpsActionCenterElement = (tagName = "absolute-voice-ops-action-center", options = {}) => {
640
+ if (typeof window === "undefined" || typeof customElements === "undefined" || customElements.get(tagName)) {
641
+ return;
642
+ }
643
+ customElements.define(tagName, class AbsoluteVoiceOpsActionCenterElement extends HTMLElement {
644
+ mounted;
645
+ connectedCallback() {
646
+ this.mounted = mountVoiceOpsActionCenter(this, {
647
+ ...options,
648
+ description: this.getAttribute("description") ?? options.description,
649
+ title: this.getAttribute("title") ?? options.title
650
+ });
651
+ }
652
+ disconnectedCallback() {
653
+ this.mounted?.close();
654
+ this.mounted = undefined;
655
+ }
656
+ });
657
+ };
658
+
659
+ // src/vue/useVoiceOpsActionCenter.ts
660
+ import { onUnmounted as onUnmounted2, ref as ref2, shallowRef as shallowRef2 } from "vue";
661
+ function useVoiceOpsActionCenter(options = {}) {
662
+ const store = createVoiceOpsActionCenterStore(options);
663
+ const actions = shallowRef2([]);
664
+ const error = ref2(null);
665
+ const isRunning = ref2(false);
666
+ const lastResult = shallowRef2(undefined);
667
+ const runningActionId = ref2(undefined);
668
+ const updatedAt = ref2(undefined);
669
+ const sync = () => {
670
+ const snapshot = store.getSnapshot();
671
+ actions.value = snapshot.actions;
672
+ error.value = snapshot.error;
673
+ isRunning.value = snapshot.isRunning;
674
+ lastResult.value = snapshot.lastResult;
675
+ runningActionId.value = snapshot.runningActionId;
676
+ updatedAt.value = snapshot.updatedAt;
677
+ };
678
+ const unsubscribe = store.subscribe(sync);
679
+ sync();
680
+ onUnmounted2(() => {
681
+ unsubscribe();
682
+ store.close();
683
+ });
684
+ return {
685
+ actions,
686
+ error,
687
+ isRunning,
688
+ lastResult,
689
+ run: store.run,
690
+ runningActionId,
691
+ setActions: store.setActions,
692
+ updatedAt
693
+ };
694
+ }
695
+
696
+ // src/vue/VoiceOpsActionCenter.ts
697
+ var VoiceOpsActionCenter = defineComponent2({
698
+ name: "VoiceOpsActionCenter",
699
+ props: {
700
+ actions: Array,
701
+ description: String,
702
+ title: String
703
+ },
704
+ setup(props) {
705
+ const options = {
706
+ actions: props.actions,
707
+ description: props.description,
708
+ title: props.title
709
+ };
710
+ const center = useVoiceOpsActionCenter(options);
711
+ return () => {
712
+ const model = createVoiceOpsActionCenterViewModel({
713
+ actions: center.actions.value,
714
+ error: center.error.value,
715
+ isRunning: center.isRunning.value,
716
+ lastResult: center.lastResult.value,
717
+ runningActionId: center.runningActionId.value,
718
+ updatedAt: center.updatedAt.value
719
+ }, options);
720
+ return h2("section", {
721
+ class: [
722
+ "absolute-voice-ops-action-center",
723
+ `absolute-voice-ops-action-center--${model.status}`
724
+ ]
725
+ }, [
726
+ h2("header", { class: "absolute-voice-ops-action-center__header" }, [
727
+ h2("span", { class: "absolute-voice-ops-action-center__eyebrow" }, model.title),
728
+ h2("strong", { class: "absolute-voice-ops-action-center__label" }, model.label)
729
+ ]),
730
+ h2("p", { class: "absolute-voice-ops-action-center__description" }, model.description),
731
+ h2("div", { class: "absolute-voice-ops-action-center__actions" }, model.actions.map((action) => h2("button", {
732
+ disabled: action.disabled,
733
+ key: action.id,
734
+ onClick: () => {
735
+ center.run(action.id).catch(() => {});
736
+ },
737
+ type: "button"
738
+ }, action.isRunning ? "Working..." : action.label))),
739
+ h2("p", { class: "absolute-voice-ops-action-center__result" }, model.lastResultLabel),
740
+ model.error ? h2("p", { class: "absolute-voice-ops-action-center__error" }, model.error) : null
741
+ ]);
742
+ };
743
+ }
744
+ });
745
+ // src/vue/VoiceDeliveryRuntime.ts
746
+ import { defineComponent as defineComponent3, h as h3 } from "vue";
747
+
380
748
  // src/client/deliveryRuntime.ts
381
749
  var getDefaultActionPath = (path, action, options) => {
382
750
  if (action === "tick") {
@@ -515,9 +883,9 @@ var createVoiceDeliveryRuntimeStore = (path = "/api/voice-delivery-runtime", opt
515
883
  };
516
884
 
517
885
  // 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;");
886
+ var DEFAULT_TITLE3 = "Voice Delivery Runtime";
887
+ var DEFAULT_DESCRIPTION3 = "Audit and trace delivery worker health from your AbsoluteJS voice app.";
888
+ var escapeHtml3 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
521
889
  var createSurface = (id, summary) => {
522
890
  if (!summary) {
523
891
  return {
@@ -551,7 +919,7 @@ var createVoiceDeliveryRuntimeViewModel = (snapshot, options = {}) => {
551
919
  ];
552
920
  const hasWarnings = surfaces.some((surface) => surface.status === "warn");
553
921
  return {
554
- description: options.description ?? DEFAULT_DESCRIPTION2,
922
+ description: options.description ?? DEFAULT_DESCRIPTION3,
555
923
  error: snapshot.error,
556
924
  actionError: snapshot.actionError,
557
925
  actionStatus: snapshot.actionStatus,
@@ -560,32 +928,32 @@ var createVoiceDeliveryRuntimeViewModel = (snapshot, options = {}) => {
560
928
  label: snapshot.error ? "Unavailable" : report ? report.isRunning ? "Running" : "Stopped" : "Checking",
561
929
  status: snapshot.error ? "error" : report ? hasWarnings ? "warn" : "pass" : "loading",
562
930
  surfaces,
563
- title: options.title ?? DEFAULT_TITLE2,
931
+ title: options.title ?? DEFAULT_TITLE3,
564
932
  updatedAt: snapshot.updatedAt
565
933
  };
566
934
  };
567
935
  var renderVoiceDeliveryRuntimeHTML = (snapshot, options = {}) => {
568
936
  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>
937
+ const surfaces = model.surfaces.map((surface) => `<li class="absolute-voice-delivery-runtime__surface absolute-voice-delivery-runtime__surface--${escapeHtml3(surface.status)}">
938
+ <span>${escapeHtml3(surface.label)}</span>
939
+ <strong>${escapeHtml3(surface.detail)}</strong>
572
940
  <small>${String(surface.failed)} failed &middot; ${String(surface.deadLettered)} dead-lettered</small>
573
941
  </li>`).join("");
574
942
  const actions = options.includeActions === false ? "" : `<div class="absolute-voice-delivery-runtime__actions">
575
943
  <button type="button" data-absolute-voice-delivery-runtime-action="tick">${model.actionStatus === "running" ? "Working..." : "Tick workers"}</button>
576
944
  <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
945
  </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)}">
946
+ const actionError = model.actionError ? `<p class="absolute-voice-delivery-runtime__error">${escapeHtml3(model.actionError)}</p>` : "";
947
+ return `<section class="absolute-voice-delivery-runtime absolute-voice-delivery-runtime--${escapeHtml3(model.status)}">
580
948
  <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>
949
+ <span class="absolute-voice-delivery-runtime__eyebrow">${escapeHtml3(model.title)}</span>
950
+ <strong class="absolute-voice-delivery-runtime__label">${escapeHtml3(model.label)}</strong>
583
951
  </header>
584
- <p class="absolute-voice-delivery-runtime__description">${escapeHtml2(model.description)}</p>
952
+ <p class="absolute-voice-delivery-runtime__description">${escapeHtml3(model.description)}</p>
585
953
  <ul class="absolute-voice-delivery-runtime__surfaces">${surfaces}</ul>
586
954
  ${actions}
587
955
  ${actionError}
588
- ${model.error ? `<p class="absolute-voice-delivery-runtime__error">${escapeHtml2(model.error)}</p>` : ""}
956
+ ${model.error ? `<p class="absolute-voice-delivery-runtime__error">${escapeHtml3(model.error)}</p>` : ""}
589
957
  </section>`;
590
958
  };
591
959
  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 +1011,15 @@ var defineVoiceDeliveryRuntimeElement = (tagName = "absolute-voice-delivery-runt
643
1011
  };
644
1012
 
645
1013
  // src/vue/useVoiceDeliveryRuntime.ts
646
- import { onUnmounted as onUnmounted2, ref as ref2, shallowRef as shallowRef2 } from "vue";
1014
+ import { onUnmounted as onUnmounted3, ref as ref3, shallowRef as shallowRef3 } from "vue";
647
1015
  function useVoiceDeliveryRuntime(path = "/api/voice-delivery-runtime", options = {}) {
648
1016
  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);
1017
+ const actionError = ref3(null);
1018
+ const actionStatus = ref3("idle");
1019
+ const error = ref3(null);
1020
+ const isLoading = ref3(false);
1021
+ const report = shallowRef3(undefined);
1022
+ const updatedAt = ref3(undefined);
655
1023
  const sync = () => {
656
1024
  const snapshot = store.getSnapshot();
657
1025
  actionError.value = snapshot.actionError;
@@ -666,7 +1034,7 @@ function useVoiceDeliveryRuntime(path = "/api/voice-delivery-runtime", options =
666
1034
  if (typeof window !== "undefined") {
667
1035
  store.refresh().catch(() => {});
668
1036
  }
669
- onUnmounted2(() => {
1037
+ onUnmounted3(() => {
670
1038
  unsubscribe();
671
1039
  store.close();
672
1040
  });
@@ -684,7 +1052,7 @@ function useVoiceDeliveryRuntime(path = "/api/voice-delivery-runtime", options =
684
1052
  }
685
1053
 
686
1054
  // src/vue/VoiceDeliveryRuntime.ts
687
- var VoiceDeliveryRuntime = defineComponent2({
1055
+ var VoiceDeliveryRuntime = defineComponent3({
688
1056
  name: "VoiceDeliveryRuntime",
689
1057
  props: {
690
1058
  description: String,
@@ -716,37 +1084,37 @@ var VoiceDeliveryRuntime = defineComponent2({
716
1084
  updatedAt: runtime.updatedAt.value
717
1085
  }, options);
718
1086
  const hasDeadLetters = model.surfaces.some((surface) => surface.deadLettered > 0);
719
- return h2("section", {
1087
+ return h3("section", {
720
1088
  class: [
721
1089
  "absolute-voice-delivery-runtime",
722
1090
  `absolute-voice-delivery-runtime--${model.status}`
723
1091
  ]
724
1092
  }, [
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)
1093
+ h3("header", { class: "absolute-voice-delivery-runtime__header" }, [
1094
+ h3("span", { class: "absolute-voice-delivery-runtime__eyebrow" }, model.title),
1095
+ h3("strong", { class: "absolute-voice-delivery-runtime__label" }, model.label)
728
1096
  ]),
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", {
1097
+ h3("p", { class: "absolute-voice-delivery-runtime__description" }, model.description),
1098
+ h3("ul", { class: "absolute-voice-delivery-runtime__surfaces" }, model.surfaces.map((surface) => h3("li", {
731
1099
  class: [
732
1100
  "absolute-voice-delivery-runtime__surface",
733
1101
  `absolute-voice-delivery-runtime__surface--${surface.status}`
734
1102
  ],
735
1103
  key: surface.id
736
1104
  }, [
737
- h2("span", surface.label),
738
- h2("strong", surface.detail),
739
- h2("small", `${surface.failed} failed / ${surface.deadLettered} dead-lettered`)
1105
+ h3("span", surface.label),
1106
+ h3("strong", surface.detail),
1107
+ h3("small", `${surface.failed} failed / ${surface.deadLettered} dead-lettered`)
740
1108
  ]))),
741
- props.includeActions ? h2("div", { class: "absolute-voice-delivery-runtime__actions" }, [
742
- h2("button", {
1109
+ props.includeActions ? h3("div", { class: "absolute-voice-delivery-runtime__actions" }, [
1110
+ h3("button", {
743
1111
  disabled: model.actionStatus === "running",
744
1112
  onClick: () => {
745
1113
  runtime.tick().catch(() => {});
746
1114
  },
747
1115
  type: "button"
748
1116
  }, model.actionStatus === "running" ? "Working..." : "Tick workers"),
749
- h2("button", {
1117
+ h3("button", {
750
1118
  disabled: model.actionStatus === "running" || !hasDeadLetters,
751
1119
  onClick: () => {
752
1120
  runtime.requeueDeadLetters().catch(() => {});
@@ -754,14 +1122,14 @@ var VoiceDeliveryRuntime = defineComponent2({
754
1122
  type: "button"
755
1123
  }, "Requeue dead letters")
756
1124
  ]) : 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
1125
+ model.actionError ? h3("p", { class: "absolute-voice-delivery-runtime__error" }, model.actionError) : null,
1126
+ model.error ? h3("p", { class: "absolute-voice-delivery-runtime__error" }, model.error) : null
759
1127
  ]);
760
1128
  };
761
1129
  }
762
1130
  });
763
1131
  // src/vue/VoiceProviderSimulationControls.ts
764
- import { computed, defineComponent as defineComponent3, h as h3 } from "vue";
1132
+ import { computed, defineComponent as defineComponent4, h as h4 } from "vue";
765
1133
 
766
1134
  // src/client/providerSimulationControls.ts
767
1135
  var postSimulation = async (pathPrefix, mode, provider, fetchImpl) => {
@@ -843,7 +1211,7 @@ var createVoiceProviderSimulationControlsStore = (options) => {
843
1211
  };
844
1212
 
845
1213
  // src/client/providerSimulationControlsWidget.ts
846
- var escapeHtml3 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
1214
+ var escapeHtml4 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
847
1215
  var formatKind = (kind) => (kind ?? "stt").toUpperCase();
848
1216
  var createVoiceProviderSimulationControlsViewModel = (snapshot, options) => {
849
1217
  const configuredProviders = options.providers.filter((provider) => provider.configured !== false);
@@ -863,18 +1231,18 @@ var createVoiceProviderSimulationControlsViewModel = (snapshot, options) => {
863
1231
  };
864
1232
  var renderVoiceProviderSimulationControlsHTML = (snapshot, options) => {
865
1233
  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("");
1234
+ 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("");
1235
+ 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
1236
  return `<section class="absolute-voice-provider-simulation absolute-voice-provider-simulation--${snapshot.error ? "error" : snapshot.isRunning ? "running" : "ready"}">
869
1237
  <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>
1238
+ <span class="absolute-voice-provider-simulation__eyebrow">${escapeHtml4(model.title)}</span>
1239
+ <strong class="absolute-voice-provider-simulation__label">${escapeHtml4(model.label)}</strong>
872
1240
  </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>`}
1241
+ <p class="absolute-voice-provider-simulation__description">${escapeHtml4(model.description)}</p>
1242
+ ${model.canSimulateFailure ? "" : `<p class="absolute-voice-provider-simulation__empty">${escapeHtml4(options.fallbackRequiredMessage ?? "Configure fallback providers before simulating failure.")}</p>`}
875
1243
  <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>` : ""}
1244
+ ${snapshot.error ? `<p class="absolute-voice-provider-simulation__error">${escapeHtml4(snapshot.error)}</p>` : ""}
1245
+ ${model.resultText ? `<pre class="absolute-voice-provider-simulation__result">${escapeHtml4(model.resultText)}</pre>` : ""}
878
1246
  </section>`;
879
1247
  };
880
1248
  var bindVoiceProviderSimulationControls = (element, store) => {
@@ -940,15 +1308,15 @@ var defineVoiceProviderSimulationControlsElement = (tagName = "absolute-voice-pr
940
1308
  };
941
1309
 
942
1310
  // src/vue/useVoiceProviderSimulationControls.ts
943
- import { onUnmounted as onUnmounted3, ref as ref3 } from "vue";
1311
+ import { onUnmounted as onUnmounted4, ref as ref4 } from "vue";
944
1312
  function useVoiceProviderSimulationControls(options) {
945
1313
  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);
1314
+ const error = ref4(null);
1315
+ const isRunning = ref4(false);
1316
+ const lastResult = ref4(null);
1317
+ const mode = ref4(null);
1318
+ const provider = ref4(null);
1319
+ const updatedAt = ref4(undefined);
952
1320
  const sync = () => {
953
1321
  const snapshot = store.getSnapshot();
954
1322
  error.value = snapshot.error;
@@ -960,7 +1328,7 @@ function useVoiceProviderSimulationControls(options) {
960
1328
  };
961
1329
  const unsubscribe = store.subscribe(sync);
962
1330
  sync();
963
- onUnmounted3(() => {
1331
+ onUnmounted4(() => {
964
1332
  unsubscribe();
965
1333
  store.close();
966
1334
  });
@@ -976,7 +1344,7 @@ function useVoiceProviderSimulationControls(options) {
976
1344
  }
977
1345
 
978
1346
  // src/vue/VoiceProviderSimulationControls.ts
979
- var VoiceProviderSimulationControls = defineComponent3({
1347
+ var VoiceProviderSimulationControls = defineComponent4({
980
1348
  name: "VoiceProviderSimulationControls",
981
1349
  props: {
982
1350
  class: { default: "", type: String },
@@ -1018,40 +1386,40 @@ var VoiceProviderSimulationControls = defineComponent3({
1018
1386
  const run = (provider, mode) => {
1019
1387
  controls.run(provider, mode).catch(() => {});
1020
1388
  };
1021
- return () => h3("section", {
1389
+ return () => h4("section", {
1022
1390
  class: [
1023
1391
  "absolute-voice-provider-simulation",
1024
1392
  `absolute-voice-provider-simulation--${controls.error.value ? "error" : controls.isRunning.value ? "running" : "ready"}`,
1025
1393
  props.class
1026
1394
  ]
1027
1395
  }, [
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)
1396
+ h4("header", { class: "absolute-voice-provider-simulation__header" }, [
1397
+ h4("span", { class: "absolute-voice-provider-simulation__eyebrow" }, model.value.title),
1398
+ h4("strong", { class: "absolute-voice-provider-simulation__label" }, model.value.label)
1031
1399
  ]),
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", {
1400
+ h4("p", { class: "absolute-voice-provider-simulation__description" }, model.value.description),
1401
+ model.value.canSimulateFailure ? null : h4("p", { class: "absolute-voice-provider-simulation__empty" }, props.fallbackRequiredMessage ?? "Configure fallback providers before simulating failure."),
1402
+ h4("div", { class: "absolute-voice-provider-simulation__actions" }, [
1403
+ ...model.value.failureProviders.map((provider) => h4("button", {
1036
1404
  disabled: !model.value.canSimulateFailure || controls.isRunning.value,
1037
1405
  key: `fail-${provider.provider}`,
1038
1406
  onClick: () => run(provider.provider, "failure"),
1039
1407
  type: "button"
1040
1408
  }, `Simulate ${provider.provider} ${props.kind.toUpperCase()} failure`)),
1041
- ...model.value.providers.map((provider) => h3("button", {
1409
+ ...model.value.providers.map((provider) => h4("button", {
1042
1410
  disabled: controls.isRunning.value,
1043
1411
  key: `recover-${provider.provider}`,
1044
1412
  onClick: () => run(provider.provider, "recovery"),
1045
1413
  type: "button"
1046
1414
  }, `Mark ${provider.provider} recovered`))
1047
1415
  ]),
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
1416
+ controls.error.value ? h4("p", { class: "absolute-voice-provider-simulation__error" }, controls.error.value) : null,
1417
+ model.value.resultText ? h4("pre", { class: "absolute-voice-provider-simulation__result" }, model.value.resultText) : null
1050
1418
  ]);
1051
1419
  }
1052
1420
  });
1053
1421
  // src/vue/VoiceProviderCapabilities.ts
1054
- import { computed as computed2, defineComponent as defineComponent4, h as h4 } from "vue";
1422
+ import { computed as computed2, defineComponent as defineComponent5, h as h5 } from "vue";
1055
1423
 
1056
1424
  // src/client/providerCapabilities.ts
1057
1425
  var fetchVoiceProviderCapabilities = async (path = "/api/provider-capabilities", options = {}) => {
@@ -1133,9 +1501,9 @@ var createVoiceProviderCapabilitiesStore = (path = "/api/provider-capabilities",
1133
1501
  };
1134
1502
 
1135
1503
  // 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;");
1504
+ var DEFAULT_TITLE4 = "Provider Capabilities";
1505
+ var DEFAULT_DESCRIPTION4 = "Configured, selected, and healthy voice providers for this deployment.";
1506
+ var escapeHtml5 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
1139
1507
  var formatProvider = (provider) => provider.split(/[-_\s]+/).filter(Boolean).map((part) => `${part[0]?.toUpperCase() ?? ""}${part.slice(1)}`).join(" ") || provider;
1140
1508
  var formatKind2 = (kind) => kind.toUpperCase();
1141
1509
  var formatStatus = (status) => status.split("-").map((part) => `${part[0]?.toUpperCase() ?? ""}${part.slice(1)}`).join(" ");
@@ -1179,36 +1547,36 @@ var createVoiceProviderCapabilitiesViewModel = (snapshot, options = {}) => {
1179
1547
  const selectedCount = snapshot.report?.selected ?? capabilities.filter((capability) => capability.selected).length;
1180
1548
  return {
1181
1549
  capabilities,
1182
- description: options.description ?? DEFAULT_DESCRIPTION3,
1550
+ description: options.description ?? DEFAULT_DESCRIPTION4,
1183
1551
  error: snapshot.error,
1184
1552
  isLoading: snapshot.isLoading,
1185
1553
  label: snapshot.error ? "Unavailable" : capabilities.length ? warningCount > 0 ? `${warningCount} needs attention` : `${selectedCount} selected` : snapshot.isLoading ? "Checking" : "No capabilities",
1186
1554
  status: snapshot.error ? "error" : capabilities.length ? warningCount > 0 ? "warning" : "ready" : snapshot.isLoading ? "loading" : "empty",
1187
- title: options.title ?? DEFAULT_TITLE3,
1555
+ title: options.title ?? DEFAULT_TITLE4,
1188
1556
  updatedAt: snapshot.updatedAt
1189
1557
  };
1190
1558
  };
1191
1559
  var renderVoiceProviderCapabilitiesHTML = (snapshot, options = {}) => {
1192
1560
  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)}">
1561
+ 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
1562
  <header>
1195
- <strong>${escapeHtml4(capability.label)}</strong>
1196
- <span>${escapeHtml4(formatStatus(capability.status))}</span>
1563
+ <strong>${escapeHtml5(capability.label)}</strong>
1564
+ <span>${escapeHtml5(formatStatus(capability.status))}</span>
1197
1565
  </header>
1198
- <p>${escapeHtml4(capability.detail)}</p>
1566
+ <p>${escapeHtml5(capability.detail)}</p>
1199
1567
  <dl>${capability.rows.map((row) => `<div>
1200
- <dt>${escapeHtml4(row.label)}</dt>
1201
- <dd>${escapeHtml4(row.value)}</dd>
1568
+ <dt>${escapeHtml5(row.label)}</dt>
1569
+ <dd>${escapeHtml5(row.value)}</dd>
1202
1570
  </div>`).join("")}</dl>
1203
1571
  </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)}">
1572
+ return `<section class="absolute-voice-provider-capabilities absolute-voice-provider-capabilities--${escapeHtml5(model.status)}">
1205
1573
  <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>
1574
+ <span class="absolute-voice-provider-capabilities__eyebrow">${escapeHtml5(model.title)}</span>
1575
+ <strong class="absolute-voice-provider-capabilities__label">${escapeHtml5(model.label)}</strong>
1208
1576
  </header>
1209
- <p class="absolute-voice-provider-capabilities__description">${escapeHtml4(model.description)}</p>
1577
+ <p class="absolute-voice-provider-capabilities__description">${escapeHtml5(model.description)}</p>
1210
1578
  ${capabilities}
1211
- ${model.error ? `<p class="absolute-voice-provider-capabilities__error">${escapeHtml4(model.error)}</p>` : ""}
1579
+ ${model.error ? `<p class="absolute-voice-provider-capabilities__error">${escapeHtml5(model.error)}</p>` : ""}
1212
1580
  </section>`;
1213
1581
  };
1214
1582
  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 +1618,13 @@ var defineVoiceProviderCapabilitiesElement = (tagName = "absolute-voice-provider
1250
1618
  };
1251
1619
 
1252
1620
  // src/vue/useVoiceProviderCapabilities.ts
1253
- import { onUnmounted as onUnmounted4, shallowRef as shallowRef3 } from "vue";
1621
+ import { onUnmounted as onUnmounted5, shallowRef as shallowRef4 } from "vue";
1254
1622
  function useVoiceProviderCapabilities(path = "/api/provider-capabilities", options = {}) {
1255
1623
  const store = createVoiceProviderCapabilitiesStore(path, options);
1256
- const error = shallowRef3(null);
1257
- const isLoading = shallowRef3(false);
1258
- const report = shallowRef3();
1259
- const updatedAt = shallowRef3(undefined);
1624
+ const error = shallowRef4(null);
1625
+ const isLoading = shallowRef4(false);
1626
+ const report = shallowRef4();
1627
+ const updatedAt = shallowRef4(undefined);
1260
1628
  const sync = () => {
1261
1629
  const snapshot = store.getSnapshot();
1262
1630
  error.value = snapshot.error;
@@ -1267,7 +1635,7 @@ function useVoiceProviderCapabilities(path = "/api/provider-capabilities", optio
1267
1635
  const unsubscribe = store.subscribe(sync);
1268
1636
  sync();
1269
1637
  store.refresh().catch(() => {});
1270
- onUnmounted4(() => {
1638
+ onUnmounted5(() => {
1271
1639
  unsubscribe();
1272
1640
  store.close();
1273
1641
  });
@@ -1281,7 +1649,7 @@ function useVoiceProviderCapabilities(path = "/api/provider-capabilities", optio
1281
1649
  }
1282
1650
 
1283
1651
  // src/vue/VoiceProviderCapabilities.ts
1284
- var VoiceProviderCapabilities = defineComponent4({
1652
+ var VoiceProviderCapabilities = defineComponent5({
1285
1653
  name: "VoiceProviderCapabilities",
1286
1654
  props: {
1287
1655
  class: {
@@ -1318,41 +1686,41 @@ var VoiceProviderCapabilities = defineComponent4({
1318
1686
  report: capabilities.report.value,
1319
1687
  updatedAt: capabilities.updatedAt.value
1320
1688
  }, options));
1321
- return () => h4("section", {
1689
+ return () => h5("section", {
1322
1690
  class: [
1323
1691
  "absolute-voice-provider-capabilities",
1324
1692
  `absolute-voice-provider-capabilities--${model.value.status}`,
1325
1693
  props.class
1326
1694
  ]
1327
1695
  }, [
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)
1696
+ h5("header", { class: "absolute-voice-provider-capabilities__header" }, [
1697
+ h5("span", { class: "absolute-voice-provider-capabilities__eyebrow" }, model.value.title),
1698
+ h5("strong", { class: "absolute-voice-provider-capabilities__label" }, model.value.label)
1331
1699
  ]),
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", {
1700
+ h5("p", { class: "absolute-voice-provider-capabilities__description" }, model.value.description),
1701
+ model.value.capabilities.length ? h5("div", { class: "absolute-voice-provider-capabilities__providers" }, model.value.capabilities.map((capability) => h5("article", {
1334
1702
  class: [
1335
1703
  "absolute-voice-provider-capabilities__provider",
1336
1704
  `absolute-voice-provider-capabilities__provider--${capability.status}`
1337
1705
  ],
1338
1706
  key: `${capability.kind}:${capability.provider}`
1339
1707
  }, [
1340
- h4("header", [
1341
- h4("strong", capability.label),
1342
- h4("span", capability.status)
1708
+ h5("header", [
1709
+ h5("strong", capability.label),
1710
+ h5("span", capability.status)
1343
1711
  ]),
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)
1712
+ h5("p", capability.detail),
1713
+ h5("dl", capability.rows.map((row) => h5("div", { key: row.label }, [
1714
+ h5("dt", row.label),
1715
+ h5("dd", row.value)
1348
1716
  ])))
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
1717
+ ]))) : h5("p", { class: "absolute-voice-provider-capabilities__empty" }, "Configure provider capabilities to see deployment coverage."),
1718
+ model.value.error ? h5("p", { class: "absolute-voice-provider-capabilities__error" }, model.value.error) : null
1351
1719
  ]);
1352
1720
  }
1353
1721
  });
1354
1722
  // src/vue/VoiceProviderStatus.ts
1355
- import { computed as computed3, defineComponent as defineComponent5, h as h5 } from "vue";
1723
+ import { computed as computed3, defineComponent as defineComponent6, h as h6 } from "vue";
1356
1724
 
1357
1725
  // src/client/providerStatus.ts
1358
1726
  var fetchVoiceProviderStatus = async (path = "/api/provider-status", options = {}) => {
@@ -1435,9 +1803,9 @@ var createVoiceProviderStatusStore = (path = "/api/provider-status", options = {
1435
1803
  };
1436
1804
 
1437
1805
  // 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;");
1806
+ var DEFAULT_TITLE5 = "Voice Providers";
1807
+ var DEFAULT_DESCRIPTION5 = "Live provider health, fallback counts, latency, and suppression state from your self-hosted trace store.";
1808
+ var escapeHtml6 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
1441
1809
  var formatProvider2 = (provider) => provider.split(/[-_\s]+/).filter(Boolean).map((part) => `${part[0]?.toUpperCase() ?? ""}${part.slice(1)}`).join(" ") || provider;
1442
1810
  var formatStatus2 = (status) => status.split("-").map((part) => `${part[0]?.toUpperCase() ?? ""}${part.slice(1)}`).join(" ");
1443
1811
  var formatLatency = (value) => typeof value === "number" ? `${value}ms` : "No samples";
@@ -1481,37 +1849,37 @@ var createVoiceProviderStatusViewModel = (snapshot, options = {}) => {
1481
1849
  const warningCount = providers.filter((provider) => isWarningStatus2(provider.status)).length;
1482
1850
  const healthyCount = providers.filter((provider) => provider.status === "healthy").length;
1483
1851
  return {
1484
- description: options.description ?? DEFAULT_DESCRIPTION4,
1852
+ description: options.description ?? DEFAULT_DESCRIPTION5,
1485
1853
  error: snapshot.error,
1486
1854
  isLoading: snapshot.isLoading,
1487
1855
  label: snapshot.error ? "Unavailable" : providers.length ? warningCount > 0 ? `${warningCount} needs attention` : `${healthyCount} healthy` : snapshot.isLoading ? "Checking" : "No provider traffic",
1488
1856
  providers,
1489
1857
  status: snapshot.error ? "error" : providers.length ? warningCount > 0 ? "warning" : "ready" : snapshot.isLoading ? "loading" : "empty",
1490
- title: options.title ?? DEFAULT_TITLE4,
1858
+ title: options.title ?? DEFAULT_TITLE5,
1491
1859
  updatedAt: snapshot.updatedAt
1492
1860
  };
1493
1861
  };
1494
1862
  var renderVoiceProviderStatusHTML = (snapshot, options = {}) => {
1495
1863
  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)}">
1864
+ 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
1865
  <header>
1498
- <strong>${escapeHtml5(provider.label)}</strong>
1499
- <span>${escapeHtml5(formatStatus2(provider.status))}</span>
1866
+ <strong>${escapeHtml6(provider.label)}</strong>
1867
+ <span>${escapeHtml6(formatStatus2(provider.status))}</span>
1500
1868
  </header>
1501
- <p>${escapeHtml5(provider.detail)}</p>
1869
+ <p>${escapeHtml6(provider.detail)}</p>
1502
1870
  <dl>${provider.rows.map((row) => `<div>
1503
- <dt>${escapeHtml5(row.label)}</dt>
1504
- <dd>${escapeHtml5(row.value)}</dd>
1871
+ <dt>${escapeHtml6(row.label)}</dt>
1872
+ <dd>${escapeHtml6(row.value)}</dd>
1505
1873
  </div>`).join("")}</dl>
1506
1874
  </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)}">
1875
+ return `<section class="absolute-voice-provider-status absolute-voice-provider-status--${escapeHtml6(model.status)}">
1508
1876
  <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>
1877
+ <span class="absolute-voice-provider-status__eyebrow">${escapeHtml6(model.title)}</span>
1878
+ <strong class="absolute-voice-provider-status__label">${escapeHtml6(model.label)}</strong>
1511
1879
  </header>
1512
- <p class="absolute-voice-provider-status__description">${escapeHtml5(model.description)}</p>
1880
+ <p class="absolute-voice-provider-status__description">${escapeHtml6(model.description)}</p>
1513
1881
  ${providers}
1514
- ${model.error ? `<p class="absolute-voice-provider-status__error">${escapeHtml5(model.error)}</p>` : ""}
1882
+ ${model.error ? `<p class="absolute-voice-provider-status__error">${escapeHtml6(model.error)}</p>` : ""}
1515
1883
  </section>`;
1516
1884
  };
1517
1885
  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 +1921,13 @@ var defineVoiceProviderStatusElement = (tagName = "absolute-voice-provider-statu
1553
1921
  };
1554
1922
 
1555
1923
  // src/vue/useVoiceProviderStatus.ts
1556
- import { onUnmounted as onUnmounted5, ref as ref4, shallowRef as shallowRef4 } from "vue";
1924
+ import { onUnmounted as onUnmounted6, ref as ref5, shallowRef as shallowRef5 } from "vue";
1557
1925
  function useVoiceProviderStatus(path = "/api/provider-status", options = {}) {
1558
1926
  const store = createVoiceProviderStatusStore(path, options);
1559
- const error = ref4(null);
1560
- const isLoading = ref4(false);
1561
- const providers = shallowRef4([]);
1562
- const updatedAt = ref4(undefined);
1927
+ const error = ref5(null);
1928
+ const isLoading = ref5(false);
1929
+ const providers = shallowRef5([]);
1930
+ const updatedAt = ref5(undefined);
1563
1931
  const sync = () => {
1564
1932
  const snapshot = store.getSnapshot();
1565
1933
  error.value = snapshot.error;
@@ -1570,7 +1938,7 @@ function useVoiceProviderStatus(path = "/api/provider-status", options = {}) {
1570
1938
  const unsubscribe = store.subscribe(sync);
1571
1939
  sync();
1572
1940
  store.refresh().catch(() => {});
1573
- onUnmounted5(() => {
1941
+ onUnmounted6(() => {
1574
1942
  unsubscribe();
1575
1943
  store.close();
1576
1944
  });
@@ -1584,7 +1952,7 @@ function useVoiceProviderStatus(path = "/api/provider-status", options = {}) {
1584
1952
  }
1585
1953
 
1586
1954
  // src/vue/VoiceProviderStatus.ts
1587
- var VoiceProviderStatus = defineComponent5({
1955
+ var VoiceProviderStatus = defineComponent6({
1588
1956
  name: "VoiceProviderStatus",
1589
1957
  props: {
1590
1958
  class: {
@@ -1621,41 +1989,41 @@ var VoiceProviderStatus = defineComponent5({
1621
1989
  providers: status.providers.value,
1622
1990
  updatedAt: status.updatedAt.value
1623
1991
  }, options));
1624
- return () => h5("section", {
1992
+ return () => h6("section", {
1625
1993
  class: [
1626
1994
  "absolute-voice-provider-status",
1627
1995
  `absolute-voice-provider-status--${model.value.status}`,
1628
1996
  props.class
1629
1997
  ]
1630
1998
  }, [
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)
1999
+ h6("header", { class: "absolute-voice-provider-status__header" }, [
2000
+ h6("span", { class: "absolute-voice-provider-status__eyebrow" }, model.value.title),
2001
+ h6("strong", { class: "absolute-voice-provider-status__label" }, model.value.label)
1634
2002
  ]),
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", {
2003
+ h6("p", { class: "absolute-voice-provider-status__description" }, model.value.description),
2004
+ model.value.providers.length ? h6("div", { class: "absolute-voice-provider-status__providers" }, model.value.providers.map((provider) => h6("article", {
1637
2005
  class: [
1638
2006
  "absolute-voice-provider-status__provider",
1639
2007
  `absolute-voice-provider-status__provider--${provider.status}`
1640
2008
  ],
1641
2009
  key: provider.provider
1642
2010
  }, [
1643
- h5("header", [
1644
- h5("strong", provider.label),
1645
- h5("span", provider.status)
2011
+ h6("header", [
2012
+ h6("strong", provider.label),
2013
+ h6("span", provider.status)
1646
2014
  ]),
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)
2015
+ h6("p", provider.detail),
2016
+ h6("dl", provider.rows.map((row) => h6("div", { key: row.label }, [
2017
+ h6("dt", row.label),
2018
+ h6("dd", row.value)
1651
2019
  ])))
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
2020
+ ]))) : h6("p", { class: "absolute-voice-provider-status__empty" }, "Run voice traffic to see provider health."),
2021
+ model.value.error ? h6("p", { class: "absolute-voice-provider-status__error" }, model.value.error) : null
1654
2022
  ]);
1655
2023
  }
1656
2024
  });
1657
2025
  // src/vue/VoiceRoutingStatus.ts
1658
- import { computed as computed4, defineComponent as defineComponent6, h as h6 } from "vue";
2026
+ import { computed as computed4, defineComponent as defineComponent7, h as h7 } from "vue";
1659
2027
 
1660
2028
  // src/client/routingStatus.ts
1661
2029
  var fetchVoiceRoutingStatus = async (path = "/api/routing/latest", options = {}) => {
@@ -1738,9 +2106,9 @@ var createVoiceRoutingStatusStore = (path = "/api/routing/latest", options = {})
1738
2106
  };
1739
2107
 
1740
2108
  // 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;");
2109
+ var DEFAULT_TITLE6 = "Voice Routing";
2110
+ var DEFAULT_DESCRIPTION6 = "Latest provider routing decision from the self-hosted trace store.";
2111
+ var escapeHtml7 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
1744
2112
  var formatValue = (value, fallback = "None") => typeof value === "string" && value.trim() ? value : typeof value === "number" && Number.isFinite(value) ? String(value) : fallback;
1745
2113
  var createVoiceRoutingStatusViewModel = (snapshot, options = {}) => {
1746
2114
  const decision = snapshot.decision;
@@ -1764,30 +2132,30 @@ var createVoiceRoutingStatusViewModel = (snapshot, options = {}) => {
1764
2132
  ] : [];
1765
2133
  return {
1766
2134
  decision,
1767
- description: options.description ?? DEFAULT_DESCRIPTION5,
2135
+ description: options.description ?? DEFAULT_DESCRIPTION6,
1768
2136
  error: snapshot.error,
1769
2137
  isLoading: snapshot.isLoading,
1770
2138
  label: snapshot.error ? "Unavailable" : decision ? `${formatValue(decision.kind).toUpperCase()} ${formatValue(decision.status, "unknown")}` : snapshot.isLoading ? "Checking" : "No routing yet",
1771
2139
  rows,
1772
2140
  status: snapshot.error ? "error" : decision ? "ready" : snapshot.isLoading ? "loading" : "empty",
1773
- title: options.title ?? DEFAULT_TITLE5,
2141
+ title: options.title ?? DEFAULT_TITLE6,
1774
2142
  updatedAt: snapshot.updatedAt
1775
2143
  };
1776
2144
  };
1777
2145
  var renderVoiceRoutingStatusHTML = (snapshot, options = {}) => {
1778
2146
  const model = createVoiceRoutingStatusViewModel(snapshot, options);
1779
2147
  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>
2148
+ <span>${escapeHtml7(row.label)}</span>
2149
+ <strong>${escapeHtml7(row.value)}</strong>
1782
2150
  </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)}">
2151
+ return `<section class="absolute-voice-routing-status absolute-voice-routing-status--${escapeHtml7(model.status)}">
1784
2152
  <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>
2153
+ <span class="absolute-voice-routing-status__eyebrow">${escapeHtml7(model.title)}</span>
2154
+ <strong class="absolute-voice-routing-status__label">${escapeHtml7(model.label)}</strong>
1787
2155
  </header>
1788
- <p class="absolute-voice-routing-status__description">${escapeHtml6(model.description)}</p>
2156
+ <p class="absolute-voice-routing-status__description">${escapeHtml7(model.description)}</p>
1789
2157
  ${rows}
1790
- ${model.error ? `<p class="absolute-voice-routing-status__error">${escapeHtml6(model.error)}</p>` : ""}
2158
+ ${model.error ? `<p class="absolute-voice-routing-status__error">${escapeHtml7(model.error)}</p>` : ""}
1791
2159
  </section>`;
1792
2160
  };
1793
2161
  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 +2197,13 @@ var defineVoiceRoutingStatusElement = (tagName = "absolute-voice-routing-status"
1829
2197
  };
1830
2198
 
1831
2199
  // src/vue/useVoiceRoutingStatus.ts
1832
- import { onUnmounted as onUnmounted6, ref as ref5, shallowRef as shallowRef5 } from "vue";
2200
+ import { onUnmounted as onUnmounted7, ref as ref6, shallowRef as shallowRef6 } from "vue";
1833
2201
  function useVoiceRoutingStatus(path = "/api/routing/latest", options = {}) {
1834
2202
  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);
2203
+ const decision = shallowRef6(null);
2204
+ const error = ref6(null);
2205
+ const isLoading = ref6(false);
2206
+ const updatedAt = ref6(undefined);
1839
2207
  const sync = () => {
1840
2208
  const snapshot = store.getSnapshot();
1841
2209
  decision.value = snapshot.decision;
@@ -1846,7 +2214,7 @@ function useVoiceRoutingStatus(path = "/api/routing/latest", options = {}) {
1846
2214
  const unsubscribe = store.subscribe(sync);
1847
2215
  sync();
1848
2216
  store.refresh().catch(() => {});
1849
- onUnmounted6(() => {
2217
+ onUnmounted7(() => {
1850
2218
  unsubscribe();
1851
2219
  store.close();
1852
2220
  });
@@ -1860,7 +2228,7 @@ function useVoiceRoutingStatus(path = "/api/routing/latest", options = {}) {
1860
2228
  }
1861
2229
 
1862
2230
  // src/vue/VoiceRoutingStatus.ts
1863
- var VoiceRoutingStatus = defineComponent6({
2231
+ var VoiceRoutingStatus = defineComponent7({
1864
2232
  name: "VoiceRoutingStatus",
1865
2233
  props: {
1866
2234
  class: {
@@ -1897,28 +2265,28 @@ var VoiceRoutingStatus = defineComponent6({
1897
2265
  isLoading: status.isLoading.value,
1898
2266
  updatedAt: status.updatedAt.value
1899
2267
  }, options));
1900
- return () => h6("section", {
2268
+ return () => h7("section", {
1901
2269
  class: [
1902
2270
  "absolute-voice-routing-status",
1903
2271
  `absolute-voice-routing-status--${model.value.status}`,
1904
2272
  props.class
1905
2273
  ]
1906
2274
  }, [
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)
2275
+ h7("header", { class: "absolute-voice-routing-status__header" }, [
2276
+ h7("span", { class: "absolute-voice-routing-status__eyebrow" }, model.value.title),
2277
+ h7("strong", { class: "absolute-voice-routing-status__label" }, model.value.label)
1910
2278
  ]),
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
2279
+ h7("p", { class: "absolute-voice-routing-status__description" }, model.value.description),
2280
+ model.value.rows.length ? h7("div", { class: "absolute-voice-routing-status__grid" }, model.value.rows.map((row) => h7("div", { key: row.label }, [
2281
+ h7("span", row.label),
2282
+ h7("strong", row.value)
2283
+ ]))) : h7("p", { class: "absolute-voice-routing-status__empty" }, "Start a voice session to see the selected provider."),
2284
+ model.value.error ? h7("p", { class: "absolute-voice-routing-status__error" }, model.value.error) : null
1917
2285
  ]);
1918
2286
  }
1919
2287
  });
1920
2288
  // src/vue/VoiceTurnLatency.ts
1921
- import { computed as computed5, defineComponent as defineComponent7, h as h7 } from "vue";
2289
+ import { computed as computed5, defineComponent as defineComponent8, h as h8 } from "vue";
1922
2290
 
1923
2291
  // src/client/turnLatency.ts
1924
2292
  var fetchVoiceTurnLatency = async (path = "/api/turn-latency", options = {}) => {
@@ -2024,10 +2392,10 @@ var createVoiceTurnLatencyStore = (path = "/api/turn-latency", options = {}) =>
2024
2392
  };
2025
2393
 
2026
2394
  // 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.";
2395
+ var DEFAULT_TITLE7 = "Turn Latency";
2396
+ var DEFAULT_DESCRIPTION7 = "Per-turn timing from first transcript to commit and assistant response start.";
2029
2397
  var DEFAULT_PROOF_LABEL = "Run latency proof";
2030
- var escapeHtml7 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
2398
+ var escapeHtml8 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
2031
2399
  var formatMs = (value) => typeof value === "number" ? `${Math.round(value)}ms` : "n/a";
2032
2400
  var createVoiceTurnLatencyViewModel = (snapshot, options = {}) => {
2033
2401
  const turns = (snapshot.report?.turns ?? []).map((turn) => ({
@@ -2041,39 +2409,39 @@ var createVoiceTurnLatencyViewModel = (snapshot, options = {}) => {
2041
2409
  const warningCount = snapshot.report?.warnings ?? turns.filter((turn) => turn.status === "warn").length;
2042
2410
  const failedCount = snapshot.report?.failed ?? turns.filter((turn) => turn.status === "fail").length;
2043
2411
  return {
2044
- description: options.description ?? DEFAULT_DESCRIPTION6,
2412
+ description: options.description ?? DEFAULT_DESCRIPTION7,
2045
2413
  error: snapshot.error,
2046
2414
  isLoading: snapshot.isLoading,
2047
2415
  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
2416
  proofLabel: options.proofPath ? options.proofLabel ?? DEFAULT_PROOF_LABEL : undefined,
2049
2417
  showProofAction: Boolean(options.proofPath),
2050
2418
  status: snapshot.error ? "error" : turns.length ? failedCount > 0 || warningCount > 0 ? "warning" : "ready" : snapshot.isLoading ? "loading" : "empty",
2051
- title: options.title ?? DEFAULT_TITLE6,
2419
+ title: options.title ?? DEFAULT_TITLE7,
2052
2420
  turns,
2053
2421
  updatedAt: snapshot.updatedAt
2054
2422
  };
2055
2423
  };
2056
2424
  var renderVoiceTurnLatencyHTML = (snapshot, options = {}) => {
2057
2425
  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)}">
2426
+ 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
2427
  <header>
2060
- <strong>${escapeHtml7(turn.label)}</strong>
2061
- <span>${escapeHtml7(turn.status)}</span>
2428
+ <strong>${escapeHtml8(turn.label)}</strong>
2429
+ <span>${escapeHtml8(turn.status)}</span>
2062
2430
  </header>
2063
2431
  <dl>${turn.rows.map((row) => `<div>
2064
- <dt>${escapeHtml7(row.label)}</dt>
2065
- <dd>${escapeHtml7(row.value)}</dd>
2432
+ <dt>${escapeHtml8(row.label)}</dt>
2433
+ <dd>${escapeHtml8(row.value)}</dd>
2066
2434
  </div>`).join("")}</dl>
2067
2435
  </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)}">
2436
+ return `<section class="absolute-voice-turn-latency absolute-voice-turn-latency--${escapeHtml8(model.status)}">
2069
2437
  <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>
2438
+ <span class="absolute-voice-turn-latency__eyebrow">${escapeHtml8(model.title)}</span>
2439
+ <strong class="absolute-voice-turn-latency__label">${escapeHtml8(model.label)}</strong>
2072
2440
  </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>` : ""}
2441
+ <p class="absolute-voice-turn-latency__description">${escapeHtml8(model.description)}</p>
2442
+ ${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
2443
  ${turns}
2076
- ${model.error ? `<p class="absolute-voice-turn-latency__error">${escapeHtml7(model.error)}</p>` : ""}
2444
+ ${model.error ? `<p class="absolute-voice-turn-latency__error">${escapeHtml8(model.error)}</p>` : ""}
2077
2445
  </section>`;
2078
2446
  };
2079
2447
  var mountVoiceTurnLatency = (element, path = "/api/turn-latency", options = {}) => {
@@ -2124,13 +2492,13 @@ var defineVoiceTurnLatencyElement = (tagName = "absolute-voice-turn-latency") =>
2124
2492
  };
2125
2493
 
2126
2494
  // src/vue/useVoiceTurnLatency.ts
2127
- import { onUnmounted as onUnmounted7, shallowRef as shallowRef6 } from "vue";
2495
+ import { onUnmounted as onUnmounted8, shallowRef as shallowRef7 } from "vue";
2128
2496
  function useVoiceTurnLatency(path = "/api/turn-latency", options = {}) {
2129
2497
  const store = createVoiceTurnLatencyStore(path, options);
2130
- const error = shallowRef6(null);
2131
- const isLoading = shallowRef6(false);
2132
- const report = shallowRef6();
2133
- const updatedAt = shallowRef6(undefined);
2498
+ const error = shallowRef7(null);
2499
+ const isLoading = shallowRef7(false);
2500
+ const report = shallowRef7();
2501
+ const updatedAt = shallowRef7(undefined);
2134
2502
  const sync = () => {
2135
2503
  const snapshot = store.getSnapshot();
2136
2504
  error.value = snapshot.error;
@@ -2141,7 +2509,7 @@ function useVoiceTurnLatency(path = "/api/turn-latency", options = {}) {
2141
2509
  const unsubscribe = store.subscribe(sync);
2142
2510
  sync();
2143
2511
  store.refresh().catch(() => {});
2144
- onUnmounted7(() => {
2512
+ onUnmounted8(() => {
2145
2513
  unsubscribe();
2146
2514
  store.close();
2147
2515
  });
@@ -2156,7 +2524,7 @@ function useVoiceTurnLatency(path = "/api/turn-latency", options = {}) {
2156
2524
  }
2157
2525
 
2158
2526
  // src/vue/VoiceTurnLatency.ts
2159
- var VoiceTurnLatency = defineComponent7({
2527
+ var VoiceTurnLatency = defineComponent8({
2160
2528
  name: "VoiceTurnLatency",
2161
2529
  props: {
2162
2530
  class: { default: "", type: String },
@@ -2182,47 +2550,47 @@ var VoiceTurnLatency = defineComponent7({
2182
2550
  report: latency.report.value,
2183
2551
  updatedAt: latency.updatedAt.value
2184
2552
  }, options));
2185
- return () => h7("section", {
2553
+ return () => h8("section", {
2186
2554
  class: [
2187
2555
  "absolute-voice-turn-latency",
2188
2556
  `absolute-voice-turn-latency--${model.value.status}`,
2189
2557
  props.class
2190
2558
  ]
2191
2559
  }, [
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)
2560
+ h8("header", { class: "absolute-voice-turn-latency__header" }, [
2561
+ h8("span", { class: "absolute-voice-turn-latency__eyebrow" }, model.value.title),
2562
+ h8("strong", { class: "absolute-voice-turn-latency__label" }, model.value.label)
2195
2563
  ]),
2196
- h7("p", { class: "absolute-voice-turn-latency__description" }, model.value.description),
2197
- model.value.showProofAction ? h7("button", {
2564
+ h8("p", { class: "absolute-voice-turn-latency__description" }, model.value.description),
2565
+ model.value.showProofAction ? h8("button", {
2198
2566
  class: "absolute-voice-turn-latency__proof",
2199
2567
  onClick: () => {
2200
2568
  latency.runProof().catch(() => {});
2201
2569
  },
2202
2570
  type: "button"
2203
2571
  }, model.value.proofLabel) : null,
2204
- model.value.turns.length ? h7("div", { class: "absolute-voice-turn-latency__turns" }, model.value.turns.map((turn) => h7("article", {
2572
+ model.value.turns.length ? h8("div", { class: "absolute-voice-turn-latency__turns" }, model.value.turns.map((turn) => h8("article", {
2205
2573
  class: [
2206
2574
  "absolute-voice-turn-latency__turn",
2207
2575
  `absolute-voice-turn-latency__turn--${turn.status}`
2208
2576
  ],
2209
2577
  key: `${turn.sessionId}:${turn.turnId}`
2210
2578
  }, [
2211
- h7("header", [
2212
- h7("strong", turn.label),
2213
- h7("span", turn.status)
2579
+ h8("header", [
2580
+ h8("strong", turn.label),
2581
+ h8("span", turn.status)
2214
2582
  ]),
2215
- h7("dl", turn.rows.map((row) => h7("div", { key: row.label }, [
2216
- h7("dt", row.label),
2217
- h7("dd", row.value)
2583
+ h8("dl", turn.rows.map((row) => h8("div", { key: row.label }, [
2584
+ h8("dt", row.label),
2585
+ h8("dd", row.value)
2218
2586
  ])))
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
2587
+ ]))) : h8("p", { class: "absolute-voice-turn-latency__empty" }, "Complete a voice turn to see latency diagnostics."),
2588
+ model.value.error ? h8("p", { class: "absolute-voice-turn-latency__error" }, model.value.error) : null
2221
2589
  ]);
2222
2590
  }
2223
2591
  });
2224
2592
  // src/vue/VoiceTurnQuality.ts
2225
- import { computed as computed6, defineComponent as defineComponent8, h as h8 } from "vue";
2593
+ import { computed as computed6, defineComponent as defineComponent9, h as h9 } from "vue";
2226
2594
 
2227
2595
  // src/client/turnQuality.ts
2228
2596
  var fetchVoiceTurnQuality = async (path = "/api/turn-quality", options = {}) => {
@@ -2304,9 +2672,9 @@ var createVoiceTurnQualityStore = (path = "/api/turn-quality", options = {}) =>
2304
2672
  };
2305
2673
 
2306
2674
  // 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;");
2675
+ var DEFAULT_TITLE8 = "Turn Quality";
2676
+ var DEFAULT_DESCRIPTION8 = "Per-turn STT confidence, fallback selection, corrections, and transcript coverage.";
2677
+ var escapeHtml9 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
2310
2678
  var formatConfidence = (value) => typeof value === "number" ? `${Math.round(value * 100)}%` : "n/a";
2311
2679
  var formatMaybe = (value) => value === undefined || value === "" ? "n/a" : String(value);
2312
2680
  var getTurnDetail = (turn) => {
@@ -2344,37 +2712,37 @@ var createVoiceTurnQualityViewModel = (snapshot, options = {}) => {
2344
2712
  const warningCount = snapshot.report?.warnings ?? turns.filter((turn) => turn.status === "warn").length;
2345
2713
  const failedCount = snapshot.report?.failed ?? turns.filter((turn) => turn.status === "fail").length;
2346
2714
  return {
2347
- description: options.description ?? DEFAULT_DESCRIPTION7,
2715
+ description: options.description ?? DEFAULT_DESCRIPTION8,
2348
2716
  error: snapshot.error,
2349
2717
  isLoading: snapshot.isLoading,
2350
2718
  label: snapshot.error ? "Unavailable" : turns.length ? failedCount > 0 ? `${failedCount} failed` : warningCount > 0 ? `${warningCount} warnings` : `${turns.length} healthy` : snapshot.isLoading ? "Checking" : "No turns",
2351
2719
  status: snapshot.error ? "error" : turns.length ? failedCount > 0 || warningCount > 0 ? "warning" : "ready" : snapshot.isLoading ? "loading" : "empty",
2352
- title: options.title ?? DEFAULT_TITLE7,
2720
+ title: options.title ?? DEFAULT_TITLE8,
2353
2721
  turns,
2354
2722
  updatedAt: snapshot.updatedAt
2355
2723
  };
2356
2724
  };
2357
2725
  var renderVoiceTurnQualityHTML = (snapshot, options = {}) => {
2358
2726
  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)}">
2727
+ 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
2728
  <header>
2361
- <strong>${escapeHtml8(turn.label)}</strong>
2362
- <span>${escapeHtml8(turn.status)}</span>
2729
+ <strong>${escapeHtml9(turn.label)}</strong>
2730
+ <span>${escapeHtml9(turn.status)}</span>
2363
2731
  </header>
2364
- <p>${escapeHtml8(turn.detail)}</p>
2732
+ <p>${escapeHtml9(turn.detail)}</p>
2365
2733
  <dl>${turn.rows.map((row) => `<div>
2366
- <dt>${escapeHtml8(row.label)}</dt>
2367
- <dd>${escapeHtml8(row.value)}</dd>
2734
+ <dt>${escapeHtml9(row.label)}</dt>
2735
+ <dd>${escapeHtml9(row.value)}</dd>
2368
2736
  </div>`).join("")}</dl>
2369
2737
  </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)}">
2738
+ return `<section class="absolute-voice-turn-quality absolute-voice-turn-quality--${escapeHtml9(model.status)}">
2371
2739
  <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>
2740
+ <span class="absolute-voice-turn-quality__eyebrow">${escapeHtml9(model.title)}</span>
2741
+ <strong class="absolute-voice-turn-quality__label">${escapeHtml9(model.label)}</strong>
2374
2742
  </header>
2375
- <p class="absolute-voice-turn-quality__description">${escapeHtml8(model.description)}</p>
2743
+ <p class="absolute-voice-turn-quality__description">${escapeHtml9(model.description)}</p>
2376
2744
  ${turns}
2377
- ${model.error ? `<p class="absolute-voice-turn-quality__error">${escapeHtml8(model.error)}</p>` : ""}
2745
+ ${model.error ? `<p class="absolute-voice-turn-quality__error">${escapeHtml9(model.error)}</p>` : ""}
2378
2746
  </section>`;
2379
2747
  };
2380
2748
  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 +2784,13 @@ var defineVoiceTurnQualityElement = (tagName = "absolute-voice-turn-quality") =>
2416
2784
  };
2417
2785
 
2418
2786
  // src/vue/useVoiceTurnQuality.ts
2419
- import { onUnmounted as onUnmounted8, shallowRef as shallowRef7 } from "vue";
2787
+ import { onUnmounted as onUnmounted9, shallowRef as shallowRef8 } from "vue";
2420
2788
  function useVoiceTurnQuality(path = "/api/turn-quality", options = {}) {
2421
2789
  const store = createVoiceTurnQualityStore(path, options);
2422
- const error = shallowRef7(null);
2423
- const isLoading = shallowRef7(false);
2424
- const report = shallowRef7();
2425
- const updatedAt = shallowRef7(undefined);
2790
+ const error = shallowRef8(null);
2791
+ const isLoading = shallowRef8(false);
2792
+ const report = shallowRef8();
2793
+ const updatedAt = shallowRef8(undefined);
2426
2794
  const sync = () => {
2427
2795
  const snapshot = store.getSnapshot();
2428
2796
  error.value = snapshot.error;
@@ -2433,7 +2801,7 @@ function useVoiceTurnQuality(path = "/api/turn-quality", options = {}) {
2433
2801
  const unsubscribe = store.subscribe(sync);
2434
2802
  sync();
2435
2803
  store.refresh().catch(() => {});
2436
- onUnmounted8(() => {
2804
+ onUnmounted9(() => {
2437
2805
  unsubscribe();
2438
2806
  store.close();
2439
2807
  });
@@ -2441,7 +2809,7 @@ function useVoiceTurnQuality(path = "/api/turn-quality", options = {}) {
2441
2809
  }
2442
2810
 
2443
2811
  // src/vue/VoiceTurnQuality.ts
2444
- var VoiceTurnQuality = defineComponent8({
2812
+ var VoiceTurnQuality = defineComponent9({
2445
2813
  name: "VoiceTurnQuality",
2446
2814
  props: {
2447
2815
  class: { default: "", type: String },
@@ -2463,41 +2831,41 @@ var VoiceTurnQuality = defineComponent8({
2463
2831
  report: quality.report.value,
2464
2832
  updatedAt: quality.updatedAt.value
2465
2833
  }, options));
2466
- return () => h8("section", {
2834
+ return () => h9("section", {
2467
2835
  class: [
2468
2836
  "absolute-voice-turn-quality",
2469
2837
  `absolute-voice-turn-quality--${model.value.status}`,
2470
2838
  props.class
2471
2839
  ]
2472
2840
  }, [
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)
2841
+ h9("header", { class: "absolute-voice-turn-quality__header" }, [
2842
+ h9("span", { class: "absolute-voice-turn-quality__eyebrow" }, model.value.title),
2843
+ h9("strong", { class: "absolute-voice-turn-quality__label" }, model.value.label)
2476
2844
  ]),
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", {
2845
+ h9("p", { class: "absolute-voice-turn-quality__description" }, model.value.description),
2846
+ model.value.turns.length ? h9("div", { class: "absolute-voice-turn-quality__turns" }, model.value.turns.map((turn) => h9("article", {
2479
2847
  class: [
2480
2848
  "absolute-voice-turn-quality__turn",
2481
2849
  `absolute-voice-turn-quality__turn--${turn.status}`
2482
2850
  ],
2483
2851
  key: `${turn.sessionId}:${turn.turnId}`
2484
2852
  }, [
2485
- h8("header", [
2486
- h8("strong", turn.label),
2487
- h8("span", turn.status)
2853
+ h9("header", [
2854
+ h9("strong", turn.label),
2855
+ h9("span", turn.status)
2488
2856
  ]),
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)
2857
+ h9("p", turn.detail),
2858
+ h9("dl", turn.rows.map((row) => h9("div", { key: row.label }, [
2859
+ h9("dt", row.label),
2860
+ h9("dd", row.value)
2493
2861
  ])))
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
2862
+ ]))) : h9("p", { class: "absolute-voice-turn-quality__empty" }, "Complete a voice turn to see STT quality diagnostics."),
2863
+ model.value.error ? h9("p", { class: "absolute-voice-turn-quality__error" }, model.value.error) : null
2496
2864
  ]);
2497
2865
  }
2498
2866
  });
2499
2867
  // src/vue/useVoiceCampaignDialerProof.ts
2500
- import { onUnmounted as onUnmounted9, shallowRef as shallowRef8 } from "vue";
2868
+ import { onUnmounted as onUnmounted10, shallowRef as shallowRef9 } from "vue";
2501
2869
 
2502
2870
  // src/client/campaignDialerProof.ts
2503
2871
  var fetchVoiceCampaignDialerProofStatus = async (path = "/api/voice/campaigns/dialer-proof", options = {}) => {
@@ -2620,11 +2988,11 @@ var createVoiceCampaignDialerProofStore = (path = "/api/voice/campaigns/dialer-p
2620
2988
  // src/vue/useVoiceCampaignDialerProof.ts
2621
2989
  function useVoiceCampaignDialerProof(path = "/api/voice/campaigns/dialer-proof", options = {}) {
2622
2990
  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);
2991
+ const error = shallowRef9(null);
2992
+ const isLoading = shallowRef9(false);
2993
+ const report = shallowRef9();
2994
+ const status = shallowRef9();
2995
+ const updatedAt = shallowRef9(undefined);
2628
2996
  const sync = () => {
2629
2997
  const snapshot = store.getSnapshot();
2630
2998
  error.value = snapshot.error;
@@ -2638,7 +3006,7 @@ function useVoiceCampaignDialerProof(path = "/api/voice/campaigns/dialer-proof",
2638
3006
  if (typeof window !== "undefined") {
2639
3007
  store.refresh().catch(() => {});
2640
3008
  }
2641
- onUnmounted9(() => {
3009
+ onUnmounted10(() => {
2642
3010
  unsubscribe();
2643
3011
  store.close();
2644
3012
  });
@@ -2653,7 +3021,7 @@ function useVoiceCampaignDialerProof(path = "/api/voice/campaigns/dialer-proof",
2653
3021
  };
2654
3022
  }
2655
3023
  // src/vue/useVoiceStream.ts
2656
- import { onUnmounted as onUnmounted10, ref as ref6, shallowRef as shallowRef9 } from "vue";
3024
+ import { onUnmounted as onUnmounted11, ref as ref7, shallowRef as shallowRef10 } from "vue";
2657
3025
 
2658
3026
  // src/client/actions.ts
2659
3027
  var normalizeErrorMessage = (value) => {
@@ -3298,16 +3666,16 @@ var createVoiceStream = (path, options = {}) => {
3298
3666
  // src/vue/useVoiceStream.ts
3299
3667
  function useVoiceStream(path, options = {}) {
3300
3668
  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([]);
3669
+ const assistantAudio = shallowRef10([]);
3670
+ const assistantTexts = shallowRef10([]);
3671
+ const call = shallowRef10(null);
3672
+ const error = ref7(null);
3673
+ const isConnected = ref7(false);
3674
+ const partial = ref7("");
3675
+ const reconnect = shallowRef10(stream.reconnect);
3676
+ const sessionId = ref7(stream.sessionId);
3677
+ const status = ref7(stream.status);
3678
+ const turns = shallowRef10([]);
3311
3679
  const sync = () => {
3312
3680
  assistantAudio.value = [...stream.assistantAudio];
3313
3681
  assistantTexts.value = [...stream.assistantTexts];
@@ -3326,7 +3694,7 @@ function useVoiceStream(path, options = {}) {
3326
3694
  unsubscribe();
3327
3695
  stream.close();
3328
3696
  };
3329
- onUnmounted10(destroy);
3697
+ onUnmounted11(destroy);
3330
3698
  return {
3331
3699
  assistantAudio,
3332
3700
  assistantTexts,
@@ -3345,7 +3713,7 @@ function useVoiceStream(path, options = {}) {
3345
3713
  };
3346
3714
  }
3347
3715
  // src/vue/useVoiceController.ts
3348
- import { onUnmounted as onUnmounted11, ref as ref7, shallowRef as shallowRef10 } from "vue";
3716
+ import { onUnmounted as onUnmounted12, ref as ref8, shallowRef as shallowRef11 } from "vue";
3349
3717
 
3350
3718
  // src/client/htmx.ts
3351
3719
  var DEFAULT_EVENT_NAME = "voice-refresh";
@@ -3991,17 +4359,17 @@ var createVoiceController = (path, options = {}) => {
3991
4359
  // src/vue/useVoiceController.ts
3992
4360
  function useVoiceController(path, options = {}) {
3993
4361
  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([]);
4362
+ const assistantAudio = shallowRef11([]);
4363
+ const assistantTexts = shallowRef11([]);
4364
+ const error = ref8(null);
4365
+ const isConnected = ref8(false);
4366
+ const isRecording = ref8(false);
4367
+ const partial = ref8("");
4368
+ const reconnect = shallowRef11(controller.reconnect);
4369
+ const recordingError = ref8(null);
4370
+ const sessionId = ref8(controller.sessionId);
4371
+ const status = ref8(controller.status);
4372
+ const turns = shallowRef11([]);
4005
4373
  const sync = () => {
4006
4374
  assistantAudio.value = [...controller.assistantAudio];
4007
4375
  assistantTexts.value = [...controller.assistantTexts];
@@ -4021,7 +4389,7 @@ function useVoiceController(path, options = {}) {
4021
4389
  unsubscribe();
4022
4390
  controller.close();
4023
4391
  };
4024
- onUnmounted11(destroy);
4392
+ onUnmounted12(destroy);
4025
4393
  return {
4026
4394
  assistantAudio,
4027
4395
  assistantTexts,
@@ -4044,7 +4412,7 @@ function useVoiceController(path, options = {}) {
4044
4412
  };
4045
4413
  }
4046
4414
  // src/vue/useVoiceTraceTimeline.ts
4047
- import { onUnmounted as onUnmounted12, ref as ref8, shallowRef as shallowRef11 } from "vue";
4415
+ import { onUnmounted as onUnmounted13, ref as ref9, shallowRef as shallowRef12 } from "vue";
4048
4416
 
4049
4417
  // src/client/traceTimeline.ts
4050
4418
  var fetchVoiceTraceTimeline = async (path = "/api/voice-traces", options = {}) => {
@@ -4129,10 +4497,10 @@ var createVoiceTraceTimelineStore = (path = "/api/voice-traces", options = {}) =
4129
4497
  // src/vue/useVoiceTraceTimeline.ts
4130
4498
  function useVoiceTraceTimeline(path = "/api/voice-traces", options = {}) {
4131
4499
  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);
4500
+ const error = ref9(null);
4501
+ const isLoading = ref9(false);
4502
+ const report = shallowRef12(null);
4503
+ const updatedAt = ref9(undefined);
4136
4504
  const sync = () => {
4137
4505
  const snapshot = store.getSnapshot();
4138
4506
  error.value = snapshot.error;
@@ -4143,7 +4511,7 @@ function useVoiceTraceTimeline(path = "/api/voice-traces", options = {}) {
4143
4511
  const unsubscribe = store.subscribe(sync);
4144
4512
  sync();
4145
4513
  store.refresh().catch(() => {});
4146
- onUnmounted12(() => {
4514
+ onUnmounted13(() => {
4147
4515
  unsubscribe();
4148
4516
  store.close();
4149
4517
  });
@@ -4156,7 +4524,7 @@ function useVoiceTraceTimeline(path = "/api/voice-traces", options = {}) {
4156
4524
  };
4157
4525
  }
4158
4526
  // src/vue/useVoiceWorkflowStatus.ts
4159
- import { onUnmounted as onUnmounted13, ref as ref9, shallowRef as shallowRef12 } from "vue";
4527
+ import { onUnmounted as onUnmounted14, ref as ref10, shallowRef as shallowRef13 } from "vue";
4160
4528
 
4161
4529
  // src/client/workflowStatus.ts
4162
4530
  var fetchVoiceWorkflowStatus = async (path = "/evals/scenarios/json", options = {}) => {
@@ -4240,10 +4608,10 @@ var createVoiceWorkflowStatusStore = (path = "/evals/scenarios/json", options =
4240
4608
  // src/vue/useVoiceWorkflowStatus.ts
4241
4609
  function useVoiceWorkflowStatus(path = "/evals/scenarios/json", options = {}) {
4242
4610
  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);
4611
+ const error = ref10(null);
4612
+ const isLoading = ref10(false);
4613
+ const report = shallowRef13(undefined);
4614
+ const updatedAt = ref10(undefined);
4247
4615
  const sync = () => {
4248
4616
  const snapshot = store.getSnapshot();
4249
4617
  error.value = snapshot.error;
@@ -4256,7 +4624,7 @@ function useVoiceWorkflowStatus(path = "/evals/scenarios/json", options = {}) {
4256
4624
  if (typeof window !== "undefined") {
4257
4625
  store.refresh().catch(() => {});
4258
4626
  }
4259
- onUnmounted13(() => {
4627
+ onUnmounted14(() => {
4260
4628
  unsubscribe();
4261
4629
  store.close();
4262
4630
  });
@@ -4279,6 +4647,7 @@ export {
4279
4647
  useVoiceProviderSimulationControls,
4280
4648
  useVoiceProviderCapabilities,
4281
4649
  useVoiceOpsStatus,
4650
+ useVoiceOpsActionCenter,
4282
4651
  useVoiceDeliveryRuntime,
4283
4652
  useVoiceController,
4284
4653
  useVoiceCampaignDialerProof,
@@ -4289,5 +4658,6 @@ export {
4289
4658
  VoiceProviderSimulationControls,
4290
4659
  VoiceProviderCapabilities,
4291
4660
  VoiceOpsStatus,
4661
+ VoiceOpsActionCenter,
4292
4662
  VoiceDeliveryRuntime
4293
4663
  };