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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -2062,6 +2062,84 @@ var createVoiceOpsStatusStore = (path = "/api/voice/ops-status", options = {}) =
2062
2062
  }
2063
2063
  };
2064
2064
  };
2065
+ // src/client/deliveryRuntime.ts
2066
+ var fetchVoiceDeliveryRuntime = async (path = "/api/voice-delivery-runtime", options = {}) => {
2067
+ const fetchImpl = options.fetch ?? globalThis.fetch;
2068
+ const response = await fetchImpl(path);
2069
+ if (!response.ok) {
2070
+ throw new Error(`Voice delivery runtime failed: HTTP ${response.status}`);
2071
+ }
2072
+ return await response.json();
2073
+ };
2074
+ var createVoiceDeliveryRuntimeStore = (path = "/api/voice-delivery-runtime", options = {}) => {
2075
+ const listeners = new Set;
2076
+ let closed = false;
2077
+ let timer;
2078
+ let snapshot = {
2079
+ error: null,
2080
+ isLoading: false
2081
+ };
2082
+ const emit = () => {
2083
+ for (const listener of listeners) {
2084
+ listener();
2085
+ }
2086
+ };
2087
+ const refresh = async () => {
2088
+ if (closed) {
2089
+ return snapshot.report;
2090
+ }
2091
+ snapshot = {
2092
+ ...snapshot,
2093
+ error: null,
2094
+ isLoading: true
2095
+ };
2096
+ emit();
2097
+ try {
2098
+ const report = await fetchVoiceDeliveryRuntime(path, options);
2099
+ snapshot = {
2100
+ error: null,
2101
+ isLoading: false,
2102
+ report,
2103
+ updatedAt: Date.now()
2104
+ };
2105
+ emit();
2106
+ return report;
2107
+ } catch (error) {
2108
+ snapshot = {
2109
+ ...snapshot,
2110
+ error: error instanceof Error ? error.message : String(error),
2111
+ isLoading: false
2112
+ };
2113
+ emit();
2114
+ throw error;
2115
+ }
2116
+ };
2117
+ const close = () => {
2118
+ closed = true;
2119
+ if (timer) {
2120
+ clearInterval(timer);
2121
+ timer = undefined;
2122
+ }
2123
+ listeners.clear();
2124
+ };
2125
+ if (typeof window !== "undefined" && options.intervalMs && options.intervalMs > 0) {
2126
+ timer = setInterval(() => {
2127
+ refresh().catch(() => {});
2128
+ }, options.intervalMs);
2129
+ }
2130
+ return {
2131
+ close,
2132
+ getServerSnapshot: () => snapshot,
2133
+ getSnapshot: () => snapshot,
2134
+ refresh,
2135
+ subscribe: (listener) => {
2136
+ listeners.add(listener);
2137
+ return () => {
2138
+ listeners.delete(listener);
2139
+ };
2140
+ }
2141
+ };
2142
+ };
2065
2143
  // src/client/opsStatusWidget.ts
2066
2144
  var DEFAULT_TITLE = "Voice Ops Status";
2067
2145
  var DEFAULT_DESCRIPTION = "Certified workflow, provider, and handoff readiness from your AbsoluteJS voice app.";
@@ -2186,6 +2264,108 @@ var defineVoiceOpsStatusElement = (tagName = "absolute-voice-ops-status") => {
2186
2264
  }
2187
2265
  });
2188
2266
  };
