@absolutejs/voice 0.0.22-beta.459 → 0.0.22-beta.460

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.
@@ -3235,6 +3235,176 @@ var createVoiceSessionSnapshot = (path, options = {}) => {
3235
3235
  getViewModel: () => createVoiceSessionSnapshotViewModel(store.getSnapshot(), options)
3236
3236
  };
3237
3237
  };
3238
+ // src/client/sessionObservability.ts
3239
+ var fetchVoiceSessionObservability = async (path, options = {}) => {
3240
+ const fetchImpl = options.fetch ?? globalThis.fetch;
3241
+ const response = await fetchImpl(path);
3242
+ if (!response.ok) {
3243
+ throw new Error(`Voice session observability failed: HTTP ${response.status}`);
3244
+ }
3245
+ return await response.json();
3246
+ };
3247
+ var createVoiceSessionObservabilityStore = (path, options = {}) => {
3248
+ const listeners = new Set;
3249
+ let closed = false;
3250
+ let timer;
3251
+ let snapshot = {
3252
+ error: null,
3253
+ isLoading: false,
3254
+ report: null
3255
+ };
3256
+ const emit = () => {
3257
+ for (const listener of listeners) {
3258
+ listener();
3259
+ }
3260
+ };
3261
+ const refresh = async () => {
3262
+ if (closed) {
3263
+ return snapshot.report;
3264
+ }
3265
+ snapshot = {
3266
+ ...snapshot,
3267
+ error: null,
3268
+ isLoading: true
3269
+ };
3270
+ emit();
3271
+ try {
3272
+ const report = await fetchVoiceSessionObservability(path, options);
3273
+ snapshot = {
3274
+ error: null,
3275
+ isLoading: false,
3276
+ report,
3277
+ updatedAt: Date.now()
3278
+ };
3279
+ emit();
3280
+ return report;
3281
+ } catch (error) {
3282
+ snapshot = {
3283
+ ...snapshot,
3284
+ error: error instanceof Error ? error.message : String(error),
3285
+ isLoading: false
3286
+ };
3287
+ emit();
3288
+ throw error;
3289
+ }
3290
+ };
3291
+ const close = () => {
3292
+ closed = true;
3293
+ if (timer) {
3294
+ clearInterval(timer);
3295
+ timer = undefined;
3296
+ }
3297
+ listeners.clear();
3298
+ };
3299
+ if (options.intervalMs && options.intervalMs > 0) {
3300
+ timer = setInterval(() => {
3301
+ refresh().catch(() => {});
3302
+ }, options.intervalMs);
3303
+ }
3304
+ return {
3305
+ close,
3306
+ getServerSnapshot: () => snapshot,
3307
+ getSnapshot: () => snapshot,
3308
+ refresh,
3309
+ subscribe: (listener) => {
3310
+ listeners.add(listener);
3311
+ return () => {
3312
+ listeners.delete(listener);
3313
+ };
3314
+ }
3315
+ };
3316
+ };
3317
+
3318
+ // src/client/sessionObservabilityWidget.ts
3319
+ var DEFAULT_TITLE6 = "Session Observability";
3320
+ var DEFAULT_DESCRIPTION6 = "One support/debug report for a voice call across traces, provider recovery, tools, handoffs, guardrails, turn waterfalls, and incident handoff.";
3321
+ var escapeHtml8 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
3322
+ var formatMs = (value) => typeof value === "number" ? `${value}ms` : "n/a";
3323
+ var createVoiceSessionObservabilityViewModel = (snapshot, options = {}) => {
3324
+ const report = snapshot.report;
3325
+ const turns = (report?.turns ?? []).slice(0, options.maxTurns ?? 3).map((turn) => ({
3326
+ ...turn,
3327
+ durationLabel: formatMs(turn.durationMs),
3328
+ label: `${turn.transcripts} transcripts / ${turn.toolCalls} tools / ${turn.providerDecisions} provider decisions`
3329
+ }));
3330
+ return {
3331
+ description: options.description ?? DEFAULT_DESCRIPTION6,
3332
+ error: snapshot.error,
3333
+ isLoading: snapshot.isLoading,
3334
+ label: snapshot.error ? "Unavailable" : report ? `${report.summary.turns} turns / ${report.summary.fallbacks} fallbacks / ${report.summary.errors} errors` : snapshot.isLoading ? "Checking" : "No session loaded",
3335
+ links: report?.links ?? [],
3336
+ sessionId: report?.sessionId,
3337
+ status: snapshot.error ? "error" : report?.status === "failed" ? "failed" : report?.status === "warning" ? "warning" : report ? "ready" : snapshot.isLoading ? "loading" : "empty",
3338
+ title: options.title ?? DEFAULT_TITLE6,
3339
+ turns,
3340
+ updatedAt: snapshot.updatedAt
3341
+ };
3342
+ };
3343
+ var renderLinks = (links) => links.length ? `<p class="absolute-voice-session-observability__actions">${links.map((link) => `<a href="${escapeHtml8(link.href)}">${escapeHtml8(link.label)}</a>`).join("")}</p>` : "";
3344
+ var renderVoiceSessionObservabilityHTML = (snapshot, options = {}) => {
3345
+ const model = createVoiceSessionObservabilityViewModel(snapshot, options);
3346
+ const turns = model.turns.length ? `<div class="absolute-voice-session-observability__turns">${model.turns.map((turn) => `<article class="absolute-voice-session-observability__turn"><header><strong>${escapeHtml8(turn.turnId)}</strong><span>${escapeHtml8(turn.durationLabel)}</span></header><p>${escapeHtml8(turn.label)}</p></article>`).join("")}</div>` : '<p class="absolute-voice-session-observability__empty">Open a voice session to see turn waterfalls.</p>';
3347
+ return `<section class="absolute-voice-session-observability absolute-voice-session-observability--${escapeHtml8(model.status)}">
3348
+ <header class="absolute-voice-session-observability__header">
3349
+ <span class="absolute-voice-session-observability__eyebrow">${escapeHtml8(model.title)}</span>
3350
+ <strong class="absolute-voice-session-observability__label">${escapeHtml8(model.label)}</strong>
3351
+ </header>
3352
+ <p class="absolute-voice-session-observability__description">${escapeHtml8(model.description)}</p>
3353
+ ${model.sessionId ? `<p class="absolute-voice-session-observability__session">${escapeHtml8(model.sessionId)}</p>` : ""}
3354
+ ${renderLinks(model.links)}
3355
+ ${turns}
3356
+ ${model.error ? `<p class="absolute-voice-session-observability__error">${escapeHtml8(model.error)}</p>` : ""}
3357
+ </section>`;
3358
+ };
3359
+ var getVoiceSessionObservabilityCSS = () => `.absolute-voice-session-observability{border:1px solid #c8d9bf;border-radius:20px;background:#fbfff3;color:#18220d;padding:18px;box-shadow:0 18px 40px rgba(24,34,13,.12);font-family:inherit}.absolute-voice-session-observability--error,.absolute-voice-session-observability--failed{border-color:#f2a7a7;background:#fff5f3}.absolute-voice-session-observability--warning{border-color:#fbbf24;background:#fffaf0}.absolute-voice-session-observability__header,.absolute-voice-session-observability__turn header{align-items:start;display:flex;gap:12px;justify-content:space-between}.absolute-voice-session-observability__eyebrow{color:#4d7c0f;font-size:12px;font-weight:800;letter-spacing:.08em;text-transform:uppercase}.absolute-voice-session-observability__label{font-size:24px;line-height:1}.absolute-voice-session-observability__description,.absolute-voice-session-observability__turn p,.absolute-voice-session-observability__empty,.absolute-voice-session-observability__session{color:#4b5f3e}.absolute-voice-session-observability__actions{display:flex;flex-wrap:wrap;gap:10px;margin:14px 0}.absolute-voice-session-observability__actions a{color:#3f6212;font-weight:800}.absolute-voice-session-observability__turns{display:grid;gap:12px;margin-top:14px}.absolute-voice-session-observability__turn{background:#fff;border:1px solid #dcebcf;border-radius:16px;padding:14px}.absolute-voice-session-observability__turn p{margin:10px 0 0}.absolute-voice-session-observability__empty{margin:14px 0 0}.absolute-voice-session-observability__error{color:#9f1239;font-weight:700}`;
3360
+ var mountVoiceSessionObservability = (element, path, options = {}) => {
3361
+ const store = createVoiceSessionObservabilityStore(path, options);
3362
+ const render = () => {
3363
+ element.innerHTML = renderVoiceSessionObservabilityHTML(store.getSnapshot(), options);
3364
+ };
3365
+ const unsubscribe = store.subscribe(render);
3366
+ render();
3367
+ store.refresh().catch(() => {});
3368
+ return {
3369
+ close: () => {
3370
+ unsubscribe();
3371
+ store.close();
3372
+ },
3373
+ refresh: store.refresh
3374
+ };
3375
+ };
3376
+ var defineVoiceSessionObservabilityElement = (tagName = "absolute-voice-session-observability") => {
3377
+ if (typeof window === "undefined" || typeof customElements === "undefined" || customElements.get(tagName)) {
3378
+ return;
3379
+ }
3380
+ customElements.define(tagName, class AbsoluteVoiceSessionObservabilityElement extends HTMLElement {
3381
+ mounted;
3382
+ connectedCallback() {
3383
+ const intervalMs = Number(this.getAttribute("interval-ms") ?? 5000);
3384
+ const maxTurns = Number(this.getAttribute("max-turns") ?? 3);
3385
+ this.mounted = mountVoiceSessionObservability(this, this.getAttribute("path") ?? "/api/voice/session-observability/latest", {
3386
+ description: this.getAttribute("description") ?? undefined,
3387
+ intervalMs: Number.isFinite(intervalMs) ? intervalMs : 5000,
3388
+ maxTurns: Number.isFinite(maxTurns) ? maxTurns : 3,
3389
+ title: this.getAttribute("title") ?? undefined
3390
+ });
3391
+ }
3392
+ disconnectedCallback() {
3393
+ this.mounted?.close();
3394
+ this.mounted = undefined;
3395
+ }
3396
+ });
3397
+ };
3398
+
3399
+ // src/svelte/createVoiceSessionObservability.ts
3400
+ var createVoiceSessionObservability = (path = "/api/voice/session-observability/latest", options = {}) => {
3401
+ const store = createVoiceSessionObservabilityStore(path, options);
3402
+ return {
3403
+ ...store,
3404
+ getHTML: () => renderVoiceSessionObservabilityHTML(store.getSnapshot(), options),
3405
+ getViewModel: () => createVoiceSessionObservabilityViewModel(store.getSnapshot(), options)
3406
+ };
3407
+ };
3238
3408
  // src/client/profileComparison.ts
