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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -387,7 +387,333 @@ var VoiceOpsStatus = ({
387
387
  ]
388
388
  }, undefined, true, undefined, this);
389
389
  };
390
+ // src/client/opsActionCenter.ts
391
+ var createVoiceOpsActionCenterActions = (options = {}) => {
392
+ const deliveryRuntimePath = options.deliveryRuntimePath ?? "/api/voice-delivery-runtime";
393
+ const actions = [];
394
+ if (options.includeProductionReadiness !== false) {
395
+ actions.push({
396
+ description: "Refresh the production readiness report.",
397
+ id: "production-readiness",
398
+ label: "Refresh readiness",
399
+ method: "GET",
400
+ path: options.productionReadinessPath ?? "/api/production-readiness"
401
+ });
402
+ }
403
+ if (options.includeDeliveryRuntime !== false) {
404
+ actions.push({
405
+ description: "Drain pending and failed audit/trace deliveries.",
406
+ id: "delivery-runtime.tick",
407
+ label: "Tick delivery workers",
408
+ method: "POST",
409
+ path: `${deliveryRuntimePath.replace(/\/$/, "")}/tick`
410
+ }, {
411
+ description: "Move reviewed dead letters back to live delivery queues.",
412
+ id: "delivery-runtime.requeue-dead-letters",
413
+ label: "Requeue dead letters",
414
+ method: "POST",
415
+ path: `${deliveryRuntimePath.replace(/\/$/, "")}/requeue-dead-letters`
416
+ });
417
+ }
418
+ if (options.includeTurnLatencyProof !== false) {
419
+ actions.push({
420
+ description: "Run the synthetic turn latency proof.",
421
+ id: "turn-latency.proof",
422
+ label: "Run latency proof",
423
+ method: "POST",
424
+ path: options.turnLatencyProofPath ?? "/api/turn-latency/proof"
425
+ });
426
+ }
427
+ if (options.includeProviderSimulation !== false) {
428
+ const pathPrefix = options.providerSimulationPathPrefix ?? "/api/stt-simulate";
429
+ for (const provider of options.providers ?? []) {
430
+ actions.push({
431
+ description: `Simulate ${provider} provider failure.`,
432
+ id: `provider.${provider}.failure`,
433
+ label: `Simulate ${provider} failure`,
434
+ method: "POST",
435
+ path: `${pathPrefix}/failure?provider=${encodeURIComponent(provider)}`
436
+ }, {
437
+ description: `Mark ${provider} provider recovered.`,
438
+ id: `provider.${provider}.recovery`,
439
+ label: `Recover ${provider}`,
440
+ method: "POST",
441
+ path: `${pathPrefix}/recovery?provider=${encodeURIComponent(provider)}`
442
+ });
443
+ }
444
+ }
445
+ return actions;
446
+ };
447
+ var runVoiceOpsAction = async (action, options = {}) => {
448
+ const fetchImpl = options.fetch ?? globalThis.fetch;
449
+ const response = await fetchImpl(action.path, {
450
+ method: action.method ?? "POST"
451
+ });
452
+ const body = await response.json().catch(() => null);
453
+ if (!response.ok) {
454
+ const message = body && typeof body === "object" && "error" in body ? String(body.error) : `Voice ops action "${action.id}" failed: HTTP ${response.status}`;
455
+ throw new Error(message);
456
+ }
457
+ return {
458
+ actionId: action.id,
459
+ body,
460
+ ok: response.ok,
461
+ ranAt: Date.now(),
462
+ status: response.status
463
+ };
464
+ };
465
+ var createVoiceOpsActionCenterStore = (options = {}) => {
466
+ const listeners = new Set;
467
+ let closed = false;
468
+ let timer;
469
+ let snapshot = {
470
+ actions: options.actions ?? createVoiceOpsActionCenterActions(),
471
+ error: null,
472
+ isRunning: false
473
+ };
474
+ const emit = () => {
475
+ for (const listener of listeners) {
476
+ listener();
477
+ }
478
+ };
479
+ const setActions = (actions) => {
480
+ snapshot = { ...snapshot, actions, updatedAt: Date.now() };
481
+ emit();
482
+ };
483
+ const run = async (actionId) => {
484
+ if (closed) {
485
+ return snapshot.lastResult;
486
+ }
487
+ const action = snapshot.actions.find((item) => item.id === actionId);
488
+ if (!action) {
489
+ throw new Error(`Voice ops action "${actionId}" is not configured.`);
490
+ }
491
+ if (action.disabled) {
492
+ throw new Error(`Voice ops action "${actionId}" is disabled.`);
493
+ }
494
+ snapshot = {
495
+ ...snapshot,
496
+ error: null,
497
+ isRunning: true,
498
+ runningActionId: action.id
499
+ };
500
+ emit();
501
+ try {
502
+ const result = await runVoiceOpsAction(action, options);
503
+ snapshot = {
504
+ ...snapshot,
505
+ error: null,
506
+ isRunning: false,
507
+ lastResult: result,
508
+ runningActionId: undefined,
509
+ updatedAt: Date.now()
510
+ };
511
+ emit();
512
+ return result;
513
+ } catch (error) {
514
+ snapshot = {
515
+ ...snapshot,
516
+ error: error instanceof Error ? error.message : String(error),
517
+ isRunning: false,
518
+ runningActionId: undefined
519
+ };
520
+ emit();
521
+ throw error;
522
+ }
523
+ };
524
+ const close = () => {
525
+ closed = true;
526
+ if (timer) {
527
+ clearInterval(timer);
528
+ timer = undefined;
529
+ }
530
+ listeners.clear();
531
+ };
532
+ if (options.intervalMs && options.intervalMs > 0) {
533
+ timer = setInterval(() => {
534
+ emit();
535
+ }, options.intervalMs);
536
+ }
537
+ return {
538
+ close,
539
+ getServerSnapshot: () => snapshot,
540
+ getSnapshot: () => snapshot,
541
+ run,
542
+ setActions,
543
+ subscribe: (listener) => {
544
+ listeners.add(listener);
545
+ return () => {
546
+ listeners.delete(listener);
547
+ };
548
+ }
549
+ };
550
+ };
551
+
552
+ // src/client/opsActionCenterWidget.ts
553
+ var DEFAULT_TITLE2 = "Voice Ops Action Center";
554
+ var DEFAULT_DESCRIPTION2 = "Run production voice proofs and operator actions from one primitive panel.";
555
+ var escapeHtml2 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
556
+ var createVoiceOpsActionCenterViewModel = (snapshot, options = {}) => {
557
+ const status = snapshot.error ? "error" : snapshot.isRunning ? "running" : snapshot.lastResult ? "completed" : "ready";
558
+ return {
559
+ actions: snapshot.actions.map((action) => ({
560
+ description: action.description ?? "",
561
+ disabled: Boolean(action.disabled || snapshot.isRunning),
562
+ id: action.id,
563
+ isRunning: snapshot.runningActionId === action.id,
564
+ label: action.label
565
+ })),
566
+ description: options.description ?? DEFAULT_DESCRIPTION2,
567
+ error: snapshot.error,
568
+ isRunning: snapshot.isRunning,
569
+ label: status === "error" ? "Needs attention" : status === "running" ? "Running" : status === "completed" ? "Action completed" : "Ready",
570
+ lastResultLabel: snapshot.lastResult ? `${snapshot.lastResult.actionId} returned HTTP ${snapshot.lastResult.status}` : "No action has run yet.",
571
+ status,
572
+ title: options.title ?? DEFAULT_TITLE2
573
+ };
574
+ };
575
+ var renderVoiceOpsActionCenterHTML = (snapshot, options = {}) => {
576
+ const model = createVoiceOpsActionCenterViewModel(snapshot, options);
577
+ const actions = model.actions.map((action) => `<button type="button" data-absolute-voice-ops-action="${escapeHtml2(action.id)}"${action.disabled ? " disabled" : ""}>
578
+ ${escapeHtml2(action.isRunning ? "Working..." : action.label)}
579
+ </button>`).join("");
580
+ return `<section class="absolute-voice-ops-action-center absolute-voice-ops-action-center--${escapeHtml2(model.status)}">
581
+ <header class="absolute-voice-ops-action-center__header">
582
+ <span class="absolute-voice-ops-action-center__eyebrow">${escapeHtml2(model.title)}</span>
583
+ <strong class="absolute-voice-ops-action-center__label">${escapeHtml2(model.label)}</strong>
584
+ </header>
585
+ <p class="absolute-voice-ops-action-center__description">${escapeHtml2(model.description)}</p>
586
+ <div class="absolute-voice-ops-action-center__actions">${actions}</div>
587
+ <p class="absolute-voice-ops-action-center__result">${escapeHtml2(model.lastResultLabel)}</p>
588
+ ${model.error ? `<p class="absolute-voice-ops-action-center__error">${escapeHtml2(model.error)}</p>` : ""}
589
+ </section>`;
590
+ };
591
+ 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}`;
592
+ var mountVoiceOpsActionCenter = (element, options = {}) => {
593
+ const store = createVoiceOpsActionCenterStore(options);
594
+ const render = () => {
595
+ element.innerHTML = renderVoiceOpsActionCenterHTML(store.getSnapshot(), options);
596
+ };
597
+ const unsubscribe = store.subscribe(render);
598
+ const handleClick = (event) => {
599
+ const target = event.target;
600
+ if (!(target instanceof Element)) {
601
+ return;
602
+ }
603
+ const action = target.closest("[data-absolute-voice-ops-action]");
604
+ const actionId = action?.getAttribute("data-absolute-voice-ops-action");
605
+ if (actionId) {
606
+ store.run(actionId).catch(() => {});
607
+ }
608
+ };
609
+ element.addEventListener?.("click", handleClick);
610
+ render();
611
+ return {
612
+ close: () => {
613
+ element.removeEventListener?.("click", handleClick);
614
+ unsubscribe();
615
+ store.close();
616
+ },
617
+ run: store.run
618
+ };
619
+ };
620
+ var defineVoiceOpsActionCenterElement = (tagName = "absolute-voice-ops-action-center", options = {}) => {
621
+ if (typeof window === "undefined" || typeof customElements === "undefined" || customElements.get(tagName)) {
622
+ return;
623
+ }
624
+ customElements.define(tagName, class AbsoluteVoiceOpsActionCenterElement extends HTMLElement {
625
+ mounted;
626
+ connectedCallback() {
627
+ this.mounted = mountVoiceOpsActionCenter(this, {
628
+ ...options,
629
+ description: this.getAttribute("description") ?? options.description,
630
+ title: this.getAttribute("title") ?? options.title
631
+ });
632
+ }
633
+ disconnectedCallback() {
634
+ this.mounted?.close();
635
+ this.mounted = undefined;
636
+ }
637
+ });
638
+ };
639
+
640
+ // src/react/useVoiceOpsActionCenter.tsx
641
+ import { useEffect as useEffect2, useRef as useRef2, useSyncExternalStore as useSyncExternalStore2 } from "react";
642
+ var useVoiceOpsActionCenter = (options = {}) => {
643
+ const storeRef = useRef2(null);
644
+ if (!storeRef.current) {
645
+ storeRef.current = createVoiceOpsActionCenterStore(options);
646
+ }
647
+ const store = storeRef.current;
648
+ useEffect2(() => () => store.close(), [store]);
649
+ return {
650
+ ...useSyncExternalStore2(store.subscribe, store.getSnapshot, store.getServerSnapshot),
651
+ run: store.run,
652
+ setActions: store.setActions
653
+ };
654
+ };
655
+
656
+ // src/react/VoiceOpsActionCenter.tsx
657
+ import { jsxDEV as jsxDEV2 } from "react/jsx-dev-runtime";
658
+ var VoiceOpsActionCenter = ({
659
+ className,
660
+ ...options
661
+ }) => {
662
+ const snapshot = useVoiceOpsActionCenter(options);
663
+ const model = createVoiceOpsActionCenterViewModel(snapshot, options);
664
+ return /* @__PURE__ */ jsxDEV2("section", {
665
+ className: [
666
+ "absolute-voice-ops-action-center",
667
+ `absolute-voice-ops-action-center--${model.status}`,
668
+ className
669
+ ].filter(Boolean).join(" "),
670
+ children: [
671
+ /* @__PURE__ */ jsxDEV2("header", {
672
+ className: "absolute-voice-ops-action-center__header",
673
+ children: [
674
+ /* @__PURE__ */ jsxDEV2("span", {
675
+ className: "absolute-voice-ops-action-center__eyebrow",
676
+ children: model.title
677
+ }, undefined, false, undefined, this),
678
+ /* @__PURE__ */ jsxDEV2("strong", {
679
+ className: "absolute-voice-ops-action-center__label",
680
+ children: model.label
681
+ }, undefined, false, undefined, this)
682
+ ]
683
+ }, undefined, true, undefined, this),
684
+ /* @__PURE__ */ jsxDEV2("p", {
685
+ className: "absolute-voice-ops-action-center__description",
686
+ children: model.description
687
+ }, undefined, false, undefined, this),
688
+ /* @__PURE__ */ jsxDEV2("div", {
689
+ className: "absolute-voice-ops-action-center__actions",
690
+ children: model.actions.map((action) => /* @__PURE__ */ jsxDEV2("button", {
691
+ disabled: action.disabled,
692
+ onClick: () => {
693
+ snapshot.run(action.id).catch(() => {});
694
+ },
695
+ type: "button",
696
+ children: action.isRunning ? "Working..." : action.label
697
+ }, action.id, false, undefined, this))
698
+ }, undefined, false, undefined, this),
699
+ /* @__PURE__ */ jsxDEV2("p", {
700
+ className: "absolute-voice-ops-action-center__result",
701
+ children: model.lastResultLabel
702
+ }, undefined, false, undefined, this),
703
+ model.error ? /* @__PURE__ */ jsxDEV2("p", {
704
+ className: "absolute-voice-ops-action-center__error",
705
+ children: model.error
706
+ }, undefined, false, undefined, this) : null
707
+ ]
708
+ }, undefined, true, undefined, this);
709
+ };
390
710
  // src/client/deliveryRuntime.ts
711
+ var getDefaultActionPath = (path, action, options) => {
712
+ if (action === "tick") {
713
+ return options.tickPath ?? `${path.replace(/\/$/, "")}/tick`;
714
+ }
715
+ return options.requeueDeadLettersPath ?? `${path.replace(/\/$/, "")}/requeue-dead-letters`;
716
+ };
391
717
  var fetchVoiceDeliveryRuntime = async (path = "/api/voice-delivery-runtime", options = {}) => {
392
718
  const fetchImpl = options.fetch ?? globalThis.fetch;
393
719
  const response = await fetchImpl(path);
@@ -396,11 +722,29 @@ var fetchVoiceDeliveryRuntime = async (path = "/api/voice-delivery-runtime", opt
396
722
  }
397
723
  return await response.json();
398
724
  };
725
+ var runVoiceDeliveryRuntimeAction = async (action, path = "/api/voice-delivery-runtime", options = {}) => {
726
+ const fetchImpl = options.fetch ?? globalThis.fetch;
727
+ const response = await fetchImpl(getDefaultActionPath(path, action, options), {
728
+ method: "POST"
729
+ });
730
+ if (!response.ok) {
731
+ throw new Error(`Voice delivery runtime ${action} failed: HTTP ${response.status}`);
732
+ }
733
+ const body = await response.json();
734
+ return {
735
+ action,
736
+ result: body.result,
737
+ summary: body.summary,
738
+ updatedAt: Date.now()
739
+ };
740
+ };
399
741
  var createVoiceDeliveryRuntimeStore = (path = "/api/voice-delivery-runtime", options = {}) => {
400
742
  const listeners = new Set;
401
743
  let closed = false;
402
744
  let timer;
403
745
  let snapshot = {
746
+ actionError: null,
747
+ actionStatus: "idle",
404
748
  error: null,
405
749
  isLoading: false
406
750
  };
@@ -422,6 +766,7 @@ var createVoiceDeliveryRuntimeStore = (path = "/api/voice-delivery-runtime", opt
422
766
  try {
423
767
  const report = await fetchVoiceDeliveryRuntime(path, options);
424
768
  snapshot = {
769
+ ...snapshot,
425
770
  error: null,
426
771
  isLoading: false,
427
772
  report,
@@ -439,6 +784,37 @@ var createVoiceDeliveryRuntimeStore = (path = "/api/voice-delivery-runtime", opt
439
784
  throw error;
440
785
  }
441
786
  };
787
+ const runAction = async (action) => {
788
+ if (closed) {
789
+ return snapshot.lastAction;
790
+ }
791
+ snapshot = {
792
+ ...snapshot,
793
+ actionError: null,
794
+ actionStatus: "running"
795
+ };
796
+ emit();
797
+ try {
798
+ const result = await runVoiceDeliveryRuntimeAction(action, path, options);
799
+ snapshot = {
800
+ ...snapshot,
801
+ actionError: null,
802
+ actionStatus: "completed",
803
+ lastAction: result
804
+ };
805
+ emit();
806
+ await refresh();
807
+ return result;
808
+ } catch (error) {
809
+ snapshot = {
810
+ ...snapshot,
811
+ actionError: error instanceof Error ? error.message : String(error),
812
+ actionStatus: "failed"
813
+ };
814
+ emit();
815
+ throw error;
816
+ }
817
+ };
442
818
  const close = () => {
443
819
  closed = true;
444
820
  if (timer) {
@@ -456,7 +832,9 @@ var createVoiceDeliveryRuntimeStore = (path = "/api/voice-delivery-runtime", opt
456
832
  close,
457
833
  getServerSnapshot: () => snapshot,
458
834
  getSnapshot: () => snapshot,
835
+ requeueDeadLetters: () => runAction("requeue-dead-letters"),
459
836
  refresh,
837
+ tick: () => runAction("tick"),
460
838
  subscribe: (listener) => {
461
839
  listeners.add(listener);
462
840
  return () => {
@@ -467,9 +845,9 @@ var createVoiceDeliveryRuntimeStore = (path = "/api/voice-delivery-runtime", opt
467
845
  };
468
846
 
469
847
  // src/client/deliveryRuntimeWidget.ts
470
- var DEFAULT_TITLE2 = "Voice Delivery Runtime";
471
- var DEFAULT_DESCRIPTION2 = "Audit and trace delivery worker health from your AbsoluteJS voice app.";
472
- var escapeHtml2 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
848
+ var DEFAULT_TITLE3 = "Voice Delivery Runtime";
849
+ var DEFAULT_DESCRIPTION3 = "Audit and trace delivery worker health from your AbsoluteJS voice app.";
850
+ var escapeHtml3 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
473
851
  var createSurface = (id, summary) => {
474
852
  if (!summary) {
475
853
  return {
@@ -503,45 +881,70 @@ var createVoiceDeliveryRuntimeViewModel = (snapshot, options = {}) => {
503
881
  ];
504
882
  const hasWarnings = surfaces.some((surface) => surface.status === "warn");
505
883
  return {
506
- description: options.description ?? DEFAULT_DESCRIPTION2,
884
+ description: options.description ?? DEFAULT_DESCRIPTION3,
507
885
  error: snapshot.error,
886
+ actionError: snapshot.actionError,
887
+ actionStatus: snapshot.actionStatus,
508
888
  isLoading: snapshot.isLoading,
509
889
  isRunning: Boolean(report?.isRunning),
510
890
  label: snapshot.error ? "Unavailable" : report ? report.isRunning ? "Running" : "Stopped" : "Checking",
511
891
  status: snapshot.error ? "error" : report ? hasWarnings ? "warn" : "pass" : "loading",
512
892
  surfaces,
513
- title: options.title ?? DEFAULT_TITLE2,
893
+ title: options.title ?? DEFAULT_TITLE3,
514
894
  updatedAt: snapshot.updatedAt
515
895
  };
516
896
  };
517
897
  var renderVoiceDeliveryRuntimeHTML = (snapshot, options = {}) => {
518
898
  const model = createVoiceDeliveryRuntimeViewModel(snapshot, options);
519
- const surfaces = model.surfaces.map((surface) => `<li class="absolute-voice-delivery-runtime__surface absolute-voice-delivery-runtime__surface--${escapeHtml2(surface.status)}">
520
- <span>${escapeHtml2(surface.label)}</span>
521
- <strong>${escapeHtml2(surface.detail)}</strong>
899
+ const surfaces = model.surfaces.map((surface) => `<li class="absolute-voice-delivery-runtime__surface absolute-voice-delivery-runtime__surface--${escapeHtml3(surface.status)}">
900
+ <span>${escapeHtml3(surface.label)}</span>
901
+ <strong>${escapeHtml3(surface.detail)}</strong>
522
902
  <small>${String(surface.failed)} failed &middot; ${String(surface.deadLettered)} dead-lettered</small>
523
903
  </li>`).join("");
