@absolutejs/voice 0.0.22-beta.404 → 0.0.22-beta.406

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.
@@ -2629,6 +2629,191 @@ var createVoiceProofTrends = (path = "/api/voice/proof-trends", options = {}) =>
2629
2629
  subscribe: store.subscribe
2630
2630
  };
2631
2631
  };
2632
+ // src/client/callDebugger.ts
2633
+ var fetchVoiceCallDebugger = async (path, options = {}) => {
2634
+ const fetchImpl = options.fetch ?? globalThis.fetch;
2635
+ const response = await fetchImpl(path);
2636
+ if (!response.ok) {
2637
+ throw new Error(`Voice call debugger failed: HTTP ${response.status}`);
2638
+ }
2639
+ return await response.json();
2640
+ };
2641
+ var createVoiceCallDebuggerStore = (path, options = {}) => {
2642
+ const listeners = new Set;
2643
+ let closed = false;
2644
+ let timer;
2645
+ let snapshot = {
2646
+ error: null,
2647
+ isLoading: false
2648
+ };
2649
+ const emit = () => {
2650
+ for (const listener of listeners) {
2651
+ listener();
2652
+ }
2653
+ };
2654
+ const refresh = async () => {
2655
+ if (closed) {
2656
+ return snapshot.report;
2657
+ }
2658
+ snapshot = { ...snapshot, error: null, isLoading: true };
2659
+ emit();
2660
+ try {
2661
+ const report = await fetchVoiceCallDebugger(path, options);
2662
+ snapshot = {
2663
+ error: null,
2664
+ isLoading: false,
2665
+ report,
2666
+ updatedAt: Date.now()
2667
+ };
2668
+ emit();
2669
+ return report;
2670
+ } catch (error) {
2671
+ snapshot = {
2672
+ ...snapshot,
2673
+ error: error instanceof Error ? error.message : String(error),
2674
+ isLoading: false
2675
+ };
2676
+ emit();
2677
+ throw error;
2678
+ }
2679
+ };
2680
+ const close = () => {
2681
+ closed = true;
2682
+ if (timer) {
2683
+ clearInterval(timer);
2684
+ timer = undefined;
2685
+ }
2686
+ listeners.clear();
2687
+ };
2688
+ if (options.intervalMs && options.intervalMs > 0) {
2689
+ timer = setInterval(() => {
2690
+ refresh().catch(() => {});
2691
+ }, options.intervalMs);
2692
+ }
2693
+ return {
2694
+ close,
2695
+ getServerSnapshot: () => snapshot,
2696
+ getSnapshot: () => snapshot,
2697
+ refresh,
2698
+ subscribe: (listener) => {
2699
+ listeners.add(listener);
2700
+ return () => {
2701
+ listeners.delete(listener);
2702
+ };
2703
+ }
2704
+ };
2705
+ };
2706
+
2707
+ // src/client/callDebuggerWidget.ts
2708
+ var DEFAULT_TITLE4 = "Call Debugger";
2709
+ var DEFAULT_DESCRIPTION4 = "Open the latest call artifact with snapshot, operations record, failure replay, provider path, transcript, and incident markdown.";
2710
+ var DEFAULT_LINK_LABEL = "Open debugger";
2711
+ var escapeHtml6 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
2712
+ var defaultHref = (path, report) => {
2713
+ if (path.startsWith("/api/voice-call-debugger/")) {
2714
+ return path.replace("/api/voice-call-debugger/", "/voice-call-debugger/");
2715
+ }
2716
+ return report ? `/voice-call-debugger/${encodeURIComponent(report.sessionId)}` : path;
2717
+ };
2718
+ var resolveHref = (path, state, options) => {
2719
+ if (typeof options.href === "function") {
2720
+ return options.href({ report: state.report });
2721
+ }
2722
+ return options.href ?? defaultHref(path, state.report);
2723
+ };
2724
+ var createVoiceCallDebuggerLaunchViewModel = (path, state, options = {}) => {
2725
+ const report = state.report;
2726
+ const href = resolveHref(path, state, options);
2727
+ return {
2728
+ description: options.description ?? DEFAULT_DESCRIPTION4,
2729
+ error: state.error,
2730
+ href,
2731
+ isLoading: state.isLoading,
2732
+ label: state.error ? "Unavailable" : report ? `${report.status} \xB7 ${report.sessionId}` : state.isLoading ? "Loading" : "No call loaded",
2733
+ rows: report ? [
2734
+ { label: "Events", value: String(report.operationsRecord.summary.eventCount) },
2735
+ { label: "Turns", value: String(report.operationsRecord.summary.turnCount) },
2736
+ { label: "Errors", value: String(report.operationsRecord.summary.errorCount) },
2737
+ {
2738
+ label: "Provider recovery",
2739
+ value: report.operationsRecord.providerDecisionSummary.recoveryStatus
2740
+ },
2741
+ {
2742
+ label: "Fallbacks",
2743
+ value: String(report.operationsRecord.providerDecisionSummary.fallbacks)
2744
+ },
2745
+ { label: "Snapshot", value: report.snapshot.status }
2746
+ ] : [],
2747
+ status: state.error ? "error" : report ? report.status === "healthy" ? "ready" : "warning" : state.isLoading ? "loading" : "empty",
2748
+ title: options.title ?? DEFAULT_TITLE4,
2749
+ updatedAt: state.updatedAt
2750
+ };
2751
+ };
2752
+ var renderVoiceCallDebuggerLaunchHTML = (path, state, options = {}) => {
2753
+ const model = createVoiceCallDebuggerLaunchViewModel(path, state, options);
2754
+ const rows = model.rows.length ? `<dl>${model.rows.map((row) => `<div>
2755
+ <dt>${escapeHtml6(row.label)}</dt>
2756
+ <dd>${escapeHtml6(row.value)}</dd>
2757
+ </div>`).join("")}</dl>` : '<p class="absolute-voice-call-debugger-launch__empty">Load a call debugger report to see the latest support artifact.</p>';
2758
+ return `<section class="absolute-voice-call-debugger-launch absolute-voice-call-debugger-launch--${escapeHtml6(model.status)}">
2759
+ <header class="absolute-voice-call-debugger-launch__header">
2760
+ <span class="absolute-voice-call-debugger-launch__eyebrow">${escapeHtml6(model.title)}</span>
2761
+ <strong class="absolute-voice-call-debugger-launch__label">${escapeHtml6(model.label)}</strong>
2762
+ </header>
2763
+ <p class="absolute-voice-call-debugger-launch__description">${escapeHtml6(model.description)}</p>
2764
+ <a class="absolute-voice-call-debugger-launch__link" href="${escapeHtml6(model.href)}">${escapeHtml6(options.linkLabel ?? DEFAULT_LINK_LABEL)}</a>
2765
+ ${rows}
2766
+ ${model.error ? `<p class="absolute-voice-call-debugger-launch__error">${escapeHtml6(model.error)}</p>` : ""}
2767
+ </section>`;
2768
+ };
2769
+ var mountVoiceCallDebuggerLaunch = (element, path, options = {}) => {
2770
+ const store = createVoiceCallDebuggerStore(path, options);
2771
+ const render = () => {
2772
+ element.innerHTML = renderVoiceCallDebuggerLaunchHTML(path, store.getSnapshot(), options);
2773
+ };
2774
+ const unsubscribe = store.subscribe(render);
2775
+ render();
2776
+ store.refresh().catch(() => {});
2777
+ return {
2778
+ close: () => {
2779
+ unsubscribe();
2780
+ store.close();
2781
+ },
2782
+ refresh: store.refresh
2783
+ };
2784
+ };
2785
+ var defineVoiceCallDebuggerLaunchElement = (tagName = "absolute-voice-call-debugger-launch") => {
2786
+ if (typeof window === "undefined" || typeof customElements === "undefined" || customElements.get(tagName)) {
2787
+ return;
2788
+ }
2789
+ customElements.define(tagName, class AbsoluteVoiceCallDebuggerLaunchElement extends HTMLElement {
2790
+ mounted;
2791
+ connectedCallback() {
2792
+ const intervalMs = Number(this.getAttribute("interval-ms") ?? 0);
2793
+ this.mounted = mountVoiceCallDebuggerLaunch(this, this.getAttribute("path") ?? "/api/voice-call-debugger/latest", {
2794
+ description: this.getAttribute("description") ?? undefined,
2795
+ href: this.getAttribute("href") ?? undefined,
2796
+ intervalMs: Number.isFinite(intervalMs) ? intervalMs : 0,
2797
+ linkLabel: this.getAttribute("link-label") ?? undefined,
2798
+ title: this.getAttribute("title") ?? undefined
2799
+ });
2800
+ }
2801
+ disconnectedCallback() {
2802
+ this.mounted?.close();
2803
+ this.mounted = undefined;
2804
+ }
2805
+ });
2806
+ };
2807
+
2808
+ // src/svelte/createVoiceCallDebugger.ts
2809
+ var createVoiceCallDebugger = (path, options = {}) => {
2810
+ const store = createVoiceCallDebuggerStore(path, options);
2811
+ return {
2812
+ ...store,
2813
+ getHTML: () => renderVoiceCallDebuggerLaunchHTML(path, store.getSnapshot(), options),
2814
+ getViewModel: () => createVoiceCallDebuggerLaunchViewModel(path, store.getSnapshot(), options)
2815
+ };
2816
+ };
2632
2817
  // src/client/sessionSnapshot.ts