3239
3409
  var fetchVoiceProfileComparison = async (path = "/api/voice/real-call-profile-history", options = {}) => {
3240
3410
  const fetchImpl = options.fetch ?? globalThis.fetch;
@@ -3485,7 +3655,7 @@ var createVoiceProviderSimulationControlsStore = (options) => {
3485
3655
  };
3486
3656
 
3487
3657
  // src/client/providerSimulationControlsWidget.ts
3488
- var escapeHtml8 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
3658
+ var escapeHtml9 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
3489
3659
  var formatKind = (kind) => (kind ?? "stt").toUpperCase();
3490
3660
  var createVoiceProviderSimulationControlsViewModel = (snapshot, options) => {
3491
3661
  const configuredProviders = options.providers.filter((provider) => provider.configured !== false);
@@ -3505,18 +3675,18 @@ var createVoiceProviderSimulationControlsViewModel = (snapshot, options) => {
3505
3675
  };
3506
3676
  var renderVoiceProviderSimulationControlsHTML = (snapshot, options) => {
3507
3677
  const model = createVoiceProviderSimulationControlsViewModel(snapshot, options);
3508
- 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("");
3509
- 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("");
3678
+ const failureButtons = model.failureProviders.map((provider) => `<button type="button" data-voice-provider-fail="${escapeHtml9(provider.provider)}"${!model.canSimulateFailure || snapshot.isRunning ? " disabled" : ""}>Simulate ${escapeHtml9(provider.provider)} ${escapeHtml9(formatKind(options.kind))} failure</button>`).join("");
3679
+ const recoveryButtons = model.providers.map((provider) => `<button type="button" data-voice-provider-recover="${escapeHtml9(provider.provider)}"${snapshot.isRunning ? " disabled" : ""}>Mark ${escapeHtml9(provider.provider)} recovered</button>`).join("");
3510
3680
  return `<section class="absolute-voice-provider-simulation absolute-voice-provider-simulation--${snapshot.error ? "error" : snapshot.isRunning ? "running" : "ready"}">
3511
3681
  <header class="absolute-voice-provider-simulation__header">
3512
- <span class="absolute-voice-provider-simulation__eyebrow">${escapeHtml8(model.title)}</span>
3513
- <strong class="absolute-voice-provider-simulation__label">${escapeHtml8(model.label)}</strong>
3682
+ <span class="absolute-voice-provider-simulation__eyebrow">${escapeHtml9(model.title)}</span>
3683
+ <strong class="absolute-voice-provider-simulation__label">${escapeHtml9(model.label)}</strong>
3514
3684
  </header>
3515
- <p class="absolute-voice-provider-simulation__description">${escapeHtml8(model.description)}</p>
3516
- ${model.canSimulateFailure ? "" : `<p class="absolute-voice-provider-simulation__empty">${escapeHtml8(options.fallbackRequiredMessage ?? "Configure fallback providers before simulating failure.")}</p>`}
3685
+ <p class="absolute-voice-provider-simulation__description">${escapeHtml9(model.description)}</p>
3686
+ ${model.canSimulateFailure ? "" : `<p class="absolute-voice-provider-simulation__empty">${escapeHtml9(options.fallbackRequiredMessage ?? "Configure fallback providers before simulating failure.")}</p>`}
3517
3687
  <div class="absolute-voice-provider-simulation__actions">${failureButtons}${recoveryButtons}</div>
3518
- ${snapshot.error ? `<p class="absolute-voice-provider-simulation__error">${escapeHtml8(snapshot.error)}</p>` : ""}
3519
- ${model.resultText ? `<pre class="absolute-voice-provider-simulation__result">${escapeHtml8(model.resultText)}</pre>` : ""}
3688
+ ${snapshot.error ? `<p class="absolute-voice-provider-simulation__error">${escapeHtml9(snapshot.error)}</p>` : ""}
3689
+ ${model.resultText ? `<pre class="absolute-voice-provider-simulation__result">${escapeHtml9(model.resultText)}</pre>` : ""}
3520
3690
  </section>`;
3521
3691
  };
3522
3692
  var bindVoiceProviderSimulationControls = (element, store) => {
@@ -3671,9 +3841,9 @@ var createVoiceProviderCapabilitiesStore = (path = "/api/provider-capabilities",
3671
3841
  };
3672
3842
 
3673
3843
  // src/client/providerCapabilitiesWidget.ts
3674
- var DEFAULT_TITLE6 = "Provider Capabilities";
3675
- var DEFAULT_DESCRIPTION6 = "Configured, selected, and healthy voice providers for this deployment.";
3676
- var escapeHtml9 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
3844
+ var DEFAULT_TITLE7 = "Provider Capabilities";
3845
+ var DEFAULT_DESCRIPTION7 = "Configured, selected, and healthy voice providers for this deployment.";
3846
+ var escapeHtml10 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
3677
3847
  var formatProvider = (provider) => provider.split(/[-_\s]+/).filter(Boolean).map((part) => `${part[0]?.toUpperCase() ?? ""}${part.slice(1)}`).join(" ") || provider;
3678
3848
  var formatKind2 = (kind) => kind.toUpperCase();
3679
3849
  var formatStatus2 = (status) => status.split("-").map((part) => `${part[0]?.toUpperCase() ?? ""}${part.slice(1)}`).join(" ");
@@ -3717,36 +3887,36 @@ var createVoiceProviderCapabilitiesViewModel = (snapshot, options = {}) => {
3717
3887
  const selectedCount = snapshot.report?.selected ?? capabilities.filter((capability) => capability.selected).length;
3718
3888
  return {
3719
3889
  capabilities,
3720
- description: options.description ?? DEFAULT_DESCRIPTION6,
3890
+ description: options.description ?? DEFAULT_DESCRIPTION7,
3721
3891
  error: snapshot.error,
3722
3892
  isLoading: snapshot.isLoading,
3723
3893
  label: snapshot.error ? "Unavailable" : capabilities.length ? warningCount > 0 ? `${warningCount} needs attention` : `${selectedCount} selected` : snapshot.isLoading ? "Checking" : "No capabilities",
3724
3894
  status: snapshot.error ? "error" : capabilities.length ? warningCount > 0 ? "warning" : "ready" : snapshot.isLoading ? "loading" : "empty",
3725
- title: options.title ?? DEFAULT_TITLE6,
3895
+ title: options.title ?? DEFAULT_TITLE7,
3726
3896
  updatedAt: snapshot.updatedAt
3727
3897
  };
3728
3898
  };
3729
3899
  var renderVoiceProviderCapabilitiesHTML = (snapshot, options = {}) => {
3730
3900
  const model = createVoiceProviderCapabilitiesViewModel(snapshot, options);
3731
- 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)}">
3901
+ 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--${escapeHtml10(capability.status)}">
3732
3902
  <header>
3733
- <strong>${escapeHtml9(capability.label)}</strong>
3734
- <span>${escapeHtml9(formatStatus2(capability.status))}</span>
3903
+ <strong>${escapeHtml10(capability.label)}</strong>
3904
+ <span>${escapeHtml10(formatStatus2(capability.status))}</span>
3735
3905
  </header>
3736
- <p>${escapeHtml9(capability.detail)}</p>
3906
+ <p>${escapeHtml10(capability.detail)}</p>
3737
3907
  <dl>${capability.rows.map((row) => `<div>
3738
- <dt>${escapeHtml9(row.label)}</dt>
3739
- <dd>${escapeHtml9(row.value)}</dd>
3908
+ <dt>${escapeHtml10(row.label)}</dt>
3909
+ <dd>${escapeHtml10(row.value)}</dd>
3740
3910
  </div>`).join("")}</dl>
3741
3911
  </article>`).join("")}</div>` : '<p class="absolute-voice-provider-capabilities__empty">Configure provider capabilities to see deployment coverage.</p>';
3742
- return `<section class="absolute-voice-provider-capabilities absolute-voice-provider-capabilities--${escapeHtml9(model.status)}">
3912
+ return `<section class="absolute-voice-provider-capabilities absolute-voice-provider-capabilities--${escapeHtml10(model.status)}">
3743
3913
  <header class="absolute-voice-provider-capabilities__header">
3744
- <span class="absolute-voice-provider-capabilities__eyebrow">${escapeHtml9(model.title)}</span>
3745
- <strong class="absolute-voice-provider-capabilities__label">${escapeHtml9(model.label)}</strong>
3914
+ <span class="absolute-voice-provider-capabilities__eyebrow">${escapeHtml10(model.title)}</span>
3915
+ <strong class="absolute-voice-provider-capabilities__label">${escapeHtml10(model.label)}</strong>
3746
3916
  </header>
3747
- <p class="absolute-voice-provider-capabilities__description">${escapeHtml9(model.description)}</p>
3917
+ <p class="absolute-voice-provider-capabilities__description">${escapeHtml10(model.description)}</p>
3748
3918
  ${capabilities}
3749
- ${model.error ? `<p class="absolute-voice-provider-capabilities__error">${escapeHtml9(model.error)}</p>` : ""}
3919
+ ${model.error ? `<p class="absolute-voice-provider-capabilities__error">${escapeHtml10(model.error)}</p>` : ""}
3750
3920
  </section>`;
3751
3921
  };
3752
3922
  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}`;
@@ -3872,9 +4042,9 @@ var createVoiceProviderContractsStore = (path = "/api/provider-contracts", optio
3872
4042
  };
3873
4043
 
3874
4044
  // src/client/providerContractsWidget.ts
3875
- var DEFAULT_TITLE7 = "Provider Contracts";
3876
- var DEFAULT_DESCRIPTION7 = "Production contract coverage for provider env, latency, fallback, streaming, and capabilities.";
3877
- var escapeHtml10 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
4045
+ var DEFAULT_TITLE8 = "Provider Contracts";
4046
+ var DEFAULT_DESCRIPTION8 = "Production contract coverage for provider env, latency, fallback, streaming, and capabilities.";
4047
+ var escapeHtml11 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
3878
4048
  var formatProvider2 = (provider) => provider.split(/[-_\s]+/).filter(Boolean).map((part) => `${part[0]?.toUpperCase() ?? ""}${part.slice(1)}`).join(" ") || provider;
3879
4049
  var formatStatus3 = (status) => status.split("-").map((part) => `${part[0]?.toUpperCase() ?? ""}${part.slice(1)}`).join(" ");
3880
4050
  var contractDetail = (row) => {
@@ -3906,38 +4076,38 @@ var createVoiceProviderContractsViewModel = (snapshot, options = {}) => {
3906
4076
  }));
3907
4077
  const warningCount = snapshot.report ? snapshot.report.failed + snapshot.report.warned : rows.filter((row) => row.status !== "pass").length;
3908
4078
  return {
3909
- description: options.description ?? DEFAULT_DESCRIPTION7,
4079
+ description: options.description ?? DEFAULT_DESCRIPTION8,
3910
4080
  error: snapshot.error,
3911
4081
  isLoading: snapshot.isLoading,
3912
4082
  label: snapshot.error ? "Unavailable" : rows.length ? warningCount > 0 ? `${warningCount} needs attention` : `${rows.length} passing` : snapshot.isLoading ? "Checking" : "No contracts",
3913
4083
  rows,
3914
4084
  status: snapshot.error ? "error" : rows.length ? warningCount > 0 ? "warning" : "ready" : snapshot.isLoading ? "loading" : "empty",
3915
- title: options.title ?? DEFAULT_TITLE7,
4085
+ title: options.title ?? DEFAULT_TITLE8,
3916
4086
  updatedAt: snapshot.updatedAt
3917
4087
  };
3918
4088
  };