2267
+ // src/client/deliveryRuntimeWidget.ts
2268
+ var DEFAULT_TITLE2 = "Voice Delivery Runtime";
2269
+ var DEFAULT_DESCRIPTION2 = "Audit and trace delivery worker health from your AbsoluteJS voice app.";
2270
+ var escapeHtml2 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
2271
+ var createSurface = (id, summary) => {
2272
+ if (!summary) {
2273
+ return {
2274
+ deadLettered: 0,
2275
+ detail: "Worker disabled",
2276
+ failed: 0,
2277
+ id,
2278
+ label: id === "audit" ? "Audit delivery" : "Trace delivery",
2279
+ pending: 0,
2280
+ status: "disabled",
2281
+ total: 0
2282
+ };
2283
+ }
2284
+ const blocked = summary.failed + summary.deadLettered;
2285
+ return {
2286
+ deadLettered: summary.deadLettered,
2287
+ detail: `${summary.delivered}/${summary.total} delivered, ${summary.pending} pending`,
2288
+ failed: summary.failed,
2289
+ id,
2290
+ label: id === "audit" ? "Audit delivery" : "Trace delivery",
2291
+ pending: summary.pending,
2292
+ status: blocked > 0 ? "warn" : "pass",
2293
+ total: summary.total
2294
+ };
2295
+ };
2296
+ var createVoiceDeliveryRuntimeViewModel = (snapshot, options = {}) => {
2297
+ const report = snapshot.report;
2298
+ const surfaces = [
2299
+ createSurface("audit", report?.summary.audit),
2300
+ createSurface("trace", report?.summary.trace)
2301
+ ];
2302
+ const hasWarnings = surfaces.some((surface) => surface.status === "warn");
2303
+ return {
2304
+ description: options.description ?? DEFAULT_DESCRIPTION2,
2305
+ error: snapshot.error,
2306
+ isLoading: snapshot.isLoading,
2307
+ isRunning: Boolean(report?.isRunning),
2308
+ label: snapshot.error ? "Unavailable" : report ? report.isRunning ? "Running" : "Stopped" : "Checking",
2309
+ status: snapshot.error ? "error" : report ? hasWarnings ? "warn" : "pass" : "loading",
2310
+ surfaces,
2311
+ title: options.title ?? DEFAULT_TITLE2,
2312
+ updatedAt: snapshot.updatedAt
2313
+ };
2314
+ };
2315
+ var renderVoiceDeliveryRuntimeHTML = (snapshot, options = {}) => {
2316
+ const model = createVoiceDeliveryRuntimeViewModel(snapshot, options);
2317
+ const surfaces = model.surfaces.map((surface) => `<li class="absolute-voice-delivery-runtime__surface absolute-voice-delivery-runtime__surface--${escapeHtml2(surface.status)}">
2318
+ <span>${escapeHtml2(surface.label)}</span>
2319
+ <strong>${escapeHtml2(surface.detail)}</strong>
2320
+ <small>${String(surface.failed)} failed &middot; ${String(surface.deadLettered)} dead-lettered</small>
2321
+ </li>`).join("");
2322
+ return `<section class="absolute-voice-delivery-runtime absolute-voice-delivery-runtime--${escapeHtml2(model.status)}">
2323
+ <header class="absolute-voice-delivery-runtime__header">
2324
+ <span class="absolute-voice-delivery-runtime__eyebrow">${escapeHtml2(model.title)}</span>
2325
+ <strong class="absolute-voice-delivery-runtime__label">${escapeHtml2(model.label)}</strong>
2326
+ </header>
2327
+ <p class="absolute-voice-delivery-runtime__description">${escapeHtml2(model.description)}</p>
2328
+ <ul class="absolute-voice-delivery-runtime__surfaces">${surfaces}</ul>
2329
+ ${model.error ? `<p class="absolute-voice-delivery-runtime__error">${escapeHtml2(model.error)}</p>` : ""}
2330
+ </section>`;
2331
+ };
2332
+ 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}`;
2333
+ var mountVoiceDeliveryRuntime = (element, path = "/api/voice-delivery-runtime", options = {}) => {
2334
+ const store = createVoiceDeliveryRuntimeStore(path, options);
2335
+ const render = () => {
2336
+ element.innerHTML = renderVoiceDeliveryRuntimeHTML(store.getSnapshot(), options);
2337
+ };
2338
+ const unsubscribe = store.subscribe(render);
2339
+ render();
2340
+ store.refresh().catch(() => {});
2341
+ return {
2342
+ close: () => {
2343
+ unsubscribe();
2344
+ store.close();
2345
+ },
2346
+ refresh: store.refresh
2347
+ };
2348
+ };
2349
+ var defineVoiceDeliveryRuntimeElement = (tagName = "absolute-voice-delivery-runtime") => {
2350
+ if (typeof window === "undefined" || typeof customElements === "undefined" || customElements.get(tagName)) {
2351
+ return;
2352
+ }
2353
+ customElements.define(tagName, class AbsoluteVoiceDeliveryRuntimeElement extends HTMLElement {
2354
+ mounted;
2355
+ connectedCallback() {
2356
+ const intervalMs = Number(this.getAttribute("interval-ms") ?? 5000);
2357
+ this.mounted = mountVoiceDeliveryRuntime(this, this.getAttribute("path") ?? "/api/voice-delivery-runtime", {
2358
+ description: this.getAttribute("description") ?? undefined,
2359
+ intervalMs: Number.isFinite(intervalMs) ? intervalMs : 5000,
2360
+ title: this.getAttribute("title") ?? undefined
2361
+ });
2362
+ }
2363
+ disconnectedCallback() {
2364
+ this.mounted?.close();
2365
+ this.mounted = undefined;
2366
+ }
2367
+ });
2368
+ };
2189
2369
  // src/client/routingStatus.ts
2190
2370
  var fetchVoiceRoutingStatus = async (path = "/api/routing/latest", options = {}) => {
2191
2371
  const fetchImpl = options.fetch ?? globalThis.fetch;
@@ -2266,9 +2446,9 @@ var createVoiceRoutingStatusStore = (path = "/api/routing/latest", options = {})
2266
2446
  };
2267
2447
  };
2268
2448
  // src/client/routingStatusWidget.ts
2269
- var DEFAULT_TITLE2 = "Voice Routing";
2270
- var DEFAULT_DESCRIPTION2 = "Latest provider routing decision from the self-hosted trace store.";
2271
- var escapeHtml2 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
2449
+ var DEFAULT_TITLE3 = "Voice Routing";
2450
+ var DEFAULT_DESCRIPTION3 = "Latest provider routing decision from the self-hosted trace store.";
2451
+ var escapeHtml3 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
2272
2452
  var formatValue = (value, fallback = "None") => typeof value === "string" && value.trim() ? value : typeof value === "number" && Number.isFinite(value) ? String(value) : fallback;
2273
2453
  var createVoiceRoutingStatusViewModel = (snapshot, options = {}) => {
2274
2454
  const decision = snapshot.decision;
@@ -2292,30 +2472,30 @@ var createVoiceRoutingStatusViewModel = (snapshot, options = {}) => {
2292
2472
  ] : [];
2293
2473
  return {
2294
2474
  decision,
2295
- description: options.description ?? DEFAULT_DESCRIPTION2,
2475
+ description: options.description ?? DEFAULT_DESCRIPTION3,
2296
2476
  error: snapshot.error,
2297
2477
  isLoading: snapshot.isLoading,
2298
2478
  label: snapshot.error ? "Unavailable" : decision ? `${formatValue(decision.kind).toUpperCase()} ${formatValue(decision.status, "unknown")}` : snapshot.isLoading ? "Checking" : "No routing yet",
2299
2479
  rows,
2300
2480
  status: snapshot.error ? "error" : decision ? "ready" : snapshot.isLoading ? "loading" : "empty",
2301
- title: options.title ?? DEFAULT_TITLE2,
2481
+ title: options.title ?? DEFAULT_TITLE3,
2302
2482
  updatedAt: snapshot.updatedAt
2303
2483
  };
2304
2484
  };
2305
2485
  var renderVoiceRoutingStatusHTML = (snapshot, options = {}) => {
2306
2486
  const model = createVoiceRoutingStatusViewModel(snapshot, options);
2307
2487
  const rows = model.rows.length ? `<div class="absolute-voice-routing-status__grid">${model.rows.map((row) => `<div>
2308
- <span>${escapeHtml2(row.label)}</span>
2309
- <strong>${escapeHtml2(row.value)}</strong>
2488
+ <span>${escapeHtml3(row.label)}</span>
2489
+ <strong>${escapeHtml3(row.value)}</strong>
2310
2490
  </div>`).join("")}</div>` : '<p class="absolute-voice-routing-status__empty">Start a voice session to see the selected provider.</p>';
2311
- return `<section class="absolute-voice-routing-status absolute-voice-routing-status--${escapeHtml2(model.status)}">
2491
+ return `<section class="absolute-voice-routing-status absolute-voice-routing-status--${escapeHtml3(model.status)}">
2312
2492
  <header class="absolute-voice-routing-status__header">
2313
- <span class="absolute-voice-routing-status__eyebrow">${escapeHtml2(model.title)}</span>
2314
- <strong class="absolute-voice-routing-status__label">${escapeHtml2(model.label)}</strong>
2493
+ <span class="absolute-voice-routing-status__eyebrow">${escapeHtml3(model.title)}</span>
2494
+ <strong class="absolute-voice-routing-status__label">${escapeHtml3(model.label)}</strong>
2315
2495
  </header>
2316
- <p class="absolute-voice-routing-status__description">${escapeHtml2(model.description)}</p>
2496
+ <p class="absolute-voice-routing-status__description">${escapeHtml3(model.description)}</p>
2317
2497
  ${rows}
2318
- ${model.error ? `<p class="absolute-voice-routing-status__error">${escapeHtml2(model.error)}</p>` : ""}
2498
+ ${model.error ? `<p class="absolute-voice-routing-status__error">${escapeHtml3(model.error)}</p>` : ""}
2319
2499
  </section>`;