2633
2818
  var withTurnId = (path, turnId) => {
2634
2819
  if (!turnId) {
@@ -2723,10 +2908,10 @@ var createVoiceSessionSnapshotStore = (path, options = {}) => {
2723
2908
  };
2724
2909
 
2725
2910
  // src/client/sessionSnapshotWidget.ts
2726
- var DEFAULT_TITLE4 = "Session Snapshot";
2727
- var DEFAULT_DESCRIPTION4 = "Portable call artifact with media graph, provider routing, proof, quality, and telephony evidence.";
2911
+ var DEFAULT_TITLE5 = "Session Snapshot";
2912
+ var DEFAULT_DESCRIPTION5 = "Portable call artifact with media graph, provider routing, proof, quality, and telephony evidence.";
2728
2913
  var DEFAULT_DOWNLOAD_LABEL = "Download snapshot";
2729
- var escapeHtml6 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
2914
+ var escapeHtml7 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
2730
2915
  var formatStatus = (status) => status ?? "n/a";
2731
2916
  var createVoiceSessionSnapshotViewModel = (state, options = {}) => {
2732
2917
  const snapshot = state.snapshot;
@@ -2742,7 +2927,7 @@ var createVoiceSessionSnapshotViewModel = (state, options = {}) => {
2742
2927
  label: artifact.label,
2743
2928
  status: formatStatus(artifact.status)
2744
2929
  })) ?? [],
2745
- description: options.description ?? DEFAULT_DESCRIPTION4,
2930
+ description: options.description ?? DEFAULT_DESCRIPTION5,
2746
2931
  error: state.error,
2747
2932
  isLoading: state.isLoading,
2748
2933
  label: state.error ? "Unavailable" : snapshot ? `${snapshot.status} \xB7 ${snapshot.sessionId}` : state.isLoading ? "Loading" : "No snapshot",
@@ -2766,30 +2951,30 @@ var createVoiceSessionSnapshotViewModel = (state, options = {}) => {
2766
2951
  ] : [],
2767
2952
  showDownload: snapshot !== undefined,
2768
2953
  status: state.error ? "error" : snapshot ? snapshot.status === "pass" ? "ready" : "warning" : state.isLoading ? "loading" : "empty",
2769
- title: options.title ?? DEFAULT_TITLE4,
2954
+ title: options.title ?? DEFAULT_TITLE5,
2770
2955
  updatedAt: state.updatedAt
2771
2956
  };
2772
2957
  };