3919
4089
  var renderVoiceProviderContractsHTML = (snapshot, options = {}) => {
3920
4090
  const model = createVoiceProviderContractsViewModel(snapshot, options);
3921
- 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)}">
4091
+ 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--${escapeHtml11(row.status)}">
3922
4092
  <header>
3923
- <strong>${escapeHtml10(row.label)}</strong>
3924
- <span>${escapeHtml10(formatStatus3(row.status))}</span>
4093
+ <strong>${escapeHtml11(row.label)}</strong>
4094
+ <span>${escapeHtml11(formatStatus3(row.status))}</span>
3925
4095
  </header>
3926
- <p>${escapeHtml10(row.detail)}</p>
3927
- ${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>` : ""}
4096
+ <p>${escapeHtml11(row.detail)}</p>
4097
+ ${row.remediations.length ? `<ul class="absolute-voice-provider-contracts__remediations">${row.remediations.map((remediation) => `<li>${remediation.href ? `<a href="${escapeHtml11(remediation.href)}">${escapeHtml11(remediation.label)}</a>` : `<strong>${escapeHtml11(remediation.label)}</strong>`}<span>${escapeHtml11(remediation.detail)}</span></li>`).join("")}</ul>` : ""}
3928
4098
  <dl>${row.rows.map((item) => `<div>
3929
- <dt>${escapeHtml10(item.label)}</dt>
3930
- <dd>${escapeHtml10(item.value)}</dd>
4099
+ <dt>${escapeHtml11(item.label)}</dt>
4100
+ <dd>${escapeHtml11(item.value)}</dd>
3931
4101
  </div>`).join("")}</dl>
3932
4102
  </article>`).join("")}</div>` : '<p class="absolute-voice-provider-contracts__empty">Configure provider contracts to see production coverage.</p>';
3933
- return `<section class="absolute-voice-provider-contracts absolute-voice-provider-contracts--${escapeHtml10(model.status)}">
4103
+ return `<section class="absolute-voice-provider-contracts absolute-voice-provider-contracts--${escapeHtml11(model.status)}">
3934
4104
  <header class="absolute-voice-provider-contracts__header">
3935
- <span class="absolute-voice-provider-contracts__eyebrow">${escapeHtml10(model.title)}</span>
3936
- <strong class="absolute-voice-provider-contracts__label">${escapeHtml10(model.label)}</strong>
4105
+ <span class="absolute-voice-provider-contracts__eyebrow">${escapeHtml11(model.title)}</span>
4106
+ <strong class="absolute-voice-provider-contracts__label">${escapeHtml11(model.label)}</strong>
3937
4107
  </header>
3938
- <p class="absolute-voice-provider-contracts__description">${escapeHtml10(model.description)}</p>
4108
+ <p class="absolute-voice-provider-contracts__description">${escapeHtml11(model.description)}</p>
3939
4109
  ${rows}
3940
- ${model.error ? `<p class="absolute-voice-provider-contracts__error">${escapeHtml10(model.error)}</p>` : ""}
4110
+ ${model.error ? `<p class="absolute-voice-provider-contracts__error">${escapeHtml11(model.error)}</p>` : ""}
3941
4111
  </section>`;