2320
2500
  };
2321
2501
  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}`;
@@ -2967,7 +3147,7 @@ var createVoiceProviderSimulationControlsStore = (options) => {
2967
3147
  };
2968
3148
  };
2969
3149
  // src/client/providerSimulationControlsWidget.ts
2970
- var escapeHtml3 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
3150
+ var escapeHtml4 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
2971
3151
  var formatKind = (kind) => (kind ?? "stt").toUpperCase();
2972
3152
  var createVoiceProviderSimulationControlsViewModel = (snapshot, options) => {
2973
3153
  const configuredProviders = options.providers.filter((provider) => provider.configured !== false);
@@ -2987,18 +3167,18 @@ var createVoiceProviderSimulationControlsViewModel = (snapshot, options) => {
2987
3167
  };
2988
3168
  var renderVoiceProviderSimulationControlsHTML = (snapshot, options) => {
2989
3169
  const model = createVoiceProviderSimulationControlsViewModel(snapshot, options);
2990
- 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("");
2991
- 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("");
3170
+ 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("");
3171
+ 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("");
2992
3172
  return `<section class="absolute-voice-provider-simulation absolute-voice-provider-simulation--${snapshot.error ? "error" : snapshot.isRunning ? "running" : "ready"}">
2993
3173
  <header class="absolute-voice-provider-simulation__header">
2994
- <span class="absolute-voice-provider-simulation__eyebrow">${escapeHtml3(model.title)}</span>
2995
- <strong class="absolute-voice-provider-simulation__label">${escapeHtml3(model.label)}</strong>
3174
+ <span class="absolute-voice-provider-simulation__eyebrow">${escapeHtml4(model.title)}</span>
3175
+ <strong class="absolute-voice-provider-simulation__label">${escapeHtml4(model.label)}</strong>
2996
3176
  </header>
2997
- <p class="absolute-voice-provider-simulation__description">${escapeHtml3(model.description)}</p>
2998
- ${model.canSimulateFailure ? "" : `<p class="absolute-voice-provider-simulation__empty">${escapeHtml3(options.fallbackRequiredMessage ?? "Configure fallback providers before simulating failure.")}</p>`}
3177
+ <p class="absolute-voice-provider-simulation__description">${escapeHtml4(model.description)}</p>
3178
+ ${model.canSimulateFailure ? "" : `<p class="absolute-voice-provider-simulation__empty">${escapeHtml4(options.fallbackRequiredMessage ?? "Configure fallback providers before simulating failure.")}</p>`}
2999
3179
  <div class="absolute-voice-provider-simulation__actions">${failureButtons}${recoveryButtons}</div>