2773
2958
  var renderVoiceSessionSnapshotHTML = (state, options = {}) => {
2774
2959
  const model = createVoiceSessionSnapshotViewModel(state, options);
2775
2960
  const rows = model.rows.length ? `<dl>${model.rows.map((row) => `<div>
2776
- <dt>${escapeHtml6(row.label)}</dt>
2777
- <dd>${escapeHtml6(row.value)}</dd>
2961
+ <dt>${escapeHtml7(row.label)}</dt>
2962
+ <dd>${escapeHtml7(row.value)}</dd>
2778
2963
  </div>`).join("")}</dl>` : '<p class="absolute-voice-session-snapshot__empty">Load a session snapshot to see support diagnostics.</p>';
2779
2964
  const artifacts = model.artifacts.length ? `<div class="absolute-voice-session-snapshot__artifacts">${model.artifacts.map((artifact) => {
2780
- const body = `<strong>${escapeHtml6(artifact.label)}</strong><span>${escapeHtml6(artifact.status)}</span>`;
2781
- return artifact.href ? `<a href="${escapeHtml6(artifact.href)}">${body}</a>` : `<div>${body}</div>`;
2965
+ const body = `<strong>${escapeHtml7(artifact.label)}</strong><span>${escapeHtml7(artifact.status)}</span>`;
2966
+ return artifact.href ? `<a href="${escapeHtml7(artifact.href)}">${body}</a>` : `<div>${body}</div>`;
2782
2967
  }).join("")}</div>` : "";
2783
- return `<section class="absolute-voice-session-snapshot absolute-voice-session-snapshot--${escapeHtml6(model.status)}">
2968
+ return `<section class="absolute-voice-session-snapshot absolute-voice-session-snapshot--${escapeHtml7(model.status)}">
2784
2969
  <header class="absolute-voice-session-snapshot__header">
2785
- <span class="absolute-voice-session-snapshot__eyebrow">${escapeHtml6(model.title)}</span>
2786
- <strong class="absolute-voice-session-snapshot__label">${escapeHtml6(model.label)}</strong>
2970
+ <span class="absolute-voice-session-snapshot__eyebrow">${escapeHtml7(model.title)}</span>
2971
+ <strong class="absolute-voice-session-snapshot__label">${escapeHtml7(model.label)}</strong>
2787
2972
  </header>
2788
- <p class="absolute-voice-session-snapshot__description">${escapeHtml6(model.description)}</p>
2789
- ${model.showDownload ? `<button class="absolute-voice-session-snapshot__download" data-absolute-voice-session-snapshot-download type="button">${escapeHtml6(options.downloadLabel ?? DEFAULT_DOWNLOAD_LABEL)}</button>` : ""}
2973
+ <p class="absolute-voice-session-snapshot__description">${escapeHtml7(model.description)}</p>
2974
+ ${model.showDownload ? `<button class="absolute-voice-session-snapshot__download" data-absolute-voice-session-snapshot-download type="button">${escapeHtml7(options.downloadLabel ?? DEFAULT_DOWNLOAD_LABEL)}</button>` : ""}
2790
2975
  ${rows}
2791
2976
  ${artifacts}
2792
- ${model.error ? `<p class="absolute-voice-session-snapshot__error">${escapeHtml6(model.error)}</p>` : ""}
2977
+ ${model.error ? `<p class="absolute-voice-session-snapshot__error">${escapeHtml7(model.error)}</p>` : ""}
2793
2978
  </section>`;
2794
2979
  };
2795
2980
  var downloadBlob = (blob, filename) => {
@@ -3111,7 +3296,7 @@ var createVoiceProviderSimulationControlsStore = (options) => {
3111
3296
  };
3112
3297
 
3113
3298
  // src/client/providerSimulationControlsWidget.ts
3114
- var escapeHtml7 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
3299
+ var escapeHtml8 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
3115
3300
  var formatKind = (kind) => (kind ?? "stt").toUpperCase();
3116
3301
  var createVoiceProviderSimulationControlsViewModel = (snapshot, options) => {
3117
3302
  const configuredProviders = options.providers.filter((provider) => provider.configured !== false);
@@ -3131,18 +3316,18 @@ var createVoiceProviderSimulationControlsViewModel = (snapshot, options) => {
3131
3316
  };
3132
3317
  var renderVoiceProviderSimulationControlsHTML = (snapshot, options) => {
3133
3318
  const model = createVoiceProviderSimulationControlsViewModel(snapshot, options);
3134
- const failureButtons = model.failureProviders.map((provider) => `<button type="button" data-voice-provider-fail="${escapeHtml7(provider.provider)}"${!model.canSimulateFailure || snapshot.isRunning ? " disabled" : ""}>Simulate ${escapeHtml7(provider.provider)} ${escapeHtml7(formatKind(options.kind))} failure</button>`).join("");
3135
- const recoveryButtons = model.providers.map((provider) => `<button type="button" data-voice-provider-recover="${escapeHtml7(provider.provider)}"${snapshot.isRunning ? " disabled" : ""}>Mark ${escapeHtml7(provider.provider)} recovered</button>`).join("");
3319
+ const failureButtons = model.failureProviders.map((provider) => `<button type="button" data-voice-provider-fail="${escapeHtml8(provider.provider)}"${!model.canSimulateFailure || snapshot.isRunning ? " disabled" : ""}>Simulate ${escapeHtml8(provider.provider)} ${escapeHtml8(formatKind(options.kind))} failure</button>`).join("");
3320
+ const recoveryButtons = model.providers.map((provider) => `<button type="button" data-voice-provider-recover="${escapeHtml8(provider.provider)}"${snapshot.isRunning ? " disabled" : ""}>Mark ${escapeHtml8(provider.provider)} recovered</button>`).join("");
3136
3321
  return `<section class="absolute-voice-provider-simulation absolute-voice-provider-simulation--${snapshot.error ? "error" : snapshot.isRunning ? "running" : "ready"}">
3137
3322
  <header class="absolute-voice-provider-simulation__header">
3138
- <span class="absolute-voice-provider-simulation__eyebrow">${escapeHtml7(model.title)}</span>
3139
- <strong class="absolute-voice-provider-simulation__label">${escapeHtml7(model.label)}</strong>
3323
+ <span class="absolute-voice-provider-simulation__eyebrow">${escapeHtml8(model.title)}</span>
3324
+ <strong class="absolute-voice-provider-simulation__label">${escapeHtml8(model.label)}</strong>
3140
3325
  </header>
3141
- <p class="absolute-voice-provider-simulation__description">${escapeHtml7(model.description)}</p>
3142
- ${model.canSimulateFailure ? "" : `<p class="absolute-voice-provider-simulation__empty">${escapeHtml7(options.fallbackRequiredMessage ?? "Configure fallback providers before simulating failure.")}</p>`}
3326
+ <p class="absolute-voice-provider-simulation__description">${escapeHtml8(model.description)}</p>
3327
+ ${model.canSimulateFailure ? "" : `<p class="absolute-voice-provider-simulation__empty">${escapeHtml8(options.fallbackRequiredMessage ?? "Configure fallback providers before simulating failure.")}</p>`}
3143
3328
  <div class="absolute-voice-provider-simulation__actions">${failureButtons}${recoveryButtons}</div>
3144
- ${snapshot.error ? `<p class="absolute-voice-provider-simulation__error">${escapeHtml7(snapshot.error)}</p>` : ""}
3145
- ${model.resultText ? `<pre class="absolute-voice-provider-simulation__result">${escapeHtml7(model.resultText)}</pre>` : ""}
3329
+ ${snapshot.error ? `<p class="absolute-voice-provider-simulation__error">${escapeHtml8(snapshot.error)}</p>` : ""}
3330
+ ${model.resultText ? `<pre class="absolute-voice-provider-simulation__result">${escapeHtml8(model.resultText)}</pre>` : ""}
3146
3331
  </section>`;
3147
3332
  };
3148
3333
  var bindVoiceProviderSimulationControls = (element, store) => {
@@ -3297,9 +3482,9 @@ var createVoiceProviderCapabilitiesStore = (path = "/api/provider-capabilities",
3297
3482
  };
3298
3483
 
3299
3484
  // src/client/providerCapabilitiesWidget.ts
3300
- var DEFAULT_TITLE5 = "Provider Capabilities";
3301
- var DEFAULT_DESCRIPTION5 = "Configured, selected, and healthy voice providers for this deployment.";
3302
- var escapeHtml8 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
3485
+ var DEFAULT_TITLE6 = "Provider Capabilities";
3486
+ var DEFAULT_DESCRIPTION6 = "Configured, selected, and healthy voice providers for this deployment.";
3487
+ var escapeHtml9 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
3303
3488
  var formatProvider = (provider) => provider.split(/[-_\s]+/).filter(Boolean).map((part) => `${part[0]?.toUpperCase() ?? ""}${part.slice(1)}`).join(" ") || provider;
3304
3489
  var formatKind2 = (kind) => kind.toUpperCase();
3305
3490
  var formatStatus2 = (status) => status.split("-").map((part) => `${part[0]?.toUpperCase() ?? ""}${part.slice(1)}`).join(" ");
@@ -3343,36 +3528,36 @@ var createVoiceProviderCapabilitiesViewModel = (snapshot, options = {}) => {
3343
3528
  const selectedCount = snapshot.report?.selected ?? capabilities.filter((capability) => capability.selected).length;
3344
3529
  return {
3345
3530
  capabilities,
3346
- description: options.description ?? DEFAULT_DESCRIPTION5,
3531
+ description: options.description ?? DEFAULT_DESCRIPTION6,
3347
3532
  error: snapshot.error,
3348
3533
  isLoading: snapshot.isLoading,
3349
3534
  label: snapshot.error ? "Unavailable" : capabilities.length ? warningCount > 0 ? `${warningCount} needs attention` : `${selectedCount} selected` : snapshot.isLoading ? "Checking" : "No capabilities",
3350
3535
  status: snapshot.error ? "error" : capabilities.length ? warningCount > 0 ? "warning" : "ready" : snapshot.isLoading ? "loading" : "empty",
3351
- title: options.title ?? DEFAULT_TITLE5,
3536
+ title: options.title ?? DEFAULT_TITLE6,
3352
3537
  updatedAt: snapshot.updatedAt
3353
3538
  };
3354
3539
  };
3355
3540
  var renderVoiceProviderCapabilitiesHTML = (snapshot, options = {}) => {
3356
3541
  const model = createVoiceProviderCapabilitiesViewModel(snapshot, options);
3357
- 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--${escapeHtml8(capability.status)}">
3542
+ 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--${escapeHtml9(capability.status)}">
3358
3543
  <header>
3359
- <strong>${escapeHtml8(capability.label)}</strong>
3360
- <span>${escapeHtml8(formatStatus2(capability.status))}</span>
3544
+ <strong>${escapeHtml9(capability.label)}</strong>
3545
+ <span>${escapeHtml9(formatStatus2(capability.status))}</span>
3361
3546
  </header>
3362
- <p>${escapeHtml8(capability.detail)}</p>
3547
+ <p>${escapeHtml9(capability.detail)}</p>
3363
3548
  <dl>${capability.rows.map((row) => `<div>
3364
- <dt>${escapeHtml8(row.label)}</dt>
3365
- <dd>${escapeHtml8(row.value)}</dd>
3549
+ <dt>${escapeHtml9(row.label)}</dt>
3550
+ <dd>${escapeHtml9(row.value)}</dd>
3366
3551
  </div>`).join("")}</dl>
3367
3552
  </article>`).join("")}</div>` : '<p class="absolute-voice-provider-capabilities__empty">Configure provider capabilities to see deployment coverage.</p>';
3368
- return `<section class="absolute-voice-provider-capabilities absolute-voice-provider-capabilities--${escapeHtml8(model.status)}">
3553
+ return `<section class="absolute-voice-provider-capabilities absolute-voice-provider-capabilities--${escapeHtml9(model.status)}">
3369
3554
  <header class="absolute-voice-provider-capabilities__header">
3370
- <span class="absolute-voice-provider-capabilities__eyebrow">${escapeHtml8(model.title)}</span>
3371
- <strong class="absolute-voice-provider-capabilities__label">${escapeHtml8(model.label)}</strong>
3555
+ <span class="absolute-voice-provider-capabilities__eyebrow">${escapeHtml9(model.title)}</span>
3556
+ <strong class="absolute-voice-provider-capabilities__label">${escapeHtml9(model.label)}</strong>
3372
3557
  </header>
3373
- <p class="absolute-voice-provider-capabilities__description">${escapeHtml8(model.description)}</p>
3558
+ <p class="absolute-voice-provider-capabilities__description">${escapeHtml9(model.description)}</p>
3374
3559
  ${capabilities}
3375
- ${model.error ? `<p class="absolute-voice-provider-capabilities__error">${escapeHtml8(model.error)}</p>` : ""}
3560
+ ${model.error ? `<p class="absolute-voice-provider-capabilities__error">${escapeHtml9(model.error)}</p>` : ""}
3376
3561
  </section>`;
3377
3562
  };