3942
4112
  };
3943
4113
  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}`;
@@ -5470,9 +5640,9 @@ var createVoiceProviderStatusStore = (path = "/api/provider-status", options = {
5470
5640
  };
5471
5641
 
5472
5642
  // src/client/providerStatusWidget.ts
5473
- var DEFAULT_TITLE8 = "Voice Providers";
5474
- var DEFAULT_DESCRIPTION8 = "Live provider health, fallback counts, latency, and suppression state from your self-hosted trace store.";
5475
- var escapeHtml11 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
5643
+ var DEFAULT_TITLE9 = "Voice Providers";
5644
+ var DEFAULT_DESCRIPTION9 = "Live provider health, fallback counts, latency, and suppression state from your self-hosted trace store.";
5645
+ var escapeHtml12 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
5476
5646
  var formatProvider3 = (provider) => provider.split(/[-_\s]+/).filter(Boolean).map((part) => `${part[0]?.toUpperCase() ?? ""}${part.slice(1)}`).join(" ") || provider;
5477
5647
  var formatStatus4 = (status) => status.split("-").map((part) => `${part[0]?.toUpperCase() ?? ""}${part.slice(1)}`).join(" ");
5478
5648
  var formatLatency = (value) => typeof value === "number" ? `${value}ms` : "No samples";
@@ -5516,37 +5686,37 @@ var createVoiceProviderStatusViewModel = (snapshot, options = {}) => {
5516
5686
  const warningCount = providers.filter((provider) => isWarningStatus2(provider.status)).length;
5517
5687
  const healthyCount = providers.filter((provider) => provider.status === "healthy").length;
5518
5688
  return {
5519
- description: options.description ?? DEFAULT_DESCRIPTION8,
5689
+ description: options.description ?? DEFAULT_DESCRIPTION9,
5520
5690
  error: snapshot.error,
5521
5691
  isLoading: snapshot.isLoading,
5522
5692
  label: snapshot.error ? "Unavailable" : providers.length ? warningCount > 0 ? `${warningCount} needs attention` : `${healthyCount} healthy` : snapshot.isLoading ? "Checking" : "No provider traffic",
5523
5693
  providers,
5524
5694
  status: snapshot.error ? "error" : providers.length ? warningCount > 0 ? "warning" : "ready" : snapshot.isLoading ? "loading" : "empty",
5525
- title: options.title ?? DEFAULT_TITLE8,
5695
+ title: options.title ?? DEFAULT_TITLE9,
5526
5696
  updatedAt: snapshot.updatedAt
5527
5697
  };
5528
5698
  };
5529
5699
  var renderVoiceProviderStatusHTML = (snapshot, options = {}) => {
5530
5700
  const model = createVoiceProviderStatusViewModel(snapshot, options);
5531
- 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)}">
5701
+ 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--${escapeHtml12(provider.status)}">
5532
5702
  <header>
5533
- <strong>${escapeHtml11(provider.label)}</strong>
5534
- <span>${escapeHtml11(formatStatus4(provider.status))}</span>
5703
+ <strong>${escapeHtml12(provider.label)}</strong>
5704
+ <span>${escapeHtml12(formatStatus4(provider.status))}</span>
5535
5705
  </header>
5536
- <p>${escapeHtml11(provider.detail)}</p>
5706
+ <p>${escapeHtml12(provider.detail)}</p>
5537
5707
  <dl>${provider.rows.map((row) => `<div>
5538
- <dt>${escapeHtml11(row.label)}</dt>
5539
- <dd>${escapeHtml11(row.value)}</dd>
5708
+ <dt>${escapeHtml12(row.label)}</dt>
5709
+ <dd>${escapeHtml12(row.value)}</dd>
5540
5710
  </div>`).join("")}</dl>
5541
5711
  </article>`).join("")}</div>` : '<p class="absolute-voice-provider-status__empty">Run voice traffic to see provider health.</p>';
5542
- return `<section class="absolute-voice-provider-status absolute-voice-provider-status--${escapeHtml11(model.status)}">
5712
+ return `<section class="absolute-voice-provider-status absolute-voice-provider-status--${escapeHtml12(model.status)}">
5543
5713
  <header class="absolute-voice-provider-status__header">
5544
- <span class="absolute-voice-provider-status__eyebrow">${escapeHtml11(model.title)}</span>
5545
- <strong class="absolute-voice-provider-status__label">${escapeHtml11(model.label)}</strong>
5714
+ <span class="absolute-voice-provider-status__eyebrow">${escapeHtml12(model.title)}</span>
5715
+ <strong class="absolute-voice-provider-status__label">${escapeHtml12(model.label)}</strong>
5546
5716
  </header>
5547
- <p class="absolute-voice-provider-status__description">${escapeHtml11(model.description)}</p>
5717
+ <p class="absolute-voice-provider-status__description">${escapeHtml12(model.description)}</p>
5548
5718
  ${providers}
5549
- ${model.error ? `<p class="absolute-voice-provider-status__error">${escapeHtml11(model.error)}</p>` : ""}
5719
+ ${model.error ? `<p class="absolute-voice-provider-status__error">${escapeHtml12(model.error)}</p>` : ""}
5550
5720
  </section>`;