524
- return `<section class="absolute-voice-delivery-runtime absolute-voice-delivery-runtime--${escapeHtml2(model.status)}">
904
+ const actions = options.includeActions === false ? "" : `<div class="absolute-voice-delivery-runtime__actions">
905
+ <button type="button" data-absolute-voice-delivery-runtime-action="tick">${model.actionStatus === "running" ? "Working..." : "Tick workers"}</button>
906
+ <button type="button" data-absolute-voice-delivery-runtime-action="requeue-dead-letters"${model.surfaces.some((surface) => surface.deadLettered > 0) ? "" : " disabled"}>Requeue dead letters</button>
907
+ </div>`;
908
+ const actionError = model.actionError ? `<p class="absolute-voice-delivery-runtime__error">${escapeHtml3(model.actionError)}</p>` : "";
909
+ return `<section class="absolute-voice-delivery-runtime absolute-voice-delivery-runtime--${escapeHtml3(model.status)}">
525
910
  <header class="absolute-voice-delivery-runtime__header">
526
- <span class="absolute-voice-delivery-runtime__eyebrow">${escapeHtml2(model.title)}</span>
527
- <strong class="absolute-voice-delivery-runtime__label">${escapeHtml2(model.label)}</strong>
911
+ <span class="absolute-voice-delivery-runtime__eyebrow">${escapeHtml3(model.title)}</span>
912
+ <strong class="absolute-voice-delivery-runtime__label">${escapeHtml3(model.label)}</strong>
528
913
  </header>
529
- <p class="absolute-voice-delivery-runtime__description">${escapeHtml2(model.description)}</p>
914
+ <p class="absolute-voice-delivery-runtime__description">${escapeHtml3(model.description)}</p>
530
915
  <ul class="absolute-voice-delivery-runtime__surfaces">${surfaces}</ul>
531
- ${model.error ? `<p class="absolute-voice-delivery-runtime__error">${escapeHtml2(model.error)}</p>` : ""}
916
+ ${actions}
917
+ ${actionError}
918
+ ${model.error ? `<p class="absolute-voice-delivery-runtime__error">${escapeHtml3(model.error)}</p>` : ""}
532
919
  </section>`;
533
920
  };
534
- var getVoiceDeliveryRuntimeCSS = () => `.absolute-voice-delivery-runtime{border:1px solid #c9d8cf;border-radius:20px;background:#f6fff9;color:#0d1b12;padding:18px;box-shadow:0 18px 40px rgba(19,55,35,.12);font-family:inherit}.absolute-voice-delivery-runtime--warn,.absolute-voice-delivery-runtime--error{border-color:#f2b56b;background:#fff9ed}.absolute-voice-delivery-runtime__header{align-items:start;display:flex;gap:12px;justify-content:space-between}.absolute-voice-delivery-runtime__eyebrow{color:#4e6b59;font-size:12px;font-weight:800;letter-spacing:.08em;text-transform:uppercase}.absolute-voice-delivery-runtime__label{font-size:28px;line-height:1}.absolute-voice-delivery-runtime__description{color:#33483b;margin:12px 0 0}.absolute-voice-delivery-runtime__surfaces{display:grid;gap:8px;list-style:none;margin:16px 0 0;padding:0}.absolute-voice-delivery-runtime__surface{background:#fff;border:1px solid #d9eadf;border-radius:14px;display:grid;gap:4px;padding:10px 12px}.absolute-voice-delivery-runtime__surface--warn{border-color:#f2b56b}.absolute-voice-delivery-runtime__surface--disabled{opacity:.72}.absolute-voice-delivery-runtime__surface span,.absolute-voice-delivery-runtime__surface small{color:#587063}.absolute-voice-delivery-runtime__error{color:#9f1239;font-weight:700}`;
921
+ 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}`;
535
922
  var mountVoiceDeliveryRuntime = (element, path = "/api/voice-delivery-runtime", options = {}) => {
536
923
  const store = createVoiceDeliveryRuntimeStore(path, options);
537
924
  const render = () => {
538
925
  element.innerHTML = renderVoiceDeliveryRuntimeHTML(store.getSnapshot(), options);
539
926
  };
540
927
  const unsubscribe = store.subscribe(render);
928
+ const handleClick = (event) => {
929
+ const target = event.target;
930
+ if (!(target instanceof Element)) {
931
+ return;
932
+ }
933
+ const action = target.closest("[data-absolute-voice-delivery-runtime-action]");
934
+ const actionName = action?.getAttribute("data-absolute-voice-delivery-runtime-action");
935
+ if (actionName === "tick") {
936
+ store.tick().catch(() => {});
937
+ }
938
+ if (actionName === "requeue-dead-letters") {
939
+ store.requeueDeadLetters().catch(() => {});
940
+ }
941
+ };
942
+ element.addEventListener?.("click", handleClick);
541
943
  render();
542
944
  store.refresh().catch(() => {});
543
945
  return {
544
946
  close: () => {
947
+ element.removeEventListener?.("click", handleClick);
545
948
  unsubscribe();
546
949
  store.close();
547
950
  },
@@ -570,68 +973,72 @@ var defineVoiceDeliveryRuntimeElement = (tagName = "absolute-voice-delivery-runt
570
973
  };
571
974
 
572
975
  // src/react/useVoiceDeliveryRuntime.tsx
573
- import { useEffect as useEffect2, useRef as useRef2, useSyncExternalStore as useSyncExternalStore2 } from "react";
976
+ import { useEffect as useEffect3, useRef as useRef3, useSyncExternalStore as useSyncExternalStore3 } from "react";
574
977
  var useVoiceDeliveryRuntime = (path = "/api/voice-delivery-runtime", options = {}) => {
575
- const storeRef = useRef2(null);
978
+ const storeRef = useRef3(null);
576
979
  if (!storeRef.current) {
577
980
  storeRef.current = createVoiceDeliveryRuntimeStore(path, options);
578
981
  }
579
982
  const store = storeRef.current;
580
- useEffect2(() => {
983
+ useEffect3(() => {
581
984
  store.refresh().catch(() => {});
582
985
  return () => store.close();
583
986
  }, [store]);
584
987
  return {
585
- ...useSyncExternalStore2(store.subscribe, store.getSnapshot, store.getServerSnapshot),
586
- refresh: store.refresh
988
+ ...useSyncExternalStore3(store.subscribe, store.getSnapshot, store.getServerSnapshot),
989
+ requeueDeadLetters: store.requeueDeadLetters,
990
+ refresh: store.refresh,
991
+ tick: store.tick
587
992
  };
588
993
  };
589
994
 
590
995
  // src/react/VoiceDeliveryRuntime.tsx
591
- import { jsxDEV as jsxDEV2 } from "react/jsx-dev-runtime";
996
+ import { jsxDEV as jsxDEV3 } from "react/jsx-dev-runtime";
592
997
  var VoiceDeliveryRuntime = ({
593
998
  className,
999
+ includeActions = true,
594
1000
  path = "/api/voice-delivery-runtime",
595
1001
  ...options
596
1002
  }) => {
597
1003
  const snapshot = useVoiceDeliveryRuntime(path, options);
598
1004
  const model = createVoiceDeliveryRuntimeViewModel(snapshot, options);
599
- return /* @__PURE__ */ jsxDEV2("section", {
1005
+ const hasDeadLetters = model.surfaces.some((surface) => surface.deadLettered > 0);
1006
+ return /* @__PURE__ */ jsxDEV3("section", {
600
1007
  className: [
601
1008
  "absolute-voice-delivery-runtime",
602
1009
  `absolute-voice-delivery-runtime--${model.status}`,
603
1010
  className
604
1011
  ].filter(Boolean).join(" "),
605
1012
  children: [
606
- /* @__PURE__ */ jsxDEV2("header", {
1013
+ /* @__PURE__ */ jsxDEV3("header", {
607
1014
  className: "absolute-voice-delivery-runtime__header",
608
1015
  children: [
609
- /* @__PURE__ */ jsxDEV2("span", {
1016
+ /* @__PURE__ */ jsxDEV3("span", {
610
1017
  className: "absolute-voice-delivery-runtime__eyebrow",
611
1018
  children: model.title
612
1019
  }, undefined, false, undefined, this),
613
- /* @__PURE__ */ jsxDEV2("strong", {
1020
+ /* @__PURE__ */ jsxDEV3("strong", {
614
1021
  className: "absolute-voice-delivery-runtime__label",
615
1022
  children: model.label
616
1023
  }, undefined, false, undefined, this)
617
1024
  ]
618
1025
  }, undefined, true, undefined, this),
619
- /* @__PURE__ */ jsxDEV2("p", {
1026
+ /* @__PURE__ */ jsxDEV3("p", {
620
1027
  className: "absolute-voice-delivery-runtime__description",
621
1028
  children: model.description
622
1029
  }, undefined, false, undefined, this),
623
- /* @__PURE__ */ jsxDEV2("ul", {
1030
+ /* @__PURE__ */ jsxDEV3("ul", {
624
1031
  className: "absolute-voice-delivery-runtime__surfaces",
625
- children: model.surfaces.map((surface) => /* @__PURE__ */ jsxDEV2("li", {
1032
+ children: model.surfaces.map((surface) => /* @__PURE__ */ jsxDEV3("li", {
626
1033
  className: `absolute-voice-delivery-runtime__surface absolute-voice-delivery-runtime__surface--${surface.status}`,
627
1034
  children: [
628
- /* @__PURE__ */ jsxDEV2("span", {
1035
+ /* @__PURE__ */ jsxDEV3("span", {
629
1036
  children: surface.label
630
1037
  }, undefined, false, undefined, this),
631
- /* @__PURE__ */ jsxDEV2("strong", {
1038
+ /* @__PURE__ */ jsxDEV3("strong", {
632
1039
  children: surface.detail
633
1040
  }, undefined, false, undefined, this),
634
- /* @__PURE__ */ jsxDEV2("small", {
1041
+ /* @__PURE__ */ jsxDEV3("small", {
635
1042
  children: [
636
1043
  surface.failed,
637
1044
  " failed / ",
@@ -642,7 +1049,32 @@ var VoiceDeliveryRuntime = ({
642
1049
  ]
643
1050
  }, surface.id, true, undefined, this))
644
1051
  }, undefined, false, undefined, this),
645
- model.error ? /* @__PURE__ */ jsxDEV2("p", {
1052
+ includeActions ? /* @__PURE__ */ jsxDEV3("div", {
1053
+ className: "absolute-voice-delivery-runtime__actions",
1054
+ children: [
1055
+ /* @__PURE__ */ jsxDEV3("button", {
1056
+ disabled: model.actionStatus === "running",
1057
+ onClick: () => {
1058
+ snapshot.tick().catch(() => {});
1059
+ },
1060
+ type: "button",
1061
+ children: model.actionStatus === "running" ? "Working..." : "Tick workers"
1062
+ }, undefined, false, undefined, this),
1063
+ /* @__PURE__ */ jsxDEV3("button", {
1064
+ disabled: model.actionStatus === "running" || !hasDeadLetters,
1065
+ onClick: () => {
1066
+ snapshot.requeueDeadLetters().catch(() => {});
1067
+ },
1068
+ type: "button",
1069
+ children: "Requeue dead letters"
1070
+ }, undefined, false, undefined, this)
1071
+ ]
1072
+ }, undefined, true, undefined, this) : null,
1073
+ model.actionError ? /* @__PURE__ */ jsxDEV3("p", {
1074
+ className: "absolute-voice-delivery-runtime__error",
1075
+ children: model.actionError
1076
+ }, undefined, false, undefined, this) : null,
1077
+ model.error ? /* @__PURE__ */ jsxDEV3("p", {
646
1078
  className: "absolute-voice-delivery-runtime__error",
647
1079
  children: model.error
648
1080
  }, undefined, false, undefined, this) : null
@@ -729,7 +1161,7 @@ var createVoiceProviderSimulationControlsStore = (options) => {
729
1161
  };
730
1162
 
731
1163
  // src/client/providerSimulationControlsWidget.ts
732
- var escapeHtml3 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
1164
+ var escapeHtml4 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
733
1165
  var formatKind = (kind) => (kind ?? "stt").toUpperCase();
734
1166
  var createVoiceProviderSimulationControlsViewModel = (snapshot, options) => {
735
1167
  const configuredProviders = options.providers.filter((provider) => provider.configured !== false);
@@ -749,18 +1181,18 @@ var createVoiceProviderSimulationControlsViewModel = (snapshot, options) => {
749
1181
  };
750
1182
  var renderVoiceProviderSimulationControlsHTML = (snapshot, options) => {
751
1183
  const model = createVoiceProviderSimulationControlsViewModel(snapshot, options);
752
- 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("");
753
- 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("");
1184
+ 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("");
1185
+ 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("");
754
1186
  return `<section class="absolute-voice-provider-simulation absolute-voice-provider-simulation--${snapshot.error ? "error" : snapshot.isRunning ? "running" : "ready"}">