3378
3563
  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}`;
@@ -3498,9 +3683,9 @@ var createVoiceProviderContractsStore = (path = "/api/provider-contracts", optio
3498
3683
  };
3499
3684
 
3500
3685
  // src/client/providerContractsWidget.ts
3501
- var DEFAULT_TITLE6 = "Provider Contracts";
3502
- var DEFAULT_DESCRIPTION6 = "Production contract coverage for provider env, latency, fallback, streaming, and capabilities.";
3503
- var escapeHtml9 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
3686
+ var DEFAULT_TITLE7 = "Provider Contracts";
3687
+ var DEFAULT_DESCRIPTION7 = "Production contract coverage for provider env, latency, fallback, streaming, and capabilities.";
3688
+ var escapeHtml10 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
3504
3689
  var formatProvider2 = (provider) => provider.split(/[-_\s]+/).filter(Boolean).map((part) => `${part[0]?.toUpperCase() ?? ""}${part.slice(1)}`).join(" ") || provider;
3505
3690
  var formatStatus3 = (status) => status.split("-").map((part) => `${part[0]?.toUpperCase() ?? ""}${part.slice(1)}`).join(" ");
3506
3691
  var contractDetail = (row) => {
@@ -3532,38 +3717,38 @@ var createVoiceProviderContractsViewModel = (snapshot, options = {}) => {
3532
3717
  }));
3533
3718
  const warningCount = snapshot.report ? snapshot.report.failed + snapshot.report.warned : rows.filter((row) => row.status !== "pass").length;
3534
3719
  return {
3535
- description: options.description ?? DEFAULT_DESCRIPTION6,
3720
+ description: options.description ?? DEFAULT_DESCRIPTION7,
3536
3721
  error: snapshot.error,
3537
3722
  isLoading: snapshot.isLoading,
3538
3723
  label: snapshot.error ? "Unavailable" : rows.length ? warningCount > 0 ? `${warningCount} needs attention` : `${rows.length} passing` : snapshot.isLoading ? "Checking" : "No contracts",
3539
3724
  rows,
3540
3725
  status: snapshot.error ? "error" : rows.length ? warningCount > 0 ? "warning" : "ready" : snapshot.isLoading ? "loading" : "empty",
3541
- title: options.title ?? DEFAULT_TITLE6,
3726
+ title: options.title ?? DEFAULT_TITLE7,
3542
3727
  updatedAt: snapshot.updatedAt
3543
3728
  };
3544
3729
  };
3545
3730
  var renderVoiceProviderContractsHTML = (snapshot, options = {}) => {
3546
3731
  const model = createVoiceProviderContractsViewModel(snapshot, options);
3547
- const rows = model.rows.length ? `<div class="absolute-voice-provider-contracts__rows">${model.rows.map((row) => `<article class="absolute-voice-provider-contracts__row absolute-voice-provider-contracts__row--${escapeHtml9(row.status)}">
3732
+ const rows = model.rows.length ? `<div class="absolute-voice-provider-contracts__rows">${model.rows.map((row) => `<article class="absolute-voice-provider-contracts__row absolute-voice-provider-contracts__row--${escapeHtml10(row.status)}">
3548
3733
  <header>
3549
- <strong>${escapeHtml9(row.label)}</strong>
3550
- <span>${escapeHtml9(formatStatus3(row.status))}</span>
3734
+ <strong>${escapeHtml10(row.label)}</strong>
3735
+ <span>${escapeHtml10(formatStatus3(row.status))}</span>
3551
3736
  </header>
3552
- <p>${escapeHtml9(row.detail)}</p>
3553
- ${row.remediations.length ? `<ul class="absolute-voice-provider-contracts__remediations">${row.remediations.map((remediation) => `<li>${remediation.href ? `<a href="${escapeHtml9(remediation.href)}">${escapeHtml9(remediation.label)}</a>` : `<strong>${escapeHtml9(remediation.label)}</strong>`}<span>${escapeHtml9(remediation.detail)}</span></li>`).join("")}</ul>` : ""}
3737
+ <p>${escapeHtml10(row.detail)}</p>
3738
+ ${row.remediations.length ? `<ul class="absolute-voice-provider-contracts__remediations">${row.remediations.map((remediation) => `<li>${remediation.href ? `<a href="${escapeHtml10(remediation.href)}">${escapeHtml10(remediation.label)}</a>` : `<strong>${escapeHtml10(remediation.label)}</strong>`}<span>${escapeHtml10(remediation.detail)}</span></li>`).join("")}</ul>` : ""}
3554
3739
  <dl>${row.rows.map((item) => `<div>
3555
- <dt>${escapeHtml9(item.label)}</dt>
3556
- <dd>${escapeHtml9(item.value)}</dd>
3740
+ <dt>${escapeHtml10(item.label)}</dt>
3741
+ <dd>${escapeHtml10(item.value)}</dd>
3557
3742
  </div>`).join("")}</dl>
3558
3743
  </article>`).join("")}</div>` : '<p class="absolute-voice-provider-contracts__empty">Configure provider contracts to see production coverage.</p>';
3559
- return `<section class="absolute-voice-provider-contracts absolute-voice-provider-contracts--${escapeHtml9(model.status)}">
3744
+ return `<section class="absolute-voice-provider-contracts absolute-voice-provider-contracts--${escapeHtml10(model.status)}">
3560
3745
  <header class="absolute-voice-provider-contracts__header">
3561
- <span class="absolute-voice-provider-contracts__eyebrow">${escapeHtml9(model.title)}</span>
3562
- <strong class="absolute-voice-provider-contracts__label">${escapeHtml9(model.label)}</strong>
3746
+ <span class="absolute-voice-provider-contracts__eyebrow">${escapeHtml10(model.title)}</span>
3747
+ <strong class="absolute-voice-provider-contracts__label">${escapeHtml10(model.label)}</strong>
3563
3748
  </header>
3564
- <p class="absolute-voice-provider-contracts__description">${escapeHtml9(model.description)}</p>
3749
+ <p class="absolute-voice-provider-contracts__description">${escapeHtml10(model.description)}</p>
3565
3750
  ${rows}
3566
- ${model.error ? `<p class="absolute-voice-provider-contracts__error">${escapeHtml9(model.error)}</p>` : ""}
3751
+ ${model.error ? `<p class="absolute-voice-provider-contracts__error">${escapeHtml10(model.error)}</p>` : ""}
3567
3752
  </section>`;
3568
3753
  };
3569
3754
  var getVoiceProviderContractsCSS = () => `.absolute-voice-provider-contracts{border:1px solid #b8dcc7;border-radius:20px;background:#f7fff9;color:#09140d;padding:18px;box-shadow:0 18px 40px rgba(21,83,45,.12);font-family:inherit}.absolute-voice-provider-contracts--error,.absolute-voice-provider-contracts--warning{border-color:#f2a7a7;background:#fff7f4}.absolute-voice-provider-contracts__header,.absolute-voice-provider-contracts__row header{align-items:start;display:flex;gap:12px;justify-content:space-between}.absolute-voice-provider-contracts__eyebrow{color:#166534;font-size:12px;font-weight:800;letter-spacing:.08em;text-transform:uppercase}.absolute-voice-provider-contracts__label{font-size:24px;line-height:1}.absolute-voice-provider-contracts__description,.absolute-voice-provider-contracts__row p,.absolute-voice-provider-contracts__row dt,.absolute-voice-provider-contracts__empty{color:#405448}.absolute-voice-provider-contracts__rows{display:grid;gap:12px;margin-top:14px}.absolute-voice-provider-contracts__row{background:#fff;border:1px solid #d6eadb;border-radius:16px;padding:14px}.absolute-voice-provider-contracts__row--pass{border-color:#86efac}.absolute-voice-provider-contracts__row--warn,.absolute-voice-provider-contracts__row--fail{border-color:#f2a7a7}.absolute-voice-provider-contracts__row p{margin:10px 0}.absolute-voice-provider-contracts__remediations{display:grid;gap:8px;list-style:none;margin:0 0 10px;padding:0}.absolute-voice-provider-contracts__remediations li{background:#fff7ed;border:1px solid #fed7aa;border-radius:12px;display:grid;gap:3px;padding:8px}.absolute-voice-provider-contracts__remediations a,.absolute-voice-provider-contracts__remediations strong{color:#9a3412}.absolute-voice-provider-contracts__remediations span{color:#7c2d12}.absolute-voice-provider-contracts__row dl{display:grid;gap:8px;grid-template-columns:repeat(2,minmax(0,1fr));margin:0}.absolute-voice-provider-contracts__row div{background:#f7fff9;border:1px solid #d6eadb;border-radius:12px;padding:8px}.absolute-voice-provider-contracts__row dt{font-size:12px}.absolute-voice-provider-contracts__row dd{font-weight:800;margin:4px 0 0}.absolute-voice-provider-contracts__error{color:#9f1239;font-weight:700}`;
@@ -5086,9 +5271,9 @@ var createVoiceProviderStatusStore = (path = "/api/provider-status", options = {
5086
5271
  };
5087
5272
 
5088
5273
  // src/client/providerStatusWidget.ts
5089
- var DEFAULT_TITLE7 = "Voice Providers";
5090
- var DEFAULT_DESCRIPTION7 = "Live provider health, fallback counts, latency, and suppression state from your self-hosted trace store.";
5091
- var escapeHtml10 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
5274
+ var DEFAULT_TITLE8 = "Voice Providers";
5275
+ var DEFAULT_DESCRIPTION8 = "Live provider health, fallback counts, latency, and suppression state from your self-hosted trace store.";
5276
+ var escapeHtml11 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
5092
5277
  var formatProvider3 = (provider) => provider.split(/[-_\s]+/).filter(Boolean).map((part) => `${part[0]?.toUpperCase() ?? ""}${part.slice(1)}`).join(" ") || provider;
5093
5278
  var formatStatus4 = (status) => status.split("-").map((part) => `${part[0]?.toUpperCase() ?? ""}${part.slice(1)}`).join(" ");
5094
5279
  var formatLatency = (value) => typeof value === "number" ? `${value}ms` : "No samples";
@@ -5132,37 +5317,37 @@ var createVoiceProviderStatusViewModel = (snapshot, options = {}) => {
5132
5317
  const warningCount = providers.filter((provider) => isWarningStatus2(provider.status)).length;
5133
5318
  const healthyCount = providers.filter((provider) => provider.status === "healthy").length;
5134
5319
  return {
5135
- description: options.description ?? DEFAULT_DESCRIPTION7,
5320
+ description: options.description ?? DEFAULT_DESCRIPTION8,
5136
5321
  error: snapshot.error,
5137
5322
  isLoading: snapshot.isLoading,
5138
5323
  label: snapshot.error ? "Unavailable" : providers.length ? warningCount > 0 ? `${warningCount} needs attention` : `${healthyCount} healthy` : snapshot.isLoading ? "Checking" : "No provider traffic",
5139
5324
  providers,
5140
5325
  status: snapshot.error ? "error" : providers.length ? warningCount > 0 ? "warning" : "ready" : snapshot.isLoading ? "loading" : "empty",
5141
- title: options.title ?? DEFAULT_TITLE7,
5326
+ title: options.title ?? DEFAULT_TITLE8,
5142
5327
  updatedAt: snapshot.updatedAt
5143
5328
  };
5144
5329
  };
5145
5330
  var renderVoiceProviderStatusHTML = (snapshot, options = {}) => {
5146
5331
  const model = createVoiceProviderStatusViewModel(snapshot, options);
5147
- 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--${escapeHtml10(provider.status)}">
5332
+ 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--${escapeHtml11(provider.status)}">
5148
5333
  <header>
5149
- <strong>${escapeHtml10(provider.label)}</strong>
5150
- <span>${escapeHtml10(formatStatus4(provider.status))}</span>
5334
+ <strong>${escapeHtml11(provider.label)}</strong>
5335
+ <span>${escapeHtml11(formatStatus4(provider.status))}</span>
5151
5336
  </header>
5152
- <p>${escapeHtml10(provider.detail)}</p>
5337
+ <p>${escapeHtml11(provider.detail)}</p>
5153
5338
  <dl>${provider.rows.map((row) => `<div>
5154
- <dt>${escapeHtml10(row.label)}</dt>
5155
- <dd>${escapeHtml10(row.value)}</dd>
5339
+ <dt>${escapeHtml11(row.label)}</dt>
5340
+ <dd>${escapeHtml11(row.value)}</dd>
5156
5341
  </div>`).join("")}</dl>
5157
5342
  </article>`).join("")}</div>` : '<p class="absolute-voice-provider-status__empty">Run voice traffic to see provider health.</p>';
5158
- return `<section class="absolute-voice-provider-status absolute-voice-provider-status--${escapeHtml10(model.status)}">
5343
+ return `<section class="absolute-voice-provider-status absolute-voice-provider-status--${escapeHtml11(model.status)}">
5159
5344
  <header class="absolute-voice-provider-status__header">
5160
- <span class="absolute-voice-provider-status__eyebrow">${escapeHtml10(model.title)}</span>
5161
- <strong class="absolute-voice-provider-status__label">${escapeHtml10(model.label)}</strong>
5345
+ <span class="absolute-voice-provider-status__eyebrow">${escapeHtml11(model.title)}</span>
5346
+ <strong class="absolute-voice-provider-status__label">${escapeHtml11(model.label)}</strong>
5162
5347
  </header>
5163
- <p class="absolute-voice-provider-status__description">${escapeHtml10(model.description)}</p>
5348
+ <p class="absolute-voice-provider-status__description">${escapeHtml11(model.description)}</p>
5164
5349
  ${providers}
5165
- ${model.error ? `<p class="absolute-voice-provider-status__error">${escapeHtml10(model.error)}</p>` : ""}
5350
+ ${model.error ? `<p class="absolute-voice-provider-status__error">${escapeHtml11(model.error)}</p>` : ""}
5166
5351
  </section>`;
5167
5352
  };
5168
5353
  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}`;
@@ -5293,9 +5478,9 @@ var createVoiceRoutingStatusStore = (path = "/api/routing/latest", options = {})
5293
5478
  };
5294
5479
 
5295
5480
  // src/client/routingStatusWidget.ts
5296
- var DEFAULT_TITLE8 = "Voice Routing";
5297
- var DEFAULT_DESCRIPTION8 = "Latest provider routing decision from the self-hosted trace store.";
5298
- var escapeHtml11 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
5481
+ var DEFAULT_TITLE9 = "Voice Routing";
5482
+ var DEFAULT_DESCRIPTION9 = "Latest provider routing decision from the self-hosted trace store.";
5483
+ var escapeHtml12 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
5299
5484
  var formatValue = (value, fallback = "None") => typeof value === "string" && value.trim() ? value : typeof value === "number" && Number.isFinite(value) ? String(value) : fallback;
5300
5485
  var formatProviderRoutes = (routes) => routes && typeof routes === "object" ? Object.entries(routes).map(([role, provider]) => `${role}: ${formatValue(provider)}`).join(", ") || "None" : "None";
5301
5486
  var getProviderRoute = (routes, role) => routes && typeof routes === "object" ? formatValue(routes[role], "Not configured") : "Not configured";
@@ -5364,35 +5549,35 @@ var createVoiceRoutingStatusViewModel = (snapshot, options = {}) => {
5364
5549
  return {
5365
5550
  activeStack,
5366
5551
  decision,
5367
- description: options.description ?? DEFAULT_DESCRIPTION8,
5552
+ description: options.description ?? DEFAULT_DESCRIPTION9,
5368
5553
  error: snapshot.error,
5369
5554
  isLoading: snapshot.isLoading,
5370
5555
  label: snapshot.error ? "Unavailable" : decision ? `${formatValue(decision.kind).toUpperCase()} ${formatValue(decision.status, "unknown")}` : snapshot.isLoading ? "Checking" : "No routing yet",
5371
5556
  rows,
5372
5557
  status: snapshot.error ? "error" : decision ? "ready" : snapshot.isLoading ? "loading" : "empty",
5373
- title: options.title ?? DEFAULT_TITLE8,
5558
+ title: options.title ?? DEFAULT_TITLE9,
5374
5559
  updatedAt: snapshot.updatedAt
5375
5560
  };
5376
5561
  };
5377
5562
  var renderVoiceRoutingStatusHTML = (snapshot, options = {}) => {
5378
5563
  const model = createVoiceRoutingStatusViewModel(snapshot, options);
5379
5564
  const activeStack = model.activeStack.length ? `<div class="absolute-voice-routing-status__stack" aria-label="Active voice stack">${model.activeStack.map((item) => `<div>
5380
- <span>${escapeHtml11(item.label)}</span>
5381
- <strong>${escapeHtml11(item.value)}</strong>
5565
+ <span>${escapeHtml12(item.label)}</span>
5566
+ <strong>${escapeHtml12(item.value)}</strong>
5382
5567
  </div>`).join("")}</div>` : "";
5383
5568
  const rows = model.rows.length ? `<div class="absolute-voice-routing-status__grid">${model.rows.map((row) => `<div>
5384
- <span>${escapeHtml11(row.label)}</span>
5385
- <strong>${escapeHtml11(row.value)}</strong>
5569
+ <span>${escapeHtml12(row.label)}</span>
5570
+ <strong>${escapeHtml12(row.value)}</strong>
5386
5571
  </div>`).join("")}</div>` : '<p class="absolute-voice-routing-status__empty">Start a voice session to see the selected provider.</p>';
5387
- return `<section class="absolute-voice-routing-status absolute-voice-routing-status--${escapeHtml11(model.status)}">
5572
+ return `<section class="absolute-voice-routing-status absolute-voice-routing-status--${escapeHtml12(model.status)}">
5388
5573
  <header class="absolute-voice-routing-status__header">
5389
- <span class="absolute-voice-routing-status__eyebrow">${escapeHtml11(model.title)}</span>
5390
- <strong class="absolute-voice-routing-status__label">${escapeHtml11(model.label)}</strong>
5574
+ <span class="absolute-voice-routing-status__eyebrow">${escapeHtml12(model.title)}</span>
5575
+ <strong class="absolute-voice-routing-status__label">${escapeHtml12(model.label)}</strong>
5391
5576
  </header>
5392
- <p class="absolute-voice-routing-status__description">${escapeHtml11(model.description)}</p>
5577
+ <p class="absolute-voice-routing-status__description">${escapeHtml12(model.description)}</p>
5393
5578
  ${activeStack}
5394
5579
  ${rows}
5395
- ${model.error ? `<p class="absolute-voice-routing-status__error">${escapeHtml11(model.error)}</p>` : ""}
5580
+ ${model.error ? `<p class="absolute-voice-routing-status__error">${escapeHtml12(model.error)}</p>` : ""}
5396
5581
  </section>`;
5397
5582
  };
5398
5583
  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__stack{background:linear-gradient(135deg,#16130d,#49391f);border-radius:18px;color:#fff;display:grid;gap:8px;grid-template-columns:repeat(5,minmax(0,1fr));margin-top:14px;padding:12px}.absolute-voice-routing-status__stack div{border-left:1px solid rgba(255,255,255,.18);padding-left:10px}.absolute-voice-routing-status__stack div:first-child{border-left:0;padding-left:0}.absolute-voice-routing-status__stack span{color:#e9d9b8;display:block;font-size:11px;font-weight:800;letter-spacing:.08em;margin-bottom:5px;text-transform:uppercase}.absolute-voice-routing-status__stack strong{display:block;font-size:13px;line-height:1.25;overflow-wrap:anywhere}.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}@media (max-width:760px){.absolute-voice-routing-status__stack{grid-template-columns:repeat(2,minmax(0,1fr))}.absolute-voice-routing-status__stack div{border-left:0;border-top:1px solid rgba(255,255,255,.18);padding-left:0;padding-top:8px}.absolute-voice-routing-status__stack div:first-child{border-top:0;padding-top:0}}`;
@@ -5523,9 +5708,9 @@ var createVoiceTraceTimelineStore = (path = "/api/voice-traces", options = {}) =
5523
5708
  };
5524
5709
 
5525
5710
  // src/client/traceTimelineWidget.ts
5526
- var DEFAULT_TITLE9 = "Voice Traces";
5527
- var DEFAULT_DESCRIPTION9 = "Latest call timelines with provider latency, fallbacks, handoffs, and errors from your self-hosted trace store.";
5528
- var escapeHtml12 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
5711
+ var DEFAULT_TITLE10 = "Voice Traces";
5712
+ var DEFAULT_DESCRIPTION10 = "Latest call timelines with provider latency, fallbacks, handoffs, and errors from your self-hosted trace store.";
5713
+ var escapeHtml13 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
5529
5714
  var formatMs = (value) => typeof value === "number" ? `${value}ms` : "n/a";
5530
5715
  var formatProviders = (session) => session.providers.length ? session.providers.map((provider) => provider.provider).join(", ") : "No providers";
5531
5716
  var createVoiceTraceTimelineViewModel = (snapshot, options = {}) => {
@@ -5541,13 +5726,13 @@ var createVoiceTraceTimelineViewModel = (snapshot, options = {}) => {
5541
5726
  const failed = sessions.filter((session) => session.status === "failed").length;
5542
5727
  const warnings = sessions.filter((session) => session.status === "warning").length;
5543
5728
  return {
5544
- description: options.description ?? DEFAULT_DESCRIPTION9,
5729
+ description: options.description ?? DEFAULT_DESCRIPTION10,
5545
5730
  error: snapshot.error,
5546
5731
  isLoading: snapshot.isLoading,
5547
5732
  label: snapshot.error ? "Unavailable" : failed > 0 ? `${failed} failed` : warnings > 0 ? `${warnings} warning` : sessions.length ? `${sessions.length} recent` : snapshot.isLoading ? "Checking" : "No traces yet",
5548
5733
  sessions,
5549
5734
  status: snapshot.error ? "error" : failed > 0 ? "failed" : warnings > 0 ? "warning" : sessions.length ? "ready" : snapshot.isLoading ? "loading" : "empty",
5550
- title: options.title ?? DEFAULT_TITLE9,
5735
+ title: options.title ?? DEFAULT_TITLE10,
5551
5736
  updatedAt: snapshot.updatedAt
5552
5737
  };
5553
5738
  };
@@ -5555,27 +5740,27 @@ var renderVoiceTraceTimelineWidgetHTML = (snapshot, options = {}) => {
5555
5740
  const model = createVoiceTraceTimelineViewModel(snapshot, options);
5556
5741
  const sessions = model.sessions.length ? `<div class="absolute-voice-trace-timeline__sessions">${model.sessions.map((session) => {
5557
5742
  const supportLinks = [
5558
- `<a href="${escapeHtml12(session.detailHref)}">Open timeline</a>`,
5559
- session.operationsRecordHref ? `<a href="${escapeHtml12(session.operationsRecordHref)}">Open operations record</a>` : undefined,
5560
- session.incidentBundleHref ? `<a href="${escapeHtml12(session.incidentBundleHref)}">Export incident bundle</a>` : undefined
5743
+ `<a href="${escapeHtml13(session.detailHref)}">Open timeline</a>`,
5744
+ session.operationsRecordHref ? `<a href="${escapeHtml13(session.operationsRecordHref)}">Open operations record</a>` : undefined,
5745
+ session.incidentBundleHref ? `<a href="${escapeHtml13(session.incidentBundleHref)}">Export incident bundle</a>` : undefined
5561
5746
  ].filter(Boolean).join("");
5562
- return `<article class="absolute-voice-trace-timeline__session absolute-voice-trace-timeline__session--${escapeHtml12(session.status)}">
5747
+ return `<article class="absolute-voice-trace-timeline__session absolute-voice-trace-timeline__session--${escapeHtml13(session.status)}">
5563
5748
  <header>
5564
- <strong>${escapeHtml12(session.sessionId)}</strong>
5565
- <span>${escapeHtml12(session.status)}</span>
5749
+ <strong>${escapeHtml13(session.sessionId)}</strong>
5750
+ <span>${escapeHtml13(session.status)}</span>
5566
5751
  </header>
5567
- <p>${escapeHtml12(session.label)} \xB7 ${escapeHtml12(session.durationLabel)} \xB7 ${escapeHtml12(session.providerLabel)}</p>
5752
+ <p>${escapeHtml13(session.label)} \xB7 ${escapeHtml13(session.durationLabel)} \xB7 ${escapeHtml13(session.providerLabel)}</p>
5568
5753
  <p class="absolute-voice-trace-timeline__actions">${supportLinks}</p>
5569
5754
  </article>`;
5570
5755
  }).join("")}</div>` : '<p class="absolute-voice-trace-timeline__empty">Run a voice session to see call timelines.</p>';
5571
- return `<section class="absolute-voice-trace-timeline absolute-voice-trace-timeline--${escapeHtml12(model.status)}">
5756
+ return `<section class="absolute-voice-trace-timeline absolute-voice-trace-timeline--${escapeHtml13(model.status)}">
5572
5757
  <header class="absolute-voice-trace-timeline__header">
5573
- <span class="absolute-voice-trace-timeline__eyebrow">${escapeHtml12(model.title)}</span>
5574
- <strong class="absolute-voice-trace-timeline__label">${escapeHtml12(model.label)}</strong>
5758
+ <span class="absolute-voice-trace-timeline__eyebrow">${escapeHtml13(model.title)}</span>
5759
+ <strong class="absolute-voice-trace-timeline__label">${escapeHtml13(model.label)}</strong>
5575
5760
  </header>
5576
- <p class="absolute-voice-trace-timeline__description">${escapeHtml12(model.description)}</p>
5761
+ <p class="absolute-voice-trace-timeline__description">${escapeHtml13(model.description)}</p>
5577
5762
  ${sessions}
5578
- ${model.error ? `<p class="absolute-voice-trace-timeline__error">${escapeHtml12(model.error)}</p>` : ""}
5763
+ ${model.error ? `<p class="absolute-voice-trace-timeline__error">${escapeHtml13(model.error)}</p>` : ""}
5579
5764
  </section>`;
5580
5765
  };