5551
5721
  };
5552
5722
  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}`;
@@ -5677,9 +5847,9 @@ var createVoiceRoutingStatusStore = (path = "/api/routing/latest", options = {})
5677
5847
  };
5678
5848
 
5679
5849
  // src/client/routingStatusWidget.ts
5680
- var DEFAULT_TITLE9 = "Voice Routing";
5681
- var DEFAULT_DESCRIPTION9 = "Latest provider routing decision from the self-hosted trace store.";
5682
- var escapeHtml12 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
5850
+ var DEFAULT_TITLE10 = "Voice Routing";
5851
+ var DEFAULT_DESCRIPTION10 = "Latest provider routing decision from the self-hosted trace store.";
5852
+ var escapeHtml13 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
5683
5853
  var formatValue = (value, fallback = "None") => typeof value === "string" && value.trim() ? value : typeof value === "number" && Number.isFinite(value) ? String(value) : fallback;
5684
5854
  var formatProviderRoutes = (routes) => routes && typeof routes === "object" ? Object.entries(routes).map(([role, provider]) => `${role}: ${formatValue(provider)}`).join(", ") || "None" : "None";
5685
5855
  var getProviderRoute = (routes, role) => routes && typeof routes === "object" ? formatValue(routes[role], "Not configured") : "Not configured";
@@ -5748,35 +5918,35 @@ var createVoiceRoutingStatusViewModel = (snapshot, options = {}) => {
5748
5918
  return {
5749
5919
  activeStack,
5750
5920
  decision,
5751
- description: options.description ?? DEFAULT_DESCRIPTION9,
5921
+ description: options.description ?? DEFAULT_DESCRIPTION10,
5752
5922
  error: snapshot.error,
5753
5923
  isLoading: snapshot.isLoading,
5754
5924
  label: snapshot.error ? "Unavailable" : decision ? `${formatValue(decision.kind).toUpperCase()} ${formatValue(decision.status, "unknown")}` : snapshot.isLoading ? "Checking" : "No routing yet",
5755
5925
  rows,
5756
5926
  status: snapshot.error ? "error" : decision ? "ready" : snapshot.isLoading ? "loading" : "empty",
5757
- title: options.title ?? DEFAULT_TITLE9,
5927
+ title: options.title ?? DEFAULT_TITLE10,
5758
5928
  updatedAt: snapshot.updatedAt
5759
5929
  };
5760
5930
  };
5761
5931
  var renderVoiceRoutingStatusHTML = (snapshot, options = {}) => {
5762
5932
  const model = createVoiceRoutingStatusViewModel(snapshot, options);
5763
5933
  const activeStack = model.activeStack.length ? `<div class="absolute-voice-routing-status__stack" aria-label="Active voice stack">${model.activeStack.map((item) => `<div>
5764
- <span>${escapeHtml12(item.label)}</span>
5765
- <strong>${escapeHtml12(item.value)}</strong>
5934
+ <span>${escapeHtml13(item.label)}</span>
5935
+ <strong>${escapeHtml13(item.value)}</strong>
5766
5936
  </div>`).join("")}</div>` : "";
5767
5937
  const rows = model.rows.length ? `<div class="absolute-voice-routing-status__grid">${model.rows.map((row) => `<div>
5768
- <span>${escapeHtml12(row.label)}</span>
5769
- <strong>${escapeHtml12(row.value)}</strong>
5938
+ <span>${escapeHtml13(row.label)}</span>
5939
+ <strong>${escapeHtml13(row.value)}</strong>
5770
5940
  </div>`).join("")}</div>` : '<p class="absolute-voice-routing-status__empty">Start a voice session to see the selected provider.</p>';
5771
- return `<section class="absolute-voice-routing-status absolute-voice-routing-status--${escapeHtml12(model.status)}">
5941
+ return `<section class="absolute-voice-routing-status absolute-voice-routing-status--${escapeHtml13(model.status)}">
5772
5942
  <header class="absolute-voice-routing-status__header">
5773
- <span class="absolute-voice-routing-status__eyebrow">${escapeHtml12(model.title)}</span>
5774
- <strong class="absolute-voice-routing-status__label">${escapeHtml12(model.label)}</strong>
5943
+ <span class="absolute-voice-routing-status__eyebrow">${escapeHtml13(model.title)}</span>
5944
+ <strong class="absolute-voice-routing-status__label">${escapeHtml13(model.label)}</strong>
5775
5945
  </header>
5776
- <p class="absolute-voice-routing-status__description">${escapeHtml12(model.description)}</p>
5946
+ <p class="absolute-voice-routing-status__description">${escapeHtml13(model.description)}</p>
5777
5947
  ${activeStack}
5778
5948
  ${rows}
5779
- ${model.error ? `<p class="absolute-voice-routing-status__error">${escapeHtml12(model.error)}</p>` : ""}
5949
+ ${model.error ? `<p class="absolute-voice-routing-status__error">${escapeHtml13(model.error)}</p>` : ""}
5780
5950
  </section>`;
5781
5951
  };