755
1187
  <header class="absolute-voice-provider-simulation__header">
756
- <span class="absolute-voice-provider-simulation__eyebrow">${escapeHtml3(model.title)}</span>
757
- <strong class="absolute-voice-provider-simulation__label">${escapeHtml3(model.label)}</strong>
1188
+ <span class="absolute-voice-provider-simulation__eyebrow">${escapeHtml4(model.title)}</span>
1189
+ <strong class="absolute-voice-provider-simulation__label">${escapeHtml4(model.label)}</strong>
758
1190
  </header>
759
- <p class="absolute-voice-provider-simulation__description">${escapeHtml3(model.description)}</p>
760
- ${model.canSimulateFailure ? "" : `<p class="absolute-voice-provider-simulation__empty">${escapeHtml3(options.fallbackRequiredMessage ?? "Configure fallback providers before simulating failure.")}</p>`}
1191
+ <p class="absolute-voice-provider-simulation__description">${escapeHtml4(model.description)}</p>
1192
+ ${model.canSimulateFailure ? "" : `<p class="absolute-voice-provider-simulation__empty">${escapeHtml4(options.fallbackRequiredMessage ?? "Configure fallback providers before simulating failure.")}</p>`}
761
1193
  <div class="absolute-voice-provider-simulation__actions">${failureButtons}${recoveryButtons}</div>
762
- ${snapshot.error ? `<p class="absolute-voice-provider-simulation__error">${escapeHtml3(snapshot.error)}</p>` : ""}
763
- ${model.resultText ? `<pre class="absolute-voice-provider-simulation__result">${escapeHtml3(model.resultText)}</pre>` : ""}
1194
+ ${snapshot.error ? `<p class="absolute-voice-provider-simulation__error">${escapeHtml4(snapshot.error)}</p>` : ""}
1195
+ ${model.resultText ? `<pre class="absolute-voice-provider-simulation__result">${escapeHtml4(model.resultText)}</pre>` : ""}
764
1196
  </section>`;
765
1197
  };
766
1198
  var bindVoiceProviderSimulationControls = (element, store) => {
@@ -826,22 +1258,22 @@ var defineVoiceProviderSimulationControlsElement = (tagName = "absolute-voice-pr
826
1258
  };
827
1259
 
828
1260
  // src/react/useVoiceProviderSimulationControls.tsx
829
- import { useEffect as useEffect3, useRef as useRef3, useSyncExternalStore as useSyncExternalStore3 } from "react";
1261
+ import { useEffect as useEffect4, useRef as useRef4, useSyncExternalStore as useSyncExternalStore4 } from "react";
830
1262
  var useVoiceProviderSimulationControls = (options) => {
831
- const storeRef = useRef3(null);
1263
+ const storeRef = useRef4(null);
832
1264
  if (!storeRef.current) {
833
1265
  storeRef.current = createVoiceProviderSimulationControlsStore(options);
834
1266
  }
835
1267
  const store = storeRef.current;
836
- useEffect3(() => () => store.close(), [store]);
1268
+ useEffect4(() => () => store.close(), [store]);
837
1269
  return {
838
- ...useSyncExternalStore3(store.subscribe, store.getSnapshot, store.getServerSnapshot),
1270
+ ...useSyncExternalStore4(store.subscribe, store.getSnapshot, store.getServerSnapshot),
839
1271
  run: store.run
840
1272
  };
841
1273
  };
842
1274
 
843
1275
  // src/react/VoiceProviderSimulationControls.tsx
844
- import { jsxDEV as jsxDEV3 } from "react/jsx-dev-runtime";
1276
+ import { jsxDEV as jsxDEV4 } from "react/jsx-dev-runtime";
845
1277
  var VoiceProviderSimulationControls = ({
846
1278
  className,
847
1279
  ...options
@@ -851,38 +1283,38 @@ var VoiceProviderSimulationControls = ({
851
1283
  const run = (provider, mode) => {
852
1284
  snapshot.run(provider, mode).catch(() => {});
853
1285
  };
854
- return /* @__PURE__ */ jsxDEV3("section", {
1286
+ return /* @__PURE__ */ jsxDEV4("section", {
855
1287
  className: [
856
1288
  "absolute-voice-provider-simulation",
857
1289
  `absolute-voice-provider-simulation--${snapshot.error ? "error" : snapshot.isRunning ? "running" : "ready"}`,
858
1290
  className
859
1291
  ].filter(Boolean).join(" "),
860
1292
  children: [
861
- /* @__PURE__ */ jsxDEV3("header", {
1293
+ /* @__PURE__ */ jsxDEV4("header", {
862
1294
  className: "absolute-voice-provider-simulation__header",
863
1295
  children: [
864
- /* @__PURE__ */ jsxDEV3("span", {
1296
+ /* @__PURE__ */ jsxDEV4("span", {
865
1297
  className: "absolute-voice-provider-simulation__eyebrow",
866
1298
  children: model.title
867
1299
  }, undefined, false, undefined, this),
868
- /* @__PURE__ */ jsxDEV3("strong", {
1300
+ /* @__PURE__ */ jsxDEV4("strong", {
869
1301
  className: "absolute-voice-provider-simulation__label",
870
1302
  children: model.label
871
1303
  }, undefined, false, undefined, this)
872
1304
  ]
873
1305
  }, undefined, true, undefined, this),
874
- /* @__PURE__ */ jsxDEV3("p", {
1306
+ /* @__PURE__ */ jsxDEV4("p", {
875
1307
  className: "absolute-voice-provider-simulation__description",
876
1308
  children: model.description
877
1309
  }, undefined, false, undefined, this),
878
- model.canSimulateFailure ? null : /* @__PURE__ */ jsxDEV3("p", {
1310
+ model.canSimulateFailure ? null : /* @__PURE__ */ jsxDEV4("p", {
879
1311
  className: "absolute-voice-provider-simulation__empty",
880
1312
  children: options.fallbackRequiredMessage ?? "Configure fallback providers before simulating failure."
881
1313
  }, undefined, false, undefined, this),
882
- /* @__PURE__ */ jsxDEV3("div", {
1314
+ /* @__PURE__ */ jsxDEV4("div", {
883
1315
  className: "absolute-voice-provider-simulation__actions",
884
1316
  children: [
885
- model.failureProviders.map((provider) => /* @__PURE__ */ jsxDEV3("button", {
1317
+ model.failureProviders.map((provider) => /* @__PURE__ */ jsxDEV4("button", {
886
1318
  disabled: !model.canSimulateFailure || snapshot.isRunning,
887
1319
  onClick: () => run(provider.provider, "failure"),
888
1320
  type: "button",
@@ -895,7 +1327,7 @@ var VoiceProviderSimulationControls = ({
895
1327
  "failure"
896
1328
  ]
897
1329
  }, `fail-${provider.provider}`, true, undefined, this)),
898
- model.providers.map((provider) => /* @__PURE__ */ jsxDEV3("button", {
1330
+ model.providers.map((provider) => /* @__PURE__ */ jsxDEV4("button", {
899
1331
  disabled: snapshot.isRunning,
900
1332
  onClick: () => run(provider.provider, "recovery"),
901
1333
  type: "button",
@@ -907,11 +1339,11 @@ var VoiceProviderSimulationControls = ({
907
1339
  }, `recover-${provider.provider}`, true, undefined, this))
908
1340
  ]
909
1341
  }, undefined, true, undefined, this),
910
- snapshot.error ? /* @__PURE__ */ jsxDEV3("p", {
1342
+ snapshot.error ? /* @__PURE__ */ jsxDEV4("p", {
911
1343
  className: "absolute-voice-provider-simulation__error",
912
1344
  children: snapshot.error
913
1345
  }, undefined, false, undefined, this) : null,
914
- model.resultText ? /* @__PURE__ */ jsxDEV3("pre", {
1346
+ model.resultText ? /* @__PURE__ */ jsxDEV4("pre", {
915
1347
  className: "absolute-voice-provider-simulation__result",
916
1348
  children: model.resultText
917
1349
  }, undefined, false, undefined, this) : null
@@ -919,7 +1351,7 @@ var VoiceProviderSimulationControls = ({
919
1351
  }, undefined, true, undefined, this);
920
1352
  };
921
1353
  // src/react/useVoiceProviderCapabilities.tsx
922
- import { useEffect as useEffect4, useRef as useRef4, useSyncExternalStore as useSyncExternalStore4 } from "react";
1354
+ import { useEffect as useEffect5, useRef as useRef5, useSyncExternalStore as useSyncExternalStore5 } from "react";
923
1355
 
924
1356
  // src/client/providerCapabilities.ts
925
1357
  var fetchVoiceProviderCapabilities = async (path = "/api/provider-capabilities", options = {}) => {
@@ -1002,25 +1434,25 @@ var createVoiceProviderCapabilitiesStore = (path = "/api/provider-capabilities",
1002
1434
 
1003
1435
  // src/react/useVoiceProviderCapabilities.tsx
1004
1436
  var useVoiceProviderCapabilities = (path = "/api/provider-capabilities", options = {}) => {
1005
- const storeRef = useRef4(null);
1437
+ const storeRef = useRef5(null);
1006
1438
  if (!storeRef.current) {
1007
1439
  storeRef.current = createVoiceProviderCapabilitiesStore(path, options);
1008
1440
  }
1009
1441
  const store = storeRef.current;
1010
- useEffect4(() => {
1442
+ useEffect5(() => {
1011
1443
  store.refresh().catch(() => {});
1012
1444
  return () => store.close();
1013
1445
  }, [store]);
1014
1446
  return {
1015
- ...useSyncExternalStore4(store.subscribe, store.getSnapshot, store.getServerSnapshot),
1447
+ ...useSyncExternalStore5(store.subscribe, store.getSnapshot, store.getServerSnapshot),
1016
1448
  refresh: store.refresh
1017
1449
  };
1018
1450
  };
1019
1451
 
1020
1452
  // src/client/providerCapabilitiesWidget.ts
1021
- var DEFAULT_TITLE3 = "Provider Capabilities";
1022
- var DEFAULT_DESCRIPTION3 = "Configured, selected, and healthy voice providers for this deployment.";
1023
- var escapeHtml4 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
1453
+ var DEFAULT_TITLE4 = "Provider Capabilities";
1454
+ var DEFAULT_DESCRIPTION4 = "Configured, selected, and healthy voice providers for this deployment.";
1455
+ var escapeHtml5 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
1024
1456
  var formatProvider = (provider) => provider.split(/[-_\s]+/).filter(Boolean).map((part) => `${part[0]?.toUpperCase() ?? ""}${part.slice(1)}`).join(" ") || provider;
1025
1457
  var formatKind2 = (kind) => kind.toUpperCase();
1026
1458
  var formatStatus = (status) => status.split("-").map((part) => `${part[0]?.toUpperCase() ?? ""}${part.slice(1)}`).join(" ");
@@ -1064,36 +1496,36 @@ var createVoiceProviderCapabilitiesViewModel = (snapshot, options = {}) => {
1064
1496
  const selectedCount = snapshot.report?.selected ?? capabilities.filter((capability) => capability.selected).length;
1065
1497
  return {
1066
1498
  capabilities,
1067
- description: options.description ?? DEFAULT_DESCRIPTION3,
1499
+ description: options.description ?? DEFAULT_DESCRIPTION4,
1068
1500
  error: snapshot.error,
1069
1501
  isLoading: snapshot.isLoading,
1070
1502
  label: snapshot.error ? "Unavailable" : capabilities.length ? warningCount > 0 ? `${warningCount} needs attention` : `${selectedCount} selected` : snapshot.isLoading ? "Checking" : "No capabilities",
1071
1503
  status: snapshot.error ? "error" : capabilities.length ? warningCount > 0 ? "warning" : "ready" : snapshot.isLoading ? "loading" : "empty",
1072
- title: options.title ?? DEFAULT_TITLE3,
1504
+ title: options.title ?? DEFAULT_TITLE4,
1073
1505
  updatedAt: snapshot.updatedAt
1074
1506
  };
1075
1507
  };
1076
1508
  var renderVoiceProviderCapabilitiesHTML = (snapshot, options = {}) => {
1077
1509
  const model = createVoiceProviderCapabilitiesViewModel(snapshot, options);
1078
- const capabilities = model.capabilities.length ? `<div class="absolute-voice-provider-capabilities__providers">${model.capabilities.map((capability) => `<article class="absolute-voice-provider-capabilities__provider absolute-voice-provider-capabilities__provider--${escapeHtml4(capability.status)}">
1510
+ 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)}">
1079
1511
  <header>
1080
- <strong>${escapeHtml4(capability.label)}</strong>
1081
- <span>${escapeHtml4(formatStatus(capability.status))}</span>
1512
+ <strong>${escapeHtml5(capability.label)}</strong>
1513
+ <span>${escapeHtml5(formatStatus(capability.status))}</span>
1082
1514
  </header>
1083
- <p>${escapeHtml4(capability.detail)}</p>
1515
+ <p>${escapeHtml5(capability.detail)}</p>
1084
1516
  <dl>${capability.rows.map((row) => `<div>
1085
- <dt>${escapeHtml4(row.label)}</dt>
1086
- <dd>${escapeHtml4(row.value)}</dd>
1517
+ <dt>${escapeHtml5(row.label)}</dt>
1518
+ <dd>${escapeHtml5(row.value)}</dd>
1087
1519
  </div>`).join("")}</dl>
1088
1520
  </article>`).join("")}</div>` : '<p class="absolute-voice-provider-capabilities__empty">Configure provider capabilities to see deployment coverage.</p>';
1089
- return `<section class="absolute-voice-provider-capabilities absolute-voice-provider-capabilities--${escapeHtml4(model.status)}">
1521
+ return `<section class="absolute-voice-provider-capabilities absolute-voice-provider-capabilities--${escapeHtml5(model.status)}">
1090
1522
  <header class="absolute-voice-provider-capabilities__header">
1091
- <span class="absolute-voice-provider-capabilities__eyebrow">${escapeHtml4(model.title)}</span>
1092
- <strong class="absolute-voice-provider-capabilities__label">${escapeHtml4(model.label)}</strong>
1523
+ <span class="absolute-voice-provider-capabilities__eyebrow">${escapeHtml5(model.title)}</span>
1524
+ <strong class="absolute-voice-provider-capabilities__label">${escapeHtml5(model.label)}</strong>
1093
1525
  </header>
1094
- <p class="absolute-voice-provider-capabilities__description">${escapeHtml4(model.description)}</p>
1526
+ <p class="absolute-voice-provider-capabilities__description">${escapeHtml5(model.description)}</p>
1095
1527
  ${capabilities}
1096
- ${model.error ? `<p class="absolute-voice-provider-capabilities__error">${escapeHtml4(model.error)}</p>` : ""}
1528
+ ${model.error ? `<p class="absolute-voice-provider-capabilities__error">${escapeHtml5(model.error)}</p>` : ""}
1097
1529
  </section>`;