5581
5766
  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__actions{display:flex;flex-wrap:wrap;gap:10px}.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}`;
@@ -5705,9 +5890,9 @@ var createVoiceAgentSquadStatusStore = (path = "/api/voice-traces", options = {}
5705
5890
  };
5706
5891
 
5707
5892
  // src/client/agentSquadStatusWidget.ts
5708
- var DEFAULT_TITLE10 = "Voice Agent Squad";
5709
- var DEFAULT_DESCRIPTION10 = "Current specialist and recent handoffs from your self-hosted voice traces.";
5710
- var escapeHtml13 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
5893
+ var DEFAULT_TITLE11 = "Voice Agent Squad";
5894
+ var DEFAULT_DESCRIPTION11 = "Current specialist and recent handoffs from your self-hosted voice traces.";
5895
+ var escapeHtml14 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
5711
5896
  var labelFor = (current) => {
5712
5897
  if (!current)
5713
5898
  return "Waiting for specialist activity";
@@ -5721,37 +5906,37 @@ var labelFor = (current) => {
5721
5906
  };
5722
5907
  var createVoiceAgentSquadStatusViewModel = (snapshot, options = {}) => ({
5723
5908
  current: snapshot.report.current,
5724
- description: options.description ?? DEFAULT_DESCRIPTION10,
5909
+ description: options.description ?? DEFAULT_DESCRIPTION11,
5725
5910
  error: snapshot.error,
5726
5911
  isLoading: snapshot.isLoading,
5727
5912
  label: snapshot.error ? "Unavailable" : labelFor(snapshot.report.current),
5728
5913
  sessionCount: snapshot.report.sessionCount,
5729
5914
  sessions: snapshot.report.sessions,
5730
- title: options.title ?? DEFAULT_TITLE10,
5915
+ title: options.title ?? DEFAULT_TITLE11,
5731
5916
  updatedAt: snapshot.updatedAt
5732
5917
  });
5733
5918
  var renderVoiceAgentSquadStatusHTML = (snapshot, options = {}) => {
5734
5919
  const model = createVoiceAgentSquadStatusViewModel(snapshot, options);
5735
5920
  const current = model.current;
5736
5921
  const rows = model.sessions.length ? model.sessions.slice(0, 5).map((session) => `<li>