3000
- ${snapshot.error ? `<p class="absolute-voice-provider-simulation__error">${escapeHtml3(snapshot.error)}</p>` : ""}
3001
- ${model.resultText ? `<pre class="absolute-voice-provider-simulation__result">${escapeHtml3(model.resultText)}</pre>` : ""}
3180
+ ${snapshot.error ? `<p class="absolute-voice-provider-simulation__error">${escapeHtml4(snapshot.error)}</p>` : ""}
3181
+ ${model.resultText ? `<pre class="absolute-voice-provider-simulation__result">${escapeHtml4(model.resultText)}</pre>` : ""}
3002
3182
  </section>`;
3003
3183
  };
3004
3184
  var bindVoiceProviderSimulationControls = (element, store) => {
@@ -3063,9 +3243,9 @@ var defineVoiceProviderSimulationControlsElement = (tagName = "absolute-voice-pr
3063
3243
  });
3064
3244
  };
3065
3245
  // src/client/providerStatusWidget.ts
3066
- var DEFAULT_TITLE3 = "Voice Providers";
3067
- var DEFAULT_DESCRIPTION3 = "Live provider health, fallback counts, latency, and suppression state from your self-hosted trace store.";
3068
- var escapeHtml4 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
3246
+ var DEFAULT_TITLE4 = "Voice Providers";
3247
+ var DEFAULT_DESCRIPTION4 = "Live provider health, fallback counts, latency, and suppression state from your self-hosted trace store.";
3248
+ var escapeHtml5 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
3069
3249
  var formatProvider = (provider) => provider.split(/[-_\s]+/).filter(Boolean).map((part) => `${part[0]?.toUpperCase() ?? ""}${part.slice(1)}`).join(" ") || provider;
3070
3250
  var formatStatus = (status) => status.split("-").map((part) => `${part[0]?.toUpperCase() ?? ""}${part.slice(1)}`).join(" ");
3071
3251
  var formatLatency = (value) => typeof value === "number" ? `${value}ms` : "No samples";
@@ -3109,37 +3289,37 @@ var createVoiceProviderStatusViewModel = (snapshot, options = {}) => {
3109
3289
  const warningCount = providers.filter((provider) => isWarningStatus(provider.status)).length;
3110
3290
  const healthyCount = providers.filter((provider) => provider.status === "healthy").length;
3111
3291
  return {
3112
- description: options.description ?? DEFAULT_DESCRIPTION3,
3292
+ description: options.description ?? DEFAULT_DESCRIPTION4,
3113
3293
  error: snapshot.error,
3114
3294
  isLoading: snapshot.isLoading,
3115
3295
  label: snapshot.error ? "Unavailable" : providers.length ? warningCount > 0 ? `${warningCount} needs attention` : `${healthyCount} healthy` : snapshot.isLoading ? "Checking" : "No provider traffic",
3116
3296
  providers,
3117
3297
  status: snapshot.error ? "error" : providers.length ? warningCount > 0 ? "warning" : "ready" : snapshot.isLoading ? "loading" : "empty",
3118
- title: options.title ?? DEFAULT_TITLE3,
3298
+ title: options.title ?? DEFAULT_TITLE4,
3119
3299
  updatedAt: snapshot.updatedAt
3120
3300
  };
3121
3301
  };
3122
3302
  var renderVoiceProviderStatusHTML = (snapshot, options = {}) => {
3123
3303
  const model = createVoiceProviderStatusViewModel(snapshot, options);
3124
- const providers = model.providers.length ? `<div class="absolute-voice-provider-status__providers">${model.providers.map((provider) => `<article class="absolute-voice-provider-status__provider absolute-voice-provider-status__provider--${escapeHtml4(provider.status)}">
3304
+ 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)}">
3125
3305
  <header>
3126
- <strong>${escapeHtml4(provider.label)}</strong>
3127
- <span>${escapeHtml4(formatStatus(provider.status))}</span>
3306
+ <strong>${escapeHtml5(provider.label)}</strong>
3307
+ <span>${escapeHtml5(formatStatus(provider.status))}</span>
3128
3308
  </header>
3129
- <p>${escapeHtml4(provider.detail)}</p>
3309
+ <p>${escapeHtml5(provider.detail)}</p>
3130
3310
  <dl>${provider.rows.map((row) => `<div>
3131
- <dt>${escapeHtml4(row.label)}</dt>
3132
- <dd>${escapeHtml4(row.value)}</dd>
3311
+ <dt>${escapeHtml5(row.label)}</dt>
3312
+ <dd>${escapeHtml5(row.value)}</dd>
3133
3313
  </div>`).join("")}</dl>
3134
3314
  </article>`).join("")}</div>` : '<p class="absolute-voice-provider-status__empty">Run voice traffic to see provider health.</p>';
3135
- return `<section class="absolute-voice-provider-status absolute-voice-provider-status--${escapeHtml4(model.status)}">
3315
+ return `<section class="absolute-voice-provider-status absolute-voice-provider-status--${escapeHtml5(model.status)}">
3136
3316
  <header class="absolute-voice-provider-status__header">
3137
- <span class="absolute-voice-provider-status__eyebrow">${escapeHtml4(model.title)}</span>
3138
- <strong class="absolute-voice-provider-status__label">${escapeHtml4(model.label)}</strong>
3317
+ <span class="absolute-voice-provider-status__eyebrow">${escapeHtml5(model.title)}</span>
3318
+ <strong class="absolute-voice-provider-status__label">${escapeHtml5(model.label)}</strong>
3139
3319
  </header>
3140
- <p class="absolute-voice-provider-status__description">${escapeHtml4(model.description)}</p>
3320
+ <p class="absolute-voice-provider-status__description">${escapeHtml5(model.description)}</p>
3141
3321
  ${providers}
3142
- ${model.error ? `<p class="absolute-voice-provider-status__error">${escapeHtml4(model.error)}</p>` : ""}
3322
+ ${model.error ? `<p class="absolute-voice-provider-status__error">${escapeHtml5(model.error)}</p>` : ""}
3143
3323
  </section>`;
3144
3324
  };