5782
5952
  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}}`;
@@ -5907,16 +6077,16 @@ var createVoiceTraceTimelineStore = (path = "/api/voice-traces", options = {}) =
5907
6077
  };
5908
6078
 
5909
6079
  // src/client/traceTimelineWidget.ts
5910
- var DEFAULT_TITLE10 = "Voice Traces";
5911
- var DEFAULT_DESCRIPTION10 = "Latest call timelines with provider latency, fallbacks, handoffs, and errors from your self-hosted trace store.";
5912
- var escapeHtml13 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
5913
- var formatMs = (value) => typeof value === "number" ? `${value}ms` : "n/a";
6080
+ var DEFAULT_TITLE11 = "Voice Traces";
6081
+ var DEFAULT_DESCRIPTION11 = "Latest call timelines with provider latency, fallbacks, handoffs, and errors from your self-hosted trace store.";
6082
+ var escapeHtml14 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
6083
+ var formatMs2 = (value) => typeof value === "number" ? `${value}ms` : "n/a";
5914
6084
  var formatProviders = (session) => session.providers.length ? session.providers.map((provider) => provider.provider).join(", ") : "No providers";
5915
6085
  var createVoiceTraceTimelineViewModel = (snapshot, options = {}) => {
5916
6086
  const sessions = (snapshot.report?.sessions ?? []).slice(0, options.limit ?? 3).map((session) => ({
5917
6087
  ...session,
5918
6088
  detailHref: `${options.detailBasePath ?? "/traces"}/${encodeURIComponent(session.sessionId)}`,
5919
- durationLabel: formatMs(session.summary.callDurationMs),
6089
+ durationLabel: formatMs2(session.summary.callDurationMs),
5920
6090
  incidentBundleHref: options.incidentBundleBasePath === false ? undefined : `${options.incidentBundleBasePath ?? "/voice-incidents"}/${encodeURIComponent(session.sessionId)}/markdown`,
5921
6091
  label: `${session.summary.eventCount} events / ${session.summary.turnCount} turns`,
5922
6092
  operationsRecordHref: options.operationsRecordBasePath === false ? undefined : `${options.operationsRecordBasePath ?? "/voice-operations"}/${encodeURIComponent(session.sessionId)}`,
@@ -5925,13 +6095,13 @@ var createVoiceTraceTimelineViewModel = (snapshot, options = {}) => {
5925
6095
  const failed = sessions.filter((session) => session.status === "failed").length;
5926
6096
  const warnings = sessions.filter((session) => session.status === "warning").length;
5927
6097
  return {
5928
- description: options.description ?? DEFAULT_DESCRIPTION10,
6098
+ description: options.description ?? DEFAULT_DESCRIPTION11,
5929
6099
  error: snapshot.error,
5930
6100
  isLoading: snapshot.isLoading,
5931
6101
  label: snapshot.error ? "Unavailable" : failed > 0 ? `${failed} failed` : warnings > 0 ? `${warnings} warning` : sessions.length ? `${sessions.length} recent` : snapshot.isLoading ? "Checking" : "No traces yet",
5932
6102
  sessions,
5933
6103
  status: snapshot.error ? "error" : failed > 0 ? "failed" : warnings > 0 ? "warning" : sessions.length ? "ready" : snapshot.isLoading ? "loading" : "empty",
5934
- title: options.title ?? DEFAULT_TITLE10,
6104
+ title: options.title ?? DEFAULT_TITLE11,
5935
6105
  updatedAt: snapshot.updatedAt
5936
6106
  };
5937
6107
  };
@@ -5939,27 +6109,27 @@ var renderVoiceTraceTimelineWidgetHTML = (snapshot, options = {}) => {
5939
6109
  const model = createVoiceTraceTimelineViewModel(snapshot, options);
5940
6110
  const sessions = model.sessions.length ? `<div class="absolute-voice-trace-timeline__sessions">${model.sessions.map((session) => {
5941
6111
  const supportLinks = [
5942
- `<a href="${escapeHtml13(session.detailHref)}">Open timeline</a>`,
5943
- session.operationsRecordHref ? `<a href="${escapeHtml13(session.operationsRecordHref)}">Open operations record</a>` : undefined,
5944
- session.incidentBundleHref ? `<a href="${escapeHtml13(session.incidentBundleHref)}">Export incident bundle</a>` : undefined
6112
+ `<a href="${escapeHtml14(session.detailHref)}">Open timeline</a>`,
6113
+ session.operationsRecordHref ? `<a href="${escapeHtml14(session.operationsRecordHref)}">Open operations record</a>` : undefined,
6114
+ session.incidentBundleHref ? `<a href="${escapeHtml14(session.incidentBundleHref)}">Export incident bundle</a>` : undefined
5945
6115
  ].filter(Boolean).join("");
5946
- return `<article class="absolute-voice-trace-timeline__session absolute-voice-trace-timeline__session--${escapeHtml13(session.status)}">
6116
+ return `<article class="absolute-voice-trace-timeline__session absolute-voice-trace-timeline__session--${escapeHtml14(session.status)}">
5947
6117
  <header>
5948
- <strong>${escapeHtml13(session.sessionId)}</strong>
5949
- <span>${escapeHtml13(session.status)}</span>
6118
+ <strong>${escapeHtml14(session.sessionId)}</strong>
6119
+ <span>${escapeHtml14(session.status)}</span>
5950
6120
  </header>
5951
- <p>${escapeHtml13(session.label)} \xB7 ${escapeHtml13(session.durationLabel)} \xB7 ${escapeHtml13(session.providerLabel)}</p>
6121
+ <p>${escapeHtml14(session.label)} \xB7 ${escapeHtml14(session.durationLabel)} \xB7 ${escapeHtml14(session.providerLabel)}</p>
5952
6122
  <p class="absolute-voice-trace-timeline__actions">${supportLinks}</p>
5953
6123
  </article>`;
5954
6124
  }).join("")}</div>` : '<p class="absolute-voice-trace-timeline__empty">Run a voice session to see call timelines.</p>';
5955
- return `<section class="absolute-voice-trace-timeline absolute-voice-trace-timeline--${escapeHtml13(model.status)}">
6125
+ return `<section class="absolute-voice-trace-timeline absolute-voice-trace-timeline--${escapeHtml14(model.status)}">
5956
6126
  <header class="absolute-voice-trace-timeline__header">
5957
- <span class="absolute-voice-trace-timeline__eyebrow">${escapeHtml13(model.title)}</span>
5958
- <strong class="absolute-voice-trace-timeline__label">${escapeHtml13(model.label)}</strong>
6127
+ <span class="absolute-voice-trace-timeline__eyebrow">${escapeHtml14(model.title)}</span>
6128
+ <strong class="absolute-voice-trace-timeline__label">${escapeHtml14(model.label)}</strong>
5959
6129
  </header>
5960
- <p class="absolute-voice-trace-timeline__description">${escapeHtml13(model.description)}</p>
6130
+ <p class="absolute-voice-trace-timeline__description">${escapeHtml14(model.description)}</p>
5961
6131
  ${sessions}
5962
- ${model.error ? `<p class="absolute-voice-trace-timeline__error">${escapeHtml13(model.error)}</p>` : ""}
6132
+ ${model.error ? `<p class="absolute-voice-trace-timeline__error">${escapeHtml14(model.error)}</p>` : ""}
5963
6133
  </section>`;
5964
6134
  };
5965
6135
  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}`;
@@ -6089,9 +6259,9 @@ var createVoiceAgentSquadStatusStore = (path = "/api/voice-traces", options = {}
6089
6259
  };
6090
6260
 
6091
6261
  // src/client/agentSquadStatusWidget.ts
6092
- var DEFAULT_TITLE11 = "Voice Agent Squad";
6093
- var DEFAULT_DESCRIPTION11 = "Current specialist and recent handoffs from your self-hosted voice traces.";
6094
- var escapeHtml14 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
6262
+ var DEFAULT_TITLE12 = "Voice Agent Squad";
6263
+ var DEFAULT_DESCRIPTION12 = "Current specialist and recent handoffs from your self-hosted voice traces.";
6264
+ var escapeHtml15 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
6095
6265
  var labelFor = (current) => {
6096
6266
  if (!current)
6097
6267
  return "Waiting for specialist activity";
@@ -6105,37 +6275,37 @@ var labelFor = (current) => {
6105
6275
  };
6106
6276
  var createVoiceAgentSquadStatusViewModel = (snapshot, options = {}) => ({
6107
6277
  current: snapshot.report.current,
6108
- description: options.description ?? DEFAULT_DESCRIPTION11,
6278
+ description: options.description ?? DEFAULT_DESCRIPTION12,
6109
6279
  error: snapshot.error,
6110
6280
  isLoading: snapshot.isLoading,
6111
6281
  label: snapshot.error ? "Unavailable" : labelFor(snapshot.report.current),
6112
6282
  sessionCount: snapshot.report.sessionCount,
6113
6283
  sessions: snapshot.report.sessions,
6114
- title: options.title ?? DEFAULT_TITLE11,
6284
+ title: options.title ?? DEFAULT_TITLE12,
6115
6285
  updatedAt: snapshot.updatedAt
6116
6286
  });
6117
6287
  var renderVoiceAgentSquadStatusHTML = (snapshot, options = {}) => {
6118
6288
  const model = createVoiceAgentSquadStatusViewModel(snapshot, options);
6119
6289
  const current = model.current;
6120
6290
  const rows = model.sessions.length ? model.sessions.slice(0, 5).map((session) => `<li>
6121
- <span>${escapeHtml14(session.sessionId)}</span>
6122
- <strong>${escapeHtml14(session.targetAgentId ?? "none")}</strong>
6123
- <em>${escapeHtml14(session.status)}</em>
6124
- ${session.summary || session.reason ? `<p>${escapeHtml14(session.summary ?? session.reason ?? "")}</p>` : ""}
6291
+ <span>${escapeHtml15(session.sessionId)}</span>
6292
+ <strong>${escapeHtml15(session.targetAgentId ?? "none")}</strong>
6293
+ <em>${escapeHtml15(session.status)}</em>
6294
+ ${session.summary || session.reason ? `<p>${escapeHtml15(session.summary ?? session.reason ?? "")}</p>` : ""}
6125
6295
  </li>`).join("") : "<li><span>No squad traces yet.</span><strong>Waiting</strong></li>";
6126
6296
  return `<section class="absolute-voice-agent-squad-status">
6127
6297
  <header>
6128
- <span>${escapeHtml14(model.title)}</span>
6129
- <strong>${escapeHtml14(model.label)}</strong>
6298
+ <span>${escapeHtml15(model.title)}</span>
6299
+ <strong>${escapeHtml15(model.label)}</strong>
6130
6300
  </header>
6131
- <p>${escapeHtml14(model.description)}</p>
6301
+ <p>${escapeHtml15(model.description)}</p>
6132
6302
  <div>
6133
- <span>Session</span><strong>${escapeHtml14(current?.sessionId ?? "n/a")}</strong>
6134
- <span>From</span><strong>${escapeHtml14(current?.fromAgentId ?? "n/a")}</strong>
6135
- <span>Status</span><strong>${escapeHtml14(current?.status ?? "idle")}</strong>
6303
+ <span>Session</span><strong>${escapeHtml15(current?.sessionId ?? "n/a")}</strong>
6304
+ <span>From</span><strong>${escapeHtml15(current?.fromAgentId ?? "n/a")}</strong>
6305
+ <span>Status</span><strong>${escapeHtml15(current?.status ?? "idle")}</strong>
6136
6306
  </div>
6137
6307
  <ul>${rows}</ul>
6138
- ${model.error ? `<p class="absolute-voice-agent-squad-status__error">${escapeHtml14(model.error)}</p>` : ""}
6308
+ ${model.error ? `<p class="absolute-voice-agent-squad-status__error">${escapeHtml15(model.error)}</p>` : ""}
6139
6309
  </section>`;
6140
6310
  };
6141
6311
  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}`;
@@ -6295,56 +6465,56 @@ var createVoiceTurnLatencyStore = (path = "/api/turn-latency", options = {}) =>
6295
6465
  };
6296
6466
 
6297
6467
  // src/client/turnLatencyWidget.ts
6298
- var DEFAULT_TITLE12 = "Turn Latency";
6299
- var DEFAULT_DESCRIPTION12 = "Per-turn timing from first transcript to commit and assistant response start.";
6468
+ var DEFAULT_TITLE13 = "Turn Latency";
6469
+ var DEFAULT_DESCRIPTION13 = "Per-turn timing from first transcript to commit and assistant response start.";
6300
6470
  var DEFAULT_PROOF_LABEL = "Run latency proof";
6301
- var escapeHtml15 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
6302
- var formatMs2 = (value) => typeof value === "number" ? `${Math.round(value)}ms` : "n/a";
6471
+ var escapeHtml16 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
6472
+ var formatMs3 = (value) => typeof value === "number" ? `${Math.round(value)}ms` : "n/a";
6303
6473
  var createVoiceTurnLatencyViewModel = (snapshot, options = {}) => {
6304
6474
  const turns = (snapshot.report?.turns ?? []).map((turn) => ({
6305
6475
  ...turn,
6306
6476
  label: turn.text || "Empty turn",
6307
6477
  rows: turn.stages.map((stage) => ({
6308
6478
  label: stage.label,
6309
- value: formatMs2(stage.valueMs)
6479
+ value: formatMs3(stage.valueMs)
6310
6480
  }))
6311
6481
  }));
6312
6482
  const warningCount = snapshot.report?.warnings ?? turns.filter((turn) => turn.status === "warn").length;
6313
6483
  const failedCount = snapshot.report?.failed ?? turns.filter((turn) => turn.status === "fail").length;
6314
6484
  return {
6315
- description: options.description ?? DEFAULT_DESCRIPTION12,
6485
+ description: options.description ?? DEFAULT_DESCRIPTION13,
6316
6486
  error: snapshot.error,
6317
6487
  isLoading: snapshot.isLoading,
6318
- label: snapshot.error ? "Unavailable" : turns.length ? failedCount > 0 ? `${failedCount} slow` : warningCount > 0 ? `${warningCount} warnings` : `avg ${formatMs2(snapshot.report?.averageTotalMs)}` : snapshot.isLoading ? "Checking" : "No turns",
6488
+ label: snapshot.error ? "Unavailable" : turns.length ? failedCount > 0 ? `${failedCount} slow` : warningCount > 0 ? `${warningCount} warnings` : `avg ${formatMs3(snapshot.report?.averageTotalMs)}` : snapshot.isLoading ? "Checking" : "No turns",
6319
6489
  proofLabel: options.proofPath ? options.proofLabel ?? DEFAULT_PROOF_LABEL : undefined,
6320
6490
  showProofAction: Boolean(options.proofPath),
6321
6491
  status: snapshot.error ? "error" : turns.length ? failedCount > 0 || warningCount > 0 ? "warning" : "ready" : snapshot.isLoading ? "loading" : "empty",
6322
- title: options.title ?? DEFAULT_TITLE12,
6492
+ title: options.title ?? DEFAULT_TITLE13,
6323
6493
  turns,
6324
6494
  updatedAt: snapshot.updatedAt
6325
6495
  };
6326
6496
  };
6327
6497
  var renderVoiceTurnLatencyHTML = (snapshot, options = {}) => {
6328
6498
  const model = createVoiceTurnLatencyViewModel(snapshot, options);
6329
- 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)}">
6499
+ 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--${escapeHtml16(turn.status)}">
6330
6500
  <header>
6331
- <strong>${escapeHtml15(turn.label)}</strong>
6332
- <span>${escapeHtml15(turn.status)}</span>
6501
+ <strong>${escapeHtml16(turn.label)}</strong>
6502
+ <span>${escapeHtml16(turn.status)}</span>
6333
6503
  </header>
6334
6504
  <dl>${turn.rows.map((row) => `<div>
6335
- <dt>${escapeHtml15(row.label)}</dt>
6336
- <dd>${escapeHtml15(row.value)}</dd>
6505
+ <dt>${escapeHtml16(row.label)}</dt>
6506
+ <dd>${escapeHtml16(row.value)}</dd>
6337
6507
  </div>`).join("")}</dl>
6338
6508
  </article>`).join("")}</div>` : '<p class="absolute-voice-turn-latency__empty">Complete a voice turn to see latency diagnostics.</p>';
6339
- return `<section class="absolute-voice-turn-latency absolute-voice-turn-latency--${escapeHtml15(model.status)}">
6509
+ return `<section class="absolute-voice-turn-latency absolute-voice-turn-latency--${escapeHtml16(model.status)}">
6340
6510
  <header class="absolute-voice-turn-latency__header">
6341
- <span class="absolute-voice-turn-latency__eyebrow">${escapeHtml15(model.title)}</span>
6342
- <strong class="absolute-voice-turn-latency__label">${escapeHtml15(model.label)}</strong>
6511
+ <span class="absolute-voice-turn-latency__eyebrow">${escapeHtml16(model.title)}</span>
6512
+ <strong class="absolute-voice-turn-latency__label">${escapeHtml16(model.label)}</strong>
6343
6513
  </header>
6344
- <p class="absolute-voice-turn-latency__description">${escapeHtml15(model.description)}</p>
6345
- ${model.showProofAction ? `<button class="absolute-voice-turn-latency__proof" data-absolute-voice-turn-latency-proof type="button">${escapeHtml15(model.proofLabel ?? DEFAULT_PROOF_LABEL)}</button>` : ""}
6514
+ <p class="absolute-voice-turn-latency__description">${escapeHtml16(model.description)}</p>
6515
+ ${model.showProofAction ? `<button class="absolute-voice-turn-latency__proof" data-absolute-voice-turn-latency-proof type="button">${escapeHtml16(model.proofLabel ?? DEFAULT_PROOF_LABEL)}</button>` : ""}
6346
6516
  ${turns}
6347
- ${model.error ? `<p class="absolute-voice-turn-latency__error">${escapeHtml15(model.error)}</p>` : ""}
6517
+ ${model.error ? `<p class="absolute-voice-turn-latency__error">${escapeHtml16(model.error)}</p>` : ""}
6348
6518
  </section>`;
6349
6519
  };