5737
- <span>${escapeHtml13(session.sessionId)}</span>
5738
- <strong>${escapeHtml13(session.targetAgentId ?? "none")}</strong>
5739
- <em>${escapeHtml13(session.status)}</em>
5740
- ${session.summary || session.reason ? `<p>${escapeHtml13(session.summary ?? session.reason ?? "")}</p>` : ""}
5922
+ <span>${escapeHtml14(session.sessionId)}</span>
5923
+ <strong>${escapeHtml14(session.targetAgentId ?? "none")}</strong>
5924
+ <em>${escapeHtml14(session.status)}</em>
5925
+ ${session.summary || session.reason ? `<p>${escapeHtml14(session.summary ?? session.reason ?? "")}</p>` : ""}
5741
5926
  </li>`).join("") : "<li><span>No squad traces yet.</span><strong>Waiting</strong></li>";
5742
5927
  return `<section class="absolute-voice-agent-squad-status">
5743
5928
  <header>
5744
- <span>${escapeHtml13(model.title)}</span>
5745
- <strong>${escapeHtml13(model.label)}</strong>
5929
+ <span>${escapeHtml14(model.title)}</span>
5930
+ <strong>${escapeHtml14(model.label)}</strong>
5746
5931
  </header>
5747
- <p>${escapeHtml13(model.description)}</p>
5932
+ <p>${escapeHtml14(model.description)}</p>
5748
5933
  <div>