1098
1530
  };
1099
1531
  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}`;
@@ -1135,7 +1567,7 @@ var defineVoiceProviderCapabilitiesElement = (tagName = "absolute-voice-provider
1135
1567
  };
1136
1568
 
1137
1569
  // src/react/VoiceProviderCapabilities.tsx
1138
- import { jsxDEV as jsxDEV4 } from "react/jsx-dev-runtime";
1570
+ import { jsxDEV as jsxDEV5 } from "react/jsx-dev-runtime";
1139
1571
  var VoiceProviderCapabilities = ({
1140
1572
  className,
1141
1573
  path = "/api/provider-capabilities",
@@ -1143,58 +1575,58 @@ var VoiceProviderCapabilities = ({
1143
1575
  }) => {
1144
1576
  const snapshot = useVoiceProviderCapabilities(path, options);
1145
1577
  const model = createVoiceProviderCapabilitiesViewModel(snapshot, options);
1146
- return /* @__PURE__ */ jsxDEV4("section", {
1578
+ return /* @__PURE__ */ jsxDEV5("section", {
1147
1579
  className: [
1148
1580
  "absolute-voice-provider-capabilities",
1149
1581
  `absolute-voice-provider-capabilities--${model.status}`,
1150
1582
  className
1151
1583
  ].filter(Boolean).join(" "),
1152
1584
  children: [
1153
- /* @__PURE__ */ jsxDEV4("header", {
1585
+ /* @__PURE__ */ jsxDEV5("header", {
1154
1586
  className: "absolute-voice-provider-capabilities__header",
1155
1587
  children: [
1156
- /* @__PURE__ */ jsxDEV4("span", {
1588
+ /* @__PURE__ */ jsxDEV5("span", {
1157
1589
  className: "absolute-voice-provider-capabilities__eyebrow",
1158
1590
  children: model.title
1159
1591
  }, undefined, false, undefined, this),
1160
- /* @__PURE__ */ jsxDEV4("strong", {
1592
+ /* @__PURE__ */ jsxDEV5("strong", {
1161
1593
  className: "absolute-voice-provider-capabilities__label",
1162
1594
  children: model.label
1163
1595
  }, undefined, false, undefined, this)
1164
1596
  ]
1165
1597
  }, undefined, true, undefined, this),
1166
- /* @__PURE__ */ jsxDEV4("p", {
1598
+ /* @__PURE__ */ jsxDEV5("p", {
1167
1599
  className: "absolute-voice-provider-capabilities__description",
1168
1600
  children: model.description
1169
1601
  }, undefined, false, undefined, this),
1170
- model.capabilities.length ? /* @__PURE__ */ jsxDEV4("div", {
1602
+ model.capabilities.length ? /* @__PURE__ */ jsxDEV5("div", {
1171
1603
  className: "absolute-voice-provider-capabilities__providers",
1172
- children: model.capabilities.map((capability) => /* @__PURE__ */ jsxDEV4("article", {
1604
+ children: model.capabilities.map((capability) => /* @__PURE__ */ jsxDEV5("article", {
1173
1605
  className: [
1174
1606
  "absolute-voice-provider-capabilities__provider",
1175
1607
  `absolute-voice-provider-capabilities__provider--${capability.status}`
1176
1608
  ].join(" "),
1177
1609
  children: [
1178
- /* @__PURE__ */ jsxDEV4("header", {
1610
+ /* @__PURE__ */ jsxDEV5("header", {
1179
1611
  children: [
1180
- /* @__PURE__ */ jsxDEV4("strong", {
1612
+ /* @__PURE__ */ jsxDEV5("strong", {
1181
1613
  children: capability.label
1182
1614
  }, undefined, false, undefined, this),
1183
- /* @__PURE__ */ jsxDEV4("span", {
1615
+ /* @__PURE__ */ jsxDEV5("span", {
1184
1616
  children: capability.status
1185
1617
  }, undefined, false, undefined, this)
1186
1618
  ]
1187
1619
  }, undefined, true, undefined, this),
1188
- /* @__PURE__ */ jsxDEV4("p", {
1620
+ /* @__PURE__ */ jsxDEV5("p", {
1189
1621
  children: capability.detail
1190
1622
  }, undefined, false, undefined, this),
1191
- /* @__PURE__ */ jsxDEV4("dl", {
1192
- children: capability.rows.map((row) => /* @__PURE__ */ jsxDEV4("div", {
1623
+ /* @__PURE__ */ jsxDEV5("dl", {
1624
+ children: capability.rows.map((row) => /* @__PURE__ */ jsxDEV5("div", {
1193
1625
  children: [
1194
- /* @__PURE__ */ jsxDEV4("dt", {
1626
+ /* @__PURE__ */ jsxDEV5("dt", {
1195
1627
  children: row.label
1196
1628
  }, undefined, false, undefined, this),
1197
- /* @__PURE__ */ jsxDEV4("dd", {
1629
+ /* @__PURE__ */ jsxDEV5("dd", {
1198
1630
  children: row.value
1199
1631
  }, undefined, false, undefined, this)
1200
1632
  ]
@@ -1202,11 +1634,11 @@ var VoiceProviderCapabilities = ({
1202
1634
  }, undefined, false, undefined, this)
1203
1635
  ]
1204
1636
  }, `${capability.kind}:${capability.provider}`, true, undefined, this))
1205
- }, undefined, false, undefined, this) : /* @__PURE__ */ jsxDEV4("p", {
1637
+ }, undefined, false, undefined, this) : /* @__PURE__ */ jsxDEV5("p", {
1206
1638
  className: "absolute-voice-provider-capabilities__empty",
1207
1639
  children: "Configure provider capabilities to see deployment coverage."
1208
1640
  }, undefined, false, undefined, this),
1209
- model.error ? /* @__PURE__ */ jsxDEV4("p", {
1641
+ model.error ? /* @__PURE__ */ jsxDEV5("p", {
1210
1642
  className: "absolute-voice-provider-capabilities__error",
1211
1643
  children: model.error
1212
1644
  }, undefined, false, undefined, this) : null
@@ -1214,7 +1646,7 @@ var VoiceProviderCapabilities = ({
1214
1646
  }, undefined, true, undefined, this);
1215
1647
  };
1216
1648
  // src/react/useVoiceProviderStatus.tsx
1217
- import { useEffect as useEffect5, useRef as useRef5, useSyncExternalStore as useSyncExternalStore5 } from "react";
1649
+ import { useEffect as useEffect6, useRef as useRef6, useSyncExternalStore as useSyncExternalStore6 } from "react";
1218
1650
 
1219
1651
  // src/client/providerStatus.ts
1220
1652
  var fetchVoiceProviderStatus = async (path = "/api/provider-status", options = {}) => {
@@ -1298,25 +1730,25 @@ var createVoiceProviderStatusStore = (path = "/api/provider-status", options = {
1298
1730
 
1299
1731
  // src/react/useVoiceProviderStatus.tsx
1300
1732
  var useVoiceProviderStatus = (path = "/api/provider-status", options = {}) => {
1301
- const storeRef = useRef5(null);
1733
+ const storeRef = useRef6(null);
1302
1734
  if (!storeRef.current) {
1303
1735
  storeRef.current = createVoiceProviderStatusStore(path, options);
1304
1736
  }
1305
1737
  const store = storeRef.current;
1306
- useEffect5(() => {
1738
+ useEffect6(() => {
1307
1739
  store.refresh().catch(() => {});
1308
1740
  return () => store.close();
1309
1741
  }, [store]);
1310
1742
  return {
1311
- ...useSyncExternalStore5(store.subscribe, store.getSnapshot, store.getServerSnapshot),
1743
+ ...useSyncExternalStore6(store.subscribe, store.getSnapshot, store.getServerSnapshot),
1312
1744
  refresh: store.refresh
1313
1745
  };
1314
1746
  };
1315
1747
 
1316
1748
  // src/client/providerStatusWidget.ts
1317
- var DEFAULT_TITLE4 = "Voice Providers";
1318
- var DEFAULT_DESCRIPTION4 = "Live provider health, fallback counts, latency, and suppression state from your self-hosted trace store.";
1319
- var escapeHtml5 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
1749
+ var DEFAULT_TITLE5 = "Voice Providers";
1750
+ var DEFAULT_DESCRIPTION5 = "Live provider health, fallback counts, latency, and suppression state from your self-hosted trace store.";
1751
+ var escapeHtml6 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
1320
1752
  var formatProvider2 = (provider) => provider.split(/[-_\s]+/).filter(Boolean).map((part) => `${part[0]?.toUpperCase() ?? ""}${part.slice(1)}`).join(" ") || provider;
1321
1753
  var formatStatus2 = (status) => status.split("-").map((part) => `${part[0]?.toUpperCase() ?? ""}${part.slice(1)}`).join(" ");
1322
1754
  var formatLatency = (value) => typeof value === "number" ? `${value}ms` : "No samples";
@@ -1360,37 +1792,37 @@ var createVoiceProviderStatusViewModel = (snapshot, options = {}) => {
1360
1792
  const warningCount = providers.filter((provider) => isWarningStatus2(provider.status)).length;
1361
1793
  const healthyCount = providers.filter((provider) => provider.status === "healthy").length;
1362
1794
  return {
1363
- description: options.description ?? DEFAULT_DESCRIPTION4,
1795
+ description: options.description ?? DEFAULT_DESCRIPTION5,
1364
1796
  error: snapshot.error,
1365
1797
  isLoading: snapshot.isLoading,
1366
1798
  label: snapshot.error ? "Unavailable" : providers.length ? warningCount > 0 ? `${warningCount} needs attention` : `${healthyCount} healthy` : snapshot.isLoading ? "Checking" : "No provider traffic",
1367
1799
  providers,
1368
1800
  status: snapshot.error ? "error" : providers.length ? warningCount > 0 ? "warning" : "ready" : snapshot.isLoading ? "loading" : "empty",
1369
- title: options.title ?? DEFAULT_TITLE4,
1801
+ title: options.title ?? DEFAULT_TITLE5,
1370
1802
  updatedAt: snapshot.updatedAt
1371
1803
  };
1372
1804
  };
1373
1805
  var renderVoiceProviderStatusHTML = (snapshot, options = {}) => {
1374
1806
  const model = createVoiceProviderStatusViewModel(snapshot, options);
1375
- 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)}">
1807
+ 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)}">
1376
1808
  <header>
1377
- <strong>${escapeHtml5(provider.label)}</strong>
1378
- <span>${escapeHtml5(formatStatus2(provider.status))}</span>
1809
+ <strong>${escapeHtml6(provider.label)}</strong>
1810
+ <span>${escapeHtml6(formatStatus2(provider.status))}</span>
1379
1811
  </header>
1380
- <p>${escapeHtml5(provider.detail)}</p>
1812
+ <p>${escapeHtml6(provider.detail)}</p>
1381
1813
  <dl>${provider.rows.map((row) => `<div>
1382
- <dt>${escapeHtml5(row.label)}</dt>
1383
- <dd>${escapeHtml5(row.value)}</dd>
1814
+ <dt>${escapeHtml6(row.label)}</dt>
1815
+ <dd>${escapeHtml6(row.value)}</dd>
1384
1816
  </div>`).join("")}</dl>
1385
1817
  </article>`).join("")}</div>` : '<p class="absolute-voice-provider-status__empty">Run voice traffic to see provider health.</p>';
1386
- return `<section class="absolute-voice-provider-status absolute-voice-provider-status--${escapeHtml5(model.status)}">
1818
+ return `<section class="absolute-voice-provider-status absolute-voice-provider-status--${escapeHtml6(model.status)}">
1387
1819
  <header class="absolute-voice-provider-status__header">
1388
- <span class="absolute-voice-provider-status__eyebrow">${escapeHtml5(model.title)}</span>
1389
- <strong class="absolute-voice-provider-status__label">${escapeHtml5(model.label)}</strong>
1820
+ <span class="absolute-voice-provider-status__eyebrow">${escapeHtml6(model.title)}</span>
1821
+ <strong class="absolute-voice-provider-status__label">${escapeHtml6(model.label)}</strong>
1390
1822
  </header>
1391
- <p class="absolute-voice-provider-status__description">${escapeHtml5(model.description)}</p>
1823
+ <p class="absolute-voice-provider-status__description">${escapeHtml6(model.description)}</p>
1392
1824
  ${providers}
1393
- ${model.error ? `<p class="absolute-voice-provider-status__error">${escapeHtml5(model.error)}</p>` : ""}
1825
+ ${model.error ? `<p class="absolute-voice-provider-status__error">${escapeHtml6(model.error)}</p>` : ""}
1394
1826
  </section>`;
1395
1827
  };