6350
6520
  var mountVoiceTurnLatency = (element, path = "/api/turn-latency", options = {}) => {
@@ -6483,9 +6653,9 @@ var createVoiceTurnQualityStore = (path = "/api/turn-quality", options = {}) =>
6483
6653
  };
6484
6654
 
6485
6655
  // src/client/turnQualityWidget.ts
6486
- var DEFAULT_TITLE13 = "Turn Quality";
6487
- var DEFAULT_DESCRIPTION13 = "Per-turn STT confidence, fallback selection, corrections, and transcript coverage.";
6488
- var escapeHtml16 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
6656
+ var DEFAULT_TITLE14 = "Turn Quality";
6657
+ var DEFAULT_DESCRIPTION14 = "Per-turn STT confidence, fallback selection, corrections, and transcript coverage.";
6658
+ var escapeHtml17 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
6489
6659
  var formatConfidence = (value) => typeof value === "number" ? `${Math.round(value * 100)}%` : "n/a";
6490
6660
  var formatMaybe = (value) => value === undefined || value === "" ? "n/a" : String(value);
6491
6661
  var getTurnDetail = (turn) => {
@@ -6529,37 +6699,37 @@ var createVoiceTurnQualityViewModel = (snapshot, options = {}) => {
6529
6699
  const warningCount = snapshot.report?.warnings ?? turns.filter((turn) => turn.status === "warn").length;
6530
6700
  const failedCount = snapshot.report?.failed ?? turns.filter((turn) => turn.status === "fail").length;
6531
6701
  return {
6532
- description: options.description ?? DEFAULT_DESCRIPTION13,
6702
+ description: options.description ?? DEFAULT_DESCRIPTION14,
6533
6703
  error: snapshot.error,
6534
6704
  isLoading: snapshot.isLoading,
6535
6705
  label: snapshot.error ? "Unavailable" : turns.length ? failedCount > 0 ? `${failedCount} failed` : warningCount > 0 ? `${warningCount} warnings` : `${turns.length} healthy` : snapshot.isLoading ? "Checking" : "No turns",
6536
6706
  status: snapshot.error ? "error" : turns.length ? failedCount > 0 || warningCount > 0 ? "warning" : "ready" : snapshot.isLoading ? "loading" : "empty",
6537
- title: options.title ?? DEFAULT_TITLE13,
6707
+ title: options.title ?? DEFAULT_TITLE14,
6538
6708
  turns,
6539
6709
  updatedAt: snapshot.updatedAt
6540
6710
  };
6541
6711
  };
6542
6712
  var renderVoiceTurnQualityHTML = (snapshot, options = {}) => {
6543
6713
  const model = createVoiceTurnQualityViewModel(snapshot, options);
6544
- 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)}">
6714
+ 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--${escapeHtml17(turn.status)}">
6545
6715
  <header>