5749
- <span>Session</span><strong>${escapeHtml13(current?.sessionId ?? "n/a")}</strong>
5750
- <span>From</span><strong>${escapeHtml13(current?.fromAgentId ?? "n/a")}</strong>
5751
- <span>Status</span><strong>${escapeHtml13(current?.status ?? "idle")}</strong>
5934
+ <span>Session</span><strong>${escapeHtml14(current?.sessionId ?? "n/a")}</strong>
5935
+ <span>From</span><strong>${escapeHtml14(current?.fromAgentId ?? "n/a")}</strong>
5936
+ <span>Status</span><strong>${escapeHtml14(current?.status ?? "idle")}</strong>
5752
5937
  </div>
5753
5938
  <ul>${rows}</ul>
5754
- ${model.error ? `<p class="absolute-voice-agent-squad-status__error">${escapeHtml13(model.error)}</p>` : ""}
5939
+ ${model.error ? `<p class="absolute-voice-agent-squad-status__error">${escapeHtml14(model.error)}</p>` : ""}
5755
5940
  </section>`;
5756
5941
  };
5757
5942
  var getVoiceAgentSquadStatusCSS = () => `.absolute-voice-agent-squad-status{border:1px solid #38bdf866;border-radius:20px;background:#0f172a;color:#f8fafc;padding:18px;font-family:inherit}.absolute-voice-agent-squad-status header{display:grid;gap:4px}.absolute-voice-agent-squad-status header span{color:#7dd3fc;font-size:12px;font-weight:900;letter-spacing:.08em;text-transform:uppercase}.absolute-voice-agent-squad-status header strong{font-size:20px}.absolute-voice-agent-squad-status p{color:#cbd5e1}.absolute-voice-agent-squad-status div{display:grid;gap:6px;grid-template-columns:max-content 1fr;margin:14px 0}.absolute-voice-agent-squad-status div span{color:#94a3b8}.absolute-voice-agent-squad-status ul{display:grid;gap:8px;list-style:none;margin:0;padding:0}.absolute-voice-agent-squad-status li{background:#020617;border:1px solid #1e293b;border-radius:14px;padding:10px}.absolute-voice-agent-squad-status li span{color:#94a3b8;display:block;font-size:12px}.absolute-voice-agent-squad-status li strong{display:block}.absolute-voice-agent-squad-status li em{color:#7dd3fc;font-style:normal}.absolute-voice-agent-squad-status__error{color:#fecaca;font-weight:800}`;
@@ -5911,10 +6096,10 @@ var createVoiceTurnLatencyStore = (path = "/api/turn-latency", options = {}) =>
5911
6096
  };
5912
6097
 
5913
6098
  // src/client/turnLatencyWidget.ts
5914
- var DEFAULT_TITLE11 = "Turn Latency";
5915
- var DEFAULT_DESCRIPTION11 = "Per-turn timing from first transcript to commit and assistant response start.";
6099
+ var DEFAULT_TITLE12 = "Turn Latency";
6100
+ var DEFAULT_DESCRIPTION12 = "Per-turn timing from first transcript to commit and assistant response start.";
5916
6101
  var DEFAULT_PROOF_LABEL = "Run latency proof";
5917
- var escapeHtml14 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
6102
+ var escapeHtml15 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
5918
6103
  var formatMs2 = (value) => typeof value === "number" ? `${Math.round(value)}ms` : "n/a";