3145
3325
  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}`;
@@ -3180,9 +3360,9 @@ var defineVoiceProviderStatusElement = (tagName = "absolute-voice-provider-statu
3180
3360
  });
3181
3361
  };
3182
3362
  // src/client/providerCapabilitiesWidget.ts
3183
- var DEFAULT_TITLE4 = "Provider Capabilities";
3184
- var DEFAULT_DESCRIPTION4 = "Configured, selected, and healthy voice providers for this deployment.";
3185
- var escapeHtml5 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
3363
+ var DEFAULT_TITLE5 = "Provider Capabilities";
3364
+ var DEFAULT_DESCRIPTION5 = "Configured, selected, and healthy voice providers for this deployment.";
3365
+ var escapeHtml6 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
3186
3366
  var formatProvider2 = (provider) => provider.split(/[-_\s]+/).filter(Boolean).map((part) => `${part[0]?.toUpperCase() ?? ""}${part.slice(1)}`).join(" ") || provider;
3187
3367
  var formatKind2 = (kind) => kind.toUpperCase();
3188
3368
  var formatStatus2 = (status) => status.split("-").map((part) => `${part[0]?.toUpperCase() ?? ""}${part.slice(1)}`).join(" ");
@@ -3226,36 +3406,36 @@ var createVoiceProviderCapabilitiesViewModel = (snapshot, options = {}) => {
3226
3406
  const selectedCount = snapshot.report?.selected ?? capabilities.filter((capability) => capability.selected).length;
3227
3407
  return {
3228
3408
  capabilities,
3229
- description: options.description ?? DEFAULT_DESCRIPTION4,
3409
+ description: options.description ?? DEFAULT_DESCRIPTION5,
3230
3410
  error: snapshot.error,
3231
3411
  isLoading: snapshot.isLoading,
3232
3412
  label: snapshot.error ? "Unavailable" : capabilities.length ? warningCount > 0 ? `${warningCount} needs attention` : `${selectedCount} selected` : snapshot.isLoading ? "Checking" : "No capabilities",
3233
3413
  status: snapshot.error ? "error" : capabilities.length ? warningCount > 0 ? "warning" : "ready" : snapshot.isLoading ? "loading" : "empty",
3234
- title: options.title ?? DEFAULT_TITLE4,
3414
+ title: options.title ?? DEFAULT_TITLE5,
3235
3415
  updatedAt: snapshot.updatedAt
3236
3416
  };
3237
3417
  };
3238
3418
  var renderVoiceProviderCapabilitiesHTML = (snapshot, options = {}) => {
3239
3419
  const model = createVoiceProviderCapabilitiesViewModel(snapshot, options);
3240
- 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)}">
3420
+ 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--${escapeHtml6(capability.status)}">
3241
3421
  <header>
3242
- <strong>${escapeHtml5(capability.label)}</strong>
3243
- <span>${escapeHtml5(formatStatus2(capability.status))}</span>
3422
+ <strong>${escapeHtml6(capability.label)}</strong>
3423
+ <span>${escapeHtml6(formatStatus2(capability.status))}</span>
3244
3424
  </header>
3245
- <p>${escapeHtml5(capability.detail)}</p>
3425
+ <p>${escapeHtml6(capability.detail)}</p>
3246
3426
  <dl>${capability.rows.map((row) => `<div>
3247
- <dt>${escapeHtml5(row.label)}</dt>
3248
- <dd>${escapeHtml5(row.value)}</dd>
3427
+ <dt>${escapeHtml6(row.label)}</dt>
3428
+ <dd>${escapeHtml6(row.value)}</dd>
3249
3429
  </div>`).join("")}</dl>
3250
3430
  </article>`).join("")}</div>` : '<p class="absolute-voice-provider-capabilities__empty">Configure provider capabilities to see deployment coverage.</p>';
3251
- return `<section class="absolute-voice-provider-capabilities absolute-voice-provider-capabilities--${escapeHtml5(model.status)}">
3431
+ return `<section class="absolute-voice-provider-capabilities absolute-voice-provider-capabilities--${escapeHtml6(model.status)}">
3252
3432
  <header class="absolute-voice-provider-capabilities__header">
3253
- <span class="absolute-voice-provider-capabilities__eyebrow">${escapeHtml5(model.title)}</span>
3254
- <strong class="absolute-voice-provider-capabilities__label">${escapeHtml5(model.label)}</strong>
3433
+ <span class="absolute-voice-provider-capabilities__eyebrow">${escapeHtml6(model.title)}</span>
3434
+ <strong class="absolute-voice-provider-capabilities__label">${escapeHtml6(model.label)}</strong>
3255
3435
  </header>
3256
- <p class="absolute-voice-provider-capabilities__description">${escapeHtml5(model.description)}</p>
3436
+ <p class="absolute-voice-provider-capabilities__description">${escapeHtml6(model.description)}</p>
3257
3437
  ${capabilities}
3258
- ${model.error ? `<p class="absolute-voice-provider-capabilities__error">${escapeHtml5(model.error)}</p>` : ""}
3438
+ ${model.error ? `<p class="absolute-voice-provider-capabilities__error">${escapeHtml6(model.error)}</p>` : ""}
3259
3439
  </section>`;
3260
3440
  };