6546
- <strong>${escapeHtml16(turn.label)}</strong>
6547
- <span>${escapeHtml16(turn.status)}</span>
6716
+ <strong>${escapeHtml17(turn.label)}</strong>
6717
+ <span>${escapeHtml17(turn.status)}</span>
6548
6718
  </header>
6549
- <p>${escapeHtml16(turn.detail)}</p>
6719
+ <p>${escapeHtml17(turn.detail)}</p>
6550
6720
  <dl>${turn.rows.map((row) => `<div>
6551
- <dt>${escapeHtml16(row.label)}</dt>
6552
- <dd>${escapeHtml16(row.value)}</dd>
6721
+ <dt>${escapeHtml17(row.label)}</dt>
6722
+ <dd>${escapeHtml17(row.value)}</dd>
6553
6723
  </div>`).join("")}</dl>
6554
6724
  </article>`).join("")}</div>` : '<p class="absolute-voice-turn-quality__empty">Complete a voice turn to see STT quality diagnostics.</p>';
6555
- return `<section class="absolute-voice-turn-quality absolute-voice-turn-quality--${escapeHtml16(model.status)}">
6725
+ return `<section class="absolute-voice-turn-quality absolute-voice-turn-quality--${escapeHtml17(model.status)}">
6556
6726
  <header class="absolute-voice-turn-quality__header">
6557
- <span class="absolute-voice-turn-quality__eyebrow">${escapeHtml16(model.title)}</span>
6558
- <strong class="absolute-voice-turn-quality__label">${escapeHtml16(model.label)}</strong>
6727
+ <span class="absolute-voice-turn-quality__eyebrow">${escapeHtml17(model.title)}</span>
6728
+ <strong class="absolute-voice-turn-quality__label">${escapeHtml17(model.label)}</strong>
6559
6729
  </header>
6560
- <p class="absolute-voice-turn-quality__description">${escapeHtml16(model.description)}</p>
6730
+ <p class="absolute-voice-turn-quality__description">${escapeHtml17(model.description)}</p>
6561
6731
  ${turns}
6562
- ${model.error ? `<p class="absolute-voice-turn-quality__error">${escapeHtml16(model.error)}</p>` : ""}
6732
+ ${model.error ? `<p class="absolute-voice-turn-quality__error">${escapeHtml17(model.error)}</p>` : ""}
6563
6733
  </section>`;
6564
6734
  };
6565
6735
  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}`;
@@ -7343,6 +7513,7 @@ export {
7343
7513
  createVoiceTraceTimeline,
7344
7514
  createVoiceStream2 as createVoiceStream,
7345
7515
  createVoiceSessionSnapshot,
7516
+ createVoiceSessionObservability,
7346
7517
  createVoiceRoutingStatus,
7347
7518
  createVoiceReconnectProfileEvidence,
7348
7519
  createVoiceReadinessFailures,