5919
6104
  var createVoiceTurnLatencyViewModel = (snapshot, options = {}) => {
5920
6105
  const turns = (snapshot.report?.turns ?? []).map((turn) => ({
@@ -5928,39 +6113,39 @@ var createVoiceTurnLatencyViewModel = (snapshot, options = {}) => {
5928
6113
  const warningCount = snapshot.report?.warnings ?? turns.filter((turn) => turn.status === "warn").length;
5929
6114
  const failedCount = snapshot.report?.failed ?? turns.filter((turn) => turn.status === "fail").length;
5930
6115
  return {
5931
- description: options.description ?? DEFAULT_DESCRIPTION11,
6116
+ description: options.description ?? DEFAULT_DESCRIPTION12,
5932
6117
  error: snapshot.error,
5933
6118
  isLoading: snapshot.isLoading,
5934
6119
  label: snapshot.error ? "Unavailable" : turns.length ? failedCount > 0 ? `${failedCount} slow` : warningCount > 0 ? `${warningCount} warnings` : `avg ${formatMs2(snapshot.report?.averageTotalMs)}` : snapshot.isLoading ? "Checking" : "No turns",
5935
6120
  proofLabel: options.proofPath ? options.proofLabel ?? DEFAULT_PROOF_LABEL : undefined,
5936
6121
  showProofAction: Boolean(options.proofPath),
5937
6122
  status: snapshot.error ? "error" : turns.length ? failedCount > 0 || warningCount > 0 ? "warning" : "ready" : snapshot.isLoading ? "loading" : "empty",
5938
- title: options.title ?? DEFAULT_TITLE11,
6123
+ title: options.title ?? DEFAULT_TITLE12,
5939
6124
  turns,
5940
6125
  updatedAt: snapshot.updatedAt
5941
6126
  };
5942
6127
  };
5943
6128
  var renderVoiceTurnLatencyHTML = (snapshot, options = {}) => {
5944
6129
  const model = createVoiceTurnLatencyViewModel(snapshot, options);
5945
- 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--${escapeHtml14(turn.status)}">
6130
+ 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--${escapeHtml15(turn.status)}">
5946
6131
  <header>
5947
- <strong>${escapeHtml14(turn.label)}</strong>
5948
- <span>${escapeHtml14(turn.status)}</span>
6132
+ <strong>${escapeHtml15(turn.label)}</strong>
6133
+ <span>${escapeHtml15(turn.status)}</span>
5949
6134
  </header>
5950
6135
  <dl>${turn.rows.map((row) => `<div>
5951
- <dt>${escapeHtml14(row.label)}</dt>
5952
- <dd>${escapeHtml14(row.value)}</dd>
6136
+ <dt>${escapeHtml15(row.label)}</dt>
6137
+ <dd>${escapeHtml15(row.value)}</dd>
5953
6138
  </div>`).join("")}</dl>
5954
6139
  </article>`).join("")}</div>` : '<p class="absolute-voice-turn-latency__empty">Complete a voice turn to see latency diagnostics.</p>';
5955
- return `<section class="absolute-voice-turn-latency absolute-voice-turn-latency--${escapeHtml14(model.status)}">
6140
+ return `<section class="absolute-voice-turn-latency absolute-voice-turn-latency--${escapeHtml15(model.status)}">
5956
6141
  <header class="absolute-voice-turn-latency__header">
5957
- <span class="absolute-voice-turn-latency__eyebrow">${escapeHtml14(model.title)}</span>
5958
- <strong class="absolute-voice-turn-latency__label">${escapeHtml14(model.label)}</strong>
6142
+ <span class="absolute-voice-turn-latency__eyebrow">${escapeHtml15(model.title)}</span>
6143
+ <strong class="absolute-voice-turn-latency__label">${escapeHtml15(model.label)}</strong>
5959
6144
  </header>
5960
- <p class="absolute-voice-turn-latency__description">${escapeHtml14(model.description)}</p>
5961
- ${model.showProofAction ? `<button class="absolute-voice-turn-latency__proof" data-absolute-voice-turn-latency-proof type="button">${escapeHtml14(model.proofLabel ?? DEFAULT_PROOF_LABEL)}</button>` : ""}
6145
+ <p class="absolute-voice-turn-latency__description">${escapeHtml15(model.description)}</p>
6146
+ ${model.showProofAction ? `<button class="absolute-voice-turn-latency__proof" data-absolute-voice-turn-latency-proof type="button">${escapeHtml15(model.proofLabel ?? DEFAULT_PROOF_LABEL)}</button>` : ""}
5962
6147
  ${turns}
5963
- ${model.error ? `<p class="absolute-voice-turn-latency__error">${escapeHtml14(model.error)}</p>` : ""}
6148
+ ${model.error ? `<p class="absolute-voice-turn-latency__error">${escapeHtml15(model.error)}</p>` : ""}
5964
6149
  </section>`;
5965
6150
  };
5966
6151
  var mountVoiceTurnLatency = (element, path = "/api/turn-latency", options = {}) => {
@@ -6099,9 +6284,9 @@ var createVoiceTurnQualityStore = (path = "/api/turn-quality", options = {}) =>
6099
6284
  };
6100
6285
 
6101
6286
  // src/client/turnQualityWidget.ts
6102
- var DEFAULT_TITLE12 = "Turn Quality";
6103
- var DEFAULT_DESCRIPTION12 = "Per-turn STT confidence, fallback selection, corrections, and transcript coverage.";
6104
- var escapeHtml15 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
6287
+ var DEFAULT_TITLE13 = "Turn Quality";
6288
+ var DEFAULT_DESCRIPTION13 = "Per-turn STT confidence, fallback selection, corrections, and transcript coverage.";
6289
+ var escapeHtml16 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
6105
6290
  var formatConfidence = (value) => typeof value === "number" ? `${Math.round(value * 100)}%` : "n/a";
6106
6291
  var formatMaybe = (value) => value === undefined || value === "" ? "n/a" : String(value);
6107
6292
  var getTurnDetail = (turn) => {
@@ -6139,37 +6324,37 @@ var createVoiceTurnQualityViewModel = (snapshot, options = {}) => {
6139
6324
  const warningCount = snapshot.report?.warnings ?? turns.filter((turn) => turn.status === "warn").length;
6140
6325
  const failedCount = snapshot.report?.failed ?? turns.filter((turn) => turn.status === "fail").length;
6141
6326
  return {
6142
- description: options.description ?? DEFAULT_DESCRIPTION12,
6327
+ description: options.description ?? DEFAULT_DESCRIPTION13,
6143
6328
  error: snapshot.error,
6144
6329
  isLoading: snapshot.isLoading,
6145
6330
  label: snapshot.error ? "Unavailable" : turns.length ? failedCount > 0 ? `${failedCount} failed` : warningCount > 0 ? `${warningCount} warnings` : `${turns.length} healthy` : snapshot.isLoading ? "Checking" : "No turns",
6146
6331
  status: snapshot.error ? "error" : turns.length ? failedCount > 0 || warningCount > 0 ? "warning" : "ready" : snapshot.isLoading ? "loading" : "empty",
6147
- title: options.title ?? DEFAULT_TITLE12,
6332
+ title: options.title ?? DEFAULT_TITLE13,
6148
6333
  turns,
6149
6334
  updatedAt: snapshot.updatedAt
6150
6335
  };
6151
6336
  };
6152
6337
  var renderVoiceTurnQualityHTML = (snapshot, options = {}) => {
6153
6338
  const model = createVoiceTurnQualityViewModel(snapshot, options);
6154
- 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--${escapeHtml15(turn.status)}">
6339
+ 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--${escapeHtml16(turn.status)}">
6155
6340
  <header>
6156
- <strong>${escapeHtml15(turn.label)}</strong>
6157
- <span>${escapeHtml15(turn.status)}</span>
6341
+ <strong>${escapeHtml16(turn.label)}</strong>
6342
+ <span>${escapeHtml16(turn.status)}</span>
6158
6343
  </header>
6159
- <p>${escapeHtml15(turn.detail)}</p>
6344
+ <p>${escapeHtml16(turn.detail)}</p>
6160
6345
  <dl>${turn.rows.map((row) => `<div>
6161
- <dt>${escapeHtml15(row.label)}</dt>
6162
- <dd>${escapeHtml15(row.value)}</dd>
6346
+ <dt>${escapeHtml16(row.label)}</dt>
6347
+ <dd>${escapeHtml16(row.value)}</dd>
6163
6348
  </div>`).join("")}</dl>
6164
6349
  </article>`).join("")}</div>` : '<p class="absolute-voice-turn-quality__empty">Complete a voice turn to see STT quality diagnostics.</p>';
6165
- return `<section class="absolute-voice-turn-quality absolute-voice-turn-quality--${escapeHtml15(model.status)}">
6350
+ return `<section class="absolute-voice-turn-quality absolute-voice-turn-quality--${escapeHtml16(model.status)}">
6166
6351
  <header class="absolute-voice-turn-quality__header">
6167
- <span class="absolute-voice-turn-quality__eyebrow">${escapeHtml15(model.title)}</span>
6168
- <strong class="absolute-voice-turn-quality__label">${escapeHtml15(model.label)}</strong>
6352
+ <span class="absolute-voice-turn-quality__eyebrow">${escapeHtml16(model.title)}</span>
6353
+ <strong class="absolute-voice-turn-quality__label">${escapeHtml16(model.label)}</strong>
6169
6354
  </header>
6170
- <p class="absolute-voice-turn-quality__description">${escapeHtml15(model.description)}</p>
6355
+ <p class="absolute-voice-turn-quality__description">${escapeHtml16(model.description)}</p>
6171
6356
  ${turns}
6172
- ${model.error ? `<p class="absolute-voice-turn-quality__error">${escapeHtml15(model.error)}</p>` : ""}
6357
+ ${model.error ? `<p class="absolute-voice-turn-quality__error">${escapeHtml16(model.error)}</p>` : ""}
6173
6358
  </section>`;
6174
6359
  };
6175
6360
  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}`;
@@ -6967,5 +7152,6 @@ export {
6967
7152
  createVoiceDeliveryRuntime,
6968
7153
  createVoiceController,
6969
7154
  createVoiceCampaignDialerProof,
7155
+ createVoiceCallDebugger,
6970
7156
  createVoiceAgentSquadStatus
6971
7157
  };