@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.
@@ -3151,6 +3151,85 @@ var createVoiceSessionSnapshotStore = (path, options = {}) => {
3151
3151
  }
3152
3152
  };
3153
3153
  };
3154
+ // src/client/sessionObservability.ts
3155
+ var fetchVoiceSessionObservability = async (path, options = {}) => {
3156
+ const fetchImpl = options.fetch ?? globalThis.fetch;
3157
+ const response = await fetchImpl(path);
3158
+ if (!response.ok) {
3159
+ throw new Error(`Voice session observability failed: HTTP ${response.status}`);
3160
+ }
3161
+ return await response.json();
3162
+ };
3163
+ var createVoiceSessionObservabilityStore = (path, options = {}) => {
3164
+ const listeners = new Set;
3165
+ let closed = false;
3166
+ let timer;
3167
+ let snapshot = {
3168
+ error: null,
3169
+ isLoading: false,
3170
+ report: null
3171
+ };
3172
+ const emit = () => {
3173
+ for (const listener of listeners) {
3174
+ listener();
3175
+ }
3176
+ };
3177
+ const refresh = async () => {
3178
+ if (closed) {
3179
+ return snapshot.report;
3180
+ }
3181
+ snapshot = {
3182
+ ...snapshot,
3183
+ error: null,
3184
+ isLoading: true
3185
+ };
3186
+ emit();
3187
+ try {
3188
+ const report = await fetchVoiceSessionObservability(path, options);
3189
+ snapshot = {
3190
+ error: null,
3191
+ isLoading: false,
3192
+ report,
3193
+ updatedAt: Date.now()
3194
+ };
3195
+ emit();
3196
+ return report;
3197
+ } catch (error) {
3198
+ snapshot = {
3199
+ ...snapshot,
3200
+ error: error instanceof Error ? error.message : String(error),
3201
+ isLoading: false
3202
+ };
3203
+ emit();
3204
+ throw error;
3205
+ }
3206
+ };
3207
+ const close = () => {
3208
+ closed = true;
3209
+ if (timer) {
3210
+ clearInterval(timer);
3211
+ timer = undefined;
3212
+ }
3213
+ listeners.clear();
3214
+ };
3215
+ if (options.intervalMs && options.intervalMs > 0) {
3216
+ timer = setInterval(() => {
3217
+ refresh().catch(() => {});
3218
+ }, options.intervalMs);
3219
+ }
3220
+ return {
3221
+ close,
3222
+ getServerSnapshot: () => snapshot,
3223
+ getSnapshot: () => snapshot,
3224
+ refresh,
3225
+ subscribe: (listener) => {
3226
+ listeners.add(listener);
3227
+ return () => {
3228
+ listeners.delete(listener);
3229
+ };
3230
+ }
3231
+ };
3232
+ };
3154
3233
  // src/client/callDebugger.ts
3155
3234
  var fetchVoiceCallDebugger = async (path, options = {}) => {
3156
3235
  const fetchImpl = options.fetch ?? globalThis.fetch;
@@ -3466,6 +3545,86 @@ var defineVoiceSessionSnapshotElement = (tagName = "absolute-voice-session-snaps
3466
3545
  }
3467
3546
  });
3468
3547
  };
3548
+ // src/client/sessionObservabilityWidget.ts
3549
+ var DEFAULT_TITLE3 = "Session Observability";
3550
+ var DEFAULT_DESCRIPTION3 = "One support/debug report for a voice call across traces, provider recovery, tools, handoffs, guardrails, turn waterfalls, and incident handoff.";
3551
+ var escapeHtml3 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
3552
+ var formatMs = (value) => typeof value === "number" ? `${value}ms` : "n/a";
3553
+ var createVoiceSessionObservabilityViewModel = (snapshot, options = {}) => {
3554
+ const report = snapshot.report;
3555
+ const turns = (report?.turns ?? []).slice(0, options.maxTurns ?? 3).map((turn) => ({
3556
+ ...turn,
3557
+ durationLabel: formatMs(turn.durationMs),
3558
+ label: `${turn.transcripts} transcripts / ${turn.toolCalls} tools / ${turn.providerDecisions} provider decisions`
3559
+ }));
3560
+ return {
3561
+ description: options.description ?? DEFAULT_DESCRIPTION3,
3562
+ error: snapshot.error,
3563
+ isLoading: snapshot.isLoading,
3564
+ label: snapshot.error ? "Unavailable" : report ? `${report.summary.turns} turns / ${report.summary.fallbacks} fallbacks / ${report.summary.errors} errors` : snapshot.isLoading ? "Checking" : "No session loaded",
3565
+ links: report?.links ?? [],
3566
+ sessionId: report?.sessionId,
3567
+ status: snapshot.error ? "error" : report?.status === "failed" ? "failed" : report?.status === "warning" ? "warning" : report ? "ready" : snapshot.isLoading ? "loading" : "empty",
3568
+ title: options.title ?? DEFAULT_TITLE3,
3569
+ turns,
3570
+ updatedAt: snapshot.updatedAt
3571
+ };
3572
+ };
3573
+ var renderLinks = (links) => links.length ? `<p class="absolute-voice-session-observability__actions">${links.map((link) => `<a href="${escapeHtml3(link.href)}">${escapeHtml3(link.label)}</a>`).join("")}</p>` : "";
3574
+ var renderVoiceSessionObservabilityHTML = (snapshot, options = {}) => {
3575
+ const model = createVoiceSessionObservabilityViewModel(snapshot, options);
3576
+ 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>${escapeHtml3(turn.turnId)}</strong><span>${escapeHtml3(turn.durationLabel)}</span></header><p>${escapeHtml3(turn.label)}</p></article>`).join("")}</div>` : '<p class="absolute-voice-session-observability__empty">Open a voice session to see turn waterfalls.</p>';
3577
+ return `<section class="absolute-voice-session-observability absolute-voice-session-observability--${escapeHtml3(model.status)}">
3578
+ <header class="absolute-voice-session-observability__header">
3579
+ <span class="absolute-voice-session-observability__eyebrow">${escapeHtml3(model.title)}</span>
3580
+ <strong class="absolute-voice-session-observability__label">${escapeHtml3(model.label)}</strong>
3581
+ </header>
3582
+ <p class="absolute-voice-session-observability__description">${escapeHtml3(model.description)}</p>
3583
+ ${model.sessionId ? `<p class="absolute-voice-session-observability__session">${escapeHtml3(model.sessionId)}</p>` : ""}
3584
+ ${renderLinks(model.links)}
3585
+ ${turns}
3586
+ ${model.error ? `<p class="absolute-voice-session-observability__error">${escapeHtml3(model.error)}</p>` : ""}
3587
+ </section>`;
3588
+ };
3589
+ 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}`;
3590
+ var mountVoiceSessionObservability = (element, path, options = {}) => {
3591
+ const store = createVoiceSessionObservabilityStore(path, options);
3592
+ const render = () => {
3593
+ element.innerHTML = renderVoiceSessionObservabilityHTML(store.getSnapshot(), options);
3594
+ };
3595
+ const unsubscribe = store.subscribe(render);
3596
+ render();
3597
+ store.refresh().catch(() => {});
3598
+ return {
3599
+ close: () => {
3600
+ unsubscribe();
3601
+ store.close();
3602
+ },
3603
+ refresh: store.refresh
3604
+ };
3605
+ };
3606
+ var defineVoiceSessionObservabilityElement = (tagName = "absolute-voice-session-observability") => {
3607
+ if (typeof window === "undefined" || typeof customElements === "undefined" || customElements.get(tagName)) {
3608
+ return;
3609
+ }
3610
+ customElements.define(tagName, class AbsoluteVoiceSessionObservabilityElement extends HTMLElement {
3611
+ mounted;
3612
+ connectedCallback() {
3613
+ const intervalMs = Number(this.getAttribute("interval-ms") ?? 5000);
3614
+ const maxTurns = Number(this.getAttribute("max-turns") ?? 3);
3615
+ this.mounted = mountVoiceSessionObservability(this, this.getAttribute("path") ?? "/api/voice/session-observability/latest", {
3616
+ description: this.getAttribute("description") ?? undefined,
3617
+ intervalMs: Number.isFinite(intervalMs) ? intervalMs : 5000,
3618
+ maxTurns: Number.isFinite(maxTurns) ? maxTurns : 3,
3619
+ title: this.getAttribute("title") ?? undefined
3620
+ });
3621
+ }
3622
+ disconnectedCallback() {
3623
+ this.mounted?.close();
3624
+ this.mounted = undefined;
3625
+ }
3626
+ });
3627
+ };
3469
3628
  // src/client/profileComparison.ts
3470
3629
  var fetchVoiceProfileComparison = async (path = "/api/voice/real-call-profile-history", options = {}) => {
3471
3630
  const fetchImpl = options.fetch ?? globalThis.fetch;
@@ -4174,8 +4333,8 @@ var createVoiceDeliveryRuntimeStore = (path = "/api/voice-delivery-runtime", opt
4174
4333
  };
4175
4334
  };
4176
4335
  // src/client/opsStatusWidget.ts
4177
- var DEFAULT_TITLE3 = "Voice Ops Status";
4178
- var DEFAULT_DESCRIPTION3 = "Certified workflow, provider, and handoff readiness from your AbsoluteJS voice app.";
4336
+ var DEFAULT_TITLE4 = "Voice Ops Status";
4337
+ var DEFAULT_DESCRIPTION4 = "Certified workflow, provider, and handoff readiness from your AbsoluteJS voice app.";
4179
4338
  var SURFACE_LABELS = {
4180
4339
  handoffs: "Handoffs",
4181
4340
  providers: "Providers",
@@ -4183,7 +4342,7 @@ var SURFACE_LABELS = {
4183
4342
  sessions: "Sessions",
4184
4343
  workflows: "Workflows"
4185
4344
  };
4186
- var escapeHtml3 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
4345
+ var escapeHtml4 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
4187
4346
  var readNumber = (value, key) => value && typeof value === "object" && (key in value) ? Number(value[key] ?? 0) : 0;
4188
4347
  var surfaceDetail = (surface) => {
4189
4348
  const total = readNumber(surface, "total");
@@ -4223,7 +4382,7 @@ var createVoiceOpsStatusViewModel = (snapshot, options = {}) => {
4223
4382
  };
4224
4383
  });
4225
4384
  return {
4226
- description: options.description ?? DEFAULT_DESCRIPTION3,
4385
+ description: options.description ?? DEFAULT_DESCRIPTION4,
4227
4386
  error: snapshot.error,
4228
4387
  isLoading: snapshot.isLoading,
4229
4388
  label: getVoiceOpsStatusLabel(report, snapshot.error),
@@ -4231,31 +4390,31 @@ var createVoiceOpsStatusViewModel = (snapshot, options = {}) => {
4231
4390
  passed: report?.passed ?? 0,
4232
4391
  status: snapshot.error ? "error" : report ? report.status : snapshot.isLoading ? "loading" : "loading",
4233
4392
  surfaces,
4234
- title: options.title ?? DEFAULT_TITLE3,
4393
+ title: options.title ?? DEFAULT_TITLE4,
4235
4394
  total: report?.total ?? 0,
4236
4395
  updatedAt: snapshot.updatedAt
4237
4396
  };
4238
4397
  };
4239
4398
  var renderVoiceOpsStatusHTML = (snapshot, options = {}) => {
4240
4399
  const model = createVoiceOpsStatusViewModel(snapshot, options);
4241
- const surfaces = model.surfaces.length ? model.surfaces.map((surface) => `<li class="absolute-voice-ops-status__surface absolute-voice-ops-status__surface--${escapeHtml3(surface.status)}">
4242
- <span>${escapeHtml3(surface.label)}</span>
4243
- <strong>${escapeHtml3(surface.detail)}</strong>
4400
+ const surfaces = model.surfaces.length ? model.surfaces.map((surface) => `<li class="absolute-voice-ops-status__surface absolute-voice-ops-status__surface--${escapeHtml4(surface.status)}">
4401
+ <span>${escapeHtml4(surface.label)}</span>
4402
+ <strong>${escapeHtml4(surface.detail)}</strong>
4244
4403
  </li>`).join("") : '<li class="absolute-voice-ops-status__surface"><span>Status</span><strong>Waiting for first check</strong></li>';
4245
- const links = model.links.length ? `<nav class="absolute-voice-ops-status__links">${model.links.slice(0, 4).map((link) => `<a href="${escapeHtml3(link.href)}">${escapeHtml3(link.label)}</a>`).join("")}</nav>` : "";
4246
- return `<section class="absolute-voice-ops-status absolute-voice-ops-status--${escapeHtml3(model.status)}">
4404
+ const links = model.links.length ? `<nav class="absolute-voice-ops-status__links">${model.links.slice(0, 4).map((link) => `<a href="${escapeHtml4(link.href)}">${escapeHtml4(link.label)}</a>`).join("")}</nav>` : "";
4405
+ return `<section class="absolute-voice-ops-status absolute-voice-ops-status--${escapeHtml4(model.status)}">
4247
4406
  <header class="absolute-voice-ops-status__header">
4248
- <span class="absolute-voice-ops-status__eyebrow">${escapeHtml3(model.title)}</span>
4249
- <strong class="absolute-voice-ops-status__label">${escapeHtml3(model.label)}</strong>
4407
+ <span class="absolute-voice-ops-status__eyebrow">${escapeHtml4(model.title)}</span>
4408
+ <strong class="absolute-voice-ops-status__label">${escapeHtml4(model.label)}</strong>
4250
4409
  </header>
4251
- <p class="absolute-voice-ops-status__description">${escapeHtml3(model.description)}</p>
4410
+ <p class="absolute-voice-ops-status__description">${escapeHtml4(model.description)}</p>
4252
4411
  <div class="absolute-voice-ops-status__summary">
4253
4412
  <span>${model.passed} passing</span>
4254
4413
  <span>${Math.max(model.total - model.passed, 0)} failing</span>
4255
4414
  <span>${model.total} checks</span>
4256
4415
  </div>
4257
4416
  <ul class="absolute-voice-ops-status__surfaces">${surfaces}</ul>
4258
- ${model.error ? `<p class="absolute-voice-ops-status__error">${escapeHtml3(model.error)}</p>` : ""}
4417
+ ${model.error ? `<p class="absolute-voice-ops-status__error">${escapeHtml4(model.error)}</p>` : ""}
4259
4418
  ${links}
4260
4419
  </section>`;
4261
4420
  };
@@ -4298,13 +4457,13 @@ var defineVoiceOpsStatusElement = (tagName = "absolute-voice-ops-status") => {
4298
4457
  });
4299
4458
  };
4300
4459
  // src/client/platformCoverageWidget.ts
4301
- var DEFAULT_TITLE4 = "Platform Replacement Coverage";
4302
- var DEFAULT_DESCRIPTION4 = "Code-owned coverage for hosted voice-platform surfaces, backed by the same proof routes used by release evidence.";
4460
+ var DEFAULT_TITLE5 = "Platform Replacement Coverage";
4461
+ var DEFAULT_DESCRIPTION5 = "Code-owned coverage for hosted voice-platform surfaces, backed by the same proof routes used by release evidence.";
4303
4462
  var DEFAULT_LINKS = [
4304
4463
  { href: "/switching-from-vapi", label: "Switching guide" },
4305
4464
  { href: "/api/voice/vapi-coverage", label: "Coverage JSON" }
4306
4465
  ];
4307
- var escapeHtml4 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
4466
+ var escapeHtml5 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
4308
4467
  var formatStatus2 = (status) => status.split("-").map((part) => `${part[0]?.toUpperCase() ?? ""}${part.slice(1)}`).join(" ");
4309
4468
  var surfaceDetail2 = (surface) => {
4310
4469
  if (surface.status === "pass") {
@@ -4328,37 +4487,37 @@ var createVoicePlatformCoverageViewModel = (snapshot, options = {}) => {
4328
4487
  label: surface.surface
4329
4488
  }));
4330
4489
  return {
4331
- description: options.description ?? DEFAULT_DESCRIPTION4,
4490
+ description: options.description ?? DEFAULT_DESCRIPTION5,
4332
4491
  error: snapshot.error,
4333
4492
  isLoading: snapshot.isLoading,
4334
4493
  label: snapshot.error ? "Unavailable" : snapshot.report ? failing.length ? `${failing.length} gaps` : `${snapshot.report.total} surfaces passing` : snapshot.isLoading ? "Checking" : "No coverage report",
4335
4494
  links: options.links ?? DEFAULT_LINKS,
4336
4495
  status: snapshot.error ? "error" : snapshot.report ? failing.length ? "warning" : "ready" : snapshot.isLoading ? "loading" : "empty",
4337
4496
  surfaces,
4338
- title: options.title ?? DEFAULT_TITLE4,
4497
+ title: options.title ?? DEFAULT_TITLE5,
4339
4498
  updatedAt: snapshot.updatedAt
4340
4499
  };
4341
4500
  };
4342
4501
  var renderVoicePlatformCoverageHTML = (snapshot, options = {}) => {
4343
4502
  const model = createVoicePlatformCoverageViewModel(snapshot, options);
4344
- const surfaces = model.surfaces.length ? `<div class="absolute-voice-platform-coverage__surfaces">${model.surfaces.map((surface) => `<article class="absolute-voice-platform-coverage__surface absolute-voice-platform-coverage__surface--${escapeHtml4(surface.status)}">
4503
+ const surfaces = model.surfaces.length ? `<div class="absolute-voice-platform-coverage__surfaces">${model.surfaces.map((surface) => `<article class="absolute-voice-platform-coverage__surface absolute-voice-platform-coverage__surface--${escapeHtml5(surface.status)}">
4345
4504
  <header>
4346
- <strong>${escapeHtml4(surface.label)}</strong>
4347
- <span>${escapeHtml4(formatStatus2(surface.status))}</span>
4505
+ <strong>${escapeHtml5(surface.label)}</strong>
4506
+ <span>${escapeHtml5(formatStatus2(surface.status))}</span>
4348
4507
  </header>
4349
- <p>${escapeHtml4(surface.detail)}</p>
4508
+ <p>${escapeHtml5(surface.detail)}</p>
4350
4509
  <small>${surface.evidence.filter((item) => item.ok).length}/${surface.evidence.length} evidence checks passing</small>
4351
- </article>`).join("")}</div>` : `<p class="absolute-voice-platform-coverage__empty">${model.error ? escapeHtml4(model.error) : "Run the proof pack to populate platform coverage evidence."}</p>`;
4352
- const links = model.links.length ? `<p class="absolute-voice-platform-coverage__links">${model.links.map((link) => `<a href="${escapeHtml4(link.href)}">${escapeHtml4(link.label)}</a>`).join("")}</p>` : "";
4353
- return `<section class="absolute-voice-platform-coverage absolute-voice-platform-coverage--${escapeHtml4(model.status)}">
4510
+ </article>`).join("")}</div>` : `<p class="absolute-voice-platform-coverage__empty">${model.error ? escapeHtml5(model.error) : "Run the proof pack to populate platform coverage evidence."}</p>`;
4511
+ const links = model.links.length ? `<p class="absolute-voice-platform-coverage__links">${model.links.map((link) => `<a href="${escapeHtml5(link.href)}">${escapeHtml5(link.label)}</a>`).join("")}</p>` : "";
4512
+ return `<section class="absolute-voice-platform-coverage absolute-voice-platform-coverage--${escapeHtml5(model.status)}">
4354
4513
  <header class="absolute-voice-platform-coverage__header">
4355
- <span class="absolute-voice-platform-coverage__eyebrow">${escapeHtml4(model.title)}</span>
4356
- <strong class="absolute-voice-platform-coverage__label">${escapeHtml4(model.label)}</strong>
4514
+ <span class="absolute-voice-platform-coverage__eyebrow">${escapeHtml5(model.title)}</span>
4515
+ <strong class="absolute-voice-platform-coverage__label">${escapeHtml5(model.label)}</strong>
4357
4516
  </header>
4358
- <p class="absolute-voice-platform-coverage__description">${escapeHtml4(model.description)}</p>
4517
+ <p class="absolute-voice-platform-coverage__description">${escapeHtml5(model.description)}</p>
4359
4518
  ${surfaces}
4360
4519
  ${links}
4361
- ${model.error ? `<p class="absolute-voice-platform-coverage__error">${escapeHtml4(model.error)}</p>` : ""}
4520
+ ${model.error ? `<p class="absolute-voice-platform-coverage__error">${escapeHtml5(model.error)}</p>` : ""}
4362
4521
  </section>`;
4363
4522
  };
4364
4523
  var getVoicePlatformCoverageCSS = () => `.absolute-voice-platform-coverage{border:1px solid #c7d2fe;border-radius:20px;background:#f8fbff;color:#111827;padding:18px;box-shadow:0 18px 40px rgba(30,64,175,.12);font-family:inherit}.absolute-voice-platform-coverage--warning,.absolute-voice-platform-coverage--error{border-color:#f2a7a7;background:#fff7f4}.absolute-voice-platform-coverage__header,.absolute-voice-platform-coverage__surface header{align-items:start;display:flex;gap:12px;justify-content:space-between}.absolute-voice-platform-coverage__eyebrow{color:#1d4ed8;font-size:12px;font-weight:800;letter-spacing:.08em;text-transform:uppercase}.absolute-voice-platform-coverage__label{font-size:24px;line-height:1}.absolute-voice-platform-coverage__description,.absolute-voice-platform-coverage__surface p,.absolute-voice-platform-coverage__surface small,.absolute-voice-platform-coverage__empty{color:#475569}.absolute-voice-platform-coverage__surfaces{display:grid;gap:10px;margin-top:14px}.absolute-voice-platform-coverage__surface{background:#fff;border:1px solid #dbeafe;border-radius:16px;padding:12px}.absolute-voice-platform-coverage__surface--pass{border-color:#86efac}.absolute-voice-platform-coverage__surface--fail,.absolute-voice-platform-coverage__surface--missing,.absolute-voice-platform-coverage__surface--stale{border-color:#f2a7a7}.absolute-voice-platform-coverage__surface p{margin:8px 0}.absolute-voice-platform-coverage__surface span{text-transform:capitalize}.absolute-voice-platform-coverage__links{display:flex;flex-wrap:wrap;gap:8px;margin:14px 0 0}.absolute-voice-platform-coverage__links a{border:1px solid #bfdbfe;border-radius:999px;color:#1d4ed8;font-weight:800;padding:6px 10px;text-decoration:none}.absolute-voice-platform-coverage__error{color:#9f1239;font-weight:700}`;
@@ -4549,16 +4708,16 @@ var summarizeVoiceProviderHealth = async (input) => {
4549
4708
  }
4550
4709
  return summaries;
4551
4710
  };