3261
3441
  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}`;
@@ -3296,9 +3476,9 @@ var defineVoiceProviderCapabilitiesElement = (tagName = "absolute-voice-provider
3296
3476
  });
3297
3477
  };
3298
3478
  // src/client/turnQualityWidget.ts
3299
- var DEFAULT_TITLE5 = "Turn Quality";
3300
- var DEFAULT_DESCRIPTION5 = "Per-turn STT confidence, fallback selection, corrections, and transcript coverage.";
3301
- var escapeHtml6 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
3479
+ var DEFAULT_TITLE6 = "Turn Quality";
3480
+ var DEFAULT_DESCRIPTION6 = "Per-turn STT confidence, fallback selection, corrections, and transcript coverage.";
3481
+ var escapeHtml7 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
3302
3482
  var formatConfidence = (value) => typeof value === "number" ? `${Math.round(value * 100)}%` : "n/a";
3303
3483
  var formatMaybe = (value) => value === undefined || value === "" ? "n/a" : String(value);
3304
3484
  var getTurnDetail = (turn) => {
@@ -3336,37 +3516,37 @@ var createVoiceTurnQualityViewModel = (snapshot, options = {}) => {
3336
3516
  const warningCount = snapshot.report?.warnings ?? turns.filter((turn) => turn.status === "warn").length;
3337
3517
  const failedCount = snapshot.report?.failed ?? turns.filter((turn) => turn.status === "fail").length;
3338
3518
  return {
3339
- description: options.description ?? DEFAULT_DESCRIPTION5,
3519
+ description: options.description ?? DEFAULT_DESCRIPTION6,
3340
3520
  error: snapshot.error,
3341
3521
  isLoading: snapshot.isLoading,
3342
3522
  label: snapshot.error ? "Unavailable" : turns.length ? failedCount > 0 ? `${failedCount} failed` : warningCount > 0 ? `${warningCount} warnings` : `${turns.length} healthy` : snapshot.isLoading ? "Checking" : "No turns",
3343
3523
  status: snapshot.error ? "error" : turns.length ? failedCount > 0 || warningCount > 0 ? "warning" : "ready" : snapshot.isLoading ? "loading" : "empty",
3344
- title: options.title ?? DEFAULT_TITLE5,
3524
+ title: options.title ?? DEFAULT_TITLE6,
3345
3525
  turns,
3346
3526
  updatedAt: snapshot.updatedAt
3347
3527
  };
3348
3528
  };
3349
3529
  var renderVoiceTurnQualityHTML = (snapshot, options = {}) => {
3350
3530
  const model = createVoiceTurnQualityViewModel(snapshot, options);
3351
- 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--${escapeHtml6(turn.status)}">
3531
+ const turns = model.turns.length ? `<div class="absolute-voice-turn-quality__turns">${model.turns.map((turn) => `<article class="absolute-voice-turn-quality__turn absolute-voice-turn-quality__turn--${escapeHtml7(turn.status)}">
3352
3532
  <header>
3353
- <strong>${escapeHtml6(turn.label)}</strong>
3354
- <span>${escapeHtml6(turn.status)}</span>
3533
+ <strong>${escapeHtml7(turn.label)}</strong>
3534
+ <span>${escapeHtml7(turn.status)}</span>
3355
3535
  </header>
3356
- <p>${escapeHtml6(turn.detail)}</p>
3536
+ <p>${escapeHtml7(turn.detail)}</p>
3357
3537
  <dl>${turn.rows.map((row) => `<div>
3358
- <dt>${escapeHtml6(row.label)}</dt>
3359
- <dd>${escapeHtml6(row.value)}</dd>
3538
+ <dt>${escapeHtml7(row.label)}</dt>
3539
+ <dd>${escapeHtml7(row.value)}</dd>
3360
3540
  </div>`).join("")}</dl>
3361
3541
  </article>`).join("")}</div>` : '<p class="absolute-voice-turn-quality__empty">Complete a voice turn to see STT quality diagnostics.</p>';
3362
- return `<section class="absolute-voice-turn-quality absolute-voice-turn-quality--${escapeHtml6(model.status)}">
3542
+ return `<section class="absolute-voice-turn-quality absolute-voice-turn-quality--${escapeHtml7(model.status)}">
3363
3543
  <header class="absolute-voice-turn-quality__header">
3364
- <span class="absolute-voice-turn-quality__eyebrow">${escapeHtml6(model.title)}</span>
3365
- <strong class="absolute-voice-turn-quality__label">${escapeHtml6(model.label)}</strong>
3544
+ <span class="absolute-voice-turn-quality__eyebrow">${escapeHtml7(model.title)}</span>
3545
+ <strong class="absolute-voice-turn-quality__label">${escapeHtml7(model.label)}</strong>
3366
3546
  </header>
3367
- <p class="absolute-voice-turn-quality__description">${escapeHtml6(model.description)}</p>
3547
+ <p class="absolute-voice-turn-quality__description">${escapeHtml7(model.description)}</p>
3368
3548
  ${turns}
3369
- ${model.error ? `<p class="absolute-voice-turn-quality__error">${escapeHtml6(model.error)}</p>` : ""}
3549
+ ${model.error ? `<p class="absolute-voice-turn-quality__error">${escapeHtml7(model.error)}</p>` : ""}
3370
3550
  </section>`;
3371
3551
  };