1396
1828
  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}`;
@@ -1432,7 +1864,7 @@ var defineVoiceProviderStatusElement = (tagName = "absolute-voice-provider-statu
1432
1864
  };
1433
1865
 
1434
1866
  // src/react/VoiceProviderStatus.tsx
1435
- import { jsxDEV as jsxDEV5 } from "react/jsx-dev-runtime";
1867
+ import { jsxDEV as jsxDEV6 } from "react/jsx-dev-runtime";
1436
1868
  var VoiceProviderStatus = ({
1437
1869
  className,
1438
1870
  path = "/api/provider-status",
@@ -1440,58 +1872,58 @@ var VoiceProviderStatus = ({
1440
1872
  }) => {
1441
1873
  const snapshot = useVoiceProviderStatus(path, options);
1442
1874
  const model = createVoiceProviderStatusViewModel(snapshot, options);
1443
- return /* @__PURE__ */ jsxDEV5("section", {
1875
+ return /* @__PURE__ */ jsxDEV6("section", {
1444
1876
  className: [
1445
1877
  "absolute-voice-provider-status",
1446
1878
  `absolute-voice-provider-status--${model.status}`,
1447
1879
  className
1448
1880
  ].filter(Boolean).join(" "),
1449
1881
  children: [
1450
- /* @__PURE__ */ jsxDEV5("header", {
1882
+ /* @__PURE__ */ jsxDEV6("header", {
1451
1883
  className: "absolute-voice-provider-status__header",
1452
1884
  children: [
1453
- /* @__PURE__ */ jsxDEV5("span", {
1885
+ /* @__PURE__ */ jsxDEV6("span", {
1454
1886
  className: "absolute-voice-provider-status__eyebrow",
1455
1887
  children: model.title
1456
1888
  }, undefined, false, undefined, this),
1457
- /* @__PURE__ */ jsxDEV5("strong", {
1889
+ /* @__PURE__ */ jsxDEV6("strong", {
1458
1890
  className: "absolute-voice-provider-status__label",
1459
1891
  children: model.label
1460
1892
  }, undefined, false, undefined, this)
1461
1893
  ]
1462
1894
  }, undefined, true, undefined, this),
1463
- /* @__PURE__ */ jsxDEV5("p", {
1895
+ /* @__PURE__ */ jsxDEV6("p", {
1464
1896
  className: "absolute-voice-provider-status__description",
1465
1897
  children: model.description
1466
1898
  }, undefined, false, undefined, this),
1467
- model.providers.length ? /* @__PURE__ */ jsxDEV5("div", {
1899
+ model.providers.length ? /* @__PURE__ */ jsxDEV6("div", {
1468
1900
  className: "absolute-voice-provider-status__providers",
1469
- children: model.providers.map((provider) => /* @__PURE__ */ jsxDEV5("article", {
1901
+ children: model.providers.map((provider) => /* @__PURE__ */ jsxDEV6("article", {
1470
1902
  className: [
1471
1903
  "absolute-voice-provider-status__provider",
1472
1904
  `absolute-voice-provider-status__provider--${provider.status}`
1473
1905
  ].join(" "),
1474
1906
  children: [
1475
- /* @__PURE__ */ jsxDEV5("header", {
1907
+ /* @__PURE__ */ jsxDEV6("header", {
1476
1908
  children: [
1477
- /* @__PURE__ */ jsxDEV5("strong", {
1909
+ /* @__PURE__ */ jsxDEV6("strong", {
1478
1910
  children: provider.label
1479
1911
  }, undefined, false, undefined, this),
1480
- /* @__PURE__ */ jsxDEV5("span", {
1912
+ /* @__PURE__ */ jsxDEV6("span", {
1481
1913
  children: provider.status
1482
1914
  }, undefined, false, undefined, this)
1483
1915
  ]
1484
1916
  }, undefined, true, undefined, this),
1485
- /* @__PURE__ */ jsxDEV5("p", {
1917
+ /* @__PURE__ */ jsxDEV6("p", {
1486
1918
  children: provider.detail
1487
1919
  }, undefined, false, undefined, this),
1488
- /* @__PURE__ */ jsxDEV5("dl", {
1489
- children: provider.rows.map((row) => /* @__PURE__ */ jsxDEV5("div", {
1920
+ /* @__PURE__ */ jsxDEV6("dl", {
1921
+ children: provider.rows.map((row) => /* @__PURE__ */ jsxDEV6("div", {
1490
1922
  children: [
1491
- /* @__PURE__ */ jsxDEV5("dt", {
1923
+ /* @__PURE__ */ jsxDEV6("dt", {
1492
1924
  children: row.label
1493
1925
  }, undefined, false, undefined, this),
1494
- /* @__PURE__ */ jsxDEV5("dd", {
1926
+ /* @__PURE__ */ jsxDEV6("dd", {
1495
1927
  children: row.value
1496
1928
  }, undefined, false, undefined, this)
1497
1929
  ]
@@ -1499,11 +1931,11 @@ var VoiceProviderStatus = ({
1499
1931
  }, undefined, false, undefined, this)
1500
1932
  ]
1501
1933
  }, provider.provider, true, undefined, this))
1502
- }, undefined, false, undefined, this) : /* @__PURE__ */ jsxDEV5("p", {
1934
+ }, undefined, false, undefined, this) : /* @__PURE__ */ jsxDEV6("p", {
1503
1935
  className: "absolute-voice-provider-status__empty",
1504
1936
  children: "Run voice traffic to see provider health."
1505
1937
  }, undefined, false, undefined, this),
1506
- model.error ? /* @__PURE__ */ jsxDEV5("p", {
1938
+ model.error ? /* @__PURE__ */ jsxDEV6("p", {
1507
1939
  className: "absolute-voice-provider-status__error",
1508
1940
  children: model.error
1509
1941
  }, undefined, false, undefined, this) : null
@@ -1511,7 +1943,7 @@ var VoiceProviderStatus = ({
1511
1943
  }, undefined, true, undefined, this);
1512
1944
  };
1513
1945
  // src/react/useVoiceRoutingStatus.tsx
1514
- import { useEffect as useEffect6, useRef as useRef6, useSyncExternalStore as useSyncExternalStore6 } from "react";
1946
+ import { useEffect as useEffect7, useRef as useRef7, useSyncExternalStore as useSyncExternalStore7 } from "react";
1515
1947
 
1516
1948
  // src/client/routingStatus.ts
1517
1949
  var fetchVoiceRoutingStatus = async (path = "/api/routing/latest", options = {}) => {
@@ -1595,25 +2027,25 @@ var createVoiceRoutingStatusStore = (path = "/api/routing/latest", options = {})
1595
2027
 
1596
2028
  // src/react/useVoiceRoutingStatus.tsx
1597
2029
  var useVoiceRoutingStatus = (path = "/api/routing/latest", options = {}) => {
1598
- const storeRef = useRef6(null);
2030
+ const storeRef = useRef7(null);
1599
2031
  if (!storeRef.current) {
1600
2032
  storeRef.current = createVoiceRoutingStatusStore(path, options);
1601
2033
  }
1602
2034
  const store = storeRef.current;
1603
- useEffect6(() => {
2035
+ useEffect7(() => {
1604
2036
  store.refresh().catch(() => {});
1605
2037
  return () => store.close();
1606
2038
  }, [store]);
1607
2039
  return {
1608
- ...useSyncExternalStore6(store.subscribe, store.getSnapshot, store.getServerSnapshot),
2040
+ ...useSyncExternalStore7(store.subscribe, store.getSnapshot, store.getServerSnapshot),
1609
2041
  refresh: store.refresh
1610
2042
  };
1611
2043
  };
1612
2044
 
1613
2045
  // src/client/routingStatusWidget.ts
1614
- var DEFAULT_TITLE5 = "Voice Routing";
1615
- var DEFAULT_DESCRIPTION5 = "Latest provider routing decision from the self-hosted trace store.";
1616
- var escapeHtml6 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
2046
+ var DEFAULT_TITLE6 = "Voice Routing";
2047
+ var DEFAULT_DESCRIPTION6 = "Latest provider routing decision from the self-hosted trace store.";
2048
+ var escapeHtml7 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
1617
2049
  var formatValue = (value, fallback = "None") => typeof value === "string" && value.trim() ? value : typeof value === "number" && Number.isFinite(value) ? String(value) : fallback;
1618
2050
  var createVoiceRoutingStatusViewModel = (snapshot, options = {}) => {
1619
2051
  const decision = snapshot.decision;
@@ -1637,30 +2069,30 @@ var createVoiceRoutingStatusViewModel = (snapshot, options = {}) => {
1637
2069
  ] : [];
1638
2070
  return {
1639
2071
  decision,
1640
- description: options.description ?? DEFAULT_DESCRIPTION5,
2072
+ description: options.description ?? DEFAULT_DESCRIPTION6,
1641
2073
  error: snapshot.error,
1642
2074
  isLoading: snapshot.isLoading,
1643
2075
  label: snapshot.error ? "Unavailable" : decision ? `${formatValue(decision.kind).toUpperCase()} ${formatValue(decision.status, "unknown")}` : snapshot.isLoading ? "Checking" : "No routing yet",
1644
2076
  rows,
1645
2077
  status: snapshot.error ? "error" : decision ? "ready" : snapshot.isLoading ? "loading" : "empty",
1646
- title: options.title ?? DEFAULT_TITLE5,
2078
+ title: options.title ?? DEFAULT_TITLE6,
1647
2079
  updatedAt: snapshot.updatedAt
1648
2080
  };
1649
2081
  };
1650
2082
  var renderVoiceRoutingStatusHTML = (snapshot, options = {}) => {
1651
2083
  const model = createVoiceRoutingStatusViewModel(snapshot, options);
1652
2084
  const rows = model.rows.length ? `<div class="absolute-voice-routing-status__grid">${model.rows.map((row) => `<div>
1653
- <span>${escapeHtml6(row.label)}</span>
1654
- <strong>${escapeHtml6(row.value)}</strong>
2085
+ <span>${escapeHtml7(row.label)}</span>
2086
+ <strong>${escapeHtml7(row.value)}</strong>
1655
2087
  </div>`).join("")}</div>` : '<p class="absolute-voice-routing-status__empty">Start a voice session to see the selected provider.</p>';
1656
- return `<section class="absolute-voice-routing-status absolute-voice-routing-status--${escapeHtml6(model.status)}">
2088
+ return `<section class="absolute-voice-routing-status absolute-voice-routing-status--${escapeHtml7(model.status)}">
1657
2089
  <header class="absolute-voice-routing-status__header">
1658
- <span class="absolute-voice-routing-status__eyebrow">${escapeHtml6(model.title)}</span>
1659
- <strong class="absolute-voice-routing-status__label">${escapeHtml6(model.label)}</strong>
2090
+ <span class="absolute-voice-routing-status__eyebrow">${escapeHtml7(model.title)}</span>
2091
+ <strong class="absolute-voice-routing-status__label">${escapeHtml7(model.label)}</strong>
1660
2092
  </header>
1661
- <p class="absolute-voice-routing-status__description">${escapeHtml6(model.description)}</p>
2093
+ <p class="absolute-voice-routing-status__description">${escapeHtml7(model.description)}</p>
1662
2094
  ${rows}
1663
- ${model.error ? `<p class="absolute-voice-routing-status__error">${escapeHtml6(model.error)}</p>` : ""}
2095
+ ${model.error ? `<p class="absolute-voice-routing-status__error">${escapeHtml7(model.error)}</p>` : ""}
1664
2096
  </section>`;
1665
2097
  };