4552
- var escapeHtml5 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
4711
+ var escapeHtml6 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
4553
4712
  var renderVoiceProviderHealthHTML = (providers) => providers.length === 0 ? '<p class="voice-provider-empty">No provider status yet.</p>' : [
4554
4713
  '<div class="voice-provider-health">',
4555
4714
  ...providers.map((provider) => {
4556
4715
  const suppressionSeconds = typeof provider.suppressionRemainingMs === "number" ? Math.ceil(provider.suppressionRemainingMs / 1000) : undefined;
4557
4716
  return [
4558
- `<article class="voice-provider-card ${escapeHtml5(provider.status)}">`,
4717
+ `<article class="voice-provider-card ${escapeHtml6(provider.status)}">`,
4559
4718
  '<div class="voice-provider-card-header">',
4560
- `<strong>${escapeHtml5(provider.provider)}</strong>`,
4561
- `<span>${escapeHtml5(provider.status)}${provider.recommended ? " \xB7 recommended" : ""}</span>`,
4719
+ `<strong>${escapeHtml6(provider.provider)}</strong>`,
4720
+ `<span>${escapeHtml6(provider.status)}${provider.recommended ? " \xB7 recommended" : ""}</span>`,
4562
4721
  "</div>",
4563
4722
  "<dl>",
4564
4723
  `<div><dt>Runs</dt><dd>${String(provider.runCount)}</dd></div>`,
@@ -4568,7 +4727,7 @@ var renderVoiceProviderHealthHTML = (providers) => providers.length === 0 ? '<p
4568
4727
  `<div><dt>Fallbacks</dt><dd>${String(provider.fallbackCount)}</dd></div>`,
4569
4728
  "</dl>",
4570
4729
  suppressionSeconds ? `<p>Temporarily suppressed for ${String(suppressionSeconds)}s.</p>` : "",
4571
- provider.lastError ? `<p>${escapeHtml5(provider.lastError)}</p>` : "",
4730
+ provider.lastError ? `<p>${escapeHtml6(provider.lastError)}</p>` : "",
4572
4731
  "</article>"
4573
4732
  ].join("");
4574
4733
  }),
@@ -4599,7 +4758,7 @@ var createVoiceProviderHealthRoutes = (options) => {
4599
4758
  };
4600
4759
 
4601
4760
  // src/resilienceRoutes.ts
4602
- var escapeHtml6 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
4761
+ var escapeHtml7 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
4603
4762
  var getString2 = (value) => typeof value === "string" ? value : undefined;
4604
4763
  var getNumber2 = (value) => typeof value === "number" && Number.isFinite(value) ? value : undefined;
4605
4764
  var getBoolean = (value) => value === true;
@@ -4747,13 +4906,13 @@ var summarizeRoutingEvents = (events) => {
4747
4906
  };
4748
4907
  var renderProviderCards = (title, providers) => {
4749
4908
  if (providers.length === 0) {
4750
- return `<p class="muted">No ${escapeHtml6(title)} provider health yet.</p>`;
4909
+ return `<p class="muted">No ${escapeHtml7(title)} provider health yet.</p>`;
4751
4910
  }
4752
4911
  return `<div class="provider-grid">${providers.map((provider) => `
4753
- <article class="card provider ${escapeHtml6(provider.status)}">
4912
+ <article class="card provider ${escapeHtml7(provider.status)}">
4754
4913
  <div class="card-header">
4755
- <strong>${escapeHtml6(provider.provider)}</strong>
4756
- <span>${escapeHtml6(provider.status)}${provider.recommended ? " \xB7 recommended" : ""}</span>
4914
+ <strong>${escapeHtml7(provider.provider)}</strong>
4915
+ <span>${escapeHtml7(provider.status)}${provider.recommended ? " \xB7 recommended" : ""}</span>
4757
4916
  </div>
4758
4917
  <dl>
4759
4918
  <div><dt>Runs</dt><dd>${provider.runCount}</dd></div>
@@ -4762,7 +4921,7 @@ var renderProviderCards = (title, providers) => {
4762
4921
  <div><dt>Timeouts</dt><dd>${provider.timeoutCount}</dd></div>
4763
4922
  <div><dt>Fallbacks</dt><dd>${provider.fallbackCount}</dd></div>
4764
4923
  </dl>
4765
- ${provider.lastError ? `<p class="muted">${escapeHtml6(provider.lastError)}</p>` : ""}
4924
+ ${provider.lastError ? `<p class="muted">${escapeHtml7(provider.lastError)}</p>` : ""}
4766
4925
  </article>
4767
4926
  `).join("")}</div>`;
4768
4927
  };
@@ -4771,24 +4930,24 @@ var renderTimeline = (events) => {
4771
4930
  return '<p class="muted">No provider routing events yet. Run the app or simulate provider failover.</p>';
4772
4931
  }
4773
4932
  return `<div class="timeline">${events.slice(0, 40).map((event) => `
4774
- <article class="card event ${escapeHtml6(event.status ?? "unknown")}">
4933
+ <article class="card event ${escapeHtml7(event.status ?? "unknown")}">
4775
4934
  <div class="card-header">
4776
- <strong>${escapeHtml6(event.kind.toUpperCase())} ${escapeHtml6(event.operation ?? "generate")}</strong>
4935
+ <strong>${escapeHtml7(event.kind.toUpperCase())} ${escapeHtml7(event.operation ?? "generate")}</strong>
4777
4936
  <span>${new Date(event.at).toLocaleString()}</span>
4778
4937
  </div>
4779
4938
  <p>
4780
- <span class="pill">${escapeHtml6(event.status ?? "unknown")}</span>
4781
- <span class="pill">provider: ${escapeHtml6(event.provider ?? "unknown")}</span>
4782
- ${event.fallbackProvider ? `<span class="pill">fallback: ${escapeHtml6(event.fallbackProvider)}</span>` : ""}
4939
+ <span class="pill">${escapeHtml7(event.status ?? "unknown")}</span>
4940
+ <span class="pill">provider: ${escapeHtml7(event.provider ?? "unknown")}</span>
4941
+ ${event.fallbackProvider ? `<span class="pill">fallback: ${escapeHtml7(event.fallbackProvider)}</span>` : ""}
4783
4942
  ${event.timedOut ? '<span class="pill danger">timed out</span>' : ""}
4784
4943
  </p>
4785
4944
  <dl>
4786
4945
  <div><dt>Attempt</dt><dd>${event.attempt ?? 0}</dd></div>
4787
4946
  <div><dt>Elapsed</dt><dd>${event.elapsedMs ?? 0}ms</dd></div>
4788
4947
  <div><dt>Budget</dt><dd>${event.latencyBudgetMs ?? 0}ms</dd></div>
4789
- <div><dt>Session</dt><dd>${escapeHtml6(event.sessionId)}</dd></div>
4948
+ <div><dt>Session</dt><dd>${escapeHtml7(event.sessionId)}</dd></div>
4790
4949
  </dl>
4791
- ${event.error ? `<p class="muted">${escapeHtml6(event.error)}</p>` : ""}
4950
+ ${event.error ? `<p class="muted">${escapeHtml7(event.error)}</p>` : ""}
4792
4951
  </article>
4793
4952
  `).join("")}</div>`;
4794
4953
  };
@@ -4798,9 +4957,9 @@ var renderSessionKind = (kind, summary) => {
4798
4957
  const status = latest?.status ?? "idle";
4799
4958
  const fallback = latest?.fallbackProvider && latest.fallbackProvider !== provider ? ` -> ${latest.fallbackProvider}` : "";
4800
4959
  return `<div>
4801
- <dt>${escapeHtml6(kind.toUpperCase())}</dt>
4802
- <dd>${escapeHtml6(provider)}${escapeHtml6(fallback)}</dd>
4803
- <small>${escapeHtml6(status)} \xB7 ${summary.runCount} event${summary.runCount === 1 ? "" : "s"} \xB7 ${summary.errorCount} error${summary.errorCount === 1 ? "" : "s"} \xB7 ${summary.fallbackCount} fallback${summary.fallbackCount === 1 ? "" : "s"}</small>
4960
+ <dt>${escapeHtml7(kind.toUpperCase())}</dt>
4961
+ <dd>${escapeHtml7(provider)}${escapeHtml7(fallback)}</dd>
4962
+ <small>${escapeHtml7(status)} \xB7 ${summary.runCount} event${summary.runCount === 1 ? "" : "s"} \xB7 ${summary.errorCount} error${summary.errorCount === 1 ? "" : "s"} \xB7 ${summary.fallbackCount} fallback${summary.fallbackCount === 1 ? "" : "s"}</small>
4804
4963
  </div>`;
4805
4964
  };
4806
4965
  var renderSessionSummaries = (sessions) => {
@@ -4808,10 +4967,10 @@ var renderSessionSummaries = (sessions) => {
4808
4967
  return '<p class="muted">No call-level routing summaries yet. Run a voice session or provider simulation.</p>';
4809
4968
  }
4810
4969
  return `<div class="session-grid">${sessions.slice(0, 12).map((session) => `
4811
- <article class="card session ${escapeHtml6(session.status)}">
4970
+ <article class="card session ${escapeHtml7(session.status)}">
4812
4971
  <div class="card-header">
4813
- <strong>${escapeHtml6(session.sessionId)}</strong>
4814
- <span>${escapeHtml6(session.status)}</span>
4972
+ <strong>${escapeHtml7(session.sessionId)}</strong>
4973
+ <span>${escapeHtml7(session.status)}</span>
4815
4974
  </div>
4816
4975
  <p>
4817
4976
  <span class="pill">${session.eventCount} routing events</span>
@@ -4838,21 +4997,21 @@ var renderSimulationControls = (kind, simulation) => {
4838
4997
  const pathPrefix = simulation.pathPrefix ?? `/api/${kind}-simulate`;
4839
4998
  const failureProviders = simulation.failureProviders ?? configuredProviders.map(({ provider }) => provider);
4840
4999
  const canFail = (provider) => configuredProviders.some((entry) => entry.provider === provider) && (!simulation.fallbackRequiredProvider || configuredProviders.some((entry) => entry.provider === simulation.fallbackRequiredProvider));
4841
- return `<div class="simulate-panel" data-sim-kind="${kind}" data-sim-prefix="${escapeHtml6(pathPrefix)}">
4842
- <p class="muted">${escapeHtml6(simulation.failureMessage ?? `Simulate ${kind.toUpperCase()} provider failure without changing provider credentials.`)}</p>
5000
+ return `<div class="simulate-panel" data-sim-kind="${kind}" data-sim-prefix="${escapeHtml7(pathPrefix)}">
5001
+ <p class="muted">${escapeHtml7(simulation.failureMessage ?? `Simulate ${kind.toUpperCase()} provider failure without changing provider credentials.`)}</p>
4843
5002
  <div class="simulate-actions">
4844
- ${failureProviders.map((provider) => `<button type="button" data-provider-fail="${escapeHtml6(provider)}"${canFail(provider) ? "" : " disabled"}>Simulate ${escapeHtml6(provider)} ${kind.toUpperCase()} failure</button>`).join("")}
4845
- ${configuredProviders.map((provider) => `<button type="button" data-provider-recover="${escapeHtml6(provider.provider)}">Mark ${escapeHtml6(provider.provider)} recovered</button>`).join("")}
5003
+ ${failureProviders.map((provider) => `<button type="button" data-provider-fail="${escapeHtml7(provider)}"${canFail(provider) ? "" : " disabled"}>Simulate ${escapeHtml7(provider)} ${kind.toUpperCase()} failure</button>`).join("")}
5004
+ ${configuredProviders.map((provider) => `<button type="button" data-provider-recover="${escapeHtml7(provider.provider)}">Mark ${escapeHtml7(provider.provider)} recovered</button>`).join("")}
4846
5005
  </div>
4847
- ${simulation.fallbackRequiredProvider && !configuredProviders.some((entry) => entry.provider === simulation.fallbackRequiredProvider) ? `<p class="muted">${escapeHtml6(simulation.fallbackRequiredMessage ?? `Configure ${simulation.fallbackRequiredProvider} to enable fallback simulation.`)}</p>` : ""}
5006
+ ${simulation.fallbackRequiredProvider && !configuredProviders.some((entry) => entry.provider === simulation.fallbackRequiredProvider) ? `<p class="muted">${escapeHtml7(simulation.fallbackRequiredMessage ?? `Configure ${simulation.fallbackRequiredProvider} to enable fallback simulation.`)}</p>` : ""}
4848
5007
  <pre class="simulate-output" hidden></pre>
4849
5008
  </div>`;
4850
5009
  };
4851
5010
  var renderVoiceResilienceHTML = (input) => {
4852
5011
  const summary = summarizeRoutingEvents(input.routingEvents);
4853
- const kindCounts = [...summary.byKind.entries()].map(([kind, count]) => `<span class="pill">${escapeHtml6(kind)}: ${String(count)}</span>`).join("");
4854
- const links = input.links?.length ? input.links.map((link) => `<a href="${escapeHtml6(link.href)}">${escapeHtml6(link.label)}</a>`).join(" \xB7 ") : "";
4855
- const snippet = escapeHtml6(`const sttSimulator = createVoiceIOProviderFailureSimulator({
5012
+ const kindCounts = [...summary.byKind.entries()].map(([kind, count]) => `<span class="pill">${escapeHtml7(kind)}: ${String(count)}</span>`).join("");
5013
+ const links = input.links?.length ? input.links.map((link) => `<a href="${escapeHtml7(link.href)}">${escapeHtml7(link.label)}</a>`).join(" \xB7 ") : "";
5014
+ const snippet = escapeHtml7(`const sttSimulator = createVoiceIOProviderFailureSimulator({
4856
5015
  kind: 'stt',
4857
5016
  providers: ['deepgram', 'assemblyai'],
4858
5017
  fallback: ['deepgram', 'assemblyai'],
@@ -4890,7 +5049,7 @@ app.use(
4890
5049
  <head>
4891
5050
  <meta charset="utf-8" />
4892
5051
  <meta name="viewport" content="width=device-width, initial-scale=1" />
4893
- <title>${escapeHtml6(input.title ?? "AbsoluteJS Voice Resilience")}</title>
5052
+ <title>${escapeHtml7(input.title ?? "AbsoluteJS Voice Resilience")}</title>
4894
5053
  <style>
4895
5054
  :root { color-scheme: dark; }
4896
5055
  body { background: radial-gradient(circle at top left, #172554, #09090b 36%, #050505); color: #f4f4f5; font-family: ui-sans-serif, system-ui, sans-serif; margin: 0; padding: 24px; }
@@ -5083,7 +5242,7 @@ var createVoiceResilienceRoutes = (options) => {
5083
5242
  };
5084
5243
 
5085
5244
  // src/providerDecisionTraces.ts
5086
- var escapeHtml7 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
5245
+ var escapeHtml8 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
5087
5246
  var getString3 = (value) => typeof value === "string" ? value : undefined;
5088
5247
  var getNumber3 = (value) => typeof value === "number" && Number.isFinite(value) ? value : undefined;
5089
5248
  var isDecisionTrace = (event) => Boolean(event && typeof event === "object" && "provider" in event && "reason" in event && "sessionId" in event && "status" in event && "surface" in event);
@@ -5324,7 +5483,7 @@ var renderVoiceProviderDecisionTraceHTML = (report, title = "Provider Decision T
5324
5483
  <head>
5325
5484
  <meta charset="utf-8" />
5326
5485
  <meta name="viewport" content="width=device-width, initial-scale=1" />
5327
- <title>${escapeHtml7(title)}</title>
5486
+ <title>${escapeHtml8(title)}</title>
5328
5487
  <style>
5329
5488
  body{font-family:ui-sans-serif,system-ui,sans-serif;margin:0;background:#f8fafc;color:#0f172a}
5330
5489
  main{max-width:1100px;margin:0 auto;padding:32px}
@@ -5338,8 +5497,8 @@ code{background:#e2e8f0;border-radius:8px;padding:2px 6px}
5338
5497
  </head>
5339
5498
  <body>
5340
5499
  <main>
5341
- <p class="status ${report.status}">${escapeHtml7(report.status)}</p>
5342
- <h1>${escapeHtml7(title)}</h1>
5500
+ <p class="status ${report.status}">${escapeHtml8(report.status)}</p>
5501
+ <h1>${escapeHtml8(title)}</h1>
5343
5502
  <p class="muted">Runtime proof for why providers were selected, skipped, failed, or recovered by fallback.</p>
5344
5503
  <section class="grid">
5345
5504
  <article class="card"><strong>${String(report.summary.decisions)}</strong><p>decisions</p></article>
@@ -5350,10 +5509,10 @@ code{background:#e2e8f0;border-radius:8px;padding:2px 6px}
5350
5509
  </section>
5351
5510
  <section class="surfaces">
5352
5511
  ${report.surfaces.map((surface) => `<article class="surface">
5353
- <header><strong>${escapeHtml7(surface.surface)}</strong> <span class="status ${surface.status}">${escapeHtml7(surface.status)}</span></header>
5512
+ <header><strong>${escapeHtml8(surface.surface)}</strong> <span class="status ${surface.status}">${escapeHtml8(surface.status)}</span></header>
5354
5513
  <p>${String(surface.decisions)} decision(s), ${String(surface.fallbacks)} fallback(s), ${String(surface.degraded)} degraded decision(s), ${String(surface.errors)} error(s).</p>
5355
- <p class="muted">Providers: ${escapeHtml7(surface.providers.join(", ") || "none")}</p>
5356
- <p>${surface.reasons.map((reason) => `<code>${escapeHtml7(reason)}</code>`).join(" ")}</p>
5514
+ <p class="muted">Providers: ${escapeHtml8(surface.providers.join(", ") || "none")}</p>
5515
+ <p>${surface.reasons.map((reason) => `<code>${escapeHtml8(reason)}</code>`).join(" ")}</p>
5357
5516
  </article>`).join(`
5358
5517
  `)}
5359
5518
  </section>
@@ -5871,7 +6030,7 @@ var exportVoiceTrace = async (input) => {
5871
6030
  };
5872
6031
  };
5873
6032
  var toNumber = (value) => typeof value === "number" && Number.isFinite(value) ? value : 0;
5874
- var escapeHtml8 = (value) => value.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;");
6033
+ var escapeHtml9 = (value) => value.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;");
5875
6034
  var formatTraceValue = (value) => {
5876
6035
  if (value === undefined || value === null) {
5877
6036
  return "";
@@ -6155,10 +6314,10 @@ var renderVoiceTraceHTML = (events, options = {}) => {
6155
6314
  const offset = summary.startedAt === undefined ? event.at : Math.max(0, event.at - summary.startedAt);
6156
6315
  return [
6157
6316
  "<tr>",
6158
- `<td>${escapeHtml8(String(offset))}</td>`,
6159
- `<td>${escapeHtml8(event.type)}</td>`,
6160
- `<td>${escapeHtml8(event.turnId ?? "")}</td>`,
6161
- `<td><code>${escapeHtml8(JSON.stringify(event.payload))}</code></td>`,
6317
+ `<td>${escapeHtml9(String(offset))}</td>`,
6318
+ `<td>${escapeHtml9(event.type)}</td>`,
6319
+ `<td>${escapeHtml9(event.turnId ?? "")}</td>`,
6320
+ `<td><code>${escapeHtml9(JSON.stringify(event.payload))}</code></td>`,
6162
6321
  "</tr>"
6163
6322
  ].join("");
6164
6323
  }).join(`
@@ -6169,7 +6328,7 @@ var renderVoiceTraceHTML = (events, options = {}) => {
6169
6328
  "<head>",
6170
6329
  '<meta charset="utf-8" />',
6171
6330
  '<meta name="viewport" content="width=device-width, initial-scale=1" />',
6172
- `<title>${escapeHtml8(options.title ?? "Voice Trace")}</title>`,
6331
+ `<title>${escapeHtml9(options.title ?? "Voice Trace")}</title>`,
6173
6332
  "<style>",
6174
6333
  "body{font-family:ui-sans-serif,system-ui,sans-serif;margin:2rem;line-height:1.45;background:#f8f7f2;color:#181713}",
6175
6334
  "main{max-width:1100px;margin:auto}",
@@ -6183,7 +6342,7 @@ var renderVoiceTraceHTML = (events, options = {}) => {
6183
6342
  "</style>",
6184
6343
  "</head>",
6185
6344
  "<body><main>",
6186
- `<h1>${escapeHtml8(options.title ?? `Voice Trace ${summary.sessionId ?? ""}`.trim())}</h1>`,
6345
+ `<h1>${escapeHtml9(options.title ?? `Voice Trace ${summary.sessionId ?? ""}`.trim())}</h1>`,
6187
6346
  `<p class="${evaluation.pass ? "pass" : "fail"}">QA: ${evaluation.pass ? "pass" : "fail"}</p>`,
6188
6347
  '<section class="summary">',
6189
6348
  `<div class="card"><strong>Events</strong><br>${summary.eventCount}</div>`,
@@ -6197,7 +6356,7 @@ var renderVoiceTraceHTML = (events, options = {}) => {
6197
6356
  eventRows,
6198
6357
  "</tbody></table>",
6199
6358
  "<h2>Markdown Export</h2>",
6200
- `<pre>${escapeHtml8(markdown)}</pre>`,
6359
+ `<pre>${escapeHtml9(markdown)}</pre>`,
6201
6360
  "</main></body></html>"
6202
6361
  ].join(`
6203
6362
  `);
@@ -8519,7 +8678,7 @@ var buildVoiceProofTrendRecommendationReport = (report, options = {}) => {
8519
8678
  }
8520
8679
  };
8521
8680
  };
8522
- var escapeHtml9 = (value) => String(value).replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
8681
+ var escapeHtml10 = (value) => String(value).replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
8523
8682
  var escapeMarkdown = (value) => value.replaceAll("|", "\\|");
8524
8683
  var renderVoiceProofTrendRecommendationMarkdown = (report, title = "Voice Provider Runtime Recommendations") => [
8525
8684
  `# ${title}`,
@@ -8554,11 +8713,11 @@ var renderVoiceProofTrendRecommendationMarkdown = (report, title = "Voice Provid
8554
8713
  ].join(`
8555
8714
  `);
8556
8715
  var renderVoiceProofTrendRecommendationHTML = (report, title = "Voice Provider Runtime Recommendations") => {
8557
- const cards = report.recommendations.map((recommendation) => `<article class="${escapeHtml9(recommendation.status)}"><p class="eyebrow">${escapeHtml9(recommendation.surface)} \xB7 ${escapeHtml9(recommendation.status)}</p><h2>${escapeHtml9(recommendation.recommendation)}</h2><p>${escapeHtml9(recommendation.nextMove)}</p><pre>${escapeHtml9(JSON.stringify(recommendation.evidence, null, 2))}</pre></article>`).join("");
8558
- const issues = report.issues.length === 0 ? "<li>None</li>" : report.issues.map((issue) => `<li>${escapeHtml9(issue)}</li>`).join("");
8559
- const providerRows = report.providers.length === 0 ? "<li>No provider-specific samples were present.</li>" : report.providers.map((provider) => `<li><strong>#${String(provider.rank)} ${escapeHtml9(provider.label ?? provider.id)}</strong><span>${escapeHtml9(provider.role ?? "provider")} \xB7 ${escapeHtml9(provider.status)} \xB7 p95 ${escapeHtml9(provider.p95Ms ?? "n/a")}ms \xB7 ${escapeHtml9(provider.samples ?? "n/a")} sample(s)</span><small>${escapeHtml9(provider.nextMove)}</small></li>`).join("");
8560
- const profileRows = report.profiles.length === 0 ? "<li>No benchmark profiles were present.</li>" : report.profiles.map((profile) => `<li><strong>${escapeHtml9(profile.label ?? profile.id)}</strong><span>${escapeHtml9(profile.status)} \xB7 ${escapeHtml9(formatProviderMix(profile.bestProviders))}</span><small>${escapeHtml9(profile.nextMove)}</small></li>`).join("");
8561
- return `<!doctype html><html lang="en"><head><meta charset="utf-8" /><meta name="viewport" content="width=device-width,initial-scale=1" /><title>${escapeHtml9(title)}</title><style>body{background:#101418;color:#f7f3e8;font-family:ui-sans-serif,system-ui,sans-serif;margin:0}main{margin:auto;max-width:1120px;padding:32px}.hero,article{background:#17201d;border:1px solid #2e3d36;border-radius:24px;margin-bottom:16px;padding:22px}.hero{background:linear-gradient(135deg,rgba(20,184,166,.18),rgba(245,158,11,.12))}.eyebrow{color:#5eead4;font-weight:900;letter-spacing:.1em;text-transform:uppercase}h1{font-size:clamp(2.2rem,6vw,4.7rem);letter-spacing:-.06em;line-height:.92;margin:.2rem 0 1rem}.summary{display:flex;flex-wrap:wrap;gap:10px}.pill{border:1px solid #42534a;border-radius:999px;padding:8px 12px}.pass{border-color:rgba(34,197,94,.55)}.warn{border-color:rgba(245,158,11,.7)}.fail{border-color:rgba(239,68,68,.75)}pre{background:#0b1110;border-radius:14px;overflow:auto;padding:12px}a{color:#5eead4}li{margin:.45rem 0}li span,li small{display:block;color:#c9d3ca}</style></head><body><main><section class="hero"><p class="eyebrow">Sustained proof recommendations</p><h1>${escapeHtml9(title)}</h1><p>Generated ${escapeHtml9(report.generatedAt)} from ${escapeHtml9(report.source)}.</p><div class="summary"><span class="pill">Status ${escapeHtml9(report.status)}</span><span class="pill">Provider ${report.summary.keepCurrentProviderPath ? "keep" : "change"}</span><span class="pill">Best mix ${escapeHtml9(formatProviderMix(report.bestProviders))}</span><span class="pill">Profiles ${String(report.profiles.length)}</span><span class="pill">Runtime ${report.summary.keepCurrentRuntimeChannel ? "keep" : "tune"}</span><span class="pill">${String(report.summary.recommendedActions)} action(s)</span></div></section>${cards}<section class="hero"><h2>Benchmark Profiles</h2><ul>${profileRows}</ul></section><section class="hero"><h2>Provider Comparison</h2><ul>${providerRows}</ul></section><section class="hero"><h2>Issues</h2><ul>${issues}</ul></section></main></body></html>`;
8716
+ const cards = report.recommendations.map((recommendation) => `<article class="${escapeHtml10(recommendation.status)}"><p class="eyebrow">${escapeHtml10(recommendation.surface)} \xB7 ${escapeHtml10(recommendation.status)}</p><h2>${escapeHtml10(recommendation.recommendation)}</h2><p>${escapeHtml10(recommendation.nextMove)}</p><pre>${escapeHtml10(JSON.stringify(recommendation.evidence, null, 2))}</pre></article>`).join("");
8717
+ const issues = report.issues.length === 0 ? "<li>None</li>" : report.issues.map((issue) => `<li>${escapeHtml10(issue)}</li>`).join("");
8718
+ const providerRows = report.providers.length === 0 ? "<li>No provider-specific samples were present.</li>" : report.providers.map((provider) => `<li><strong>#${String(provider.rank)} ${escapeHtml10(provider.label ?? provider.id)}</strong><span>${escapeHtml10(provider.role ?? "provider")} \xB7 ${escapeHtml10(provider.status)} \xB7 p95 ${escapeHtml10(provider.p95Ms ?? "n/a")}ms \xB7 ${escapeHtml10(provider.samples ?? "n/a")} sample(s)</span><small>${escapeHtml10(provider.nextMove)}</small></li>`).join("");
8719
+ const profileRows = report.profiles.length === 0 ? "<li>No benchmark profiles were present.</li>" : report.profiles.map((profile) => `<li><strong>${escapeHtml10(profile.label ?? profile.id)}</strong><span>${escapeHtml10(profile.status)} \xB7 ${escapeHtml10(formatProviderMix(profile.bestProviders))}</span><small>${escapeHtml10(profile.nextMove)}</small></li>`).join("");
8720
+ return `<!doctype html><html lang="en"><head><meta charset="utf-8" /><meta name="viewport" content="width=device-width,initial-scale=1" /><title>${escapeHtml10(title)}</title><style>body{background:#101418;color:#f7f3e8;font-family:ui-sans-serif,system-ui,sans-serif;margin:0}main{margin:auto;max-width:1120px;padding:32px}.hero,article{background:#17201d;border:1px solid #2e3d36;border-radius:24px;margin-bottom:16px;padding:22px}.hero{background:linear-gradient(135deg,rgba(20,184,166,.18),rgba(245,158,11,.12))}.eyebrow{color:#5eead4;font-weight:900;letter-spacing:.1em;text-transform:uppercase}h1{font-size:clamp(2.2rem,6vw,4.7rem);letter-spacing:-.06em;line-height:.92;margin:.2rem 0 1rem}.summary{display:flex;flex-wrap:wrap;gap:10px}.pill{border:1px solid #42534a;border-radius:999px;padding:8px 12px}.pass{border-color:rgba(34,197,94,.55)}.warn{border-color:rgba(245,158,11,.7)}.fail{border-color:rgba(239,68,68,.75)}pre{background:#0b1110;border-radius:14px;overflow:auto;padding:12px}a{color:#5eead4}li{margin:.45rem 0}li span,li small{display:block;color:#c9d3ca}</style></head><body><main><section class="hero"><p class="eyebrow">Sustained proof recommendations</p><h1>${escapeHtml10(title)}</h1><p>Generated ${escapeHtml10(report.generatedAt)} from ${escapeHtml10(report.source)}.</p><div class="summary"><span class="pill">Status ${escapeHtml10(report.status)}</span><span class="pill">Provider ${report.summary.keepCurrentProviderPath ? "keep" : "change"}</span><span class="pill">Best mix ${escapeHtml10(formatProviderMix(report.bestProviders))}</span><span class="pill">Profiles ${String(report.profiles.length)}</span><span class="pill">Runtime ${report.summary.keepCurrentRuntimeChannel ? "keep" : "tune"}</span><span class="pill">${String(report.summary.recommendedActions)} action(s)</span></div></section>${cards}<section class="hero"><h2>Benchmark Profiles</h2><ul>${profileRows}</ul></section><section class="hero"><h2>Provider Comparison</h2><ul>${providerRows}</ul></section><section class="hero"><h2>Issues</h2><ul>${issues}</ul></section></main></body></html>`;
8562
8721
  };
8563
8722
  var renderVoiceRealCallProfileHistoryMarkdown = (report, title = "Voice Real-Call Profile History") => [
8564
8723
  `# ${title}`,
@@ -8592,11 +8751,11 @@ var renderVoiceRealCallProfileHistoryMarkdown = (report, title = "Voice Real-Cal
8592
8751
  ].join(`
8593
8752
  `);
8594
8753
  var renderVoiceRealCallProfileHistoryHTML = (report, title = "Voice Real-Call Profile History") => {
8595
- const profileRows = report.summary.profiles?.length ? report.summary.profiles.map((profile) => `<tr><td>${escapeHtml9(profile.label ?? profile.id)}</td><td>${escapeHtml9(profile.status ?? "unknown")}</td><td>${escapeHtml9(profile.maxLiveP95Ms ?? "n/a")}</td><td>${escapeHtml9(profile.maxProviderP95Ms ?? "n/a")}</td><td>${escapeHtml9(profile.maxTurnP95Ms ?? "n/a")}</td><td>${escapeHtml9(formatProviderMix(profile.providers ?? []))}</td></tr>`).join("") : '<tr><td colspan="6">No profiles present.</td></tr>';
8596
- const defaultRows = report.defaults.profiles.length > 0 ? report.defaults.profiles.map((profile) => `<tr><td>${escapeHtml9(profile.label ?? profile.profileId)}</td><td>${escapeHtml9(profile.status)}</td><td>${escapeHtml9(Object.entries(profile.providerRoutes).map(([role, provider]) => `${role}: ${provider}`).join(", ") || "n/a")}</td><td>${escapeHtml9(profile.latencyBudgets.maxLiveP95Ms ?? "n/a")}</td><td>${escapeHtml9(profile.latencyBudgets.maxProviderP95Ms ?? "n/a")}</td><td>${escapeHtml9(profile.latencyBudgets.maxTurnP95Ms ?? "n/a")}</td></tr>`).join("") : '<tr><td colspan="6">No actionable defaults present.</td></tr>';
8597
- const recommendations = report.recommendations.recommendations.map((recommendation) => `<article class="${escapeHtml9(recommendation.status)}"><p class="eyebrow">${escapeHtml9(recommendation.surface)} \xB7 ${escapeHtml9(recommendation.status)}</p><h2>${escapeHtml9(recommendation.recommendation)}</h2><p>${escapeHtml9(recommendation.nextMove)}</p></article>`).join("");
8598
- const issues = report.issues.length === 0 ? "<li>None</li>" : report.issues.map((issue) => `<li>${escapeHtml9(issue)}</li>`).join("");
8599
- return `<!doctype html><html lang="en"><head><meta charset="utf-8" /><meta name="viewport" content="width=device-width,initial-scale=1" /><title>${escapeHtml9(title)}</title><style>body{background:#111510;color:#f6f0dd;font-family:ui-sans-serif,system-ui,sans-serif;margin:0}main{margin:auto;max-width:1120px;padding:32px}.hero,article,.card{background:#182117;border:1px solid #32412d;border-radius:24px;margin-bottom:16px;padding:22px}.hero{background:linear-gradient(135deg,rgba(132,204,22,.16),rgba(20,184,166,.12))}.eyebrow{color:#bef264;font-weight:900;letter-spacing:.1em;text-transform:uppercase}h1{font-size:clamp(2.2rem,6vw,4.7rem);letter-spacing:-.06em;line-height:.92;margin:.2rem 0 1rem}.summary{display:flex;flex-wrap:wrap;gap:10px}.pill{border:1px solid #52624b;border-radius:999px;padding:8px 12px}.pass{border-color:rgba(34,197,94,.55)}.warn{border-color:rgba(245,158,11,.7)}.fail{border-color:rgba(239,68,68,.75)}table{border-collapse:collapse;width:100%}td,th{border-bottom:1px solid #32412d;padding:10px;text-align:left}</style></head><body><main><section class="hero"><p class="eyebrow">Real-call benchmark history</p><h1>${escapeHtml9(title)}</h1><p>Generated ${escapeHtml9(report.generatedAt)} from ${escapeHtml9(report.source)}.</p><div class="summary"><span class="pill">Status ${escapeHtml9(report.status)}</span><span class="pill">Reports ${String(report.reports)}</span><span class="pill">Profiles ${String(report.summary.profileCount)}</span><span class="pill">Defaults ${String(report.defaults.summary.actionableProfiles)}/${String(report.defaults.summary.profileCount)}</span><span class="pill">Cycles ${String(report.summary.cycles ?? 0)}</span><span class="pill">Best mix ${escapeHtml9(formatProviderMix(report.recommendations.bestProviders))}</span></div></section><section class="card"><h2>Profiles</h2><table><thead><tr><th>Profile</th><th>Status</th><th>Live p95</th><th>Provider p95</th><th>Turn p95</th><th>Provider mix</th></tr></thead><tbody>${profileRows}</tbody></table></section><section class="card"><h2>Actionable Defaults</h2><table><thead><tr><th>Profile</th><th>Status</th><th>Provider routes</th><th>Live budget</th><th>Provider budget</th><th>Turn budget</th></tr></thead><tbody>${defaultRows}</tbody></table></section>${recommendations}<section class="card"><h2>Issues</h2><ul>${issues}</ul></section></main></body></html>`;
8754
+ const profileRows = report.summary.profiles?.length ? report.summary.profiles.map((profile) => `<tr><td>${escapeHtml10(profile.label ?? profile.id)}</td><td>${escapeHtml10(profile.status ?? "unknown")}</td><td>${escapeHtml10(profile.maxLiveP95Ms ?? "n/a")}</td><td>${escapeHtml10(profile.maxProviderP95Ms ?? "n/a")}</td><td>${escapeHtml10(profile.maxTurnP95Ms ?? "n/a")}</td><td>${escapeHtml10(formatProviderMix(profile.providers ?? []))}</td></tr>`).join("") : '<tr><td colspan="6">No profiles present.</td></tr>';
8755
+ const defaultRows = report.defaults.profiles.length > 0 ? report.defaults.profiles.map((profile) => `<tr><td>${escapeHtml10(profile.label ?? profile.profileId)}</td><td>${escapeHtml10(profile.status)}</td><td>${escapeHtml10(Object.entries(profile.providerRoutes).map(([role, provider]) => `${role}: ${provider}`).join(", ") || "n/a")}</td><td>${escapeHtml10(profile.latencyBudgets.maxLiveP95Ms ?? "n/a")}</td><td>${escapeHtml10(profile.latencyBudgets.maxProviderP95Ms ?? "n/a")}</td><td>${escapeHtml10(profile.latencyBudgets.maxTurnP95Ms ?? "n/a")}</td></tr>`).join("") : '<tr><td colspan="6">No actionable defaults present.</td></tr>';
8756
+ const recommendations = report.recommendations.recommendations.map((recommendation) => `<article class="${escapeHtml10(recommendation.status)}"><p class="eyebrow">${escapeHtml10(recommendation.surface)} \xB7 ${escapeHtml10(recommendation.status)}</p><h2>${escapeHtml10(recommendation.recommendation)}</h2><p>${escapeHtml10(recommendation.nextMove)}</p></article>`).join("");
8757
+ const issues = report.issues.length === 0 ? "<li>None</li>" : report.issues.map((issue) => `<li>${escapeHtml10(issue)}</li>`).join("");
8758
+ return `<!doctype html><html lang="en"><head><meta charset="utf-8" /><meta name="viewport" content="width=device-width,initial-scale=1" /><title>${escapeHtml10(title)}</title><style>body{background:#111510;color:#f6f0dd;font-family:ui-sans-serif,system-ui,sans-serif;margin:0}main{margin:auto;max-width:1120px;padding:32px}.hero,article,.card{background:#182117;border:1px solid #32412d;border-radius:24px;margin-bottom:16px;padding:22px}.hero{background:linear-gradient(135deg,rgba(132,204,22,.16),rgba(20,184,166,.12))}.eyebrow{color:#bef264;font-weight:900;letter-spacing:.1em;text-transform:uppercase}h1{font-size:clamp(2.2rem,6vw,4.7rem);letter-spacing:-.06em;line-height:.92;margin:.2rem 0 1rem}.summary{display:flex;flex-wrap:wrap;gap:10px}.pill{border:1px solid #52624b;border-radius:999px;padding:8px 12px}.pass{border-color:rgba(34,197,94,.55)}.warn{border-color:rgba(245,158,11,.7)}.fail{border-color:rgba(239,68,68,.75)}table{border-collapse:collapse;width:100%}td,th{border-bottom:1px solid #32412d;padding:10px;text-align:left}</style></head><body><main><section class="hero"><p class="eyebrow">Real-call benchmark history</p><h1>${escapeHtml10(title)}</h1><p>Generated ${escapeHtml10(report.generatedAt)} from ${escapeHtml10(report.source)}.</p><div class="summary"><span class="pill">Status ${escapeHtml10(report.status)}</span><span class="pill">Reports ${String(report.reports)}</span><span class="pill">Profiles ${String(report.summary.profileCount)}</span><span class="pill">Defaults ${String(report.defaults.summary.actionableProfiles)}/${String(report.defaults.summary.profileCount)}</span><span class="pill">Cycles ${String(report.summary.cycles ?? 0)}</span><span class="pill">Best mix ${escapeHtml10(formatProviderMix(report.recommendations.bestProviders))}</span></div></section><section class="card"><h2>Profiles</h2><table><thead><tr><th>Profile</th><th>Status</th><th>Live p95</th><th>Provider p95</th><th>Turn p95</th><th>Provider mix</th></tr></thead><tbody>${profileRows}</tbody></table></section><section class="card"><h2>Actionable Defaults</h2><table><thead><tr><th>Profile</th><th>Status</th><th>Provider routes</th><th>Live budget</th><th>Provider budget</th><th>Turn budget</th></tr></thead><tbody>${defaultRows}</tbody></table></section>${recommendations}<section class="card"><h2>Issues</h2><ul>${issues}</ul></section></main></body></html>`;
8600
8759
  };
8601
8760
  var renderVoiceRealCallEvidenceRuntimeMarkdown = (report, title = "Voice Real-Call Evidence Runtime") => [
8602
8761
  `# ${title}`,
@@ -8619,9 +8778,9 @@ var renderVoiceRealCallEvidenceRuntimeMarkdown = (report, title = "Voice Real-Ca
8619
8778
  ].join(`
8620
8779
  `);
8621
8780
  var renderVoiceRealCallEvidenceRuntimeHTML = (report, title = "Voice Real-Call Evidence Runtime") => {
8622
- const issueItems = report.issues.length === 0 ? "<li>None</li>" : report.issues.map((issue) => `<li>${escapeHtml9(issue)}</li>`).join("");
8623
- const profileRows = report.history.summary.profiles?.length ? report.history.summary.profiles.map((profile) => `<tr><td>${escapeHtml9(profile.label ?? profile.id)}</td><td>${escapeHtml9(profile.status ?? "unknown")}</td><td>${escapeHtml9(profile.sessionCount ?? "n/a")}</td><td>${escapeHtml9(profile.maxLiveP95Ms ?? "n/a")}</td><td>${escapeHtml9(profile.maxProviderP95Ms ?? "n/a")}</td><td>${escapeHtml9(formatProviderMix(profile.providers ?? []))}</td></tr>`).join("") : '<tr><td colspan="6">No profile history has been collected yet.</td></tr>';
8624
- return `<!doctype html><html lang="en"><head><meta charset="utf-8" /><meta name="viewport" content="width=device-width,initial-scale=1" /><title>${escapeHtml9(title)}</title><style>body{background:#0f1618;color:#f2f7f2;font-family:ui-sans-serif,system-ui,sans-serif;margin:0}main{margin:auto;max-width:1120px;padding:32px}.hero,.card{background:#162225;border:1px solid #2f4548;border-radius:24px;margin-bottom:16px;padding:22px}.hero{background:linear-gradient(135deg,rgba(20,184,166,.18),rgba(132,204,22,.1))}.eyebrow{color:#99f6e4;font-weight:900;letter-spacing:.1em;text-transform:uppercase}h1{font-size:clamp(2.1rem,6vw,4.3rem);letter-spacing:-.06em;line-height:.94;margin:.2rem 0 1rem}.summary{display:flex;flex-wrap:wrap;gap:10px}.pill{border:1px solid #4b6669;border-radius:999px;padding:8px 12px}.pass{border-color:rgba(34,197,94,.55)}.warn{border-color:rgba(245,158,11,.7)}.fail,.empty,.stale{border-color:rgba(239,68,68,.75)}table{border-collapse:collapse;width:100%}td,th{border-bottom:1px solid #2f4548;padding:10px;text-align:left}</style></head><body><main><section class="hero"><p class="eyebrow">Real-call evidence runtime</p><h1>${escapeHtml9(title)}</h1><p>Generated ${escapeHtml9(report.generatedAt)} from ${escapeHtml9(report.source)}.</p><div class="summary"><span class="pill ${escapeHtml9(report.status)}">Status ${escapeHtml9(report.status)}</span><span class="pill">Stored ${String(report.summary.storedEvidence)}</span><span class="pill">Collected ${String(report.summary.collectedEvidence)}</span><span class="pill">Appended ${String(report.appended)}</span><span class="pill">Duplicates ${String(report.skippedDuplicates)}</span><span class="pill">Sessions ${String(report.summary.sessions)}</span><span class="pill">Profiles ${String(report.summary.profiles)}</span></div></section><section class="card"><h2>Rolling Profile History</h2><table><thead><tr><th>Profile</th><th>Status</th><th>Sessions</th><th>Live p95</th><th>Provider p95</th><th>Provider mix</th></tr></thead><tbody>${profileRows}</tbody></table></section><section class="card"><h2>Issues</h2><ul>${issueItems}</ul></section></main></body></html>`;
8781
+ const issueItems = report.issues.length === 0 ? "<li>None</li>" : report.issues.map((issue) => `<li>${escapeHtml10(issue)}</li>`).join("");
8782
+ const profileRows = report.history.summary.profiles?.length ? report.history.summary.profiles.map((profile) => `<tr><td>${escapeHtml10(profile.label ?? profile.id)}</td><td>${escapeHtml10(profile.status ?? "unknown")}</td><td>${escapeHtml10(profile.sessionCount ?? "n/a")}</td><td>${escapeHtml10(profile.maxLiveP95Ms ?? "n/a")}</td><td>${escapeHtml10(profile.maxProviderP95Ms ?? "n/a")}</td><td>${escapeHtml10(formatProviderMix(profile.providers ?? []))}</td></tr>`).join("") : '<tr><td colspan="6">No profile history has been collected yet.</td></tr>';
8783
+ return `<!doctype html><html lang="en"><head><meta charset="utf-8" /><meta name="viewport" content="width=device-width,initial-scale=1" /><title>${escapeHtml10(title)}</title><style>body{background:#0f1618;color:#f2f7f2;font-family:ui-sans-serif,system-ui,sans-serif;margin:0}main{margin:auto;max-width:1120px;padding:32px}.hero,.card{background:#162225;border:1px solid #2f4548;border-radius:24px;margin-bottom:16px;padding:22px}.hero{background:linear-gradient(135deg,rgba(20,184,166,.18),rgba(132,204,22,.1))}.eyebrow{color:#99f6e4;font-weight:900;letter-spacing:.1em;text-transform:uppercase}h1{font-size:clamp(2.1rem,6vw,4.3rem);letter-spacing:-.06em;line-height:.94;margin:.2rem 0 1rem}.summary{display:flex;flex-wrap:wrap;gap:10px}.pill{border:1px solid #4b6669;border-radius:999px;padding:8px 12px}.pass{border-color:rgba(34,197,94,.55)}.warn{border-color:rgba(245,158,11,.7)}.fail,.empty,.stale{border-color:rgba(239,68,68,.75)}table{border-collapse:collapse;width:100%}td,th{border-bottom:1px solid #2f4548;padding:10px;text-align:left}</style></head><body><main><section class="hero"><p class="eyebrow">Real-call evidence runtime</p><h1>${escapeHtml10(title)}</h1><p>Generated ${escapeHtml10(report.generatedAt)} from ${escapeHtml10(report.source)}.</p><div class="summary"><span class="pill ${escapeHtml10(report.status)}">Status ${escapeHtml10(report.status)}</span><span class="pill">Stored ${String(report.summary.storedEvidence)}</span><span class="pill">Collected ${String(report.summary.collectedEvidence)}</span><span class="pill">Appended ${String(report.appended)}</span><span class="pill">Duplicates ${String(report.skippedDuplicates)}</span><span class="pill">Sessions ${String(report.summary.sessions)}</span><span class="pill">Profiles ${String(report.summary.profiles)}</span></div></section><section class="card"><h2>Rolling Profile History</h2><table><thead><tr><th>Profile</th><th>Status</th><th>Sessions</th><th>Live p95</th><th>Provider p95</th><th>Provider mix</th></tr></thead><tbody>${profileRows}</tbody></table></section><section class="card"><h2>Issues</h2><ul>${issueItems}</ul></section></main></body></html>`;
8625
8784
  };
8626
8785
  var createVoiceProofTrendRecommendationRoutes = (options) => {
8627
8786
  const path = options.path ?? "/api/voice/proof-trend-recommendations";
@@ -8973,14 +9132,14 @@ var formatVoiceProofTrendAge = (ageMs) => {
8973
9132
  };
8974
9133
 
8975
9134
  // src/client/proofTrendsWidget.ts
8976
- var DEFAULT_TITLE5 = "Sustained Proof Trends";
8977
- var DEFAULT_DESCRIPTION5 = "Repeated-cycle provider, latency, recovery, and readiness evidence with freshness gating.";
9135
+ var DEFAULT_TITLE6 = "Sustained Proof Trends";
9136
+ var DEFAULT_DESCRIPTION6 = "Repeated-cycle provider, latency, recovery, and readiness evidence with freshness gating.";
8978
9137
  var DEFAULT_LINKS2 = [
8979
9138
  { href: "/voice/proof-trends", label: "Trend page" },
8980
9139
  { href: "/api/voice/proof-trends", label: "Trend JSON" }
8981
9140
  ];
8982
- var escapeHtml10 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
8983
- var formatMs = (value) => typeof value === "number" && Number.isFinite(value) ? `${Math.round(value)}ms` : "n/a";
9141
+ var escapeHtml11 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
9142
+ var formatMs2 = (value) => typeof value === "number" && Number.isFinite(value) ? `${Math.round(value)}ms` : "n/a";
8984
9143
  var statusLabel = (report) => {
8985
9144
  if (!report) {
8986
9145
  return "No trend report";
@@ -9000,10 +9159,10 @@ var createVoiceProofTrendsViewModel = (snapshot, options = {}) => {
9000
9159
  },
9001
9160
  {
9002
9161
  label: "Provider p95",
9003
- value: formatMs(report.summary.maxProviderP95Ms)
9162
+ value: formatMs2(report.summary.maxProviderP95Ms)
9004
9163
  },
9005
- { label: "Turn p95", value: formatMs(report.summary.maxTurnP95Ms) },
9006
- { label: "Live p95", value: formatMs(report.summary.maxLiveP95Ms) },
9164
+ { label: "Turn p95", value: formatMs2(report.summary.maxTurnP95Ms) },
9165
+ { label: "Live p95", value: formatMs2(report.summary.maxLiveP95Ms) },
9007
9166
  {
9008
9167
  label: "Artifact age",
9009
9168
  value: formatVoiceProofTrendAge(report.ageMs)
@@ -9014,7 +9173,7 @@ var createVoiceProofTrendsViewModel = (snapshot, options = {}) => {
9014
9173
  }
9015
9174
  ] : [];
9016
9175
  return {
9017
- description: options.description ?? DEFAULT_DESCRIPTION5,
9176
+ description: options.description ?? DEFAULT_DESCRIPTION6,
9018
9177
  error: snapshot.error,
9019
9178
  isLoading: snapshot.isLoading,
9020
9179
  label: snapshot.error ? "Unavailable" : report ? statusLabel(report) : snapshot.isLoading ? "Checking" : "No trend report",
@@ -9022,26 +9181,26 @@ var createVoiceProofTrendsViewModel = (snapshot, options = {}) => {
9022
9181
  metrics,
9023
9182
  report,
9024
9183
  status: snapshot.error ? "error" : report ? report.status === "pass" ? "ready" : "warning" : snapshot.isLoading ? "loading" : "empty",
9025
- title: options.title ?? DEFAULT_TITLE5,
9184
+ title: options.title ?? DEFAULT_TITLE6,
9026
9185
  updatedAt: snapshot.updatedAt
9027
9186
  };
9028
9187
  };
9029
9188
  var renderVoiceProofTrendsHTML = (snapshot, options = {}) => {
9030
9189
  const model = createVoiceProofTrendsViewModel(snapshot, options);
9031
9190
  const metrics = model.metrics.length ? `<div class="absolute-voice-proof-trends__metrics">${model.metrics.map((metric) => `<article>
9032
- <span>${escapeHtml10(metric.label)}</span>
9033
- <strong>${escapeHtml10(metric.value)}</strong>
9034
- </article>`).join("")}</div>` : `<p class="absolute-voice-proof-trends__empty">${model.error ? escapeHtml10(model.error) : "Run the sustained proof trends script to populate evidence."}</p>`;
9035
- const links = model.links.length ? `<p class="absolute-voice-proof-trends__links">${model.links.map((link) => `<a href="${escapeHtml10(link.href)}">${escapeHtml10(link.label)}</a>`).join("")}</p>` : "";
9036
- return `<section class="absolute-voice-proof-trends absolute-voice-proof-trends--${escapeHtml10(model.status)}">
9191
+ <span>${escapeHtml11(metric.label)}</span>
9192
+ <strong>${escapeHtml11(metric.value)}</strong>
9193
+ </article>`).join("")}</div>` : `<p class="absolute-voice-proof-trends__empty">${model.error ? escapeHtml11(model.error) : "Run the sustained proof trends script to populate evidence."}</p>`;
9194
+ const links = model.links.length ? `<p class="absolute-voice-proof-trends__links">${model.links.map((link) => `<a href="${escapeHtml11(link.href)}">${escapeHtml11(link.label)}</a>`).join("")}</p>` : "";
9195
+ return `<section class="absolute-voice-proof-trends absolute-voice-proof-trends--${escapeHtml11(model.status)}">
9037
9196
  <header class="absolute-voice-proof-trends__header">
9038
- <span class="absolute-voice-proof-trends__eyebrow">${escapeHtml10(model.title)}</span>
9039
- <strong class="absolute-voice-proof-trends__label">${escapeHtml10(model.label)}</strong>
9197
+ <span class="absolute-voice-proof-trends__eyebrow">${escapeHtml11(model.title)}</span>
9198
+ <strong class="absolute-voice-proof-trends__label">${escapeHtml11(model.label)}</strong>
9040
9199
  </header>
9041
- <p class="absolute-voice-proof-trends__description">${escapeHtml10(model.description)}</p>
9200
+ <p class="absolute-voice-proof-trends__description">${escapeHtml11(model.description)}</p>
9042
9201
  ${metrics}
9043
9202
  ${links}
9044
- ${model.error ? `<p class="absolute-voice-proof-trends__error">${escapeHtml10(model.error)}</p>` : ""}
9203
+ ${model.error ? `<p class="absolute-voice-proof-trends__error">${escapeHtml11(model.error)}</p>` : ""}
9045
9204
  </section>`;
9046
9205
  };
9047
9206
  var getVoiceProofTrendsCSS = () => `.absolute-voice-proof-trends{border:1px solid #99f6e4;border-radius:20px;background:#f0fdfa;color:#0f172a;padding:18px;box-shadow:0 18px 40px rgba(13,148,136,.12);font-family:inherit}.absolute-voice-proof-trends--warning,.absolute-voice-proof-trends--error{border-color:#f2a7a7;background:#fff7f4}.absolute-voice-proof-trends__header{align-items:start;display:flex;gap:12px;justify-content:space-between}.absolute-voice-proof-trends__eyebrow{color:#0f766e;font-size:12px;font-weight:800;letter-spacing:.08em;text-transform:uppercase}.absolute-voice-proof-trends__label{font-size:24px;line-height:1}.absolute-voice-proof-trends__description,.absolute-voice-proof-trends__empty{color:#475569}.absolute-voice-proof-trends__metrics{display:grid;gap:10px;grid-template-columns:repeat(auto-fit,minmax(130px,1fr));margin-top:14px}.absolute-voice-proof-trends__metrics article{background:#fff;border:1px solid #ccfbf1;border-radius:16px;padding:12px}.absolute-voice-proof-trends__metrics span{color:#64748b;display:block;font-size:12px;font-weight:800;text-transform:uppercase}.absolute-voice-proof-trends__metrics strong{display:block;font-size:20px;margin-top:4px}.absolute-voice-proof-trends__links{display:flex;flex-wrap:wrap;gap:8px;margin:14px 0 0}.absolute-voice-proof-trends__links a{border:1px solid #99f6e4;border-radius:999px;color:#0f766e;font-weight:800;padding:6px 10px;text-decoration:none}.absolute-voice-proof-trends__error{color:#9f1239;font-weight:700}`;
@@ -9081,8 +9240,8 @@ var defineVoiceProofTrendsElement = (tagName = "absolute-voice-proof-trends") =>
9081
9240
  });
9082
9241
  };
9083
9242
  // src/client/reconnectProfileEvidenceWidget.ts
9084
- var DEFAULT_TITLE6 = "Persisted Reconnect Evidence";
9085
- var DEFAULT_DESCRIPTION6 = "Real browser reconnect/resume evidence persisted into profile history so recovery claims are backed by durable traces.";
9243
+ var DEFAULT_TITLE7 = "Persisted Reconnect Evidence";
9244
+ var DEFAULT_DESCRIPTION7 = "Real browser reconnect/resume evidence persisted into profile history so recovery claims are backed by durable traces.";
9086
9245
  var DEFAULT_LINKS3 = [
9087
9246
  { href: "/voice/reconnect-contract", label: "Reconnect contract" },
9088
9247
  {
@@ -9090,8 +9249,8 @@ var DEFAULT_LINKS3 = [
9090
9249
  label: "Profile history JSON"
9091
9250
  }
9092
9251
  ];
9093
- var escapeHtml11 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
9094
- var formatMs2 = (value) => typeof value === "number" && Number.isFinite(value) ? `${Math.round(value)}ms` : "n/a";
9252
+ var escapeHtml12 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
9253
+ var formatMs3 = (value) => typeof value === "number" && Number.isFinite(value) ? `${Math.round(value)}ms` : "n/a";
9095
9254
  var formatCount = (value) => new Intl.NumberFormat("en-US").format(value);
9096
9255
  var formatAge = (value) => {
9097
9256
  if (!value) {
@@ -9119,7 +9278,7 @@ var createVoiceReconnectProfileEvidenceViewModel = (snapshot, options = {}) => {
9119
9278
  const latest = report?.latest;
9120
9279
  const latestAt = latest?.generatedAt ?? latest?.createdAt;
9121
9280
  return {
9122
- description: options.description ?? latest?.profileDescription ?? DEFAULT_DESCRIPTION6,
9281
+ description: options.description ?? latest?.profileDescription ?? DEFAULT_DESCRIPTION7,
9123
9282
  error: snapshot.error,
9124
9283
  isLoading: snapshot.isLoading,
9125
9284
  label: snapshot.error ? "Unavailable" : report ? report.status === "pass" ? "Reconnect evidence passing" : report.status === "warn" ? "Reconnect evidence incomplete" : report.status === "fail" ? "Reconnect evidence failing" : "Waiting for reconnect evidence" : snapshot.isLoading ? "Checking" : "No reconnect evidence",
@@ -9134,32 +9293,32 @@ var createVoiceReconnectProfileEvidenceViewModel = (snapshot, options = {}) => {
9134
9293
  { label: "Snapshots", value: formatCount(report?.snapshotCount ?? 0) },
9135
9294
  {
9136
9295
  label: "Resume p95",
9137
- value: formatMs2(report?.resumeLatencyP95Ms ?? latest?.reconnect?.resumeLatencyP95Ms)
9296
+ value: formatMs3(report?.resumeLatencyP95Ms ?? latest?.reconnect?.resumeLatencyP95Ms)
9138
9297
  },
9139
9298
  { label: "Last proof", value: formatAge(latestAt) }
9140
9299
  ],
9141
9300
  status: snapshot.error ? "error" : report ? report.status === "pass" ? "ready" : report.status === "empty" ? "empty" : "warning" : snapshot.isLoading ? "loading" : "empty",
9142
- title: options.title ?? DEFAULT_TITLE6
9301
+ title: options.title ?? DEFAULT_TITLE7
9143
9302
  };
9144
9303
  };
9145
9304
  var renderVoiceReconnectProfileEvidenceHTML = (snapshot, options = {}) => {
9146
9305
  const model = createVoiceReconnectProfileEvidenceViewModel(snapshot, options);
9147
9306
  const metrics = `<div class="absolute-voice-reconnect-evidence__metrics">${model.metrics.map((metric) => `<article>
9148
- <span>${escapeHtml11(metric.label)}</span>
9149
- <strong>${escapeHtml11(metric.value)}</strong>
9307
+ <span>${escapeHtml12(metric.label)}</span>
9308
+ <strong>${escapeHtml12(metric.value)}</strong>
9150
9309
  </article>`).join("")}</div>`;
9151
- const latest = model.latest ? `<p class="absolute-voice-reconnect-evidence__latest">Latest ${escapeHtml11(model.latest.profileLabel)} \xB7 ${escapeHtml11(model.latest.sessionId)} \xB7 ${escapeHtml11(model.latest.surfaces)}</p>` : `<p class="absolute-voice-reconnect-evidence__empty">No persisted reconnect profile evidence yet.</p>`;
9152
- const links = model.links.length ? `<p class="absolute-voice-reconnect-evidence__links">${model.links.map((link) => `<a href="${escapeHtml11(link.href)}">${escapeHtml11(link.label)}</a>`).join("")}</p>` : "";
9153
- return `<section class="absolute-voice-reconnect-evidence absolute-voice-reconnect-evidence--${escapeHtml11(model.status)}">
9310
+ const latest = model.latest ? `<p class="absolute-voice-reconnect-evidence__latest">Latest ${escapeHtml12(model.latest.profileLabel)} \xB7 ${escapeHtml12(model.latest.sessionId)} \xB7 ${escapeHtml12(model.latest.surfaces)}</p>` : `<p class="absolute-voice-reconnect-evidence__empty">No persisted reconnect profile evidence yet.</p>`;
9311
+ const links = model.links.length ? `<p class="absolute-voice-reconnect-evidence__links">${model.links.map((link) => `<a href="${escapeHtml12(link.href)}">${escapeHtml12(link.label)}</a>`).join("")}</p>` : "";
9312
+ return `<section class="absolute-voice-reconnect-evidence absolute-voice-reconnect-evidence--${escapeHtml12(model.status)}">
9154
9313
  <header class="absolute-voice-reconnect-evidence__header">
9155
- <span class="absolute-voice-reconnect-evidence__eyebrow">${escapeHtml11(model.title)}</span>
9156
- <strong class="absolute-voice-reconnect-evidence__label">${escapeHtml11(model.label)}</strong>
9314
+ <span class="absolute-voice-reconnect-evidence__eyebrow">${escapeHtml12(model.title)}</span>
9315
+ <strong class="absolute-voice-reconnect-evidence__label">${escapeHtml12(model.label)}</strong>
9157
9316
  </header>
9158
- <p class="absolute-voice-reconnect-evidence__description">${escapeHtml11(model.description)}</p>
9317
+ <p class="absolute-voice-reconnect-evidence__description">${escapeHtml12(model.description)}</p>
9159
9318
  ${metrics}
9160
9319
  ${latest}
9161
9320
  ${links}
9162
- ${model.error ? `<p class="absolute-voice-reconnect-evidence__error">${escapeHtml11(model.error)}</p>` : ""}
9321
+ ${model.error ? `<p class="absolute-voice-reconnect-evidence__error">${escapeHtml12(model.error)}</p>` : ""}
9163
9322
  </section>`;
9164
9323
  };
9165
9324
  var getVoiceReconnectProfileEvidenceCSS = () => `.absolute-voice-reconnect-evidence{border:1px solid #bae6fd;border-radius:20px;background:#f0f9ff;color:#0f172a;padding:18px;box-shadow:0 18px 40px rgba(14,165,233,.12);font-family:inherit}.absolute-voice-reconnect-evidence--warning,.absolute-voice-reconnect-evidence--error{border-color:#fbbf24;background:#fffbeb}.absolute-voice-reconnect-evidence__header{align-items:start;display:flex;gap:12px;justify-content:space-between}.absolute-voice-reconnect-evidence__eyebrow{color:#0369a1;font-size:12px;font-weight:800;letter-spacing:.08em;text-transform:uppercase}.absolute-voice-reconnect-evidence__label{font-size:24px;line-height:1}.absolute-voice-reconnect-evidence__description,.absolute-voice-reconnect-evidence__empty,.absolute-voice-reconnect-evidence__latest{color:#475569}.absolute-voice-reconnect-evidence__metrics{display:grid;gap:10px;grid-template-columns:repeat(4,minmax(0,1fr));margin-top:14px}.absolute-voice-reconnect-evidence__metrics article{background:#fff;border:1px solid #bae6fd;border-radius:16px;padding:12px}.absolute-voice-reconnect-evidence__metrics span{color:#64748b;display:block;font-size:11px;font-weight:800;text-transform:uppercase}.absolute-voice-reconnect-evidence__metrics strong{display:block;font-size:20px;margin-top:4px}.absolute-voice-reconnect-evidence__links{display:flex;flex-wrap:wrap;gap:8px;margin:14px 0 0}.absolute-voice-reconnect-evidence__links a{border:1px solid #7dd3fc;border-radius:999px;color:#0369a1;font-weight:800;padding:6px 10px;text-decoration:none}.absolute-voice-reconnect-evidence__error{color:#9f1239;font-weight:700}@media (max-width:720px){.absolute-voice-reconnect-evidence__metrics{grid-template-columns:repeat(2,minmax(0,1fr))}}`;
@@ -9200,20 +9359,20 @@ var defineVoiceReconnectProfileEvidenceElement = (tagName = "absolute-voice-reco
9200
9359
  });
9201
9360
  };
9202
9361
  // src/client/profileComparisonWidget.ts
9203
- var DEFAULT_TITLE7 = "Profile Stack Comparison";
9204
- var DEFAULT_DESCRIPTION7 = "Measured real-call evidence behind each profile default: provider routes, latency, and the next move.";
9362
+ var DEFAULT_TITLE8 = "Profile Stack Comparison";
9363
+ var DEFAULT_DESCRIPTION8 = "Measured real-call evidence behind each profile default: provider routes, latency, and the next move.";
9205
9364
  var DEFAULT_LINKS4 = [
9206
9365
  { href: "/voice/real-call-profile-history", label: "Profile history" },
9207
9366
  { href: "/api/voice/real-call-profile-history", label: "JSON" }
9208
9367
  ];
9209
- var escapeHtml12 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
9210
- var formatMs3 = (value) => typeof value === "number" && Number.isFinite(value) ? `${Math.round(value)}ms` : "n/a";
9368
+ var escapeHtml13 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
9369
+ var formatMs4 = (value) => typeof value === "number" && Number.isFinite(value) ? `${Math.round(value)}ms` : "n/a";
9211
9370
  var formatProviderRoutes = (profile) => Object.entries(profile.providerRoutes).map(([role, provider]) => `${role}: ${provider}`).join(", ") || "No complete route yet";
9212
9371
  var createProfileView = (profile) => ({
9213
9372
  evidence: [
9214
- { label: "Live p95", value: formatMs3(profile.evidence.liveP95Ms) },
9215
- { label: "Provider p95", value: formatMs3(profile.evidence.providerP95Ms) },
9216
- { label: "Turn p95", value: formatMs3(profile.evidence.turnP95Ms) }
9373
+ { label: "Live p95", value: formatMs4(profile.evidence.liveP95Ms) },
9374
+ { label: "Provider p95", value: formatMs4(profile.evidence.providerP95Ms) },
9375
+ { label: "Turn p95", value: formatMs4(profile.evidence.turnP95Ms) }
9217
9376
  ],
9218
9377
  label: profile.label ?? profile.profileId,
9219
9378
  nextMove: profile.nextMove,
@@ -9225,37 +9384,37 @@ var createVoiceProfileComparisonViewModel = (snapshot, options = {}) => {
9225
9384
  const report = snapshot.report;
9226
9385
  const profiles = report?.defaults.profiles.map(createProfileView) ?? [];
9227
9386
  return {
9228
- description: options.description ?? DEFAULT_DESCRIPTION7,
9387
+ description: options.description ?? DEFAULT_DESCRIPTION8,
9229
9388
  error: snapshot.error,
9230
9389
  isLoading: snapshot.isLoading,
9231
9390
  label: snapshot.error ? "Unavailable" : report ? `${report.defaults.summary.actionableProfiles}/${report.defaults.summary.profileCount} profiles ready` : snapshot.isLoading ? "Checking" : "No profile evidence",
9232
9391
  links: options.links ?? DEFAULT_LINKS4,
9233
9392
  profiles,
9234
9393
  status: snapshot.error ? "error" : report ? report.status === "pass" ? "ready" : "warning" : snapshot.isLoading ? "loading" : "empty",
9235
- title: options.title ?? DEFAULT_TITLE7
9394
+ title: options.title ?? DEFAULT_TITLE8
9236
9395
  };
9237
9396
  };
9238
9397
  var renderVoiceProfileComparisonHTML = (snapshot, options = {}) => {
9239
9398
  const model = createVoiceProfileComparisonViewModel(snapshot, options);
9240
- const profiles = model.profiles.length ? `<div class="absolute-voice-profile-comparison__profiles">${model.profiles.map((profile) => `<article class="absolute-voice-profile-comparison__profile absolute-voice-profile-comparison__profile--${escapeHtml12(profile.status)}">
9399
+ const profiles = model.profiles.length ? `<div class="absolute-voice-profile-comparison__profiles">${model.profiles.map((profile) => `<article class="absolute-voice-profile-comparison__profile absolute-voice-profile-comparison__profile--${escapeHtml13(profile.status)}">
9241
9400
  <header>
9242
- <span>${escapeHtml12(profile.status)}</span>
9243
- <strong>${escapeHtml12(profile.label)}</strong>
9401
+ <span>${escapeHtml13(profile.status)}</span>
9402
+ <strong>${escapeHtml13(profile.label)}</strong>
9244
9403
  </header>
9245
- <p>${escapeHtml12(profile.providerRoutes)}</p>
9246
- <div>${profile.evidence.map((metric) => `<span><small>${escapeHtml12(metric.label)}</small><b>${escapeHtml12(metric.value)}</b></span>`).join("")}</div>
9247
- <em>${escapeHtml12(profile.nextMove)}</em>
9248
- </article>`).join("")}</div>` : `<p class="absolute-voice-profile-comparison__empty">${model.error ? escapeHtml12(model.error) : "Run real-call profile collection to populate profile comparisons."}</p>`;
9249
- const links = model.links.length ? `<p class="absolute-voice-profile-comparison__links">${model.links.map((link) => `<a href="${escapeHtml12(link.href)}">${escapeHtml12(link.label)}</a>`).join("")}</p>` : "";
9250
- return `<section class="absolute-voice-profile-comparison absolute-voice-profile-comparison--${escapeHtml12(model.status)}">
9404
+ <p>${escapeHtml13(profile.providerRoutes)}</p>
9405
+ <div>${profile.evidence.map((metric) => `<span><small>${escapeHtml13(metric.label)}</small><b>${escapeHtml13(metric.value)}</b></span>`).join("")}</div>
9406
+ <em>${escapeHtml13(profile.nextMove)}</em>
9407
+ </article>`).join("")}</div>` : `<p class="absolute-voice-profile-comparison__empty">${model.error ? escapeHtml13(model.error) : "Run real-call profile collection to populate profile comparisons."}</p>`;
9408
+ const links = model.links.length ? `<p class="absolute-voice-profile-comparison__links">${model.links.map((link) => `<a href="${escapeHtml13(link.href)}">${escapeHtml13(link.label)}</a>`).join("")}</p>` : "";
9409
+ return `<section class="absolute-voice-profile-comparison absolute-voice-profile-comparison--${escapeHtml13(model.status)}">
9251
9410
  <header class="absolute-voice-profile-comparison__header">
9252
- <span class="absolute-voice-profile-comparison__eyebrow">${escapeHtml12(model.title)}</span>
9253
- <strong class="absolute-voice-profile-comparison__label">${escapeHtml12(model.label)}</strong>
9411
+ <span class="absolute-voice-profile-comparison__eyebrow">${escapeHtml13(model.title)}</span>
9412
+ <strong class="absolute-voice-profile-comparison__label">${escapeHtml13(model.label)}</strong>
9254
9413
  </header>
9255
- <p class="absolute-voice-profile-comparison__description">${escapeHtml12(model.description)}</p>
9414
+ <p class="absolute-voice-profile-comparison__description">${escapeHtml13(model.description)}</p>
9256
9415
  ${profiles}
9257
9416
  ${links}
9258
- ${model.error ? `<p class="absolute-voice-profile-comparison__error">${escapeHtml12(model.error)}</p>` : ""}
9417
+ ${model.error ? `<p class="absolute-voice-profile-comparison__error">${escapeHtml13(model.error)}</p>` : ""}
9259
9418
  </section>`;
9260
9419
  };
9261
9420
  var getVoiceProfileComparisonCSS = () => `.absolute-voice-profile-comparison{border:1px solid #c7d2fe;border-radius:20px;background:#eef2ff;color:#111827;padding:18px;box-shadow:0 18px 40px rgba(79,70,229,.12);font-family:inherit}.absolute-voice-profile-comparison--warning,.absolute-voice-profile-comparison--error{border-color:#fbbf24;background:#fffbeb}.absolute-voice-profile-comparison__header{align-items:start;display:flex;gap:12px;justify-content:space-between}.absolute-voice-profile-comparison__eyebrow{color:#4338ca;font-size:12px;font-weight:800;letter-spacing:.08em;text-transform:uppercase}.absolute-voice-profile-comparison__label{font-size:24px;line-height:1}.absolute-voice-profile-comparison__description,.absolute-voice-profile-comparison__empty{color:#4b5563}.absolute-voice-profile-comparison__profiles{display:grid;gap:12px;grid-template-columns:repeat(auto-fit,minmax(220px,1fr));margin-top:14px}.absolute-voice-profile-comparison__profile{background:#fff;border:1px solid #c7d2fe;border-radius:16px;padding:14px}.absolute-voice-profile-comparison__profile--warn{border-color:#fbbf24}.absolute-voice-profile-comparison__profile--fail{border-color:#f87171}.absolute-voice-profile-comparison__profile header{align-items:center;display:flex;gap:8px;justify-content:space-between}.absolute-voice-profile-comparison__profile header span{border:1px solid currentColor;border-radius:999px;color:#4338ca;font-size:11px;font-weight:900;padding:3px 7px;text-transform:uppercase}.absolute-voice-profile-comparison__profile p{color:#1f2937;font-weight:800;overflow-wrap:anywhere}.absolute-voice-profile-comparison__profile div{display:grid;gap:8px;grid-template-columns:repeat(3,minmax(0,1fr))}.absolute-voice-profile-comparison__profile small{color:#6b7280;display:block;font-size:11px}.absolute-voice-profile-comparison__profile b{display:block}.absolute-voice-profile-comparison__profile em{color:#4b5563;display:block;font-size:13px;margin-top:12px}.absolute-voice-profile-comparison__links{display:flex;flex-wrap:wrap;gap:8px;margin:14px 0 0}.absolute-voice-profile-comparison__links a{border:1px solid #a5b4fc;border-radius:999px;color:#4338ca;font-weight:800;padding:6px 10px;text-decoration:none}.absolute-voice-profile-comparison__error{color:#9f1239;font-weight:700}`;
@@ -9296,29 +9455,29 @@ var defineVoiceProfileComparisonElement = (tagName = "absolute-voice-profile-com
9296
9455
  });
9297
9456
  };
9298
9457
  // src/client/profileSwitchRecommendationWidget.ts
9299
- var DEFAULT_TITLE8 = "Profile Switch Recommendation";
9300
- var DEFAULT_DESCRIPTION8 = "Compares the current session against measured profile evidence and recommends whether to switch stacks.";
9301
- var escapeHtml13 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
9458
+ var DEFAULT_TITLE9 = "Profile Switch Recommendation";
9459
+ var DEFAULT_DESCRIPTION9 = "Compares the current session against measured profile evidence and recommends whether to switch stacks.";
9460
+ var escapeHtml14 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
9302
9461
  var formatRoute = (routes) => routes ? Object.entries(routes).map(([role, provider]) => `${role}: ${provider}`).join(", ") : "No route";
9303
9462
  var renderVoiceProfileSwitchRecommendationHTML = (snapshot, options = {}) => {
9304
9463
  const recommendation = snapshot.recommendation;
9305
9464
  const status = snapshot.error ? "error" : recommendation ? recommendation.status : snapshot.isLoading ? "loading" : "empty";
9306
9465
  const label = snapshot.error ? "Unavailable" : recommendation ? recommendation.status === "switch" ? `Switch to ${recommendation.recommendedProfile?.label ?? recommendation.recommendedProfile?.profileId ?? "recommended profile"}` : recommendation.status === "stay" ? "Keep current profile" : "Needs evidence" : snapshot.isLoading ? "Checking" : "No recommendation";
9307
9466
  const body = recommendation ? `<div class="absolute-voice-profile-switch__body">
9308
- <p><strong>Current:</strong> ${escapeHtml13(recommendation.currentProfile?.label ?? recommendation.currentProfile?.profileId ?? "Unknown")}</p>
9309
- <p><strong>Recommended:</strong> ${escapeHtml13(recommendation.recommendedProfile?.label ?? recommendation.recommendedProfile?.profileId ?? "None")}</p>
9310
- <p><strong>Routes:</strong> ${escapeHtml13(formatRoute(recommendation.recommendedProfile?.providerRoutes))}</p>
9311
- <ul>${recommendation.reasons.map((reason) => `<li>${escapeHtml13(reason)}</li>`).join("")}</ul>
9312
- <em>${escapeHtml13(recommendation.nextMove)}</em>
9313
- </div>` : `<p class="absolute-voice-profile-switch__empty">${escapeHtml13(snapshot.error ?? "Run session traffic to populate a recommendation.")}</p>`;
9314
- return `<section class="absolute-voice-profile-switch absolute-voice-profile-switch--${escapeHtml13(status)}">
9467
+ <p><strong>Current:</strong> ${escapeHtml14(recommendation.currentProfile?.label ?? recommendation.currentProfile?.profileId ?? "Unknown")}</p>
9468
+ <p><strong>Recommended:</strong> ${escapeHtml14(recommendation.recommendedProfile?.label ?? recommendation.recommendedProfile?.profileId ?? "None")}</p>
9469
+ <p><strong>Routes:</strong> ${escapeHtml14(formatRoute(recommendation.recommendedProfile?.providerRoutes))}</p>
9470
+ <ul>${recommendation.reasons.map((reason) => `<li>${escapeHtml14(reason)}</li>`).join("")}</ul>
9471
+ <em>${escapeHtml14(recommendation.nextMove)}</em>
9472
+ </div>` : `<p class="absolute-voice-profile-switch__empty">${escapeHtml14(snapshot.error ?? "Run session traffic to populate a recommendation.")}</p>`;
9473
+ return `<section class="absolute-voice-profile-switch absolute-voice-profile-switch--${escapeHtml14(status)}">
9315
9474
  <header class="absolute-voice-profile-switch__header">
9316
- <span class="absolute-voice-profile-switch__eyebrow">${escapeHtml13(options.title ?? DEFAULT_TITLE8)}</span>
9317
- <strong class="absolute-voice-profile-switch__label">${escapeHtml13(label)}</strong>
9475
+ <span class="absolute-voice-profile-switch__eyebrow">${escapeHtml14(options.title ?? DEFAULT_TITLE9)}</span>
9476
+ <strong class="absolute-voice-profile-switch__label">${escapeHtml14(label)}</strong>
9318
9477
  </header>
9319
- <p class="absolute-voice-profile-switch__description">${escapeHtml13(options.description ?? DEFAULT_DESCRIPTION8)}</p>
9478
+ <p class="absolute-voice-profile-switch__description">${escapeHtml14(options.description ?? DEFAULT_DESCRIPTION9)}</p>
9320
9479
  ${body}
9321
- ${snapshot.error ? `<p class="absolute-voice-profile-switch__error">${escapeHtml13(snapshot.error)}</p>` : ""}
9480
+ ${snapshot.error ? `<p class="absolute-voice-profile-switch__error">${escapeHtml14(snapshot.error)}</p>` : ""}
9322
9481
  </section>`;
9323
9482
  };
9324
9483
  var getVoiceProfileSwitchRecommendationCSS = () => `.absolute-voice-profile-switch{border:1px solid #fed7aa;border-radius:20px;background:#fff7ed;color:#1c1917;padding:18px;box-shadow:0 18px 40px rgba(234,88,12,.12);font-family:inherit}.absolute-voice-profile-switch--switch{border-color:#fdba74}.absolute-voice-profile-switch--stay{border-color:#86efac;background:#f0fdf4}.absolute-voice-profile-switch--warn,.absolute-voice-profile-switch--error{border-color:#fca5a5;background:#fff1f2}.absolute-voice-profile-switch__header{align-items:start;display:flex;gap:12px;justify-content:space-between}.absolute-voice-profile-switch__eyebrow{color:#c2410c;font-size:12px;font-weight:800;letter-spacing:.08em;text-transform:uppercase}.absolute-voice-profile-switch__label{font-size:24px;line-height:1}.absolute-voice-profile-switch__description,.absolute-voice-profile-switch__body em,.absolute-voice-profile-switch__empty{color:#57534e}.absolute-voice-profile-switch__body{background:#fff;border:1px solid #fed7aa;border-radius:16px;margin-top:14px;padding:14px}.absolute-voice-profile-switch__body p{margin:.35rem 0}.absolute-voice-profile-switch__body ul{margin:.75rem 0;padding-left:1.2rem}.absolute-voice-profile-switch__body em{display:block}.absolute-voice-profile-switch__error{color:#9f1239;font-weight:700}`;
@@ -9359,13 +9518,13 @@ var defineVoiceProfileSwitchRecommendationElement = (tagName = "absolute-voice-p
9359
9518
  });
9360
9519
  };
9361
9520
  // src/client/readinessFailuresWidget.ts
9362
- var DEFAULT_TITLE9 = "Readiness Gate Explanations";
9363
- var DEFAULT_DESCRIPTION9 = "Structured reasons for calibrated production-readiness warnings and failures.";
9521
+ var DEFAULT_TITLE10 = "Readiness Gate Explanations";
9522
+ var DEFAULT_DESCRIPTION10 = "Structured reasons for calibrated production-readiness warnings and failures.";
9364
9523
  var DEFAULT_LINKS5 = [
9365
9524
  { href: "/production-readiness", label: "Readiness page" },
9366
9525
  { href: "/voice/slo-readiness-thresholds", label: "Gate thresholds" }
9367
9526
  ];
9368
- var escapeHtml14 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
9527
+ var escapeHtml15 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
9369
9528
  var formatExplanationValue = (value, unit) => {
9370
9529
  if (value === undefined || value === null) {
9371
9530
  return "n/a";
@@ -9393,36 +9552,36 @@ var createVoiceReadinessFailuresViewModel = (snapshot, options = {}) => {
9393
9552
  const failures = snapshot.report?.checks.map(toFailureView).filter((value) => !!value) ?? [];
9394
9553
  const hasOpenIssues = failures.length > 0;
9395
9554
  return {
9396
- description: options.description ?? DEFAULT_DESCRIPTION9,
9555
+ description: options.description ?? DEFAULT_DESCRIPTION10,
9397
9556
  error: snapshot.error,
9398
9557
  failures,
9399
9558
  isLoading: snapshot.isLoading,
9400
9559
  label: snapshot.error ? "Unavailable" : snapshot.report ? hasOpenIssues ? `${failures.length} calibrated gate issue(s)` : "No calibrated gate issues" : snapshot.isLoading ? "Checking" : "No readiness report",
9401
9560
  links: options.links ?? DEFAULT_LINKS5,
9402
9561
  status: snapshot.error ? "error" : snapshot.report ? hasOpenIssues ? "warning" : "ready" : snapshot.isLoading ? "loading" : "empty",
9403
- title: options.title ?? DEFAULT_TITLE9,
9562
+ title: options.title ?? DEFAULT_TITLE10,
9404
9563
  updatedAt: snapshot.updatedAt
9405
9564
  };
9406
9565
  };
9407
9566
  var renderVoiceReadinessFailuresHTML = (snapshot, options = {}) => {
9408
9567
  const model = createVoiceReadinessFailuresViewModel(snapshot, options);
9409
- const failures = model.failures.length ? `<div class="absolute-voice-readiness-failures__items">${model.failures.map((failure) => `<article class="absolute-voice-readiness-failures__item absolute-voice-readiness-failures__item--${escapeHtml14(failure.status)}">
9410
- <span>${escapeHtml14(failure.status.toUpperCase())}</span>
9411
- <strong>${escapeHtml14(failure.label)}</strong>
9412
- <p>Observed ${escapeHtml14(failure.observed)} against ${escapeHtml14(failure.thresholdLabel)} ${escapeHtml14(failure.threshold)}.</p>
9413
- <p>${escapeHtml14(failure.remediation)}</p>
9414
- <p class="absolute-voice-readiness-failures__links">${failure.evidenceHref ? `<a href="${escapeHtml14(failure.evidenceHref)}">Evidence</a>` : ""}${failure.sourceHref ? `<a href="${escapeHtml14(failure.sourceHref)}">Threshold source</a>` : ""}</p>
9415
- </article>`).join("")}</div>` : `<p class="absolute-voice-readiness-failures__empty">${model.error ? escapeHtml14(model.error) : "No calibrated readiness gate explanations are open."}</p>`;
9416
- const links = model.links.length ? `<p class="absolute-voice-readiness-failures__links">${model.links.map((link) => `<a href="${escapeHtml14(link.href)}">${escapeHtml14(link.label)}</a>`).join("")}</p>` : "";
9417
- return `<section class="absolute-voice-readiness-failures absolute-voice-readiness-failures--${escapeHtml14(model.status)}">
9568
+ const failures = model.failures.length ? `<div class="absolute-voice-readiness-failures__items">${model.failures.map((failure) => `<article class="absolute-voice-readiness-failures__item absolute-voice-readiness-failures__item--${escapeHtml15(failure.status)}">
9569
+ <span>${escapeHtml15(failure.status.toUpperCase())}</span>
9570
+ <strong>${escapeHtml15(failure.label)}</strong>
9571
+ <p>Observed ${escapeHtml15(failure.observed)} against ${escapeHtml15(failure.thresholdLabel)} ${escapeHtml15(failure.threshold)}.</p>
9572
+ <p>${escapeHtml15(failure.remediation)}</p>
9573
+ <p class="absolute-voice-readiness-failures__links">${failure.evidenceHref ? `<a href="${escapeHtml15(failure.evidenceHref)}">Evidence</a>` : ""}${failure.sourceHref ? `<a href="${escapeHtml15(failure.sourceHref)}">Threshold source</a>` : ""}</p>
9574
+ </article>`).join("")}</div>` : `<p class="absolute-voice-readiness-failures__empty">${model.error ? escapeHtml15(model.error) : "No calibrated readiness gate explanations are open."}</p>`;
9575
+ const links = model.links.length ? `<p class="absolute-voice-readiness-failures__links">${model.links.map((link) => `<a href="${escapeHtml15(link.href)}">${escapeHtml15(link.label)}</a>`).join("")}</p>` : "";
9576
+ return `<section class="absolute-voice-readiness-failures absolute-voice-readiness-failures--${escapeHtml15(model.status)}">
9418
9577
  <header class="absolute-voice-readiness-failures__header">
9419
- <span class="absolute-voice-readiness-failures__eyebrow">${escapeHtml14(model.title)}</span>
9420
- <strong class="absolute-voice-readiness-failures__label">${escapeHtml14(model.label)}</strong>
9578
+ <span class="absolute-voice-readiness-failures__eyebrow">${escapeHtml15(model.title)}</span>
9579
+ <strong class="absolute-voice-readiness-failures__label">${escapeHtml15(model.label)}</strong>
9421
9580
  </header>
9422
- <p class="absolute-voice-readiness-failures__description">${escapeHtml14(model.description)}</p>
9581
+ <p class="absolute-voice-readiness-failures__description">${escapeHtml15(model.description)}</p>
9423
9582
  ${failures}
9424
9583
  ${links}
9425
- ${model.error ? `<p class="absolute-voice-readiness-failures__error">${escapeHtml14(model.error)}</p>` : ""}
9584
+ ${model.error ? `<p class="absolute-voice-readiness-failures__error">${escapeHtml15(model.error)}</p>` : ""}
9426
9585
  </section>`;
9427
9586
  };
9428
9587
  var getVoiceReadinessFailuresCSS = () => `.absolute-voice-readiness-failures{border:1px solid #fed7aa;border-radius:20px;background:#fff7ed;color:#1c1917;padding:18px;box-shadow:0 18px 40px rgba(234,88,12,.12);font-family:inherit}.absolute-voice-readiness-failures--ready{border-color:#86efac;background:#f0fdf4}.absolute-voice-readiness-failures--error{border-color:#fda4af;background:#fff1f2}.absolute-voice-readiness-failures__header{align-items:start;display:flex;gap:12px;justify-content:space-between}.absolute-voice-readiness-failures__eyebrow{color:#9a3412;font-size:12px;font-weight:800;letter-spacing:.08em;text-transform:uppercase}.absolute-voice-readiness-failures__label{font-size:24px;line-height:1}.absolute-voice-readiness-failures__description,.absolute-voice-readiness-failures__empty{color:#57534e}.absolute-voice-readiness-failures__items{display:grid;gap:10px;margin-top:14px}.absolute-voice-readiness-failures__item{background:white;border:1px solid #fed7aa;border-radius:16px;padding:12px}.absolute-voice-readiness-failures__item--fail{border-color:#fb7185}.absolute-voice-readiness-failures__item span{color:#9a3412;display:block;font-size:12px;font-weight:900;text-transform:uppercase}.absolute-voice-readiness-failures__item strong{display:block;font-size:18px;margin-top:4px}.absolute-voice-readiness-failures__item p{margin:.45rem 0 0}.absolute-voice-readiness-failures__links{display:flex;flex-wrap:wrap;gap:8px;margin:14px 0 0}.absolute-voice-readiness-failures__links a{border:1px solid #fdba74;border-radius:999px;color:#9a3412;font-weight:800;padding:6px 10px;text-decoration:none}.absolute-voice-readiness-failures__error{color:#9f1239;font-weight:700}`;
@@ -9462,9 +9621,9 @@ var defineVoiceReadinessFailuresElement = (tagName = "absolute-voice-readiness-f
9462
9621
  });
9463
9622
  };
9464
9623
  // src/client/opsActionCenterWidget.ts
9465
- var DEFAULT_TITLE10 = "Voice Ops Action Center";
9466
- var DEFAULT_DESCRIPTION10 = "Run production voice proofs and operator actions from one primitive panel.";
9467
- var escapeHtml15 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
9624
+ var DEFAULT_TITLE11 = "Voice Ops Action Center";
9625
+ var DEFAULT_DESCRIPTION11 = "Run production voice proofs and operator actions from one primitive panel.";
9626
+ var escapeHtml16 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
9468
9627
  var createVoiceOpsActionCenterViewModel = (snapshot, options = {}) => {
9469
9628
  const status = snapshot.error ? "error" : snapshot.isRunning ? "running" : snapshot.lastResult ? "completed" : "ready";
9470
9629
  return {
@@ -9475,29 +9634,29 @@ var createVoiceOpsActionCenterViewModel = (snapshot, options = {}) => {
9475
9634
  isRunning: snapshot.runningActionId === action.id,
9476
9635
  label: action.label
9477
9636
  })),
9478
- description: options.description ?? DEFAULT_DESCRIPTION10,
9637
+ description: options.description ?? DEFAULT_DESCRIPTION11,
9479
9638
  error: snapshot.error,
9480
9639
  isRunning: snapshot.isRunning,
9481
9640
  label: status === "error" ? "Needs attention" : status === "running" ? "Running" : status === "completed" ? "Action completed" : "Ready",
9482
9641
  lastResultLabel: snapshot.lastResult ? `${snapshot.lastResult.actionId} returned HTTP ${snapshot.lastResult.status}` : "No action has run yet.",
9483
9642
  status,
9484
- title: options.title ?? DEFAULT_TITLE10
9643
+ title: options.title ?? DEFAULT_TITLE11
9485
9644
  };
9486
9645
  };
9487
9646
  var renderVoiceOpsActionCenterHTML = (snapshot, options = {}) => {
9488
9647
  const model = createVoiceOpsActionCenterViewModel(snapshot, options);
9489
- const actions = model.actions.map((action) => `<button type="button" data-absolute-voice-ops-action="${escapeHtml15(action.id)}"${action.disabled ? " disabled" : ""}>
9490
- ${escapeHtml15(action.isRunning ? "Working..." : action.label)}
9648
+ const actions = model.actions.map((action) => `<button type="button" data-absolute-voice-ops-action="${escapeHtml16(action.id)}"${action.disabled ? " disabled" : ""}>
9649
+ ${escapeHtml16(action.isRunning ? "Working..." : action.label)}
9491
9650
  </button>`).join("");
9492
- return `<section class="absolute-voice-ops-action-center absolute-voice-ops-action-center--${escapeHtml15(model.status)}">
9651
+ return `<section class="absolute-voice-ops-action-center absolute-voice-ops-action-center--${escapeHtml16(model.status)}">
9493
9652
  <header class="absolute-voice-ops-action-center__header">
9494
- <span class="absolute-voice-ops-action-center__eyebrow">${escapeHtml15(model.title)}</span>
9495
- <strong class="absolute-voice-ops-action-center__label">${escapeHtml15(model.label)}</strong>
9653
+ <span class="absolute-voice-ops-action-center__eyebrow">${escapeHtml16(model.title)}</span>
9654
+ <strong class="absolute-voice-ops-action-center__label">${escapeHtml16(model.label)}</strong>
9496
9655
  </header>
9497
- <p class="absolute-voice-ops-action-center__description">${escapeHtml15(model.description)}</p>
9656
+ <p class="absolute-voice-ops-action-center__description">${escapeHtml16(model.description)}</p>
9498
9657
  <div class="absolute-voice-ops-action-center__actions">${actions}</div>
9499
- <p class="absolute-voice-ops-action-center__result">${escapeHtml15(model.lastResultLabel)}</p>
9500
- ${model.error ? `<p class="absolute-voice-ops-action-center__error">${escapeHtml15(model.error)}</p>` : ""}
9658
+ <p class="absolute-voice-ops-action-center__result">${escapeHtml16(model.lastResultLabel)}</p>
9659
+ ${model.error ? `<p class="absolute-voice-ops-action-center__error">${escapeHtml16(model.error)}</p>` : ""}
9501
9660
  </section>`;
9502
9661
  };
9503
9662
  var getVoiceOpsActionCenterCSS = () => `.absolute-voice-ops-action-center{border:1px solid #d5cbb8;border-radius:20px;background:#fffaf1;color:#17130b;padding:18px;box-shadow:0 18px 40px rgba(58,42,16,.12);font-family:inherit}.absolute-voice-ops-action-center--error{border-color:#f2a7a7;background:#fff5f3}.absolute-voice-ops-action-center__header{align-items:start;display:flex;gap:12px;justify-content:space-between}.absolute-voice-ops-action-center__eyebrow{color:#725d37;font-size:12px;font-weight:800;letter-spacing:.08em;text-transform:uppercase}.absolute-voice-ops-action-center__label{font-size:28px;line-height:1}.absolute-voice-ops-action-center__description,.absolute-voice-ops-action-center__result{color:#5b4b2f;margin:12px 0 0}.absolute-voice-ops-action-center__actions{display:flex;flex-wrap:wrap;gap:8px;margin-top:14px}.absolute-voice-ops-action-center__actions button{background:#7c4a03;border:0;border-radius:999px;color:#fff8e8;cursor:pointer;font:inherit;font-weight:800;padding:8px 12px}.absolute-voice-ops-action-center__actions button:disabled{cursor:not-allowed;opacity:.5}.absolute-voice-ops-action-center__error{color:#9f1239;font-weight:700}`;
@@ -10096,7 +10255,7 @@ var ACTION_LABELS = {
10096
10255
  "resume-assistant": "Resume assistant",
10097
10256
  tag: "Tag"
10098
10257
  };
10099
- var escapeHtml16 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
10258
+ var escapeHtml17 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
10100
10259
  var createVoiceLiveOpsInput = (action, input) => ({
10101
10260
  action,
10102
10261
  assignee: input.assignee,
@@ -10107,17 +10266,17 @@ var createVoiceLiveOpsInput = (action, input) => ({
10107
10266
  var renderVoiceLiveOpsHTML = (snapshot, options = {}) => {
10108
10267
  const sessionId = options.getSessionId?.() ?? "";
10109
10268
  const disabled = snapshot.isRunning || !sessionId;
10110
- const actions = VOICE_LIVE_OPS_ACTIONS.map((action) => `<button type="button" data-absolute-voice-live-ops-action="${escapeHtml16(action)}"${disabled ? " disabled" : ""}>${escapeHtml16(snapshot.runningAction === action ? "Running..." : ACTION_LABELS[action])}</button>`).join("");
10111
- const result = snapshot.error ? `<p class="absolute-voice-live-ops__error">${escapeHtml16(snapshot.error)}</p>` : snapshot.lastResult ? `<p class="absolute-voice-live-ops__result">Recorded ${escapeHtml16(snapshot.lastResult.action)}. Control: ${escapeHtml16(snapshot.lastResult.control.status)}.</p>` : '<p class="absolute-voice-live-ops__result">No live ops action has run yet.</p>';
10269
+ const actions = VOICE_LIVE_OPS_ACTIONS.map((action) => `<button type="button" data-absolute-voice-live-ops-action="${escapeHtml17(action)}"${disabled ? " disabled" : ""}>${escapeHtml17(snapshot.runningAction === action ? "Running..." : ACTION_LABELS[action])}</button>`).join("");
10270
+ const result = snapshot.error ? `<p class="absolute-voice-live-ops__error">${escapeHtml17(snapshot.error)}</p>` : snapshot.lastResult ? `<p class="absolute-voice-live-ops__result">Recorded ${escapeHtml17(snapshot.lastResult.action)}. Control: ${escapeHtml17(snapshot.lastResult.control.status)}.</p>` : '<p class="absolute-voice-live-ops__result">No live ops action has run yet.</p>';
10112
10271
  return `<section class="absolute-voice-live-ops">
10113
10272
  <header class="absolute-voice-live-ops__header">
10114
- <span>${escapeHtml16(options.title ?? "Live Ops")}</span>
10115
- <strong>${escapeHtml16(sessionId || "No active session")}</strong>
10273
+ <span>${escapeHtml17(options.title ?? "Live Ops")}</span>
10274
+ <strong>${escapeHtml17(sessionId || "No active session")}</strong>
10116
10275
  </header>
10117
- <p class="absolute-voice-live-ops__description">${escapeHtml16(options.description ?? "Pause, resume, take over, force handoff, or inject operator instructions during a live voice session.")}</p>
10118
- <label><span>Operator</span><input data-absolute-voice-live-ops-assignee value="${escapeHtml16(options.defaultAssignee ?? "operator")}" /></label>
10119
- <label><span>Tag / handoff target</span><input data-absolute-voice-live-ops-tag value="${escapeHtml16(options.defaultTag ?? "live-ops")}" /></label>
10120
- <label><span>Detail / instruction</span><input data-absolute-voice-live-ops-detail value="${escapeHtml16(options.defaultDetail ?? "Operator marked this live session.")}" /></label>
10276
+ <p class="absolute-voice-live-ops__description">${escapeHtml17(options.description ?? "Pause, resume, take over, force handoff, or inject operator instructions during a live voice session.")}</p>
10277
+ <label><span>Operator</span><input data-absolute-voice-live-ops-assignee value="${escapeHtml17(options.defaultAssignee ?? "operator")}" /></label>
10278
+ <label><span>Tag / handoff target</span><input data-absolute-voice-live-ops-tag value="${escapeHtml17(options.defaultTag ?? "live-ops")}" /></label>
10279
+ <label><span>Detail / instruction</span><input data-absolute-voice-live-ops-detail value="${escapeHtml17(options.defaultDetail ?? "Operator marked this live session.")}" /></label>
10121
10280
  <div class="absolute-voice-live-ops__actions">${actions}</div>
10122
10281
  ${result}
10123
10282
  </section>`;
@@ -10204,16 +10363,16 @@ var defineVoiceLiveOpsElement = (tagName = "absolute-voice-live-ops", options =
10204
10363
  });
10205
10364
  };
10206
10365
  // src/client/opsActionHistoryWidget.ts
10207
- var escapeHtml17 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
10366
+ var escapeHtml18 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
10208
10367
  var renderVoiceOpsActionHistoryWidgetHTML = (snapshot, options = {}) => {
10209
10368
  const report = snapshot.report;
10210
10369
  const entries = (report?.entries ?? []).slice(0, options.limit ?? 5);
10211
- const rows = entries.map((entry) => `<li class="absolute-voice-ops-action-history__entry absolute-voice-ops-action-history__entry--${entry.ok ? "success" : "error"}"><span>${escapeHtml17(entry.actionId)}</span><strong>${escapeHtml17(entry.ok ? "Success" : "Failed")}</strong><small>${escapeHtml17(new Date(entry.at).toLocaleString())}${entry.status ? ` \xB7 HTTP ${String(entry.status)}` : ""}</small></li>`).join("");
10370
+ const rows = entries.map((entry) => `<li class="absolute-voice-ops-action-history__entry absolute-voice-ops-action-history__entry--${entry.ok ? "success" : "error"}"><span>${escapeHtml18(entry.actionId)}</span><strong>${escapeHtml18(entry.ok ? "Success" : "Failed")}</strong><small>${escapeHtml18(new Date(entry.at).toLocaleString())}${entry.status ? ` \xB7 HTTP ${String(entry.status)}` : ""}</small></li>`).join("");
10212
10371
  return `<section class="absolute-voice-ops-action-history">
10213
- <header><span>Operator proof</span><strong>${escapeHtml17(options.title ?? "Action History")}</strong></header>
10372
+ <header><span>Operator proof</span><strong>${escapeHtml18(options.title ?? "Action History")}</strong></header>
10214
10373
  <p>${String(report?.total ?? 0)} action(s), ${String(report?.failed ?? 0)} failed.</p>
10215
10374
  <ul>${rows || "<li>No operator actions recorded yet.</li>"}</ul>
10216
- ${snapshot.error ? `<p class="absolute-voice-ops-action-history__error">${escapeHtml17(snapshot.error)}</p>` : ""}
10375
+ ${snapshot.error ? `<p class="absolute-voice-ops-action-history__error">${escapeHtml18(snapshot.error)}</p>` : ""}
10217
10376
  </section>`;
10218
10377
  };
10219
10378
  var getVoiceOpsActionHistoryCSS = () => `.absolute-voice-ops-action-history{border:1px solid #d8d2c4;border-radius:20px;background:#fffaf0;color:#16130d;padding:18px;font-family:inherit}.absolute-voice-ops-action-history header{align-items:start;display:flex;gap:12px;justify-content:space-between}.absolute-voice-ops-action-history header span{color:#73664f;font-size:12px;font-weight:800;letter-spacing:.08em;text-transform:uppercase}.absolute-voice-ops-action-history header strong{font-size:24px}.absolute-voice-ops-action-history p{color:#514733}.absolute-voice-ops-action-history ul{display:grid;gap:8px;list-style:none;margin:12px 0 0;padding:0}.absolute-voice-ops-action-history__entry{background:#fff;border:1px solid #eee4d2;border-radius:14px;display:grid;gap:3px;padding:10px 12px}.absolute-voice-ops-action-history__entry--error{border-color:#f2a7a7}.absolute-voice-ops-action-history__entry span{font-weight:800}.absolute-voice-ops-action-history__entry small{color:#655944}.absolute-voice-ops-action-history__error{color:#9f1239;font-weight:700}`;
@@ -10234,9 +10393,9 @@ var mountVoiceOpsActionHistory = (element, path = "/api/voice/ops-actions/histor
10234
10393
  };
10235
10394
  };
10236
10395
  // src/client/deliveryRuntimeWidget.ts
10237
- var DEFAULT_TITLE11 = "Voice Delivery Runtime";
10238
- var DEFAULT_DESCRIPTION11 = "Audit and trace delivery worker health from your AbsoluteJS voice app.";
10239
- var escapeHtml18 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
10396
+ var DEFAULT_TITLE12 = "Voice Delivery Runtime";
10397
+ var DEFAULT_DESCRIPTION12 = "Audit and trace delivery worker health from your AbsoluteJS voice app.";
10398
+ var escapeHtml19 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
10240
10399
  var createSurface = (id, summary) => {
10241
10400
  if (!summary) {
10242
10401
  return {
@@ -10270,7 +10429,7 @@ var createVoiceDeliveryRuntimeViewModel = (snapshot, options = {}) => {
10270
10429
  ];
10271
10430
  const hasWarnings = surfaces.some((surface) => surface.status === "warn");
10272
10431
  return {
10273
- description: options.description ?? DEFAULT_DESCRIPTION11,
10432
+ description: options.description ?? DEFAULT_DESCRIPTION12,
10274
10433
  error: snapshot.error,
10275
10434
  actionError: snapshot.actionError,
10276
10435
  actionStatus: snapshot.actionStatus,
@@ -10279,32 +10438,32 @@ var createVoiceDeliveryRuntimeViewModel = (snapshot, options = {}) => {
10279
10438
  label: snapshot.error ? "Unavailable" : report ? report.isRunning ? "Running" : "Stopped" : "Checking",
10280
10439
  status: snapshot.error ? "error" : report ? hasWarnings ? "warn" : "pass" : "loading",
10281
10440
  surfaces,
10282
- title: options.title ?? DEFAULT_TITLE11,
10441
+ title: options.title ?? DEFAULT_TITLE12,
10283
10442
  updatedAt: snapshot.updatedAt
10284
10443
  };
10285
10444
  };
10286
10445
  var renderVoiceDeliveryRuntimeHTML = (snapshot, options = {}) => {
10287
10446
  const model = createVoiceDeliveryRuntimeViewModel(snapshot, options);
10288
- const surfaces = model.surfaces.map((surface) => `<li class="absolute-voice-delivery-runtime__surface absolute-voice-delivery-runtime__surface--${escapeHtml18(surface.status)}">
10289
- <span>${escapeHtml18(surface.label)}</span>
10290
- <strong>${escapeHtml18(surface.detail)}</strong>
10447
+ const surfaces = model.surfaces.map((surface) => `<li class="absolute-voice-delivery-runtime__surface absolute-voice-delivery-runtime__surface--${escapeHtml19(surface.status)}">
10448
+ <span>${escapeHtml19(surface.label)}</span>
10449
+ <strong>${escapeHtml19(surface.detail)}</strong>
10291
10450
  <small>${String(surface.failed)} failed &middot; ${String(surface.deadLettered)} dead-lettered</small>
10292
10451
  </li>`).join("");
10293
10452
  const actions = options.includeActions === false ? "" : `<div class="absolute-voice-delivery-runtime__actions">
10294
10453
  <button type="button" data-absolute-voice-delivery-runtime-action="tick">${model.actionStatus === "running" ? "Working..." : "Tick workers"}</button>
10295
10454
  <button type="button" data-absolute-voice-delivery-runtime-action="requeue-dead-letters"${model.surfaces.some((surface) => surface.deadLettered > 0) ? "" : " disabled"}>Requeue dead letters</button>
10296
10455
  </div>`;
10297
- const actionError = model.actionError ? `<p class="absolute-voice-delivery-runtime__error">${escapeHtml18(model.actionError)}</p>` : "";
10298
- return `<section class="absolute-voice-delivery-runtime absolute-voice-delivery-runtime--${escapeHtml18(model.status)}">
10456
+ const actionError = model.actionError ? `<p class="absolute-voice-delivery-runtime__error">${escapeHtml19(model.actionError)}</p>` : "";
10457
+ return `<section class="absolute-voice-delivery-runtime absolute-voice-delivery-runtime--${escapeHtml19(model.status)}">
10299
10458
  <header class="absolute-voice-delivery-runtime__header">
10300
- <span class="absolute-voice-delivery-runtime__eyebrow">${escapeHtml18(model.title)}</span>
10301
- <strong class="absolute-voice-delivery-runtime__label">${escapeHtml18(model.label)}</strong>
10459
+ <span class="absolute-voice-delivery-runtime__eyebrow">${escapeHtml19(model.title)}</span>
10460
+ <strong class="absolute-voice-delivery-runtime__label">${escapeHtml19(model.label)}</strong>
10302
10461
  </header>
10303
- <p class="absolute-voice-delivery-runtime__description">${escapeHtml18(model.description)}</p>
10462
+ <p class="absolute-voice-delivery-runtime__description">${escapeHtml19(model.description)}</p>
10304
10463
  <ul class="absolute-voice-delivery-runtime__surfaces">${surfaces}</ul>
10305
10464
  ${actions}
10306
10465
  ${actionError}
10307
- ${model.error ? `<p class="absolute-voice-delivery-runtime__error">${escapeHtml18(model.error)}</p>` : ""}
10466
+ ${model.error ? `<p class="absolute-voice-delivery-runtime__error">${escapeHtml19(model.error)}</p>` : ""}
10308
10467
  </section>`;
10309
10468
  };
10310
10469
  var getVoiceDeliveryRuntimeCSS = () => `.absolute-voice-delivery-runtime{border:1px solid #c9d8cf;border-radius:20px;background:#f6fff9;color:#0d1b12;padding:18px;box-shadow:0 18px 40px rgba(19,55,35,.12);font-family:inherit}.absolute-voice-delivery-runtime--warn,.absolute-voice-delivery-runtime--error{border-color:#f2b56b;background:#fff9ed}.absolute-voice-delivery-runtime__header{align-items:start;display:flex;gap:12px;justify-content:space-between}.absolute-voice-delivery-runtime__eyebrow{color:#4e6b59;font-size:12px;font-weight:800;letter-spacing:.08em;text-transform:uppercase}.absolute-voice-delivery-runtime__label{font-size:28px;line-height:1}.absolute-voice-delivery-runtime__description{color:#33483b;margin:12px 0 0}.absolute-voice-delivery-runtime__surfaces{display:grid;gap:8px;list-style:none;margin:16px 0 0;padding:0}.absolute-voice-delivery-runtime__surface{background:#fff;border:1px solid #d9eadf;border-radius:14px;display:grid;gap:4px;padding:10px 12px}.absolute-voice-delivery-runtime__surface--warn{border-color:#f2b56b}.absolute-voice-delivery-runtime__surface--disabled{opacity:.72}.absolute-voice-delivery-runtime__surface span,.absolute-voice-delivery-runtime__surface small{color:#587063}.absolute-voice-delivery-runtime__actions{display:flex;flex-wrap:wrap;gap:8px;margin-top:14px}.absolute-voice-delivery-runtime__actions button{background:#134e2d;border:0;border-radius:999px;color:#f6fff9;cursor:pointer;font:inherit;font-weight:800;padding:8px 12px}.absolute-voice-delivery-runtime__actions button:disabled{cursor:not-allowed;opacity:.48}.absolute-voice-delivery-runtime__error{color:#9f1239;font-weight:700}`;
@@ -10440,9 +10599,9 @@ var createVoiceRoutingStatusStore = (path = "/api/routing/latest", options = {})
10440
10599
  };
10441
10600
  };
10442
10601
  // src/client/routingStatusWidget.ts
10443
- var DEFAULT_TITLE12 = "Voice Routing";
10444
- var DEFAULT_DESCRIPTION12 = "Latest provider routing decision from the self-hosted trace store.";
10445
- var escapeHtml19 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
10602
+ var DEFAULT_TITLE13 = "Voice Routing";
10603
+ var DEFAULT_DESCRIPTION13 = "Latest provider routing decision from the self-hosted trace store.";
10604
+ var escapeHtml20 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
10446
10605
  var formatValue = (value, fallback = "None") => typeof value === "string" && value.trim() ? value : typeof value === "number" && Number.isFinite(value) ? String(value) : fallback;
10447
10606
  var formatProviderRoutes2 = (routes) => routes && typeof routes === "object" ? Object.entries(routes).map(([role, provider]) => `${role}: ${formatValue(provider)}`).join(", ") || "None" : "None";
10448
10607
  var getProviderRoute = (routes, role) => routes && typeof routes === "object" ? formatValue(routes[role], "Not configured") : "Not configured";
@@ -10511,35 +10670,35 @@ var createVoiceRoutingStatusViewModel = (snapshot, options = {}) => {
10511
10670
  return {
10512
10671
  activeStack,
10513
10672
  decision,
10514
- description: options.description ?? DEFAULT_DESCRIPTION12,
10673
+ description: options.description ?? DEFAULT_DESCRIPTION13,
10515
10674
  error: snapshot.error,
10516
10675
  isLoading: snapshot.isLoading,
10517
10676
  label: snapshot.error ? "Unavailable" : decision ? `${formatValue(decision.kind).toUpperCase()} ${formatValue(decision.status, "unknown")}` : snapshot.isLoading ? "Checking" : "No routing yet",
10518
10677
  rows,
10519
10678
  status: snapshot.error ? "error" : decision ? "ready" : snapshot.isLoading ? "loading" : "empty",
10520
- title: options.title ?? DEFAULT_TITLE12,
10679
+ title: options.title ?? DEFAULT_TITLE13,
10521
10680
  updatedAt: snapshot.updatedAt
10522
10681
  };
10523
10682
  };
10524
10683
  var renderVoiceRoutingStatusHTML = (snapshot, options = {}) => {
10525
10684
  const model = createVoiceRoutingStatusViewModel(snapshot, options);
10526
10685
  const activeStack = model.activeStack.length ? `<div class="absolute-voice-routing-status__stack" aria-label="Active voice stack">${model.activeStack.map((item) => `<div>
10527
- <span>${escapeHtml19(item.label)}</span>
10528
- <strong>${escapeHtml19(item.value)}</strong>
10686
+ <span>${escapeHtml20(item.label)}</span>
10687
+ <strong>${escapeHtml20(item.value)}</strong>
10529
10688
  </div>`).join("")}</div>` : "";
10530
10689
  const rows = model.rows.length ? `<div class="absolute-voice-routing-status__grid">${model.rows.map((row) => `<div>
10531
- <span>${escapeHtml19(row.label)}</span>
10532
- <strong>${escapeHtml19(row.value)}</strong>
10690
+ <span>${escapeHtml20(row.label)}</span>
10691
+ <strong>${escapeHtml20(row.value)}</strong>
10533
10692
  </div>`).join("")}</div>` : '<p class="absolute-voice-routing-status__empty">Start a voice session to see the selected provider.</p>';
10534
- return `<section class="absolute-voice-routing-status absolute-voice-routing-status--${escapeHtml19(model.status)}">
10693
+ return `<section class="absolute-voice-routing-status absolute-voice-routing-status--${escapeHtml20(model.status)}">
10535
10694
  <header class="absolute-voice-routing-status__header">
10536
- <span class="absolute-voice-routing-status__eyebrow">${escapeHtml19(model.title)}</span>
10537
- <strong class="absolute-voice-routing-status__label">${escapeHtml19(model.label)}</strong>
10695
+ <span class="absolute-voice-routing-status__eyebrow">${escapeHtml20(model.title)}</span>
10696
+ <strong class="absolute-voice-routing-status__label">${escapeHtml20(model.label)}</strong>
10538
10697
  </header>
10539
- <p class="absolute-voice-routing-status__description">${escapeHtml19(model.description)}</p>
10698
+ <p class="absolute-voice-routing-status__description">${escapeHtml20(model.description)}</p>
10540
10699
  ${activeStack}
10541
10700
  ${rows}
10542
- ${model.error ? `<p class="absolute-voice-routing-status__error">${escapeHtml19(model.error)}</p>` : ""}
10701
+ ${model.error ? `<p class="absolute-voice-routing-status__error">${escapeHtml20(model.error)}</p>` : ""}
10543
10702
  </section>`;
10544
10703
  };
10545
10704
  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}}`;
@@ -11338,7 +11497,7 @@ var createVoiceProviderSimulationControlsStore = (options) => {
11338
11497
  };
11339
11498
  };
11340
11499
  // src/client/providerSimulationControlsWidget.ts
11341
- var escapeHtml20 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
11500
+ var escapeHtml21 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
11342
11501
  var formatKind = (kind) => (kind ?? "stt").toUpperCase();
11343
11502
  var createVoiceProviderSimulationControlsViewModel = (snapshot, options) => {
11344
11503
  const configuredProviders = options.providers.filter((provider) => provider.configured !== false);
@@ -11358,18 +11517,18 @@ var createVoiceProviderSimulationControlsViewModel = (snapshot, options) => {
11358
11517
  };
11359
11518
  var renderVoiceProviderSimulationControlsHTML = (snapshot, options) => {
11360
11519
  const model = createVoiceProviderSimulationControlsViewModel(snapshot, options);
11361
- const failureButtons = model.failureProviders.map((provider) => `<button type="button" data-voice-provider-fail="${escapeHtml20(provider.provider)}"${!model.canSimulateFailure || snapshot.isRunning ? " disabled" : ""}>Simulate ${escapeHtml20(provider.provider)} ${escapeHtml20(formatKind(options.kind))} failure</button>`).join("");
11362
- const recoveryButtons = model.providers.map((provider) => `<button type="button" data-voice-provider-recover="${escapeHtml20(provider.provider)}"${snapshot.isRunning ? " disabled" : ""}>Mark ${escapeHtml20(provider.provider)} recovered</button>`).join("");
11520
+ const failureButtons = model.failureProviders.map((provider) => `<button type="button" data-voice-provider-fail="${escapeHtml21(provider.provider)}"${!model.canSimulateFailure || snapshot.isRunning ? " disabled" : ""}>Simulate ${escapeHtml21(provider.provider)} ${escapeHtml21(formatKind(options.kind))} failure</button>`).join("");
11521
+ const recoveryButtons = model.providers.map((provider) => `<button type="button" data-voice-provider-recover="${escapeHtml21(provider.provider)}"${snapshot.isRunning ? " disabled" : ""}>Mark ${escapeHtml21(provider.provider)} recovered</button>`).join("");
11363
11522
  return `<section class="absolute-voice-provider-simulation absolute-voice-provider-simulation--${snapshot.error ? "error" : snapshot.isRunning ? "running" : "ready"}">
11364
11523
  <header class="absolute-voice-provider-simulation__header">
11365
- <span class="absolute-voice-provider-simulation__eyebrow">${escapeHtml20(model.title)}</span>
11366
- <strong class="absolute-voice-provider-simulation__label">${escapeHtml20(model.label)}</strong>
11524
+ <span class="absolute-voice-provider-simulation__eyebrow">${escapeHtml21(model.title)}</span>
11525
+ <strong class="absolute-voice-provider-simulation__label">${escapeHtml21(model.label)}</strong>
11367
11526
  </header>
11368
- <p class="absolute-voice-provider-simulation__description">${escapeHtml20(model.description)}</p>
11369
- ${model.canSimulateFailure ? "" : `<p class="absolute-voice-provider-simulation__empty">${escapeHtml20(options.fallbackRequiredMessage ?? "Configure fallback providers before simulating failure.")}</p>`}
11527
+ <p class="absolute-voice-provider-simulation__description">${escapeHtml21(model.description)}</p>
11528
+ ${model.canSimulateFailure ? "" : `<p class="absolute-voice-provider-simulation__empty">${escapeHtml21(options.fallbackRequiredMessage ?? "Configure fallback providers before simulating failure.")}</p>`}
11370
11529
  <div class="absolute-voice-provider-simulation__actions">${failureButtons}${recoveryButtons}</div>
11371
- ${snapshot.error ? `<p class="absolute-voice-provider-simulation__error">${escapeHtml20(snapshot.error)}</p>` : ""}
11372
- ${model.resultText ? `<pre class="absolute-voice-provider-simulation__result">${escapeHtml20(model.resultText)}</pre>` : ""}
11530
+ ${snapshot.error ? `<p class="absolute-voice-provider-simulation__error">${escapeHtml21(snapshot.error)}</p>` : ""}
11531
+ ${model.resultText ? `<pre class="absolute-voice-provider-simulation__result">${escapeHtml21(model.resultText)}</pre>` : ""}
11373
11532
  </section>`;
11374
11533
  };
11375
11534
  var bindVoiceProviderSimulationControls = (element, store) => {
@@ -11434,9 +11593,9 @@ var defineVoiceProviderSimulationControlsElement = (tagName = "absolute-voice-pr
11434
11593
  });
11435
11594
  };
11436
11595
  // src/client/providerStatusWidget.ts
11437
- var DEFAULT_TITLE13 = "Voice Providers";
11438
- var DEFAULT_DESCRIPTION13 = "Live provider health, fallback counts, latency, and suppression state from your self-hosted trace store.";
11439
- var escapeHtml21 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
11596
+ var DEFAULT_TITLE14 = "Voice Providers";
11597
+ var DEFAULT_DESCRIPTION14 = "Live provider health, fallback counts, latency, and suppression state from your self-hosted trace store.";
11598
+ var escapeHtml22 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
11440
11599
  var formatProvider = (provider) => provider.split(/[-_\s]+/).filter(Boolean).map((part) => `${part[0]?.toUpperCase() ?? ""}${part.slice(1)}`).join(" ") || provider;
11441
11600
  var formatStatus3 = (status) => status.split("-").map((part) => `${part[0]?.toUpperCase() ?? ""}${part.slice(1)}`).join(" ");
11442
11601
  var formatLatency = (value) => typeof value === "number" ? `${value}ms` : "No samples";
@@ -11480,37 +11639,37 @@ var createVoiceProviderStatusViewModel = (snapshot, options = {}) => {
11480
11639
  const warningCount = providers.filter((provider) => isWarningStatus(provider.status)).length;
11481
11640
  const healthyCount = providers.filter((provider) => provider.status === "healthy").length;
11482
11641
  return {
11483
- description: options.description ?? DEFAULT_DESCRIPTION13,
11642
+ description: options.description ?? DEFAULT_DESCRIPTION14,
11484
11643
  error: snapshot.error,
11485
11644
  isLoading: snapshot.isLoading,
11486
11645
  label: snapshot.error ? "Unavailable" : providers.length ? warningCount > 0 ? `${warningCount} needs attention` : `${healthyCount} healthy` : snapshot.isLoading ? "Checking" : "No provider traffic",
11487
11646
  providers,
11488
11647
  status: snapshot.error ? "error" : providers.length ? warningCount > 0 ? "warning" : "ready" : snapshot.isLoading ? "loading" : "empty",
11489
- title: options.title ?? DEFAULT_TITLE13,
11648
+ title: options.title ?? DEFAULT_TITLE14,
11490
11649
  updatedAt: snapshot.updatedAt
11491
11650
  };
11492
11651
  };
11493
11652
  var renderVoiceProviderStatusHTML = (snapshot, options = {}) => {
11494
11653
  const model = createVoiceProviderStatusViewModel(snapshot, options);
11495
- 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--${escapeHtml21(provider.status)}">
11654
+ 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--${escapeHtml22(provider.status)}">
11496
11655
  <header>
11497
- <strong>${escapeHtml21(provider.label)}</strong>
11498
- <span>${escapeHtml21(formatStatus3(provider.status))}</span>
11656
+ <strong>${escapeHtml22(provider.label)}</strong>
11657
+ <span>${escapeHtml22(formatStatus3(provider.status))}</span>
11499
11658
  </header>
11500
- <p>${escapeHtml21(provider.detail)}</p>
11659
+ <p>${escapeHtml22(provider.detail)}</p>
11501
11660
  <dl>${provider.rows.map((row) => `<div>
11502
- <dt>${escapeHtml21(row.label)}</dt>
11503
- <dd>${escapeHtml21(row.value)}</dd>
11661
+ <dt>${escapeHtml22(row.label)}</dt>
11662
+ <dd>${escapeHtml22(row.value)}</dd>
11504
11663
  </div>`).join("")}</dl>
11505
11664
  </article>`).join("")}</div>` : '<p class="absolute-voice-provider-status__empty">Run voice traffic to see provider health.</p>';
11506
- return `<section class="absolute-voice-provider-status absolute-voice-provider-status--${escapeHtml21(model.status)}">
11665
+ return `<section class="absolute-voice-provider-status absolute-voice-provider-status--${escapeHtml22(model.status)}">
11507
11666
  <header class="absolute-voice-provider-status__header">
11508
- <span class="absolute-voice-provider-status__eyebrow">${escapeHtml21(model.title)}</span>
11509
- <strong class="absolute-voice-provider-status__label">${escapeHtml21(model.label)}</strong>
11667
+ <span class="absolute-voice-provider-status__eyebrow">${escapeHtml22(model.title)}</span>
11668
+ <strong class="absolute-voice-provider-status__label">${escapeHtml22(model.label)}</strong>
11510
11669
  </header>
11511
- <p class="absolute-voice-provider-status__description">${escapeHtml21(model.description)}</p>
11670
+ <p class="absolute-voice-provider-status__description">${escapeHtml22(model.description)}</p>
11512
11671
  ${providers}
11513
- ${model.error ? `<p class="absolute-voice-provider-status__error">${escapeHtml21(model.error)}</p>` : ""}
11672
+ ${model.error ? `<p class="absolute-voice-provider-status__error">${escapeHtml22(model.error)}</p>` : ""}
11514
11673
  </section>`;
11515
11674
  };
11516
11675
  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}`;
@@ -11551,9 +11710,9 @@ var defineVoiceProviderStatusElement = (tagName = "absolute-voice-provider-statu
11551
11710
  });
11552
11711
  };
11553
11712
  // src/client/providerCapabilitiesWidget.ts
11554
- var DEFAULT_TITLE14 = "Provider Capabilities";
11555
- var DEFAULT_DESCRIPTION14 = "Configured, selected, and healthy voice providers for this deployment.";
11556
- var escapeHtml22 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
11713
+ var DEFAULT_TITLE15 = "Provider Capabilities";
11714
+ var DEFAULT_DESCRIPTION15 = "Configured, selected, and healthy voice providers for this deployment.";
11715
+ var escapeHtml23 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
11557
11716
  var formatProvider2 = (provider) => provider.split(/[-_\s]+/).filter(Boolean).map((part) => `${part[0]?.toUpperCase() ?? ""}${part.slice(1)}`).join(" ") || provider;
11558
11717
  var formatKind2 = (kind) => kind.toUpperCase();
11559
11718
  var formatStatus4 = (status) => status.split("-").map((part) => `${part[0]?.toUpperCase() ?? ""}${part.slice(1)}`).join(" ");
@@ -11597,36 +11756,36 @@ var createVoiceProviderCapabilitiesViewModel = (snapshot, options = {}) => {
11597
11756
  const selectedCount = snapshot.report?.selected ?? capabilities.filter((capability) => capability.selected).length;
11598
11757
  return {
11599
11758
  capabilities,
11600
- description: options.description ?? DEFAULT_DESCRIPTION14,
11759
+ description: options.description ?? DEFAULT_DESCRIPTION15,
11601
11760
  error: snapshot.error,
11602
11761
  isLoading: snapshot.isLoading,
11603
11762
  label: snapshot.error ? "Unavailable" : capabilities.length ? warningCount > 0 ? `${warningCount} needs attention` : `${selectedCount} selected` : snapshot.isLoading ? "Checking" : "No capabilities",
11604
11763
  status: snapshot.error ? "error" : capabilities.length ? warningCount > 0 ? "warning" : "ready" : snapshot.isLoading ? "loading" : "empty",
11605
- title: options.title ?? DEFAULT_TITLE14,
11764
+ title: options.title ?? DEFAULT_TITLE15,
11606
11765
  updatedAt: snapshot.updatedAt
11607
11766
  };
11608
11767
  };
11609
11768
  var renderVoiceProviderCapabilitiesHTML = (snapshot, options = {}) => {
11610
11769
  const model = createVoiceProviderCapabilitiesViewModel(snapshot, options);
11611
- 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--${escapeHtml22(capability.status)}">
11770
+ 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--${escapeHtml23(capability.status)}">
11612
11771
  <header>
11613
- <strong>${escapeHtml22(capability.label)}</strong>
11614
- <span>${escapeHtml22(formatStatus4(capability.status))}</span>
11772
+ <strong>${escapeHtml23(capability.label)}</strong>
11773
+ <span>${escapeHtml23(formatStatus4(capability.status))}</span>
11615
11774
  </header>
11616
- <p>${escapeHtml22(capability.detail)}</p>
11775
+ <p>${escapeHtml23(capability.detail)}</p>
11617
11776
  <dl>${capability.rows.map((row) => `<div>
11618
- <dt>${escapeHtml22(row.label)}</dt>
11619
- <dd>${escapeHtml22(row.value)}</dd>
11777
+ <dt>${escapeHtml23(row.label)}</dt>
11778
+ <dd>${escapeHtml23(row.value)}</dd>
11620
11779
  </div>`).join("")}</dl>
11621
11780
  </article>`).join("")}</div>` : '<p class="absolute-voice-provider-capabilities__empty">Configure provider capabilities to see deployment coverage.</p>';
11622
- return `<section class="absolute-voice-provider-capabilities absolute-voice-provider-capabilities--${escapeHtml22(model.status)}">
11781
+ return `<section class="absolute-voice-provider-capabilities absolute-voice-provider-capabilities--${escapeHtml23(model.status)}">
11623
11782
  <header class="absolute-voice-provider-capabilities__header">
11624
- <span class="absolute-voice-provider-capabilities__eyebrow">${escapeHtml22(model.title)}</span>
11625
- <strong class="absolute-voice-provider-capabilities__label">${escapeHtml22(model.label)}</strong>
11783
+ <span class="absolute-voice-provider-capabilities__eyebrow">${escapeHtml23(model.title)}</span>
11784
+ <strong class="absolute-voice-provider-capabilities__label">${escapeHtml23(model.label)}</strong>
11626
11785
  </header>
11627
- <p class="absolute-voice-provider-capabilities__description">${escapeHtml22(model.description)}</p>
11786
+ <p class="absolute-voice-provider-capabilities__description">${escapeHtml23(model.description)}</p>
11628
11787
  ${capabilities}
11629
- ${model.error ? `<p class="absolute-voice-provider-capabilities__error">${escapeHtml22(model.error)}</p>` : ""}
11788
+ ${model.error ? `<p class="absolute-voice-provider-capabilities__error">${escapeHtml23(model.error)}</p>` : ""}
11630
11789
  </section>`;
11631
11790
  };
11632
11791
  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}`;
@@ -11667,9 +11826,9 @@ var defineVoiceProviderCapabilitiesElement = (tagName = "absolute-voice-provider
11667
11826
  });
11668
11827
  };
11669
11828
  // src/client/providerContractsWidget.ts
11670
- var DEFAULT_TITLE15 = "Provider Contracts";
11671
- var DEFAULT_DESCRIPTION15 = "Production contract coverage for provider env, latency, fallback, streaming, and capabilities.";
11672
- var escapeHtml23 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
11829
+ var DEFAULT_TITLE16 = "Provider Contracts";
11830
+ var DEFAULT_DESCRIPTION16 = "Production contract coverage for provider env, latency, fallback, streaming, and capabilities.";
11831
+ var escapeHtml24 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
11673
11832
  var formatProvider3 = (provider) => provider.split(/[-_\s]+/).filter(Boolean).map((part) => `${part[0]?.toUpperCase() ?? ""}${part.slice(1)}`).join(" ") || provider;
11674
11833
  var formatStatus5 = (status) => status.split("-").map((part) => `${part[0]?.toUpperCase() ?? ""}${part.slice(1)}`).join(" ");
11675
11834
  var contractDetail = (row) => {
@@ -11701,38 +11860,38 @@ var createVoiceProviderContractsViewModel = (snapshot, options = {}) => {
11701
11860
  }));
11702
11861
  const warningCount = snapshot.report ? snapshot.report.failed + snapshot.report.warned : rows.filter((row) => row.status !== "pass").length;
11703
11862
  return {
11704
- description: options.description ?? DEFAULT_DESCRIPTION15,
11863
+ description: options.description ?? DEFAULT_DESCRIPTION16,
11705
11864
  error: snapshot.error,
11706
11865
  isLoading: snapshot.isLoading,
11707
11866
  label: snapshot.error ? "Unavailable" : rows.length ? warningCount > 0 ? `${warningCount} needs attention` : `${rows.length} passing` : snapshot.isLoading ? "Checking" : "No contracts",
11708
11867
  rows,
11709
11868
  status: snapshot.error ? "error" : rows.length ? warningCount > 0 ? "warning" : "ready" : snapshot.isLoading ? "loading" : "empty",
11710
- title: options.title ?? DEFAULT_TITLE15,
11869
+ title: options.title ?? DEFAULT_TITLE16,
11711
11870
  updatedAt: snapshot.updatedAt
11712
11871
  };
11713
11872
  };
11714
11873
  var renderVoiceProviderContractsHTML = (snapshot, options = {}) => {
11715
11874
  const model = createVoiceProviderContractsViewModel(snapshot, options);
11716
- 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--${escapeHtml23(row.status)}">
11875
+ 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--${escapeHtml24(row.status)}">
11717
11876
  <header>
11718
- <strong>${escapeHtml23(row.label)}</strong>
11719
- <span>${escapeHtml23(formatStatus5(row.status))}</span>
11877
+ <strong>${escapeHtml24(row.label)}</strong>
11878
+ <span>${escapeHtml24(formatStatus5(row.status))}</span>
11720
11879
  </header>
11721
- <p>${escapeHtml23(row.detail)}</p>
11722
- ${row.remediations.length ? `<ul class="absolute-voice-provider-contracts__remediations">${row.remediations.map((remediation) => `<li>${remediation.href ? `<a href="${escapeHtml23(remediation.href)}">${escapeHtml23(remediation.label)}</a>` : `<strong>${escapeHtml23(remediation.label)}</strong>`}<span>${escapeHtml23(remediation.detail)}</span></li>`).join("")}</ul>` : ""}
11880
+ <p>${escapeHtml24(row.detail)}</p>
11881
+ ${row.remediations.length ? `<ul class="absolute-voice-provider-contracts__remediations">${row.remediations.map((remediation) => `<li>${remediation.href ? `<a href="${escapeHtml24(remediation.href)}">${escapeHtml24(remediation.label)}</a>` : `<strong>${escapeHtml24(remediation.label)}</strong>`}<span>${escapeHtml24(remediation.detail)}</span></li>`).join("")}</ul>` : ""}
11723
11882
  <dl>${row.rows.map((item) => `<div>
11724
- <dt>${escapeHtml23(item.label)}</dt>
11725
- <dd>${escapeHtml23(item.value)}</dd>
11883
+ <dt>${escapeHtml24(item.label)}</dt>
11884
+ <dd>${escapeHtml24(item.value)}</dd>
11726
11885
  </div>`).join("")}</dl>
11727
11886
  </article>`).join("")}</div>` : '<p class="absolute-voice-provider-contracts__empty">Configure provider contracts to see production coverage.</p>';
11728
- return `<section class="absolute-voice-provider-contracts absolute-voice-provider-contracts--${escapeHtml23(model.status)}">
11887
+ return `<section class="absolute-voice-provider-contracts absolute-voice-provider-contracts--${escapeHtml24(model.status)}">
11729
11888
  <header class="absolute-voice-provider-contracts__header">
11730
- <span class="absolute-voice-provider-contracts__eyebrow">${escapeHtml23(model.title)}</span>
11731
- <strong class="absolute-voice-provider-contracts__label">${escapeHtml23(model.label)}</strong>
11889
+ <span class="absolute-voice-provider-contracts__eyebrow">${escapeHtml24(model.title)}</span>
11890
+ <strong class="absolute-voice-provider-contracts__label">${escapeHtml24(model.label)}</strong>
11732
11891
  </header>
11733
- <p class="absolute-voice-provider-contracts__description">${escapeHtml23(model.description)}</p>
11892
+ <p class="absolute-voice-provider-contracts__description">${escapeHtml24(model.description)}</p>
11734
11893
  ${rows}
11735
- ${model.error ? `<p class="absolute-voice-provider-contracts__error">${escapeHtml23(model.error)}</p>` : ""}
11894
+ ${model.error ? `<p class="absolute-voice-provider-contracts__error">${escapeHtml24(model.error)}</p>` : ""}
11736
11895
  </section>`;
11737
11896
  };
11738
11897
  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}`;
@@ -11773,9 +11932,9 @@ var defineVoiceProviderContractsElement = (tagName = "absolute-voice-provider-co
11773
11932
  });
11774
11933
  };
11775
11934
  // src/client/turnQualityWidget.ts
11776
- var DEFAULT_TITLE16 = "Turn Quality";
11777
- var DEFAULT_DESCRIPTION16 = "Per-turn STT confidence, fallback selection, corrections, and transcript coverage.";
11778
- var escapeHtml24 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
11935
+ var DEFAULT_TITLE17 = "Turn Quality";
11936
+ var DEFAULT_DESCRIPTION17 = "Per-turn STT confidence, fallback selection, corrections, and transcript coverage.";
11937
+ var escapeHtml25 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
11779
11938
  var formatConfidence = (value) => typeof value === "number" ? `${Math.round(value * 100)}%` : "n/a";
11780
11939
  var formatMaybe = (value) => value === undefined || value === "" ? "n/a" : String(value);
11781
11940
  var getTurnDetail = (turn) => {
@@ -11819,37 +11978,37 @@ var createVoiceTurnQualityViewModel = (snapshot, options = {}) => {
11819
11978
  const warningCount = snapshot.report?.warnings ?? turns.filter((turn) => turn.status === "warn").length;
11820
11979
  const failedCount = snapshot.report?.failed ?? turns.filter((turn) => turn.status === "fail").length;
11821
11980
  return {
11822
- description: options.description ?? DEFAULT_DESCRIPTION16,
11981
+ description: options.description ?? DEFAULT_DESCRIPTION17,
11823
11982
  error: snapshot.error,
11824
11983
  isLoading: snapshot.isLoading,
11825
11984
  label: snapshot.error ? "Unavailable" : turns.length ? failedCount > 0 ? `${failedCount} failed` : warningCount > 0 ? `${warningCount} warnings` : `${turns.length} healthy` : snapshot.isLoading ? "Checking" : "No turns",
11826
11985
  status: snapshot.error ? "error" : turns.length ? failedCount > 0 || warningCount > 0 ? "warning" : "ready" : snapshot.isLoading ? "loading" : "empty",
11827
- title: options.title ?? DEFAULT_TITLE16,
11986
+ title: options.title ?? DEFAULT_TITLE17,
11828
11987
  turns,
11829
11988
  updatedAt: snapshot.updatedAt
11830
11989
  };
11831
11990
  };
11832
11991
  var renderVoiceTurnQualityHTML = (snapshot, options = {}) => {
11833
11992
  const model = createVoiceTurnQualityViewModel(snapshot, options);
11834
- 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--${escapeHtml24(turn.status)}">
11993
+ 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--${escapeHtml25(turn.status)}">
11835
11994
  <header>
11836
- <strong>${escapeHtml24(turn.label)}</strong>
11837
- <span>${escapeHtml24(turn.status)}</span>
11995
+ <strong>${escapeHtml25(turn.label)}</strong>
11996
+ <span>${escapeHtml25(turn.status)}</span>
11838
11997
  </header>
11839
- <p>${escapeHtml24(turn.detail)}</p>
11998
+ <p>${escapeHtml25(turn.detail)}</p>
11840
11999
  <dl>${turn.rows.map((row) => `<div>
11841
- <dt>${escapeHtml24(row.label)}</dt>
11842
- <dd>${escapeHtml24(row.value)}</dd>
12000
+ <dt>${escapeHtml25(row.label)}</dt>
12001
+ <dd>${escapeHtml25(row.value)}</dd>
11843
12002
  </div>`).join("")}</dl>
11844
12003
  </article>`).join("")}</div>` : '<p class="absolute-voice-turn-quality__empty">Complete a voice turn to see STT quality diagnostics.</p>';
11845
- return `<section class="absolute-voice-turn-quality absolute-voice-turn-quality--${escapeHtml24(model.status)}">
12004
+ return `<section class="absolute-voice-turn-quality absolute-voice-turn-quality--${escapeHtml25(model.status)}">
11846
12005
  <header class="absolute-voice-turn-quality__header">
11847
- <span class="absolute-voice-turn-quality__eyebrow">${escapeHtml24(model.title)}</span>
11848
- <strong class="absolute-voice-turn-quality__label">${escapeHtml24(model.label)}</strong>
12006
+ <span class="absolute-voice-turn-quality__eyebrow">${escapeHtml25(model.title)}</span>
12007
+ <strong class="absolute-voice-turn-quality__label">${escapeHtml25(model.label)}</strong>
11849
12008
  </header>
11850
- <p class="absolute-voice-turn-quality__description">${escapeHtml24(model.description)}</p>
12009
+ <p class="absolute-voice-turn-quality__description">${escapeHtml25(model.description)}</p>
11851
12010
  ${turns}
11852
- ${model.error ? `<p class="absolute-voice-turn-quality__error">${escapeHtml24(model.error)}</p>` : ""}
12011
+ ${model.error ? `<p class="absolute-voice-turn-quality__error">${escapeHtml25(model.error)}</p>` : ""}
11853
12012
  </section>`;
11854
12013
  };
11855
12014
  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}`;
@@ -11890,56 +12049,56 @@ var defineVoiceTurnQualityElement = (tagName = "absolute-voice-turn-quality") =>
11890
12049
  });
11891
12050
  };
11892
12051
  // src/client/turnLatencyWidget.ts
11893
- var DEFAULT_TITLE17 = "Turn Latency";
11894
- var DEFAULT_DESCRIPTION17 = "Per-turn timing from first transcript to commit and assistant response start.";
12052
+ var DEFAULT_TITLE18 = "Turn Latency";
12053
+ var DEFAULT_DESCRIPTION18 = "Per-turn timing from first transcript to commit and assistant response start.";
11895
12054
  var DEFAULT_PROOF_LABEL = "Run latency proof";
11896
- var escapeHtml25 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
11897
- var formatMs4 = (value) => typeof value === "number" ? `${Math.round(value)}ms` : "n/a";
12055
+ var escapeHtml26 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
12056
+ var formatMs5 = (value) => typeof value === "number" ? `${Math.round(value)}ms` : "n/a";
11898
12057
  var createVoiceTurnLatencyViewModel = (snapshot, options = {}) => {
11899
12058
  const turns = (snapshot.report?.turns ?? []).map((turn) => ({
11900
12059
  ...turn,
11901
12060
  label: turn.text || "Empty turn",
11902
12061
  rows: turn.stages.map((stage) => ({
11903
12062
  label: stage.label,
11904
- value: formatMs4(stage.valueMs)
12063
+ value: formatMs5(stage.valueMs)
11905
12064
  }))
11906
12065
  }));
11907
12066
  const warningCount = snapshot.report?.warnings ?? turns.filter((turn) => turn.status === "warn").length;
11908
12067
  const failedCount = snapshot.report?.failed ?? turns.filter((turn) => turn.status === "fail").length;
11909
12068
  return {
11910
- description: options.description ?? DEFAULT_DESCRIPTION17,
12069
+ description: options.description ?? DEFAULT_DESCRIPTION18,
11911
12070
  error: snapshot.error,
11912
12071
  isLoading: snapshot.isLoading,
11913
- label: snapshot.error ? "Unavailable" : turns.length ? failedCount > 0 ? `${failedCount} slow` : warningCount > 0 ? `${warningCount} warnings` : `avg ${formatMs4(snapshot.report?.averageTotalMs)}` : snapshot.isLoading ? "Checking" : "No turns",
12072
+ label: snapshot.error ? "Unavailable" : turns.length ? failedCount > 0 ? `${failedCount} slow` : warningCount > 0 ? `${warningCount} warnings` : `avg ${formatMs5(snapshot.report?.averageTotalMs)}` : snapshot.isLoading ? "Checking" : "No turns",
11914
12073
  proofLabel: options.proofPath ? options.proofLabel ?? DEFAULT_PROOF_LABEL : undefined,
11915
12074
  showProofAction: Boolean(options.proofPath),
11916
12075
  status: snapshot.error ? "error" : turns.length ? failedCount > 0 || warningCount > 0 ? "warning" : "ready" : snapshot.isLoading ? "loading" : "empty",
11917
- title: options.title ?? DEFAULT_TITLE17,
12076
+ title: options.title ?? DEFAULT_TITLE18,
11918
12077
  turns,
11919
12078
  updatedAt: snapshot.updatedAt
11920
12079
  };
11921
12080
  };
11922
12081
  var renderVoiceTurnLatencyHTML = (snapshot, options = {}) => {
11923
12082
  const model = createVoiceTurnLatencyViewModel(snapshot, options);
11924
- 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--${escapeHtml25(turn.status)}">
12083
+ 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--${escapeHtml26(turn.status)}">
11925
12084
  <header>
11926
- <strong>${escapeHtml25(turn.label)}</strong>
11927
- <span>${escapeHtml25(turn.status)}</span>
12085
+ <strong>${escapeHtml26(turn.label)}</strong>
12086
+ <span>${escapeHtml26(turn.status)}</span>
11928
12087
  </header>
11929
12088
  <dl>${turn.rows.map((row) => `<div>
11930
- <dt>${escapeHtml25(row.label)}</dt>
11931
- <dd>${escapeHtml25(row.value)}</dd>
12089
+ <dt>${escapeHtml26(row.label)}</dt>
12090
+ <dd>${escapeHtml26(row.value)}</dd>
11932
12091
  </div>`).join("")}</dl>
11933
12092
  </article>`).join("")}</div>` : '<p class="absolute-voice-turn-latency__empty">Complete a voice turn to see latency diagnostics.</p>';
11934
- return `<section class="absolute-voice-turn-latency absolute-voice-turn-latency--${escapeHtml25(model.status)}">
12093
+ return `<section class="absolute-voice-turn-latency absolute-voice-turn-latency--${escapeHtml26(model.status)}">
11935
12094
  <header class="absolute-voice-turn-latency__header">
11936
- <span class="absolute-voice-turn-latency__eyebrow">${escapeHtml25(model.title)}</span>
11937
- <strong class="absolute-voice-turn-latency__label">${escapeHtml25(model.label)}</strong>
12095
+ <span class="absolute-voice-turn-latency__eyebrow">${escapeHtml26(model.title)}</span>
12096
+ <strong class="absolute-voice-turn-latency__label">${escapeHtml26(model.label)}</strong>
11938
12097
  </header>
11939
- <p class="absolute-voice-turn-latency__description">${escapeHtml25(model.description)}</p>
11940
- ${model.showProofAction ? `<button class="absolute-voice-turn-latency__proof" data-absolute-voice-turn-latency-proof type="button">${escapeHtml25(model.proofLabel ?? DEFAULT_PROOF_LABEL)}</button>` : ""}
12098
+ <p class="absolute-voice-turn-latency__description">${escapeHtml26(model.description)}</p>
12099
+ ${model.showProofAction ? `<button class="absolute-voice-turn-latency__proof" data-absolute-voice-turn-latency-proof type="button">${escapeHtml26(model.proofLabel ?? DEFAULT_PROOF_LABEL)}</button>` : ""}
11941
12100
  ${turns}
11942
- ${model.error ? `<p class="absolute-voice-turn-latency__error">${escapeHtml25(model.error)}</p>` : ""}
12101
+ ${model.error ? `<p class="absolute-voice-turn-latency__error">${escapeHtml26(model.error)}</p>` : ""}
11943
12102
  </section>`;
11944
12103
  };
11945
12104
  var mountVoiceTurnLatency = (element, path = "/api/turn-latency", options = {}) => {
@@ -11989,16 +12148,16 @@ var defineVoiceTurnLatencyElement = (tagName = "absolute-voice-turn-latency") =>
11989
12148
  });
11990
12149
  };
11991
12150
  // src/client/traceTimelineWidget.ts
11992
- var DEFAULT_TITLE18 = "Voice Traces";
11993
- var DEFAULT_DESCRIPTION18 = "Latest call timelines with provider latency, fallbacks, handoffs, and errors from your self-hosted trace store.";
11994
- var escapeHtml26 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
11995
- var formatMs5 = (value) => typeof value === "number" ? `${value}ms` : "n/a";
12151
+ var DEFAULT_TITLE19 = "Voice Traces";
12152
+ var DEFAULT_DESCRIPTION19 = "Latest call timelines with provider latency, fallbacks, handoffs, and errors from your self-hosted trace store.";
12153
+ var escapeHtml27 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
12154
+ var formatMs6 = (value) => typeof value === "number" ? `${value}ms` : "n/a";
11996
12155
  var formatProviders = (session) => session.providers.length ? session.providers.map((provider) => provider.provider).join(", ") : "No providers";
11997
12156
  var createVoiceTraceTimelineViewModel = (snapshot, options = {}) => {
11998
12157
  const sessions = (snapshot.report?.sessions ?? []).slice(0, options.limit ?? 3).map((session) => ({
11999
12158
  ...session,
12000
12159
  detailHref: `${options.detailBasePath ?? "/traces"}/${encodeURIComponent(session.sessionId)}`,
12001
- durationLabel: formatMs5(session.summary.callDurationMs),
12160
+ durationLabel: formatMs6(session.summary.callDurationMs),
12002
12161
  incidentBundleHref: options.incidentBundleBasePath === false ? undefined : `${options.incidentBundleBasePath ?? "/voice-incidents"}/${encodeURIComponent(session.sessionId)}/markdown`,
12003
12162
  label: `${session.summary.eventCount} events / ${session.summary.turnCount} turns`,
12004
12163
  operationsRecordHref: options.operationsRecordBasePath === false ? undefined : `${options.operationsRecordBasePath ?? "/voice-operations"}/${encodeURIComponent(session.sessionId)}`,
@@ -12007,13 +12166,13 @@ var createVoiceTraceTimelineViewModel = (snapshot, options = {}) => {
12007
12166
  const failed = sessions.filter((session) => session.status === "failed").length;
12008
12167
  const warnings = sessions.filter((session) => session.status === "warning").length;
12009
12168
  return {
12010
- description: options.description ?? DEFAULT_DESCRIPTION18,
12169
+ description: options.description ?? DEFAULT_DESCRIPTION19,
12011
12170
  error: snapshot.error,
12012
12171
  isLoading: snapshot.isLoading,
12013
12172
  label: snapshot.error ? "Unavailable" : failed > 0 ? `${failed} failed` : warnings > 0 ? `${warnings} warning` : sessions.length ? `${sessions.length} recent` : snapshot.isLoading ? "Checking" : "No traces yet",
12014
12173
  sessions,
12015
12174
  status: snapshot.error ? "error" : failed > 0 ? "failed" : warnings > 0 ? "warning" : sessions.length ? "ready" : snapshot.isLoading ? "loading" : "empty",
12016
- title: options.title ?? DEFAULT_TITLE18,
12175
+ title: options.title ?? DEFAULT_TITLE19,
12017
12176
  updatedAt: snapshot.updatedAt
12018
12177
  };
12019
12178
  };
@@ -12021,27 +12180,27 @@ var renderVoiceTraceTimelineWidgetHTML = (snapshot, options = {}) => {
12021
12180
  const model = createVoiceTraceTimelineViewModel(snapshot, options);
12022
12181
  const sessions = model.sessions.length ? `<div class="absolute-voice-trace-timeline__sessions">${model.sessions.map((session) => {
12023
12182
  const supportLinks = [
12024
- `<a href="${escapeHtml26(session.detailHref)}">Open timeline</a>`,
12025
- session.operationsRecordHref ? `<a href="${escapeHtml26(session.operationsRecordHref)}">Open operations record</a>` : undefined,
12026
- session.incidentBundleHref ? `<a href="${escapeHtml26(session.incidentBundleHref)}">Export incident bundle</a>` : undefined
12183
+ `<a href="${escapeHtml27(session.detailHref)}">Open timeline</a>`,
12184
+ session.operationsRecordHref ? `<a href="${escapeHtml27(session.operationsRecordHref)}">Open operations record</a>` : undefined,
12185
+ session.incidentBundleHref ? `<a href="${escapeHtml27(session.incidentBundleHref)}">Export incident bundle</a>` : undefined
12027
12186
  ].filter(Boolean).join("");
12028
- return `<article class="absolute-voice-trace-timeline__session absolute-voice-trace-timeline__session--${escapeHtml26(session.status)}">
12187
+ return `<article class="absolute-voice-trace-timeline__session absolute-voice-trace-timeline__session--${escapeHtml27(session.status)}">
12029
12188
  <header>
12030
- <strong>${escapeHtml26(session.sessionId)}</strong>
12031
- <span>${escapeHtml26(session.status)}</span>
12189
+ <strong>${escapeHtml27(session.sessionId)}</strong>
12190
+ <span>${escapeHtml27(session.status)}</span>
12032
12191
  </header>
12033
- <p>${escapeHtml26(session.label)} \xB7 ${escapeHtml26(session.durationLabel)} \xB7 ${escapeHtml26(session.providerLabel)}</p>
12192
+ <p>${escapeHtml27(session.label)} \xB7 ${escapeHtml27(session.durationLabel)} \xB7 ${escapeHtml27(session.providerLabel)}</p>
12034
12193
  <p class="absolute-voice-trace-timeline__actions">${supportLinks}</p>
12035
12194
  </article>`;
12036
12195
  }).join("")}</div>` : '<p class="absolute-voice-trace-timeline__empty">Run a voice session to see call timelines.</p>';
12037
- return `<section class="absolute-voice-trace-timeline absolute-voice-trace-timeline--${escapeHtml26(model.status)}">
12196
+ return `<section class="absolute-voice-trace-timeline absolute-voice-trace-timeline--${escapeHtml27(model.status)}">
12038
12197
  <header class="absolute-voice-trace-timeline__header">
12039
- <span class="absolute-voice-trace-timeline__eyebrow">${escapeHtml26(model.title)}</span>
12040
- <strong class="absolute-voice-trace-timeline__label">${escapeHtml26(model.label)}</strong>
12198
+ <span class="absolute-voice-trace-timeline__eyebrow">${escapeHtml27(model.title)}</span>
12199
+ <strong class="absolute-voice-trace-timeline__label">${escapeHtml27(model.label)}</strong>
12041
12200
  </header>
12042
- <p class="absolute-voice-trace-timeline__description">${escapeHtml26(model.description)}</p>
12201
+ <p class="absolute-voice-trace-timeline__description">${escapeHtml27(model.description)}</p>
12043
12202
  ${sessions}
12044
- ${model.error ? `<p class="absolute-voice-trace-timeline__error">${escapeHtml26(model.error)}</p>` : ""}
12203
+ ${model.error ? `<p class="absolute-voice-trace-timeline__error">${escapeHtml27(model.error)}</p>` : ""}
12045
12204
  </section>`;
12046
12205
  };
12047
12206
  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}`;
@@ -12087,9 +12246,9 @@ var defineVoiceTraceTimelineElement = (tagName = "absolute-voice-trace-timeline"
12087
12246
  });
12088
12247
  };
12089
12248
  // src/client/agentSquadStatusWidget.ts
12090
- var DEFAULT_TITLE19 = "Voice Agent Squad";
12091
- var DEFAULT_DESCRIPTION19 = "Current specialist and recent handoffs from your self-hosted voice traces.";
12092
- var escapeHtml27 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
12249
+ var DEFAULT_TITLE20 = "Voice Agent Squad";
12250
+ var DEFAULT_DESCRIPTION20 = "Current specialist and recent handoffs from your self-hosted voice traces.";
12251
+ var escapeHtml28 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
12093
12252
  var labelFor = (current) => {
12094
12253
  if (!current)
12095
12254
  return "Waiting for specialist activity";
@@ -12103,37 +12262,37 @@ var labelFor = (current) => {
12103
12262
  };
12104
12263
  var createVoiceAgentSquadStatusViewModel = (snapshot, options = {}) => ({
12105
12264
  current: snapshot.report.current,
12106
- description: options.description ?? DEFAULT_DESCRIPTION19,
12265
+ description: options.description ?? DEFAULT_DESCRIPTION20,
12107
12266
  error: snapshot.error,
12108
12267
  isLoading: snapshot.isLoading,
12109
12268
  label: snapshot.error ? "Unavailable" : labelFor(snapshot.report.current),
12110
12269
  sessionCount: snapshot.report.sessionCount,
12111
12270
  sessions: snapshot.report.sessions,
12112
- title: options.title ?? DEFAULT_TITLE19,
12271
+ title: options.title ?? DEFAULT_TITLE20,
12113
12272
  updatedAt: snapshot.updatedAt
12114
12273
  });
12115
12274
  var renderVoiceAgentSquadStatusHTML = (snapshot, options = {}) => {
12116
12275
  const model = createVoiceAgentSquadStatusViewModel(snapshot, options);
12117
12276
  const current = model.current;
12118
12277
  const rows = model.sessions.length ? model.sessions.slice(0, 5).map((session) => `<li>
12119
- <span>${escapeHtml27(session.sessionId)}</span>
12120
- <strong>${escapeHtml27(session.targetAgentId ?? "none")}</strong>
12121
- <em>${escapeHtml27(session.status)}</em>
12122
- ${session.summary || session.reason ? `<p>${escapeHtml27(session.summary ?? session.reason ?? "")}</p>` : ""}
12278
+ <span>${escapeHtml28(session.sessionId)}</span>
12279
+ <strong>${escapeHtml28(session.targetAgentId ?? "none")}</strong>
12280
+ <em>${escapeHtml28(session.status)}</em>
12281
+ ${session.summary || session.reason ? `<p>${escapeHtml28(session.summary ?? session.reason ?? "")}</p>` : ""}
12123
12282
  </li>`).join("") : "<li><span>No squad traces yet.</span><strong>Waiting</strong></li>";
12124
12283
  return `<section class="absolute-voice-agent-squad-status">
12125
12284
  <header>
12126
- <span>${escapeHtml27(model.title)}</span>
12127
- <strong>${escapeHtml27(model.label)}</strong>
12285
+ <span>${escapeHtml28(model.title)}</span>
12286
+ <strong>${escapeHtml28(model.label)}</strong>
12128
12287
  </header>
12129
- <p>${escapeHtml27(model.description)}</p>
12288
+ <p>${escapeHtml28(model.description)}</p>
12130
12289
  <div>
12131
- <span>Session</span><strong>${escapeHtml27(current?.sessionId ?? "n/a")}</strong>
12132
- <span>From</span><strong>${escapeHtml27(current?.fromAgentId ?? "n/a")}</strong>
12133
- <span>Status</span><strong>${escapeHtml27(current?.status ?? "idle")}</strong>
12290
+ <span>Session</span><strong>${escapeHtml28(current?.sessionId ?? "n/a")}</strong>
12291
+ <span>From</span><strong>${escapeHtml28(current?.fromAgentId ?? "n/a")}</strong>
12292
+ <span>Status</span><strong>${escapeHtml28(current?.status ?? "idle")}</strong>
12134
12293
  </div>
12135
12294
  <ul>${rows}</ul>
12136
- ${model.error ? `<p class="absolute-voice-agent-squad-status__error">${escapeHtml27(model.error)}</p>` : ""}
12295
+ ${model.error ? `<p class="absolute-voice-agent-squad-status__error">${escapeHtml28(model.error)}</p>` : ""}
12137
12296
  </section>`;
12138
12297
  };
12139
12298
  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}`;
@@ -12263,6 +12422,7 @@ export {
12263
12422
  renderVoiceTurnLatencyHTML,
12264
12423
  renderVoiceTraceTimelineWidgetHTML,
12265
12424
  renderVoiceSessionSnapshotHTML,
12425
+ renderVoiceSessionObservabilityHTML,
12266
12426
  renderVoiceRoutingStatusHTML,
12267
12427
  renderVoiceReconnectProfileEvidenceHTML,
12268
12428
  renderVoiceReadinessFailuresHTML,
@@ -12287,6 +12447,7 @@ export {
12287
12447
  mountVoiceTurnLatency,
12288
12448
  mountVoiceTraceTimeline,
12289
12449
  mountVoiceSessionSnapshot,
12450
+ mountVoiceSessionObservability,
12290
12451
  mountVoiceRoutingStatus,
12291
12452
  mountVoiceReconnectProfileEvidence,
12292
12453
  mountVoiceReadinessFailures,
@@ -12307,6 +12468,7 @@ export {
12307
12468
  mountVoiceAgentSquadStatus,
12308
12469
  getVoiceTurnQualityCSS,
12309
12470
  getVoiceTraceTimelineCSS,
12471
+ getVoiceSessionObservabilityCSS,
12310
12472
  getVoiceRoutingStatusCSS,
12311
12473
  getVoiceReconnectProfileEvidenceCSS,
12312
12474
  getVoiceReadinessFailuresCSS,
@@ -12329,6 +12491,7 @@ export {
12329
12491
  fetchVoiceTurnLatency,
12330
12492
  fetchVoiceTraceTimeline,
12331
12493
  fetchVoiceSessionSnapshot,
12494
+ fetchVoiceSessionObservability,
12332
12495
  fetchVoiceRoutingStatus,
12333
12496
  fetchVoiceReconnectProfileEvidence,
12334
12497
  fetchVoiceReadinessFailures,
@@ -12348,6 +12511,7 @@ export {
12348
12511
  defineVoiceTurnLatencyElement,
12349
12512
  defineVoiceTraceTimelineElement,
12350
12513
  defineVoiceSessionSnapshotElement,
12514
+ defineVoiceSessionObservabilityElement,
12351
12515
  defineVoiceRoutingStatusElement,
12352
12516
  defineVoiceReconnectProfileEvidenceElement,
12353
12517
  defineVoiceReadinessFailuresElement,
@@ -12376,6 +12540,8 @@ export {
12376
12540
  createVoiceStream,
12377
12541
  createVoiceSessionSnapshotViewModel,
12378
12542
  createVoiceSessionSnapshotStore,
12543
+ createVoiceSessionObservabilityViewModel,
12544
+ createVoiceSessionObservabilityStore,
12379
12545
  createVoiceRoutingStatusViewModel,
12380
12546
  createVoiceRoutingStatusStore,
12381
12547
  createVoiceReconnectProfileEvidenceViewModel,