3372
3552
  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}`;
@@ -3407,10 +3587,10 @@ var defineVoiceTurnQualityElement = (tagName = "absolute-voice-turn-quality") =>
3407
3587
  });
3408
3588
  };
3409
3589
  // src/client/turnLatencyWidget.ts
3410
- var DEFAULT_TITLE6 = "Turn Latency";
3411
- var DEFAULT_DESCRIPTION6 = "Per-turn timing from first transcript to commit and assistant response start.";
3590
+ var DEFAULT_TITLE7 = "Turn Latency";
3591
+ var DEFAULT_DESCRIPTION7 = "Per-turn timing from first transcript to commit and assistant response start.";
3412
3592
  var DEFAULT_PROOF_LABEL = "Run latency proof";
3413
- var escapeHtml7 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
3593
+ var escapeHtml8 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
3414
3594
  var formatMs = (value) => typeof value === "number" ? `${Math.round(value)}ms` : "n/a";
3415
3595
  var createVoiceTurnLatencyViewModel = (snapshot, options = {}) => {
3416
3596
  const turns = (snapshot.report?.turns ?? []).map((turn) => ({
@@ -3424,39 +3604,39 @@ var createVoiceTurnLatencyViewModel = (snapshot, options = {}) => {
3424
3604
  const warningCount = snapshot.report?.warnings ?? turns.filter((turn) => turn.status === "warn").length;
3425
3605
  const failedCount = snapshot.report?.failed ?? turns.filter((turn) => turn.status === "fail").length;
3426
3606
  return {
3427
- description: options.description ?? DEFAULT_DESCRIPTION6,
3607
+ description: options.description ?? DEFAULT_DESCRIPTION7,
3428
3608
  error: snapshot.error,
3429
3609
  isLoading: snapshot.isLoading,
3430
3610
  label: snapshot.error ? "Unavailable" : turns.length ? failedCount > 0 ? `${failedCount} slow` : warningCount > 0 ? `${warningCount} warnings` : `avg ${formatMs(snapshot.report?.averageTotalMs)}` : snapshot.isLoading ? "Checking" : "No turns",
3431
3611
  proofLabel: options.proofPath ? options.proofLabel ?? DEFAULT_PROOF_LABEL : undefined,
3432
3612
  showProofAction: Boolean(options.proofPath),
3433
3613
  status: snapshot.error ? "error" : turns.length ? failedCount > 0 || warningCount > 0 ? "warning" : "ready" : snapshot.isLoading ? "loading" : "empty",
3434
- title: options.title ?? DEFAULT_TITLE6,
3614
+ title: options.title ?? DEFAULT_TITLE7,
3435
3615
  turns,
3436
3616
  updatedAt: snapshot.updatedAt
3437
3617
  };
3438
3618
  };
3439
3619
  var renderVoiceTurnLatencyHTML = (snapshot, options = {}) => {
3440
3620
  const model = createVoiceTurnLatencyViewModel(snapshot, options);
3441
- const turns = model.turns.length ? `<div class="absolute-voice-turn-latency__turns">${model.turns.map((turn) => `<article class="absolute-voice-turn-latency__turn absolute-voice-turn-latency__turn--${escapeHtml7(turn.status)}">
3621
+ 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)}">
3442
3622
  <header>
3443
- <strong>${escapeHtml7(turn.label)}</strong>
3444
- <span>${escapeHtml7(turn.status)}</span>
3623
+ <strong>${escapeHtml8(turn.label)}</strong>
3624
+ <span>${escapeHtml8(turn.status)}</span>
3445
3625
  </header>
3446
3626
  <dl>${turn.rows.map((row) => `<div>
3447
- <dt>${escapeHtml7(row.label)}</dt>
3448
- <dd>${escapeHtml7(row.value)}</dd>
3627
+ <dt>${escapeHtml8(row.label)}</dt>
3628
+ <dd>${escapeHtml8(row.value)}</dd>
3449
3629
  </div>`).join("")}</dl>
3450
3630
  </article>`).join("")}</div>` : '<p class="absolute-voice-turn-latency__empty">Complete a voice turn to see latency diagnostics.</p>';
3451
- return `<section class="absolute-voice-turn-latency absolute-voice-turn-latency--${escapeHtml7(model.status)}">
3631
+ return `<section class="absolute-voice-turn-latency absolute-voice-turn-latency--${escapeHtml8(model.status)}">
3452
3632
  <header class="absolute-voice-turn-latency__header">
3453
- <span class="absolute-voice-turn-latency__eyebrow">${escapeHtml7(model.title)}</span>
3454
- <strong class="absolute-voice-turn-latency__label">${escapeHtml7(model.label)}</strong>
3633
+ <span class="absolute-voice-turn-latency__eyebrow">${escapeHtml8(model.title)}</span>
3634
+ <strong class="absolute-voice-turn-latency__label">${escapeHtml8(model.label)}</strong>
3455
3635
  </header>
3456
- <p class="absolute-voice-turn-latency__description">${escapeHtml7(model.description)}</p>
3457
- ${model.showProofAction ? `<button class="absolute-voice-turn-latency__proof" data-absolute-voice-turn-latency-proof type="button">${escapeHtml7(model.proofLabel ?? DEFAULT_PROOF_LABEL)}</button>` : ""}
3636
+ <p class="absolute-voice-turn-latency__description">${escapeHtml8(model.description)}</p>
3637
+ ${model.showProofAction ? `<button class="absolute-voice-turn-latency__proof" data-absolute-voice-turn-latency-proof type="button">${escapeHtml8(model.proofLabel ?? DEFAULT_PROOF_LABEL)}</button>` : ""}
3458
3638
  ${turns}
3459
- ${model.error ? `<p class="absolute-voice-turn-latency__error">${escapeHtml7(model.error)}</p>` : ""}
3639
+ ${model.error ? `<p class="absolute-voice-turn-latency__error">${escapeHtml8(model.error)}</p>` : ""}
3460
3640
  </section>`;
3461
3641
  };
3462
3642
  var mountVoiceTurnLatency = (element, path = "/api/turn-latency", options = {}) => {
@@ -3506,9 +3686,9 @@ var defineVoiceTurnLatencyElement = (tagName = "absolute-voice-turn-latency") =>
3506
3686
  });
3507
3687
  };
3508
3688
  // src/client/traceTimelineWidget.ts
3509
- var DEFAULT_TITLE7 = "Voice Traces";
3510
- var DEFAULT_DESCRIPTION7 = "Latest call timelines with provider latency, fallbacks, handoffs, and errors from your self-hosted trace store.";
3511
- var escapeHtml8 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
3689
+ var DEFAULT_TITLE8 = "Voice Traces";
3690
+ var DEFAULT_DESCRIPTION8 = "Latest call timelines with provider latency, fallbacks, handoffs, and errors from your self-hosted trace store.";
3691
+ var escapeHtml9 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
3512
3692
  var formatMs2 = (value) => typeof value === "number" ? `${value}ms` : "n/a";
3513
3693
  var formatProviders = (session) => session.providers.length ? session.providers.map((provider) => provider.provider).join(", ") : "No providers";
3514
3694
  var createVoiceTraceTimelineViewModel = (snapshot, options = {}) => {
@@ -3522,34 +3702,34 @@ var createVoiceTraceTimelineViewModel = (snapshot, options = {}) => {
3522
3702
  const failed = sessions.filter((session) => session.status === "failed").length;
3523
3703
  const warnings = sessions.filter((session) => session.status === "warning").length;
3524
3704
  return {
3525
- description: options.description ?? DEFAULT_DESCRIPTION7,
3705
+ description: options.description ?? DEFAULT_DESCRIPTION8,
3526
3706
  error: snapshot.error,
3527
3707
  isLoading: snapshot.isLoading,
3528
3708
  label: snapshot.error ? "Unavailable" : failed > 0 ? `${failed} failed` : warnings > 0 ? `${warnings} warning` : sessions.length ? `${sessions.length} recent` : snapshot.isLoading ? "Checking" : "No traces yet",
3529
3709
  sessions,
3530
3710
  status: snapshot.error ? "error" : failed > 0 ? "failed" : warnings > 0 ? "warning" : sessions.length ? "ready" : snapshot.isLoading ? "loading" : "empty",
3531
- title: options.title ?? DEFAULT_TITLE7,
3711
+ title: options.title ?? DEFAULT_TITLE8,
3532
3712
  updatedAt: snapshot.updatedAt
3533
3713
  };
3534
3714
  };
3535
3715
  var renderVoiceTraceTimelineWidgetHTML = (snapshot, options = {}) => {
3536
3716
  const model = createVoiceTraceTimelineViewModel(snapshot, options);
3537
- 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)}">
3717
+ 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--${escapeHtml9(session.status)}">
3538
3718
  <header>