1666
2098
  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}`;
@@ -1702,7 +2134,7 @@ var defineVoiceRoutingStatusElement = (tagName = "absolute-voice-routing-status"
1702
2134
  };
1703
2135
 
1704
2136
  // src/react/VoiceRoutingStatus.tsx
1705
- import { jsxDEV as jsxDEV6 } from "react/jsx-dev-runtime";
2137
+ import { jsxDEV as jsxDEV7 } from "react/jsx-dev-runtime";
1706
2138
  var VoiceRoutingStatus = ({
1707
2139
  className,
1708
2140
  path = "/api/routing/latest",
@@ -1710,47 +2142,47 @@ var VoiceRoutingStatus = ({
1710
2142
  }) => {
1711
2143
  const snapshot = useVoiceRoutingStatus(path, options);
1712
2144
  const model = createVoiceRoutingStatusViewModel(snapshot, options);
1713
- return /* @__PURE__ */ jsxDEV6("section", {
2145
+ return /* @__PURE__ */ jsxDEV7("section", {
1714
2146
  className: [
1715
2147
  "absolute-voice-routing-status",
1716
2148
  `absolute-voice-routing-status--${model.status}`,
1717
2149
  className
1718
2150
  ].filter(Boolean).join(" "),
1719
2151
  children: [
1720
- /* @__PURE__ */ jsxDEV6("header", {
2152
+ /* @__PURE__ */ jsxDEV7("header", {
1721
2153
  className: "absolute-voice-routing-status__header",
1722
2154
  children: [
1723
- /* @__PURE__ */ jsxDEV6("span", {
2155
+ /* @__PURE__ */ jsxDEV7("span", {
1724
2156
  className: "absolute-voice-routing-status__eyebrow",
1725
2157
  children: model.title
1726
2158
  }, undefined, false, undefined, this),
1727
- /* @__PURE__ */ jsxDEV6("strong", {
2159
+ /* @__PURE__ */ jsxDEV7("strong", {
1728
2160
  className: "absolute-voice-routing-status__label",
1729
2161
  children: model.label
1730
2162
  }, undefined, false, undefined, this)
1731
2163
  ]
1732
2164
  }, undefined, true, undefined, this),
1733
- /* @__PURE__ */ jsxDEV6("p", {
2165
+ /* @__PURE__ */ jsxDEV7("p", {
1734
2166
  className: "absolute-voice-routing-status__description",
1735
2167
  children: model.description
1736
2168
  }, undefined, false, undefined, this),
1737
- model.rows.length ? /* @__PURE__ */ jsxDEV6("div", {
2169
+ model.rows.length ? /* @__PURE__ */ jsxDEV7("div", {
1738
2170
  className: "absolute-voice-routing-status__grid",
1739
- children: model.rows.map((row) => /* @__PURE__ */ jsxDEV6("div", {
2171
+ children: model.rows.map((row) => /* @__PURE__ */ jsxDEV7("div", {
1740
2172
  children: [
1741
- /* @__PURE__ */ jsxDEV6("span", {
2173
+ /* @__PURE__ */ jsxDEV7("span", {
1742
2174
  children: row.label
1743
2175
  }, undefined, false, undefined, this),
1744
- /* @__PURE__ */ jsxDEV6("strong", {
2176
+ /* @__PURE__ */ jsxDEV7("strong", {
1745
2177
  children: row.value
1746
2178
  }, undefined, false, undefined, this)
1747
2179
  ]
1748
2180
  }, row.label, true, undefined, this))
1749
- }, undefined, false, undefined, this) : /* @__PURE__ */ jsxDEV6("p", {
2181
+ }, undefined, false, undefined, this) : /* @__PURE__ */ jsxDEV7("p", {
1750
2182
  className: "absolute-voice-routing-status__empty",
1751
2183
  children: "Start a voice session to see the selected provider."
1752
2184
  }, undefined, false, undefined, this),
1753
- model.error ? /* @__PURE__ */ jsxDEV6("p", {
2185
+ model.error ? /* @__PURE__ */ jsxDEV7("p", {
1754
2186
  className: "absolute-voice-routing-status__error",
1755
2187
  children: model.error
1756
2188
  }, undefined, false, undefined, this) : null
@@ -1838,9 +2270,9 @@ var createVoiceTraceTimelineStore = (path = "/api/voice-traces", options = {}) =
1838
2270
  };
1839
2271
 
1840
2272
  // src/client/traceTimelineWidget.ts
1841
- var DEFAULT_TITLE6 = "Voice Traces";
1842
- var DEFAULT_DESCRIPTION6 = "Latest call timelines with provider latency, fallbacks, handoffs, and errors from your self-hosted trace store.";
1843
- var escapeHtml7 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
2273
+ var DEFAULT_TITLE7 = "Voice Traces";
2274
+ var DEFAULT_DESCRIPTION7 = "Latest call timelines with provider latency, fallbacks, handoffs, and errors from your self-hosted trace store.";
2275
+ var escapeHtml8 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
1844
2276
  var formatMs = (value) => typeof value === "number" ? `${value}ms` : "n/a";
1845
2277
  var formatProviders = (session) => session.providers.length ? session.providers.map((provider) => provider.provider).join(", ") : "No providers";
1846
2278
  var createVoiceTraceTimelineViewModel = (snapshot, options = {}) => {
@@ -1854,34 +2286,34 @@ var createVoiceTraceTimelineViewModel = (snapshot, options = {}) => {
1854
2286
  const failed = sessions.filter((session) => session.status === "failed").length;
1855
2287
  const warnings = sessions.filter((session) => session.status === "warning").length;
1856
2288
  return {
1857
- description: options.description ?? DEFAULT_DESCRIPTION6,
2289
+ description: options.description ?? DEFAULT_DESCRIPTION7,
1858
2290
  error: snapshot.error,
1859
2291
  isLoading: snapshot.isLoading,
1860
2292
  label: snapshot.error ? "Unavailable" : failed > 0 ? `${failed} failed` : warnings > 0 ? `${warnings} warning` : sessions.length ? `${sessions.length} recent` : snapshot.isLoading ? "Checking" : "No traces yet",
1861
2293
  sessions,
1862
2294
  status: snapshot.error ? "error" : failed > 0 ? "failed" : warnings > 0 ? "warning" : sessions.length ? "ready" : snapshot.isLoading ? "loading" : "empty",
1863
- title: options.title ?? DEFAULT_TITLE6,
2295
+ title: options.title ?? DEFAULT_TITLE7,
1864
2296
  updatedAt: snapshot.updatedAt
1865
2297
  };
1866
2298
  };
1867
2299
  var renderVoiceTraceTimelineWidgetHTML = (snapshot, options = {}) => {
1868
2300
  const model = createVoiceTraceTimelineViewModel(snapshot, options);
1869
- const sessions = model.sessions.length ? `<div class="absolute-voice-trace-timeline__sessions">${model.sessions.map((session) => `<article class="absolute-voice-trace-timeline__session absolute-voice-trace-timeline__session--${escapeHtml7(session.status)}">
2301
+ const sessions = model.sessions.length ? `<div class="absolute-voice-trace-timeline__sessions">${model.sessions.map((session) => `<article class="absolute-voice-trace-timeline__session absolute-voice-trace-timeline__session--${escapeHtml8(session.status)}">
1870
2302
  <header>
1871
- <strong>${escapeHtml7(session.sessionId)}</strong>
1872
- <span>${escapeHtml7(session.status)}</span>
2303
+ <strong>${escapeHtml8(session.sessionId)}</strong>
2304
+ <span>${escapeHtml8(session.status)}</span>
1873
2305
  </header>
1874
- <p>${escapeHtml7(session.label)} \xB7 ${escapeHtml7(session.durationLabel)} \xB7 ${escapeHtml7(session.providerLabel)}</p>
1875
- <a href="${escapeHtml7(session.detailHref)}">Open timeline</a>
2306
+ <p>${escapeHtml8(session.label)} \xB7 ${escapeHtml8(session.durationLabel)} \xB7 ${escapeHtml8(session.providerLabel)}</p>
2307
+ <a href="${escapeHtml8(session.detailHref)}">Open timeline</a>
1876
2308
  </article>`).join("")}</div>` : '<p class="absolute-voice-trace-timeline__empty">Run a voice session to see call timelines.</p>';
1877
- return `<section class="absolute-voice-trace-timeline absolute-voice-trace-timeline--${escapeHtml7(model.status)}">
2309
+ return `<section class="absolute-voice-trace-timeline absolute-voice-trace-timeline--${escapeHtml8(model.status)}">
1878
2310
  <header class="absolute-voice-trace-timeline__header">
1879
- <span class="absolute-voice-trace-timeline__eyebrow">${escapeHtml7(model.title)}</span>
1880
- <strong class="absolute-voice-trace-timeline__label">${escapeHtml7(model.label)}</strong>
2311
+ <span class="absolute-voice-trace-timeline__eyebrow">${escapeHtml8(model.title)}</span>
2312
+ <strong class="absolute-voice-trace-timeline__label">${escapeHtml8(model.label)}</strong>
1881
2313
  </header>
1882
- <p class="absolute-voice-trace-timeline__description">${escapeHtml7(model.description)}</p>
2314
+ <p class="absolute-voice-trace-timeline__description">${escapeHtml8(model.description)}</p>
1883
2315
  ${sessions}
1884
- ${model.error ? `<p class="absolute-voice-trace-timeline__error">${escapeHtml7(model.error)}</p>` : ""}
2316
+ ${model.error ? `<p class="absolute-voice-trace-timeline__error">${escapeHtml8(model.error)}</p>` : ""}
1885
2317
  </section>`;
1886
2318
  };
1887
2319
  var getVoiceTraceTimelineCSS = () => `.absolute-voice-trace-timeline{border:1px solid #bad7d3;border-radius:20px;background:#f3fffb;color:#09201c;padding:18px;box-shadow:0 18px 40px rgba(9,32,28,.12);font-family:inherit}.absolute-voice-trace-timeline--error,.absolute-voice-trace-timeline--failed{border-color:#f2a7a7;background:#fff5f3}.absolute-voice-trace-timeline--warning{border-color:#fbbf24;background:#fffaf0}.absolute-voice-trace-timeline__header,.absolute-voice-trace-timeline__session header{align-items:start;display:flex;gap:12px;justify-content:space-between}.absolute-voice-trace-timeline__eyebrow{color:#17665b;font-size:12px;font-weight:800;letter-spacing:.08em;text-transform:uppercase}.absolute-voice-trace-timeline__label{font-size:24px;line-height:1}.absolute-voice-trace-timeline__description,.absolute-voice-trace-timeline__session p,.absolute-voice-trace-timeline__empty{color:#35544f}.absolute-voice-trace-timeline__sessions{display:grid;gap:12px;margin-top:14px}.absolute-voice-trace-timeline__session{background:#fff;border:1px solid #cfe7e2;border-radius:16px;padding:14px}.absolute-voice-trace-timeline__session--failed{border-color:#f2a7a7}.absolute-voice-trace-timeline__session--warning{border-color:#fbbf24}.absolute-voice-trace-timeline__session p{margin:10px 0}.absolute-voice-trace-timeline__session a{color:#0f766e;font-weight:800}.absolute-voice-trace-timeline__empty{margin:14px 0 0}.absolute-voice-trace-timeline__error{color:#9f1239;font-weight:700}`;
@@ -1926,25 +2358,25 @@ var defineVoiceTraceTimelineElement = (tagName = "absolute-voice-trace-timeline"
1926
2358
  };
1927
2359
 
1928
2360
  // src/react/useVoiceTraceTimeline.tsx
1929
- import { useEffect as useEffect7, useRef as useRef7, useSyncExternalStore as useSyncExternalStore7 } from "react";
2361
+ import { useEffect as useEffect8, useRef as useRef8, useSyncExternalStore as useSyncExternalStore8 } from "react";
1930
2362
  var useVoiceTraceTimeline = (path = "/api/voice-traces", options = {}) => {
1931
- const storeRef = useRef7(null);
2363
+ const storeRef = useRef8(null);
1932
2364
  if (!storeRef.current) {
1933
2365
  storeRef.current = createVoiceTraceTimelineStore(path, options);
1934
2366
  }
1935
2367
  const store = storeRef.current;
1936
- useEffect7(() => {
2368
+ useEffect8(() => {
1937
2369
  store.refresh().catch(() => {});
1938
2370
  return () => store.close();
1939
2371
  }, [store]);
1940
2372
  return {
1941
- ...useSyncExternalStore7(store.subscribe, store.getSnapshot, store.getServerSnapshot),
2373
+ ...useSyncExternalStore8(store.subscribe, store.getSnapshot, store.getServerSnapshot),
1942
2374
  refresh: store.refresh
1943
2375
  };
1944
2376
  };
1945
2377
 
1946
2378
  // src/react/VoiceTraceTimeline.tsx
1947
- import { jsxDEV as jsxDEV7 } from "react/jsx-dev-runtime";
2379
+ import { jsxDEV as jsxDEV8 } from "react/jsx-dev-runtime";
1948
2380
  var VoiceTraceTimeline = ({
1949
2381
  className,
1950
2382
  path = "/api/voice-traces",
@@ -1952,49 +2384,49 @@ var VoiceTraceTimeline = ({
1952
2384
  }) => {
1953
2385
  const snapshot = useVoiceTraceTimeline(path, options);
1954
2386
  const model = createVoiceTraceTimelineViewModel(snapshot, options);
1955
- return /* @__PURE__ */ jsxDEV7("section", {
2387
+ return /* @__PURE__ */ jsxDEV8("section", {
1956
2388
  className: [
1957
2389
  "absolute-voice-trace-timeline",
1958
2390
  `absolute-voice-trace-timeline--${model.status}`,
1959
2391
  className
1960
2392
  ].filter(Boolean).join(" "),
1961
2393
  children: [
1962
- /* @__PURE__ */ jsxDEV7("header", {
2394
+ /* @__PURE__ */ jsxDEV8("header", {
1963
2395
  className: "absolute-voice-trace-timeline__header",
1964
2396
  children: [
1965
- /* @__PURE__ */ jsxDEV7("span", {
2397
+ /* @__PURE__ */ jsxDEV8("span", {
1966
2398
  className: "absolute-voice-trace-timeline__eyebrow",
1967
2399
  children: model.title
1968
2400
  }, undefined, false, undefined, this),
1969
- /* @__PURE__ */ jsxDEV7("strong", {
2401
+ /* @__PURE__ */ jsxDEV8("strong", {
1970
2402
  className: "absolute-voice-trace-timeline__label",
1971
2403
  children: model.label
1972
2404
  }, undefined, false, undefined, this)
1973
2405
  ]
1974
2406
  }, undefined, true, undefined, this),
1975
- /* @__PURE__ */ jsxDEV7("p", {
2407
+ /* @__PURE__ */ jsxDEV8("p", {
1976
2408
  className: "absolute-voice-trace-timeline__description",
1977
2409
  children: model.description
1978
2410
  }, undefined, false, undefined, this),
1979
- model.sessions.length ? /* @__PURE__ */ jsxDEV7("div", {
2411
+ model.sessions.length ? /* @__PURE__ */ jsxDEV8("div", {
1980
2412
  className: "absolute-voice-trace-timeline__sessions",
1981
- children: model.sessions.map((session) => /* @__PURE__ */ jsxDEV7("article", {
2413
+ children: model.sessions.map((session) => /* @__PURE__ */ jsxDEV8("article", {
1982
2414
  className: [
1983
2415
  "absolute-voice-trace-timeline__session",
1984
2416
  `absolute-voice-trace-timeline__session--${session.status}`
1985
2417
  ].join(" "),
1986
2418
  children: [
1987
- /* @__PURE__ */ jsxDEV7("header", {
2419
+ /* @__PURE__ */ jsxDEV8("header", {
1988
2420
  children: [
1989
- /* @__PURE__ */ jsxDEV7("strong", {
2421
+ /* @__PURE__ */ jsxDEV8("strong", {
1990
2422
  children: session.sessionId
1991
2423
  }, undefined, false, undefined, this),
1992
- /* @__PURE__ */ jsxDEV7("span", {
2424
+ /* @__PURE__ */ jsxDEV8("span", {
1993
2425
  children: session.status
1994
2426
  }, undefined, false, undefined, this)
1995
2427
  ]
1996
2428
  }, undefined, true, undefined, this),
1997
- /* @__PURE__ */ jsxDEV7("p", {
2429
+ /* @__PURE__ */ jsxDEV8("p", {
1998
2430
  children: [
1999
2431
  session.label,
2000
2432
  " \xB7 ",
@@ -2004,17 +2436,17 @@ var VoiceTraceTimeline = ({
2004
2436
  session.providerLabel
2005
2437
  ]
2006
2438
  }, undefined, true, undefined, this),
2007
- /* @__PURE__ */ jsxDEV7("a", {
2439
+ /* @__PURE__ */ jsxDEV8("a", {
2008
2440
  href: session.detailHref,
2009
2441
  children: "Open timeline"
2010
2442
  }, undefined, false, undefined, this)
2011
2443
  ]
2012
2444
  }, session.sessionId, true, undefined, this))
2013
- }, undefined, false, undefined, this) : /* @__PURE__ */ jsxDEV7("p", {
2445
+ }, undefined, false, undefined, this) : /* @__PURE__ */ jsxDEV8("p", {
2014
2446
  className: "absolute-voice-trace-timeline__empty",
2015
2447
  children: "Run a voice session to see call timelines."
2016
2448
  }, undefined, false, undefined, this),
2017
- model.error ? /* @__PURE__ */ jsxDEV7("p", {
2449
+ model.error ? /* @__PURE__ */ jsxDEV8("p", {
2018
2450
  className: "absolute-voice-trace-timeline__error",
2019
2451
  children: model.error
2020
2452
  }, undefined, false, undefined, this) : null
@@ -2022,7 +2454,7 @@ var VoiceTraceTimeline = ({
2022
2454
  }, undefined, true, undefined, this);
2023
2455
  };
2024
2456
  // src/react/useVoiceTurnLatency.tsx
2025
- import { useEffect as useEffect8, useRef as useRef8, useSyncExternalStore as useSyncExternalStore8 } from "react";
2457
+ import { useEffect as useEffect9, useRef as useRef9, useSyncExternalStore as useSyncExternalStore9 } from "react";
2026
2458
 
2027
2459
  // src/client/turnLatency.ts
2028
2460
  var fetchVoiceTurnLatency = async (path = "/api/turn-latency", options = {}) => {
@@ -2129,27 +2561,27 @@ var createVoiceTurnLatencyStore = (path = "/api/turn-latency", options = {}) =>
2129
2561
 
2130
2562
  // src/react/useVoiceTurnLatency.tsx
2131
2563
  var useVoiceTurnLatency = (path = "/api/turn-latency", options = {}) => {
2132
- const storeRef = useRef8(null);
2564
+ const storeRef = useRef9(null);
2133
2565
  if (!storeRef.current) {
2134
2566
  storeRef.current = createVoiceTurnLatencyStore(path, options);
2135
2567
  }
2136
2568
  const store = storeRef.current;
2137
- useEffect8(() => {
2569
+ useEffect9(() => {
2138
2570
  store.refresh().catch(() => {});
2139
2571
  return () => store.close();
2140
2572
  }, [store]);
2141
2573
  return {
2142
- ...useSyncExternalStore8(store.subscribe, store.getSnapshot, store.getServerSnapshot),
2574
+ ...useSyncExternalStore9(store.subscribe, store.getSnapshot, store.getServerSnapshot),
2143
2575
  refresh: store.refresh,
2144
2576
  runProof: store.runProof
2145
2577
  };
2146
2578
  };
2147
2579
 
2148
2580
  // src/client/turnLatencyWidget.ts
2149
- var DEFAULT_TITLE7 = "Turn Latency";
2150
- var DEFAULT_DESCRIPTION7 = "Per-turn timing from first transcript to commit and assistant response start.";
2581
+ var DEFAULT_TITLE8 = "Turn Latency";
2582
+ var DEFAULT_DESCRIPTION8 = "Per-turn timing from first transcript to commit and assistant response start.";
2151
2583
  var DEFAULT_PROOF_LABEL = "Run latency proof";
2152
- var escapeHtml8 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
2584
+ var escapeHtml9 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
2153
2585
  var formatMs2 = (value) => typeof value === "number" ? `${Math.round(value)}ms` : "n/a";
2154
2586
  var createVoiceTurnLatencyViewModel = (snapshot, options = {}) => {
2155
2587
  const turns = (snapshot.report?.turns ?? []).map((turn) => ({
@@ -2163,39 +2595,39 @@ var createVoiceTurnLatencyViewModel = (snapshot, options = {}) => {
2163
2595
  const warningCount = snapshot.report?.warnings ?? turns.filter((turn) => turn.status === "warn").length;
2164
2596
  const failedCount = snapshot.report?.failed ?? turns.filter((turn) => turn.status === "fail").length;
2165
2597
  return {
2166
- description: options.description ?? DEFAULT_DESCRIPTION7,
2598
+ description: options.description ?? DEFAULT_DESCRIPTION8,
2167
2599
  error: snapshot.error,
2168
2600
  isLoading: snapshot.isLoading,
2169
2601
  label: snapshot.error ? "Unavailable" : turns.length ? failedCount > 0 ? `${failedCount} slow` : warningCount > 0 ? `${warningCount} warnings` : `avg ${formatMs2(snapshot.report?.averageTotalMs)}` : snapshot.isLoading ? "Checking" : "No turns",
2170
2602
  proofLabel: options.proofPath ? options.proofLabel ?? DEFAULT_PROOF_LABEL : undefined,
2171
2603
  showProofAction: Boolean(options.proofPath),
2172
2604
  status: snapshot.error ? "error" : turns.length ? failedCount > 0 || warningCount > 0 ? "warning" : "ready" : snapshot.isLoading ? "loading" : "empty",
2173
- title: options.title ?? DEFAULT_TITLE7,
2605
+ title: options.title ?? DEFAULT_TITLE8,
2174
2606
  turns,
2175
2607
  updatedAt: snapshot.updatedAt
2176
2608
  };
2177
2609
  };
2178
2610
  var renderVoiceTurnLatencyHTML = (snapshot, options = {}) => {
2179
2611
  const model = createVoiceTurnLatencyViewModel(snapshot, options);
2180
- 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)}">
2612
+ 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--${escapeHtml9(turn.status)}">
2181
2613
  <header>
2182
- <strong>${escapeHtml8(turn.label)}</strong>
2183
- <span>${escapeHtml8(turn.status)}</span>
2614
+ <strong>${escapeHtml9(turn.label)}</strong>
2615
+ <span>${escapeHtml9(turn.status)}</span>
2184
2616
  </header>
2185
2617
  <dl>${turn.rows.map((row) => `<div>
2186
- <dt>${escapeHtml8(row.label)}</dt>
2187
- <dd>${escapeHtml8(row.value)}</dd>
2618
+ <dt>${escapeHtml9(row.label)}</dt>
2619
+ <dd>${escapeHtml9(row.value)}</dd>
2188
2620
  </div>`).join("")}</dl>
2189
2621
  </article>`).join("")}</div>` : '<p class="absolute-voice-turn-latency__empty">Complete a voice turn to see latency diagnostics.</p>';
2190
- return `<section class="absolute-voice-turn-latency absolute-voice-turn-latency--${escapeHtml8(model.status)}">
2622
+ return `<section class="absolute-voice-turn-latency absolute-voice-turn-latency--${escapeHtml9(model.status)}">
2191
2623
  <header class="absolute-voice-turn-latency__header">
2192
- <span class="absolute-voice-turn-latency__eyebrow">${escapeHtml8(model.title)}</span>
2193
- <strong class="absolute-voice-turn-latency__label">${escapeHtml8(model.label)}</strong>
2624
+ <span class="absolute-voice-turn-latency__eyebrow">${escapeHtml9(model.title)}</span>
2625
+ <strong class="absolute-voice-turn-latency__label">${escapeHtml9(model.label)}</strong>
2194
2626
  </header>
2195
- <p class="absolute-voice-turn-latency__description">${escapeHtml8(model.description)}</p>
2196
- ${model.showProofAction ? `<button class="absolute-voice-turn-latency__proof" data-absolute-voice-turn-latency-proof type="button">${escapeHtml8(model.proofLabel ?? DEFAULT_PROOF_LABEL)}</button>` : ""}
2627
+ <p class="absolute-voice-turn-latency__description">${escapeHtml9(model.description)}</p>
2628
+ ${model.showProofAction ? `<button class="absolute-voice-turn-latency__proof" data-absolute-voice-turn-latency-proof type="button">${escapeHtml9(model.proofLabel ?? DEFAULT_PROOF_LABEL)}</button>` : ""}
2197
2629
  ${turns}
2198
- ${model.error ? `<p class="absolute-voice-turn-latency__error">${escapeHtml8(model.error)}</p>` : ""}
2630
+ ${model.error ? `<p class="absolute-voice-turn-latency__error">${escapeHtml9(model.error)}</p>` : ""}
2199
2631
  </section>`;
2200
2632
  };
2201
2633
  var mountVoiceTurnLatency = (element, path = "/api/turn-latency", options = {}) => {
@@ -2246,7 +2678,7 @@ var defineVoiceTurnLatencyElement = (tagName = "absolute-voice-turn-latency") =>
2246
2678
  };
2247
2679
 
2248
2680
  // src/react/VoiceTurnLatency.tsx
2249
- import { jsxDEV as jsxDEV8 } from "react/jsx-dev-runtime";
2681
+ import { jsxDEV as jsxDEV9 } from "react/jsx-dev-runtime";
2250
2682
  var VoiceTurnLatency = ({
2251
2683
  className,
2252
2684
  path = "/api/turn-latency",
@@ -2254,31 +2686,31 @@ var VoiceTurnLatency = ({
2254
2686
  }) => {
2255
2687
  const latency = useVoiceTurnLatency(path, options);
2256
2688
  const model = createVoiceTurnLatencyViewModel(latency, options);
2257
- return /* @__PURE__ */ jsxDEV8("section", {
2689
+ return /* @__PURE__ */ jsxDEV9("section", {
2258
2690
  className: [
2259
2691
  "absolute-voice-turn-latency",
2260
2692
  `absolute-voice-turn-latency--${model.status}`,
2261
2693
  className
2262
2694
  ].filter(Boolean).join(" "),
2263
2695
  children: [
2264
- /* @__PURE__ */ jsxDEV8("header", {
2696
+ /* @__PURE__ */ jsxDEV9("header", {
2265
2697
  className: "absolute-voice-turn-latency__header",
2266
2698
  children: [
2267
- /* @__PURE__ */ jsxDEV8("span", {
2699
+ /* @__PURE__ */ jsxDEV9("span", {
2268
2700
  className: "absolute-voice-turn-latency__eyebrow",
2269
2701
  children: model.title
2270
2702
  }, undefined, false, undefined, this),
2271
- /* @__PURE__ */ jsxDEV8("strong", {
2703
+ /* @__PURE__ */ jsxDEV9("strong", {
2272
2704
  className: "absolute-voice-turn-latency__label",
2273
2705
  children: model.label
2274
2706
  }, undefined, false, undefined, this)
2275
2707
  ]
2276
2708
  }, undefined, true, undefined, this),
2277
- /* @__PURE__ */ jsxDEV8("p", {
2709
+ /* @__PURE__ */ jsxDEV9("p", {
2278
2710
  className: "absolute-voice-turn-latency__description",
2279
2711
  children: model.description
2280
2712
  }, undefined, false, undefined, this),
2281
- model.showProofAction ? /* @__PURE__ */ jsxDEV8("button", {
2713
+ model.showProofAction ? /* @__PURE__ */ jsxDEV9("button", {
2282
2714
  className: "absolute-voice-turn-latency__proof",
2283
2715
  onClick: () => {
2284
2716
  latency.runProof().catch(() => {});
@@ -2286,31 +2718,31 @@ var VoiceTurnLatency = ({
2286
2718
  type: "button",
2287
2719
  children: model.proofLabel
2288
2720
  }, undefined, false, undefined, this) : null,
2289
- model.turns.length ? /* @__PURE__ */ jsxDEV8("div", {
2721
+ model.turns.length ? /* @__PURE__ */ jsxDEV9("div", {
2290
2722
  className: "absolute-voice-turn-latency__turns",
2291
- children: model.turns.map((turn) => /* @__PURE__ */ jsxDEV8("article", {
2723
+ children: model.turns.map((turn) => /* @__PURE__ */ jsxDEV9("article", {
2292
2724
  className: [
2293
2725
  "absolute-voice-turn-latency__turn",
2294
2726
  `absolute-voice-turn-latency__turn--${turn.status}`
2295
2727
  ].join(" "),
2296
2728
  children: [
2297
- /* @__PURE__ */ jsxDEV8("header", {
2729
+ /* @__PURE__ */ jsxDEV9("header", {
2298
2730
  children: [
2299
- /* @__PURE__ */ jsxDEV8("strong", {
2731
+ /* @__PURE__ */ jsxDEV9("strong", {
2300
2732
  children: turn.label
2301
2733
  }, undefined, false, undefined, this),
2302
- /* @__PURE__ */ jsxDEV8("span", {
2734
+ /* @__PURE__ */ jsxDEV9("span", {
2303
2735
  children: turn.status
2304
2736
  }, undefined, false, undefined, this)
2305
2737
  ]
2306
2738
  }, undefined, true, undefined, this),
2307
- /* @__PURE__ */ jsxDEV8("dl", {
2308
- children: turn.rows.map((row) => /* @__PURE__ */ jsxDEV8("div", {
2739
+ /* @__PURE__ */ jsxDEV9("dl", {
2740
+ children: turn.rows.map((row) => /* @__PURE__ */ jsxDEV9("div", {
2309
2741
  children: [
2310
- /* @__PURE__ */ jsxDEV8("dt", {
2742
+ /* @__PURE__ */ jsxDEV9("dt", {
2311
2743
  children: row.label
2312
2744
  }, undefined, false, undefined, this),
2313
- /* @__PURE__ */ jsxDEV8("dd", {
2745
+ /* @__PURE__ */ jsxDEV9("dd", {
2314
2746
  children: row.value
2315
2747
  }, undefined, false, undefined, this)
2316
2748
  ]
@@ -2318,11 +2750,11 @@ var VoiceTurnLatency = ({
2318
2750
  }, undefined, false, undefined, this)
2319
2751
  ]
2320
2752
  }, `${turn.sessionId}:${turn.turnId}`, true, undefined, this))
2321
- }, undefined, false, undefined, this) : /* @__PURE__ */ jsxDEV8("p", {
2753
+ }, undefined, false, undefined, this) : /* @__PURE__ */ jsxDEV9("p", {
2322
2754
  className: "absolute-voice-turn-latency__empty",
2323
2755
  children: "Complete a voice turn to see latency diagnostics."
2324
2756
  }, undefined, false, undefined, this),
2325
- model.error ? /* @__PURE__ */ jsxDEV8("p", {
2757
+ model.error ? /* @__PURE__ */ jsxDEV9("p", {
2326
2758
  className: "absolute-voice-turn-latency__error",
2327
2759
  children: model.error
2328
2760
  }, undefined, false, undefined, this) : null
@@ -2330,7 +2762,7 @@ var VoiceTurnLatency = ({
2330
2762
  }, undefined, true, undefined, this);
2331
2763
  };
2332
2764
  // src/react/useVoiceTurnQuality.tsx
2333
- import { useEffect as useEffect9, useRef as useRef9, useSyncExternalStore as useSyncExternalStore9 } from "react";
2765
+ import { useEffect as useEffect10, useRef as useRef10, useSyncExternalStore as useSyncExternalStore10 } from "react";
2334
2766
 
2335
2767
  // src/client/turnQuality.ts
2336
2768
  var fetchVoiceTurnQuality = async (path = "/api/turn-quality", options = {}) => {
@@ -2413,25 +2845,25 @@ var createVoiceTurnQualityStore = (path = "/api/turn-quality", options = {}) =>
2413
2845
 
2414
2846
  // src/react/useVoiceTurnQuality.tsx
2415
2847
  var useVoiceTurnQuality = (path = "/api/turn-quality", options = {}) => {
2416
- const storeRef = useRef9(null);
2848
+ const storeRef = useRef10(null);
2417
2849
  if (!storeRef.current) {
2418
2850
  storeRef.current = createVoiceTurnQualityStore(path, options);
2419
2851
  }
2420
2852
  const store = storeRef.current;
2421
- useEffect9(() => {
2853
+ useEffect10(() => {
2422
2854
  store.refresh().catch(() => {});
2423
2855
  return () => store.close();
2424
2856
  }, [store]);
2425
2857
  return {
2426
- ...useSyncExternalStore9(store.subscribe, store.getSnapshot, store.getServerSnapshot),
2858
+ ...useSyncExternalStore10(store.subscribe, store.getSnapshot, store.getServerSnapshot),
2427
2859
  refresh: store.refresh
2428
2860
  };
2429
2861
  };
2430
2862
 
2431
2863
  // src/client/turnQualityWidget.ts
2432
- var DEFAULT_TITLE8 = "Turn Quality";
2433
- var DEFAULT_DESCRIPTION8 = "Per-turn STT confidence, fallback selection, corrections, and transcript coverage.";
2434
- var escapeHtml9 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
2864
+ var DEFAULT_TITLE9 = "Turn Quality";
2865
+ var DEFAULT_DESCRIPTION9 = "Per-turn STT confidence, fallback selection, corrections, and transcript coverage.";
2866
+ var escapeHtml10 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
2435
2867
  var formatConfidence = (value) => typeof value === "number" ? `${Math.round(value * 100)}%` : "n/a";
2436
2868
  var formatMaybe = (value) => value === undefined || value === "" ? "n/a" : String(value);
2437
2869
  var getTurnDetail = (turn) => {
@@ -2469,37 +2901,37 @@ var createVoiceTurnQualityViewModel = (snapshot, options = {}) => {
2469
2901
  const warningCount = snapshot.report?.warnings ?? turns.filter((turn) => turn.status === "warn").length;
2470
2902
  const failedCount = snapshot.report?.failed ?? turns.filter((turn) => turn.status === "fail").length;
2471
2903
  return {
2472
- description: options.description ?? DEFAULT_DESCRIPTION8,
2904
+ description: options.description ?? DEFAULT_DESCRIPTION9,
2473
2905
  error: snapshot.error,
2474
2906
  isLoading: snapshot.isLoading,
2475
2907
  label: snapshot.error ? "Unavailable" : turns.length ? failedCount > 0 ? `${failedCount} failed` : warningCount > 0 ? `${warningCount} warnings` : `${turns.length} healthy` : snapshot.isLoading ? "Checking" : "No turns",
2476
2908
  status: snapshot.error ? "error" : turns.length ? failedCount > 0 || warningCount > 0 ? "warning" : "ready" : snapshot.isLoading ? "loading" : "empty",
2477
- title: options.title ?? DEFAULT_TITLE8,
2909
+ title: options.title ?? DEFAULT_TITLE9,
2478
2910
  turns,
2479
2911
  updatedAt: snapshot.updatedAt
2480
2912
  };
2481
2913
  };
2482
2914
  var renderVoiceTurnQualityHTML = (snapshot, options = {}) => {
2483
2915
  const model = createVoiceTurnQualityViewModel(snapshot, options);
2484
- 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)}">
2916
+ 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--${escapeHtml10(turn.status)}">
2485
2917
  <header>
2486
- <strong>${escapeHtml9(turn.label)}</strong>
2487
- <span>${escapeHtml9(turn.status)}</span>
2918
+ <strong>${escapeHtml10(turn.label)}</strong>
2919
+ <span>${escapeHtml10(turn.status)}</span>
2488
2920
  </header>
2489
- <p>${escapeHtml9(turn.detail)}</p>
2921
+ <p>${escapeHtml10(turn.detail)}</p>
2490
2922
  <dl>${turn.rows.map((row) => `<div>
2491
- <dt>${escapeHtml9(row.label)}</dt>
2492
- <dd>${escapeHtml9(row.value)}</dd>
2923
+ <dt>${escapeHtml10(row.label)}</dt>
2924
+ <dd>${escapeHtml10(row.value)}</dd>
2493
2925
  </div>`).join("")}</dl>
2494
2926
  </article>`).join("")}</div>` : '<p class="absolute-voice-turn-quality__empty">Complete a voice turn to see STT quality diagnostics.</p>';
2495
- return `<section class="absolute-voice-turn-quality absolute-voice-turn-quality--${escapeHtml9(model.status)}">
2927
+ return `<section class="absolute-voice-turn-quality absolute-voice-turn-quality--${escapeHtml10(model.status)}">
2496
2928
  <header class="absolute-voice-turn-quality__header">
2497
- <span class="absolute-voice-turn-quality__eyebrow">${escapeHtml9(model.title)}</span>
2498
- <strong class="absolute-voice-turn-quality__label">${escapeHtml9(model.label)}</strong>
2929
+ <span class="absolute-voice-turn-quality__eyebrow">${escapeHtml10(model.title)}</span>
2930
+ <strong class="absolute-voice-turn-quality__label">${escapeHtml10(model.label)}</strong>
2499
2931
  </header>
2500
- <p class="absolute-voice-turn-quality__description">${escapeHtml9(model.description)}</p>
2932
+ <p class="absolute-voice-turn-quality__description">${escapeHtml10(model.description)}</p>
2501
2933
  ${turns}
2502
- ${model.error ? `<p class="absolute-voice-turn-quality__error">${escapeHtml9(model.error)}</p>` : ""}
2934
+ ${model.error ? `<p class="absolute-voice-turn-quality__error">${escapeHtml10(model.error)}</p>` : ""}
2503
2935
  </section>`;
2504
2936
  };
2505
2937
  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}`;
@@ -2541,7 +2973,7 @@ var defineVoiceTurnQualityElement = (tagName = "absolute-voice-turn-quality") =>
2541
2973
  };
2542
2974
 
2543
2975
  // src/react/VoiceTurnQuality.tsx
2544
- import { jsxDEV as jsxDEV9 } from "react/jsx-dev-runtime";
2976
+ import { jsxDEV as jsxDEV10 } from "react/jsx-dev-runtime";
2545
2977
  var VoiceTurnQuality = ({
2546
2978
  className,
2547
2979
  path = "/api/turn-quality",
@@ -2549,58 +2981,58 @@ var VoiceTurnQuality = ({
2549
2981
  }) => {
2550
2982
  const snapshot = useVoiceTurnQuality(path, options);
2551
2983
  const model = createVoiceTurnQualityViewModel(snapshot, options);
2552
- return /* @__PURE__ */ jsxDEV9("section", {
2984
+ return /* @__PURE__ */ jsxDEV10("section", {
2553
2985
  className: [
2554
2986
  "absolute-voice-turn-quality",
2555
2987
  `absolute-voice-turn-quality--${model.status}`,
2556
2988
  className
2557
2989
  ].filter(Boolean).join(" "),
2558
2990
  children: [
2559
- /* @__PURE__ */ jsxDEV9("header", {
2991
+ /* @__PURE__ */ jsxDEV10("header", {
2560
2992
  className: "absolute-voice-turn-quality__header",
2561
2993
  children: [
2562
- /* @__PURE__ */ jsxDEV9("span", {
2994
+ /* @__PURE__ */ jsxDEV10("span", {
2563
2995
  className: "absolute-voice-turn-quality__eyebrow",
2564
2996
  children: model.title
2565
2997
  }, undefined, false, undefined, this),
2566
- /* @__PURE__ */ jsxDEV9("strong", {
2998
+ /* @__PURE__ */ jsxDEV10("strong", {
2567
2999
  className: "absolute-voice-turn-quality__label",
2568
3000
  children: model.label
2569
3001
  }, undefined, false, undefined, this)
2570
3002
  ]
2571
3003
  }, undefined, true, undefined, this),
2572
- /* @__PURE__ */ jsxDEV9("p", {
3004
+ /* @__PURE__ */ jsxDEV10("p", {
2573
3005
  className: "absolute-voice-turn-quality__description",
2574
3006
  children: model.description
2575
3007
  }, undefined, false, undefined, this),
2576
- model.turns.length ? /* @__PURE__ */ jsxDEV9("div", {
3008
+ model.turns.length ? /* @__PURE__ */ jsxDEV10("div", {
2577
3009
  className: "absolute-voice-turn-quality__turns",
2578
- children: model.turns.map((turn) => /* @__PURE__ */ jsxDEV9("article", {
3010
+ children: model.turns.map((turn) => /* @__PURE__ */ jsxDEV10("article", {
2579
3011
  className: [
2580
3012
  "absolute-voice-turn-quality__turn",
2581
3013
  `absolute-voice-turn-quality__turn--${turn.status}`
2582
3014
  ].join(" "),
2583
3015
  children: [
2584
- /* @__PURE__ */ jsxDEV9("header", {
3016
+ /* @__PURE__ */ jsxDEV10("header", {
2585
3017
  children: [
2586
- /* @__PURE__ */ jsxDEV9("strong", {
3018
+ /* @__PURE__ */ jsxDEV10("strong", {
2587
3019
  children: turn.label
2588
3020
  }, undefined, false, undefined, this),
2589
- /* @__PURE__ */ jsxDEV9("span", {
3021
+ /* @__PURE__ */ jsxDEV10("span", {
2590
3022
  children: turn.status
2591
3023
  }, undefined, false, undefined, this)
2592
3024
  ]
2593
3025
  }, undefined, true, undefined, this),
2594
- /* @__PURE__ */ jsxDEV9("p", {
3026
+ /* @__PURE__ */ jsxDEV10("p", {
2595
3027
  children: turn.detail
2596
3028
  }, undefined, false, undefined, this),
2597
- /* @__PURE__ */ jsxDEV9("dl", {
2598
- children: turn.rows.map((row) => /* @__PURE__ */ jsxDEV9("div", {
3029
+ /* @__PURE__ */ jsxDEV10("dl", {
3030
+ children: turn.rows.map((row) => /* @__PURE__ */ jsxDEV10("div", {
2599
3031
  children: [
2600
- /* @__PURE__ */ jsxDEV9("dt", {
3032
+ /* @__PURE__ */ jsxDEV10("dt", {
2601
3033
  children: row.label
2602
3034
  }, undefined, false, undefined, this),
2603
- /* @__PURE__ */ jsxDEV9("dd", {
3035
+ /* @__PURE__ */ jsxDEV10("dd", {
2604
3036
  children: row.value
2605
3037
  }, undefined, false, undefined, this)
2606
3038
  ]
@@ -2608,11 +3040,11 @@ var VoiceTurnQuality = ({
2608
3040
  }, undefined, false, undefined, this)
2609
3041
  ]
2610
3042
  }, `${turn.sessionId}:${turn.turnId}`, true, undefined, this))
2611
- }, undefined, false, undefined, this) : /* @__PURE__ */ jsxDEV9("p", {
3043
+ }, undefined, false, undefined, this) : /* @__PURE__ */ jsxDEV10("p", {
2612
3044
  className: "absolute-voice-turn-quality__empty",
2613
3045
  children: "Complete a voice turn to see STT quality diagnostics."
2614
3046
  }, undefined, false, undefined, this),
2615
- model.error ? /* @__PURE__ */ jsxDEV9("p", {
3047
+ model.error ? /* @__PURE__ */ jsxDEV10("p", {
2616
3048
  className: "absolute-voice-turn-quality__error",
2617
3049
  children: model.error
2618
3050
  }, undefined, false, undefined, this) : null
@@ -2620,7 +3052,7 @@ var VoiceTurnQuality = ({
2620
3052
  }, undefined, true, undefined, this);
2621
3053
  };
2622
3054
  // src/react/useVoiceCampaignDialerProof.tsx
2623
- import { useEffect as useEffect10, useRef as useRef10, useSyncExternalStore as useSyncExternalStore10 } from "react";
3055
+ import { useEffect as useEffect11, useRef as useRef11, useSyncExternalStore as useSyncExternalStore11 } from "react";
2624
3056
 
2625
3057
  // src/client/campaignDialerProof.ts
2626
3058
  var fetchVoiceCampaignDialerProofStatus = async (path = "/api/voice/campaigns/dialer-proof", options = {}) => {
@@ -2742,23 +3174,23 @@ var createVoiceCampaignDialerProofStore = (path = "/api/voice/campaigns/dialer-p
2742
3174
 
2743
3175
  // src/react/useVoiceCampaignDialerProof.tsx
2744
3176
  var useVoiceCampaignDialerProof = (path = "/api/voice/campaigns/dialer-proof", options = {}) => {
2745
- const storeRef = useRef10(null);
3177
+ const storeRef = useRef11(null);
2746
3178
  if (!storeRef.current) {
2747
3179
  storeRef.current = createVoiceCampaignDialerProofStore(path, options);
2748
3180
  }
2749
3181
  const store = storeRef.current;
2750
- useEffect10(() => {
3182
+ useEffect11(() => {
2751
3183
  store.refresh().catch(() => {});
2752
3184
  return () => store.close();
2753
3185
  }, [store]);
2754
3186
  return {
2755
- ...useSyncExternalStore10(store.subscribe, store.getSnapshot, store.getServerSnapshot),
3187
+ ...useSyncExternalStore11(store.subscribe, store.getSnapshot, store.getServerSnapshot),
2756
3188
  refresh: store.refresh,
2757
3189
  runProof: store.runProof
2758
3190
  };
2759
3191
  };
2760
3192
  // src/react/useVoiceStream.tsx
2761
- import { useEffect as useEffect11, useRef as useRef11, useSyncExternalStore as useSyncExternalStore11 } from "react";
3193
+ import { useEffect as useEffect12, useRef as useRef12, useSyncExternalStore as useSyncExternalStore12 } from "react";
2762
3194
 
2763
3195
  // src/client/actions.ts
2764
3196
  var normalizeErrorMessage = (value) => {
@@ -3418,13 +3850,13 @@ var EMPTY_SNAPSHOT = {
3418
3850
  turns: []
3419
3851
  };
3420
3852
  var useVoiceStream = (path, options = {}) => {
3421
- const streamRef = useRef11(null);
3853
+ const streamRef = useRef12(null);
3422
3854
  if (!streamRef.current) {
3423
3855
  streamRef.current = createVoiceStream(path, options);
3424
3856
  }
3425
3857
  const stream = streamRef.current;
3426
- useEffect11(() => () => stream.close(), [stream]);
3427
- const snapshot = useSyncExternalStore11(stream.subscribe, stream.getSnapshot, stream.getServerSnapshot) ?? EMPTY_SNAPSHOT;
3858
+ useEffect12(() => () => stream.close(), [stream]);
3859
+ const snapshot = useSyncExternalStore12(stream.subscribe, stream.getSnapshot, stream.getServerSnapshot) ?? EMPTY_SNAPSHOT;
3428
3860
  return {
3429
3861
  ...snapshot,
3430
3862
  callControl: (message) => stream.callControl(message),
@@ -3434,7 +3866,7 @@ var useVoiceStream = (path, options = {}) => {
3434
3866
  };
3435
3867
  };
3436
3868
  // src/react/useVoiceController.tsx
3437
- import { useEffect as useEffect12, useRef as useRef12, useSyncExternalStore as useSyncExternalStore12 } from "react";
3869
+ import { useEffect as useEffect13, useRef as useRef13, useSyncExternalStore as useSyncExternalStore13 } from "react";
3438
3870
 
3439
3871
  // src/client/htmx.ts
3440
3872
  var DEFAULT_EVENT_NAME = "voice-refresh";
@@ -4097,13 +4529,13 @@ var EMPTY_SNAPSHOT2 = {
4097
4529
  turns: []
4098
4530
  };
4099
4531
  var useVoiceController = (path, options = {}) => {
4100
- const controllerRef = useRef12(null);
4532
+ const controllerRef = useRef13(null);
4101
4533
  if (!controllerRef.current) {
4102
4534
  controllerRef.current = createVoiceController(path, options);
4103
4535
  }
4104
4536
  const controller = controllerRef.current;
4105
- useEffect12(() => () => controller.close(), [controller]);
4106
- const snapshot = useSyncExternalStore12(controller.subscribe, controller.getSnapshot, controller.getServerSnapshot) ?? EMPTY_SNAPSHOT2;
4537
+ useEffect13(() => () => controller.close(), [controller]);
4538
+ const snapshot = useSyncExternalStore13(controller.subscribe, controller.getSnapshot, controller.getServerSnapshot) ?? EMPTY_SNAPSHOT2;
4107
4539
  return {
4108
4540
  ...snapshot,
4109
4541
  bindHTMX: controller.bindHTMX,
@@ -4117,7 +4549,7 @@ var useVoiceController = (path, options = {}) => {
4117
4549
  };
4118
4550
  };
4119
4551
  // src/react/useVoiceWorkflowStatus.tsx
4120
- import { useEffect as useEffect13, useRef as useRef13, useSyncExternalStore as useSyncExternalStore13 } from "react";
4552
+ import { useEffect as useEffect14, useRef as useRef14, useSyncExternalStore as useSyncExternalStore14 } from "react";
4121
4553
 
4122
4554
  // src/client/workflowStatus.ts
4123
4555
  var fetchVoiceWorkflowStatus = async (path = "/evals/scenarios/json", options = {}) => {
@@ -4200,17 +4632,17 @@ var createVoiceWorkflowStatusStore = (path = "/evals/scenarios/json", options =
4200
4632
 
4201
4633
  // src/react/useVoiceWorkflowStatus.tsx
4202
4634
  var useVoiceWorkflowStatus = (path = "/evals/scenarios/json", options = {}) => {
4203
- const storeRef = useRef13(null);
4635
+ const storeRef = useRef14(null);
4204
4636
  if (!storeRef.current) {
4205
4637
  storeRef.current = createVoiceWorkflowStatusStore(path, options);
4206
4638
  }
4207
4639
  const store = storeRef.current;
4208
- useEffect13(() => {
4640
+ useEffect14(() => {
4209
4641
  store.refresh().catch(() => {});
4210
4642
  return () => store.close();
4211
4643
  }, [store]);
4212
4644
  return {
4213
- ...useSyncExternalStore13(store.subscribe, store.getSnapshot, store.getServerSnapshot),
4645
+ ...useSyncExternalStore14(store.subscribe, store.getSnapshot, store.getServerSnapshot),
4214
4646
  refresh: store.refresh
4215
4647
  };
4216
4648
  };
@@ -4225,6 +4657,7 @@ export {
4225
4657
  useVoiceProviderSimulationControls,
4226
4658
  useVoiceProviderCapabilities,
4227
4659
  useVoiceOpsStatus,
4660
+ useVoiceOpsActionCenter,
4228
4661
  useVoiceDeliveryRuntime,
4229
4662
  useVoiceController,
4230
4663
  useVoiceCampaignDialerProof,
@@ -4236,5 +4669,6 @@ export {
4236
4669
  VoiceProviderSimulationControls,
4237
4670
  VoiceProviderCapabilities,
4238
4671
  VoiceOpsStatus,
4672
+ VoiceOpsActionCenter,
4239
4673
  VoiceDeliveryRuntime
4240
4674
  };