3539
- <strong>${escapeHtml8(session.sessionId)}</strong>
3540
- <span>${escapeHtml8(session.status)}</span>
3719
+ <strong>${escapeHtml9(session.sessionId)}</strong>
3720
+ <span>${escapeHtml9(session.status)}</span>
3541
3721
  </header>
3542
- <p>${escapeHtml8(session.label)} \xB7 ${escapeHtml8(session.durationLabel)} \xB7 ${escapeHtml8(session.providerLabel)}</p>
3543
- <a href="${escapeHtml8(session.detailHref)}">Open timeline</a>
3722
+ <p>${escapeHtml9(session.label)} \xB7 ${escapeHtml9(session.durationLabel)} \xB7 ${escapeHtml9(session.providerLabel)}</p>
3723
+ <a href="${escapeHtml9(session.detailHref)}">Open timeline</a>
3544
3724
  </article>`).join("")}</div>` : '<p class="absolute-voice-trace-timeline__empty">Run a voice session to see call timelines.</p>';
3545
- return `<section class="absolute-voice-trace-timeline absolute-voice-trace-timeline--${escapeHtml8(model.status)}">
3725
+ return `<section class="absolute-voice-trace-timeline absolute-voice-trace-timeline--${escapeHtml9(model.status)}">
3546
3726
  <header class="absolute-voice-trace-timeline__header">
3547
- <span class="absolute-voice-trace-timeline__eyebrow">${escapeHtml8(model.title)}</span>
3548
- <strong class="absolute-voice-trace-timeline__label">${escapeHtml8(model.label)}</strong>
3727
+ <span class="absolute-voice-trace-timeline__eyebrow">${escapeHtml9(model.title)}</span>
3728
+ <strong class="absolute-voice-trace-timeline__label">${escapeHtml9(model.label)}</strong>
3549
3729
  </header>
3550
- <p class="absolute-voice-trace-timeline__description">${escapeHtml8(model.description)}</p>
3730
+ <p class="absolute-voice-trace-timeline__description">${escapeHtml9(model.description)}</p>
3551
3731
  ${sessions}
3552
- ${model.error ? `<p class="absolute-voice-trace-timeline__error">${escapeHtml8(model.error)}</p>` : ""}
3732
+ ${model.error ? `<p class="absolute-voice-trace-timeline__error">${escapeHtml9(model.error)}</p>` : ""}
3553
3733
  </section>`;
3554
3734
  };
3555
3735
  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}`;
@@ -3681,6 +3861,7 @@ export {
3681
3861
  renderVoiceProviderSimulationControlsHTML,
3682
3862
  renderVoiceProviderCapabilitiesHTML,
3683
3863
  renderVoiceOpsStatusHTML,
3864
+ renderVoiceDeliveryRuntimeHTML,
3684
3865
  mountVoiceTurnQuality,
3685
3866
  mountVoiceTurnLatency,
3686
3867
  mountVoiceTraceTimeline,
@@ -3689,6 +3870,7 @@ export {
3689
3870
  mountVoiceProviderSimulationControls,
3690
3871
  mountVoiceProviderCapabilities,
3691
3872
  mountVoiceOpsStatus,
3873
+ mountVoiceDeliveryRuntime,
3692
3874
  getVoiceTurnQualityCSS,
3693
3875
  getVoiceTraceTimelineCSS,
3694
3876
  getVoiceRoutingStatusCSS,
@@ -3696,6 +3878,7 @@ export {
3696
3878
  getVoiceProviderCapabilitiesCSS,
3697
3879
  getVoiceOpsStatusLabel,
3698
3880
  getVoiceOpsStatusCSS,
3881
+ getVoiceDeliveryRuntimeCSS,
3699
3882
  fetchVoiceWorkflowStatus,
3700
3883
  fetchVoiceTurnQuality,
3701
3884
  fetchVoiceTurnLatency,
@@ -3704,6 +3887,7 @@ export {
3704
3887
  fetchVoiceProviderStatus,
3705
3888
  fetchVoiceProviderCapabilities,
3706
3889
  fetchVoiceOpsStatus,
3890
+ fetchVoiceDeliveryRuntime,
3707
3891
  fetchVoiceCampaignDialerProofStatus,
3708
3892
  defineVoiceTurnQualityElement,
3709
3893
  defineVoiceTurnLatencyElement,
@@ -3713,6 +3897,7 @@ export {
3713
3897
  defineVoiceProviderSimulationControlsElement,
3714
3898
  defineVoiceProviderCapabilitiesElement,
3715
3899
  defineVoiceOpsStatusElement,
3900
+ defineVoiceDeliveryRuntimeElement,
3716
3901
  decodeVoiceAudioChunk,
3717
3902
  createVoiceWorkflowStatusStore,
3718
3903
  createVoiceTurnQualityViewModel,
@@ -3734,6 +3919,8 @@ export {
3734
3919
  createVoiceOpsStatusStore,
3735
3920
  createVoiceLiveTurnLatencyMonitor,
3736
3921
  createVoiceDuplexController,
3922
+ createVoiceDeliveryRuntimeViewModel,
3923
+ createVoiceDeliveryRuntimeStore,
3737
3924
  createVoiceController,
3738
3925
  createVoiceConnection,
3739
3926
  createVoiceCampaignDialerProofStore,