@absolutejs/voice 0.0.22-beta.353 → 0.0.22-beta.354

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.
@@ -3034,6 +3034,80 @@ var createVoiceProfileComparisonStore = (path = "/api/voice/real-call-profile-hi
3034
3034
  }
3035
3035
  };
3036
3036
  };
3037
+ // src/client/profileSwitchRecommendation.ts
3038
+ var fetchVoiceProfileSwitchRecommendation = async (path = "/api/voice/profile-switch-recommendation", options = {}) => {
3039
+ const fetchImpl = options.fetch ?? globalThis.fetch;
3040
+ const response = await fetchImpl(path);
3041
+ if (!response.ok) {
3042
+ throw new Error(`Voice profile switch recommendation failed: HTTP ${response.status}`);
3043
+ }
3044
+ return await response.json();
3045
+ };
3046
+ var createVoiceProfileSwitchRecommendationStore = (path = "/api/voice/profile-switch-recommendation", options = {}) => {
3047
+ const listeners = new Set;
3048
+ let closed = false;
3049
+ let timer;
3050
+ let snapshot = {
3051
+ error: null,
3052
+ isLoading: false
3053
+ };
3054
+ const emit = () => {
3055
+ for (const listener of listeners) {
3056
+ listener();
3057
+ }
3058
+ };
3059
+ const refresh = async () => {
3060
+ if (closed) {
3061
+ return snapshot.recommendation;
3062
+ }
3063
+ snapshot = { ...snapshot, error: null, isLoading: true };
3064
+ emit();
3065
+ try {
3066
+ const recommendation = await fetchVoiceProfileSwitchRecommendation(path, options);
3067
+ snapshot = {
3068
+ error: null,
3069
+ isLoading: false,
3070
+ recommendation,
3071
+ updatedAt: Date.now()
3072
+ };
3073
+ emit();
3074
+ return recommendation;
3075
+ } catch (error) {
3076
+ snapshot = {
3077
+ ...snapshot,
3078
+ error: error instanceof Error ? error.message : String(error),
3079
+ isLoading: false
3080
+ };
3081
+ emit();
3082
+ throw error;
3083
+ }
3084
+ };
3085
+ const close = () => {
3086
+ closed = true;
3087
+ if (timer) {
3088
+ clearInterval(timer);
3089
+ timer = undefined;
3090
+ }
3091
+ listeners.clear();
3092
+ };
3093
+ if (typeof window !== "undefined" && options.intervalMs && options.intervalMs > 0) {
3094
+ timer = setInterval(() => {
3095
+ refresh().catch(() => {});
3096
+ }, options.intervalMs);
3097
+ }
3098
+ return {
3099
+ close,
3100
+ getServerSnapshot: () => snapshot,
3101
+ getSnapshot: () => snapshot,
3102
+ refresh,
3103
+ subscribe: (listener) => {
3104
+ listeners.add(listener);
3105
+ return () => {
3106
+ listeners.delete(listener);
3107
+ };
3108
+ }
3109
+ };
3110
+ };
3037
3111
  // src/client/readinessFailures.ts
3038
3112
  var fetchVoiceReadinessFailures = async (path = "/api/production-readiness", options = {}) => {
3039
3113
  const fetchImpl = options.fetch ?? globalThis.fetch;
@@ -5071,14 +5145,77 @@ var defineVoiceProfileComparisonElement = (tagName = "absolute-voice-profile-com
5071
5145
  }
5072
5146
  });
5073
5147
  };
5148
+ // src/client/profileSwitchRecommendationWidget.ts
5149
+ var DEFAULT_TITLE5 = "Profile Switch Recommendation";
5150
+ var DEFAULT_DESCRIPTION5 = "Compares the current session against measured profile evidence and recommends whether to switch stacks.";
5151
+ var escapeHtml6 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
5152
+ var formatRoute = (routes) => routes ? Object.entries(routes).map(([role, provider]) => `${role}: ${provider}`).join(", ") : "No route";
5153
+ var renderVoiceProfileSwitchRecommendationHTML = (snapshot, options = {}) => {
5154
+ const recommendation = snapshot.recommendation;
5155
+ const status = snapshot.error ? "error" : recommendation ? recommendation.status : snapshot.isLoading ? "loading" : "empty";
5156
+ 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";
5157
+ const body = recommendation ? `<div class="absolute-voice-profile-switch__body">
5158
+ <p><strong>Current:</strong> ${escapeHtml6(recommendation.currentProfile?.label ?? recommendation.currentProfile?.profileId ?? "Unknown")}</p>
5159
+ <p><strong>Recommended:</strong> ${escapeHtml6(recommendation.recommendedProfile?.label ?? recommendation.recommendedProfile?.profileId ?? "None")}</p>
5160
+ <p><strong>Routes:</strong> ${escapeHtml6(formatRoute(recommendation.recommendedProfile?.providerRoutes))}</p>
5161
+ <ul>${recommendation.reasons.map((reason) => `<li>${escapeHtml6(reason)}</li>`).join("")}</ul>
5162
+ <em>${escapeHtml6(recommendation.nextMove)}</em>
5163
+ </div>` : `<p class="absolute-voice-profile-switch__empty">${escapeHtml6(snapshot.error ?? "Run session traffic to populate a recommendation.")}</p>`;
5164
+ return `<section class="absolute-voice-profile-switch absolute-voice-profile-switch--${escapeHtml6(status)}">
5165
+ <header class="absolute-voice-profile-switch__header">
5166
+ <span class="absolute-voice-profile-switch__eyebrow">${escapeHtml6(options.title ?? DEFAULT_TITLE5)}</span>
5167
+ <strong class="absolute-voice-profile-switch__label">${escapeHtml6(label)}</strong>
5168
+ </header>
5169
+ <p class="absolute-voice-profile-switch__description">${escapeHtml6(options.description ?? DEFAULT_DESCRIPTION5)}</p>
5170
+ ${body}
5171
+ ${snapshot.error ? `<p class="absolute-voice-profile-switch__error">${escapeHtml6(snapshot.error)}</p>` : ""}
5172
+ </section>`;
5173
+ };
5174
+ 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}`;
5175
+ var mountVoiceProfileSwitchRecommendation = (element, path = "/api/voice/profile-switch-recommendation", options = {}) => {
5176
+ const store = createVoiceProfileSwitchRecommendationStore(path, options);
5177
+ const render = () => {
5178
+ element.innerHTML = renderVoiceProfileSwitchRecommendationHTML(store.getSnapshot(), options);
5179
+ };
5180
+ const unsubscribe = store.subscribe(render);
5181
+ render();
5182
+ store.refresh().catch(() => {});
5183
+ return {
5184
+ close: () => {
5185
+ unsubscribe();
5186
+ store.close();
5187
+ },
5188
+ refresh: store.refresh
5189
+ };
5190
+ };
5191
+ var defineVoiceProfileSwitchRecommendationElement = (tagName = "absolute-voice-profile-switch") => {
5192
+ if (typeof window === "undefined" || typeof customElements === "undefined" || customElements.get(tagName)) {
5193
+ return;
5194
+ }
5195
+ customElements.define(tagName, class AbsoluteVoiceProfileSwitchElement extends HTMLElement {
5196
+ mounted;
5197
+ connectedCallback() {
5198
+ const intervalMs = Number(this.getAttribute("interval-ms") ?? 5000);
5199
+ this.mounted = mountVoiceProfileSwitchRecommendation(this, this.getAttribute("path") ?? "/api/voice/profile-switch-recommendation", {
5200
+ description: this.getAttribute("description") ?? undefined,
5201
+ intervalMs: Number.isFinite(intervalMs) ? intervalMs : 5000,
5202
+ title: this.getAttribute("title") ?? undefined
5203
+ });
5204
+ }
5205
+ disconnectedCallback() {
5206
+ this.mounted?.close();
5207
+ this.mounted = undefined;
5208
+ }
5209
+ });
5210
+ };
5074
5211
  // src/client/readinessFailuresWidget.ts
5075
- var DEFAULT_TITLE5 = "Readiness Gate Explanations";
5076
- var DEFAULT_DESCRIPTION5 = "Structured reasons for calibrated production-readiness warnings and failures.";
5212
+ var DEFAULT_TITLE6 = "Readiness Gate Explanations";
5213
+ var DEFAULT_DESCRIPTION6 = "Structured reasons for calibrated production-readiness warnings and failures.";
5077
5214
  var DEFAULT_LINKS4 = [
5078
5215
  { href: "/production-readiness", label: "Readiness page" },
5079
5216
  { href: "/voice/slo-readiness-thresholds", label: "Gate thresholds" }
5080
5217
  ];
5081
- var escapeHtml6 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
5218
+ var escapeHtml7 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
5082
5219
  var formatExplanationValue = (value, unit) => {
5083
5220
  if (value === undefined || value === null) {
5084
5221
  return "n/a";
@@ -5106,36 +5243,36 @@ var createVoiceReadinessFailuresViewModel = (snapshot, options = {}) => {
5106
5243
  const failures = snapshot.report?.checks.map(toFailureView).filter((value) => !!value) ?? [];
5107
5244
  const hasOpenIssues = failures.length > 0;
5108
5245
  return {
5109
- description: options.description ?? DEFAULT_DESCRIPTION5,
5246
+ description: options.description ?? DEFAULT_DESCRIPTION6,
5110
5247
  error: snapshot.error,
5111
5248
  failures,
5112
5249
  isLoading: snapshot.isLoading,
5113
5250
  label: snapshot.error ? "Unavailable" : snapshot.report ? hasOpenIssues ? `${failures.length} calibrated gate issue(s)` : "No calibrated gate issues" : snapshot.isLoading ? "Checking" : "No readiness report",
5114
5251
  links: options.links ?? DEFAULT_LINKS4,
5115
5252
  status: snapshot.error ? "error" : snapshot.report ? hasOpenIssues ? "warning" : "ready" : snapshot.isLoading ? "loading" : "empty",
5116
- title: options.title ?? DEFAULT_TITLE5,
5253
+ title: options.title ?? DEFAULT_TITLE6,
5117
5254
  updatedAt: snapshot.updatedAt
5118
5255
  };
5119
5256
  };
5120
5257
  var renderVoiceReadinessFailuresHTML = (snapshot, options = {}) => {
5121
5258
  const model = createVoiceReadinessFailuresViewModel(snapshot, options);
5122
- 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--${escapeHtml6(failure.status)}">
5123
- <span>${escapeHtml6(failure.status.toUpperCase())}</span>
5124
- <strong>${escapeHtml6(failure.label)}</strong>
5125
- <p>Observed ${escapeHtml6(failure.observed)} against ${escapeHtml6(failure.thresholdLabel)} ${escapeHtml6(failure.threshold)}.</p>
5126
- <p>${escapeHtml6(failure.remediation)}</p>
5127
- <p class="absolute-voice-readiness-failures__links">${failure.evidenceHref ? `<a href="${escapeHtml6(failure.evidenceHref)}">Evidence</a>` : ""}${failure.sourceHref ? `<a href="${escapeHtml6(failure.sourceHref)}">Threshold source</a>` : ""}</p>
5128
- </article>`).join("")}</div>` : `<p class="absolute-voice-readiness-failures__empty">${model.error ? escapeHtml6(model.error) : "No calibrated readiness gate explanations are open."}</p>`;
5129
- const links = model.links.length ? `<p class="absolute-voice-readiness-failures__links">${model.links.map((link) => `<a href="${escapeHtml6(link.href)}">${escapeHtml6(link.label)}</a>`).join("")}</p>` : "";
5130
- return `<section class="absolute-voice-readiness-failures absolute-voice-readiness-failures--${escapeHtml6(model.status)}">
5259
+ 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--${escapeHtml7(failure.status)}">
5260
+ <span>${escapeHtml7(failure.status.toUpperCase())}</span>
5261
+ <strong>${escapeHtml7(failure.label)}</strong>
5262
+ <p>Observed ${escapeHtml7(failure.observed)} against ${escapeHtml7(failure.thresholdLabel)} ${escapeHtml7(failure.threshold)}.</p>
5263
+ <p>${escapeHtml7(failure.remediation)}</p>
5264
+ <p class="absolute-voice-readiness-failures__links">${failure.evidenceHref ? `<a href="${escapeHtml7(failure.evidenceHref)}">Evidence</a>` : ""}${failure.sourceHref ? `<a href="${escapeHtml7(failure.sourceHref)}">Threshold source</a>` : ""}</p>
5265
+ </article>`).join("")}</div>` : `<p class="absolute-voice-readiness-failures__empty">${model.error ? escapeHtml7(model.error) : "No calibrated readiness gate explanations are open."}</p>`;
5266
+ const links = model.links.length ? `<p class="absolute-voice-readiness-failures__links">${model.links.map((link) => `<a href="${escapeHtml7(link.href)}">${escapeHtml7(link.label)}</a>`).join("")}</p>` : "";
5267
+ return `<section class="absolute-voice-readiness-failures absolute-voice-readiness-failures--${escapeHtml7(model.status)}">
5131
5268
  <header class="absolute-voice-readiness-failures__header">
5132
- <span class="absolute-voice-readiness-failures__eyebrow">${escapeHtml6(model.title)}</span>
5133
- <strong class="absolute-voice-readiness-failures__label">${escapeHtml6(model.label)}</strong>
5269
+ <span class="absolute-voice-readiness-failures__eyebrow">${escapeHtml7(model.title)}</span>
5270
+ <strong class="absolute-voice-readiness-failures__label">${escapeHtml7(model.label)}</strong>
5134
5271
  </header>
5135
- <p class="absolute-voice-readiness-failures__description">${escapeHtml6(model.description)}</p>
5272
+ <p class="absolute-voice-readiness-failures__description">${escapeHtml7(model.description)}</p>
5136
5273
  ${failures}
5137
5274
  ${links}
5138
- ${model.error ? `<p class="absolute-voice-readiness-failures__error">${escapeHtml6(model.error)}</p>` : ""}
5275
+ ${model.error ? `<p class="absolute-voice-readiness-failures__error">${escapeHtml7(model.error)}</p>` : ""}
5139
5276
  </section>`;
5140
5277
  };
5141
5278
  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}`;
@@ -5175,9 +5312,9 @@ var defineVoiceReadinessFailuresElement = (tagName = "absolute-voice-readiness-f
5175
5312
  });
5176
5313
  };
5177
5314
  // src/client/opsActionCenterWidget.ts
5178
- var DEFAULT_TITLE6 = "Voice Ops Action Center";
5179
- var DEFAULT_DESCRIPTION6 = "Run production voice proofs and operator actions from one primitive panel.";
5180
- var escapeHtml7 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
5315
+ var DEFAULT_TITLE7 = "Voice Ops Action Center";
5316
+ var DEFAULT_DESCRIPTION7 = "Run production voice proofs and operator actions from one primitive panel.";
5317
+ var escapeHtml8 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
5181
5318
  var createVoiceOpsActionCenterViewModel = (snapshot, options = {}) => {
5182
5319
  const status = snapshot.error ? "error" : snapshot.isRunning ? "running" : snapshot.lastResult ? "completed" : "ready";
5183
5320
  return {
@@ -5188,29 +5325,29 @@ var createVoiceOpsActionCenterViewModel = (snapshot, options = {}) => {
5188
5325
  isRunning: snapshot.runningActionId === action.id,
5189
5326
  label: action.label
5190
5327
  })),
5191
- description: options.description ?? DEFAULT_DESCRIPTION6,
5328
+ description: options.description ?? DEFAULT_DESCRIPTION7,
5192
5329
  error: snapshot.error,
5193
5330
  isRunning: snapshot.isRunning,
5194
5331
  label: status === "error" ? "Needs attention" : status === "running" ? "Running" : status === "completed" ? "Action completed" : "Ready",
5195
5332
  lastResultLabel: snapshot.lastResult ? `${snapshot.lastResult.actionId} returned HTTP ${snapshot.lastResult.status}` : "No action has run yet.",
5196
5333
  status,
5197
- title: options.title ?? DEFAULT_TITLE6
5334
+ title: options.title ?? DEFAULT_TITLE7
5198
5335
  };
5199
5336
  };
5200
5337
  var renderVoiceOpsActionCenterHTML = (snapshot, options = {}) => {
5201
5338
  const model = createVoiceOpsActionCenterViewModel(snapshot, options);
5202
- const actions = model.actions.map((action) => `<button type="button" data-absolute-voice-ops-action="${escapeHtml7(action.id)}"${action.disabled ? " disabled" : ""}>
5203
- ${escapeHtml7(action.isRunning ? "Working..." : action.label)}
5339
+ const actions = model.actions.map((action) => `<button type="button" data-absolute-voice-ops-action="${escapeHtml8(action.id)}"${action.disabled ? " disabled" : ""}>
5340
+ ${escapeHtml8(action.isRunning ? "Working..." : action.label)}
5204
5341
  </button>`).join("");
5205
- return `<section class="absolute-voice-ops-action-center absolute-voice-ops-action-center--${escapeHtml7(model.status)}">
5342
+ return `<section class="absolute-voice-ops-action-center absolute-voice-ops-action-center--${escapeHtml8(model.status)}">
5206
5343
  <header class="absolute-voice-ops-action-center__header">
5207
- <span class="absolute-voice-ops-action-center__eyebrow">${escapeHtml7(model.title)}</span>
5208
- <strong class="absolute-voice-ops-action-center__label">${escapeHtml7(model.label)}</strong>
5344
+ <span class="absolute-voice-ops-action-center__eyebrow">${escapeHtml8(model.title)}</span>
5345
+ <strong class="absolute-voice-ops-action-center__label">${escapeHtml8(model.label)}</strong>
5209
5346
  </header>
5210
- <p class="absolute-voice-ops-action-center__description">${escapeHtml7(model.description)}</p>
5347
+ <p class="absolute-voice-ops-action-center__description">${escapeHtml8(model.description)}</p>
5211
5348
  <div class="absolute-voice-ops-action-center__actions">${actions}</div>
5212
- <p class="absolute-voice-ops-action-center__result">${escapeHtml7(model.lastResultLabel)}</p>
5213
- ${model.error ? `<p class="absolute-voice-ops-action-center__error">${escapeHtml7(model.error)}</p>` : ""}
5349
+ <p class="absolute-voice-ops-action-center__result">${escapeHtml8(model.lastResultLabel)}</p>
5350
+ ${model.error ? `<p class="absolute-voice-ops-action-center__error">${escapeHtml8(model.error)}</p>` : ""}
5214
5351
  </section>`;
5215
5352
  };
5216
5353
  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}`;
@@ -5811,7 +5948,7 @@ var exportVoiceTrace = async (input) => {
5811
5948
  };
5812
5949
  };
5813
5950
  var toNumber = (value) => typeof value === "number" && Number.isFinite(value) ? value : 0;
5814
- var escapeHtml8 = (value) => value.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;");
5951
+ var escapeHtml9 = (value) => value.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;");
5815
5952
  var formatTraceValue = (value) => {
5816
5953
  if (value === undefined || value === null) {
5817
5954
  return "";
@@ -6091,10 +6228,10 @@ var renderVoiceTraceHTML = (events, options = {}) => {
6091
6228
  const offset = summary.startedAt === undefined ? event.at : Math.max(0, event.at - summary.startedAt);
6092
6229
  return [
6093
6230
  "<tr>",
6094
- `<td>${escapeHtml8(String(offset))}</td>`,
6095
- `<td>${escapeHtml8(event.type)}</td>`,
6096
- `<td>${escapeHtml8(event.turnId ?? "")}</td>`,
6097
- `<td><code>${escapeHtml8(JSON.stringify(event.payload))}</code></td>`,
6231
+ `<td>${escapeHtml9(String(offset))}</td>`,
6232
+ `<td>${escapeHtml9(event.type)}</td>`,
6233
+ `<td>${escapeHtml9(event.turnId ?? "")}</td>`,
6234
+ `<td><code>${escapeHtml9(JSON.stringify(event.payload))}</code></td>`,
6098
6235
  "</tr>"
6099
6236
  ].join("");
6100
6237
  }).join(`
@@ -6105,7 +6242,7 @@ var renderVoiceTraceHTML = (events, options = {}) => {
6105
6242
  "<head>",
6106
6243
  '<meta charset="utf-8" />',
6107
6244
  '<meta name="viewport" content="width=device-width, initial-scale=1" />',
6108
- `<title>${escapeHtml8(options.title ?? "Voice Trace")}</title>`,
6245
+ `<title>${escapeHtml9(options.title ?? "Voice Trace")}</title>`,
6109
6246
  "<style>",
6110
6247
  "body{font-family:ui-sans-serif,system-ui,sans-serif;margin:2rem;line-height:1.45;background:#f8f7f2;color:#181713}",
6111
6248
  "main{max-width:1100px;margin:auto}",
@@ -6119,7 +6256,7 @@ var renderVoiceTraceHTML = (events, options = {}) => {
6119
6256
  "</style>",
6120
6257
  "</head>",
6121
6258
  "<body><main>",
6122
- `<h1>${escapeHtml8(options.title ?? `Voice Trace ${summary.sessionId ?? ""}`.trim())}</h1>`,
6259
+ `<h1>${escapeHtml9(options.title ?? `Voice Trace ${summary.sessionId ?? ""}`.trim())}</h1>`,
6123
6260
  `<p class="${evaluation.pass ? "pass" : "fail"}">QA: ${evaluation.pass ? "pass" : "fail"}</p>`,
6124
6261
  '<section class="summary">',
6125
6262
  `<div class="card"><strong>Events</strong><br>${summary.eventCount}</div>`,
@@ -6133,7 +6270,7 @@ var renderVoiceTraceHTML = (events, options = {}) => {
6133
6270
  eventRows,
6134
6271
  "</tbody></table>",
6135
6272
  "<h2>Markdown Export</h2>",
6136
- `<pre>${escapeHtml8(markdown)}</pre>`,
6273
+ `<pre>${escapeHtml9(markdown)}</pre>`,
6137
6274
  "</main></body></html>"
6138
6275
  ].join(`
6139
6276
  `);
@@ -6489,7 +6626,7 @@ var ACTION_LABELS = {
6489
6626
  "resume-assistant": "Resume assistant",
6490
6627
  tag: "Tag"
6491
6628
  };
6492
- var escapeHtml9 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
6629
+ var escapeHtml10 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
6493
6630
  var createVoiceLiveOpsInput = (action, input) => ({
6494
6631
  action,
6495
6632
  assignee: input.assignee,
@@ -6500,17 +6637,17 @@ var createVoiceLiveOpsInput = (action, input) => ({
6500
6637
  var renderVoiceLiveOpsHTML = (snapshot, options = {}) => {
6501
6638
  const sessionId = options.getSessionId?.() ?? "";
6502
6639
  const disabled = snapshot.isRunning || !sessionId;
6503
- const actions = VOICE_LIVE_OPS_ACTIONS.map((action) => `<button type="button" data-absolute-voice-live-ops-action="${escapeHtml9(action)}"${disabled ? " disabled" : ""}>${escapeHtml9(snapshot.runningAction === action ? "Running..." : ACTION_LABELS[action])}</button>`).join("");
6504
- const result = snapshot.error ? `<p class="absolute-voice-live-ops__error">${escapeHtml9(snapshot.error)}</p>` : snapshot.lastResult ? `<p class="absolute-voice-live-ops__result">Recorded ${escapeHtml9(snapshot.lastResult.action)}. Control: ${escapeHtml9(snapshot.lastResult.control.status)}.</p>` : '<p class="absolute-voice-live-ops__result">No live ops action has run yet.</p>';
6640
+ const actions = VOICE_LIVE_OPS_ACTIONS.map((action) => `<button type="button" data-absolute-voice-live-ops-action="${escapeHtml10(action)}"${disabled ? " disabled" : ""}>${escapeHtml10(snapshot.runningAction === action ? "Running..." : ACTION_LABELS[action])}</button>`).join("");
6641
+ const result = snapshot.error ? `<p class="absolute-voice-live-ops__error">${escapeHtml10(snapshot.error)}</p>` : snapshot.lastResult ? `<p class="absolute-voice-live-ops__result">Recorded ${escapeHtml10(snapshot.lastResult.action)}. Control: ${escapeHtml10(snapshot.lastResult.control.status)}.</p>` : '<p class="absolute-voice-live-ops__result">No live ops action has run yet.</p>';
6505
6642
  return `<section class="absolute-voice-live-ops">
6506
6643
  <header class="absolute-voice-live-ops__header">
6507
- <span>${escapeHtml9(options.title ?? "Live Ops")}</span>
6508
- <strong>${escapeHtml9(sessionId || "No active session")}</strong>
6644
+ <span>${escapeHtml10(options.title ?? "Live Ops")}</span>
6645
+ <strong>${escapeHtml10(sessionId || "No active session")}</strong>
6509
6646
  </header>
6510
- <p class="absolute-voice-live-ops__description">${escapeHtml9(options.description ?? "Pause, resume, take over, force handoff, or inject operator instructions during a live voice session.")}</p>
6511
- <label><span>Operator</span><input data-absolute-voice-live-ops-assignee value="${escapeHtml9(options.defaultAssignee ?? "operator")}" /></label>
6512
- <label><span>Tag / handoff target</span><input data-absolute-voice-live-ops-tag value="${escapeHtml9(options.defaultTag ?? "live-ops")}" /></label>
6513
- <label><span>Detail / instruction</span><input data-absolute-voice-live-ops-detail value="${escapeHtml9(options.defaultDetail ?? "Operator marked this live session.")}" /></label>
6647
+ <p class="absolute-voice-live-ops__description">${escapeHtml10(options.description ?? "Pause, resume, take over, force handoff, or inject operator instructions during a live voice session.")}</p>
6648
+ <label><span>Operator</span><input data-absolute-voice-live-ops-assignee value="${escapeHtml10(options.defaultAssignee ?? "operator")}" /></label>
6649
+ <label><span>Tag / handoff target</span><input data-absolute-voice-live-ops-tag value="${escapeHtml10(options.defaultTag ?? "live-ops")}" /></label>
6650
+ <label><span>Detail / instruction</span><input data-absolute-voice-live-ops-detail value="${escapeHtml10(options.defaultDetail ?? "Operator marked this live session.")}" /></label>
6514
6651
  <div class="absolute-voice-live-ops__actions">${actions}</div>
6515
6652
  ${result}
6516
6653
  </section>`;
@@ -6597,16 +6734,16 @@ var defineVoiceLiveOpsElement = (tagName = "absolute-voice-live-ops", options =
6597
6734
  });
6598
6735
  };
6599
6736
  // src/client/opsActionHistoryWidget.ts
6600
- var escapeHtml10 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
6737
+ var escapeHtml11 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
6601
6738
  var renderVoiceOpsActionHistoryWidgetHTML = (snapshot, options = {}) => {
6602
6739
  const report = snapshot.report;
6603
6740
  const entries = (report?.entries ?? []).slice(0, options.limit ?? 5);
6604
- const rows = entries.map((entry) => `<li class="absolute-voice-ops-action-history__entry absolute-voice-ops-action-history__entry--${entry.ok ? "success" : "error"}"><span>${escapeHtml10(entry.actionId)}</span><strong>${escapeHtml10(entry.ok ? "Success" : "Failed")}</strong><small>${escapeHtml10(new Date(entry.at).toLocaleString())}${entry.status ? ` \xB7 HTTP ${String(entry.status)}` : ""}</small></li>`).join("");
6741
+ const rows = entries.map((entry) => `<li class="absolute-voice-ops-action-history__entry absolute-voice-ops-action-history__entry--${entry.ok ? "success" : "error"}"><span>${escapeHtml11(entry.actionId)}</span><strong>${escapeHtml11(entry.ok ? "Success" : "Failed")}</strong><small>${escapeHtml11(new Date(entry.at).toLocaleString())}${entry.status ? ` \xB7 HTTP ${String(entry.status)}` : ""}</small></li>`).join("");
6605
6742
  return `<section class="absolute-voice-ops-action-history">
6606
- <header><span>Operator proof</span><strong>${escapeHtml10(options.title ?? "Action History")}</strong></header>
6743
+ <header><span>Operator proof</span><strong>${escapeHtml11(options.title ?? "Action History")}</strong></header>
6607
6744
  <p>${String(report?.total ?? 0)} action(s), ${String(report?.failed ?? 0)} failed.</p>
6608
6745
  <ul>${rows || "<li>No operator actions recorded yet.</li>"}</ul>
6609
- ${snapshot.error ? `<p class="absolute-voice-ops-action-history__error">${escapeHtml10(snapshot.error)}</p>` : ""}
6746
+ ${snapshot.error ? `<p class="absolute-voice-ops-action-history__error">${escapeHtml11(snapshot.error)}</p>` : ""}
6610
6747
  </section>`;
6611
6748
  };
6612
6749
  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}`;
@@ -6627,9 +6764,9 @@ var mountVoiceOpsActionHistory = (element, path = "/api/voice/ops-actions/histor
6627
6764
  };
6628
6765
  };
6629
6766
  // src/client/deliveryRuntimeWidget.ts
6630
- var DEFAULT_TITLE7 = "Voice Delivery Runtime";
6631
- var DEFAULT_DESCRIPTION7 = "Audit and trace delivery worker health from your AbsoluteJS voice app.";
6632
- var escapeHtml11 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
6767
+ var DEFAULT_TITLE8 = "Voice Delivery Runtime";
6768
+ var DEFAULT_DESCRIPTION8 = "Audit and trace delivery worker health from your AbsoluteJS voice app.";
6769
+ var escapeHtml12 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
6633
6770
  var createSurface = (id, summary) => {
6634
6771
  if (!summary) {
6635
6772
  return {
@@ -6663,7 +6800,7 @@ var createVoiceDeliveryRuntimeViewModel = (snapshot, options = {}) => {
6663
6800
  ];
6664
6801
  const hasWarnings = surfaces.some((surface) => surface.status === "warn");
6665
6802
  return {
6666
- description: options.description ?? DEFAULT_DESCRIPTION7,
6803
+ description: options.description ?? DEFAULT_DESCRIPTION8,
6667
6804
  error: snapshot.error,
6668
6805
  actionError: snapshot.actionError,
6669
6806
  actionStatus: snapshot.actionStatus,
@@ -6672,32 +6809,32 @@ var createVoiceDeliveryRuntimeViewModel = (snapshot, options = {}) => {
6672
6809
  label: snapshot.error ? "Unavailable" : report ? report.isRunning ? "Running" : "Stopped" : "Checking",
6673
6810
  status: snapshot.error ? "error" : report ? hasWarnings ? "warn" : "pass" : "loading",
6674
6811
  surfaces,
6675
- title: options.title ?? DEFAULT_TITLE7,
6812
+ title: options.title ?? DEFAULT_TITLE8,
6676
6813
  updatedAt: snapshot.updatedAt
6677
6814
  };
6678
6815
  };
6679
6816
  var renderVoiceDeliveryRuntimeHTML = (snapshot, options = {}) => {
6680
6817
  const model = createVoiceDeliveryRuntimeViewModel(snapshot, options);
6681
- const surfaces = model.surfaces.map((surface) => `<li class="absolute-voice-delivery-runtime__surface absolute-voice-delivery-runtime__surface--${escapeHtml11(surface.status)}">
6682
- <span>${escapeHtml11(surface.label)}</span>
6683
- <strong>${escapeHtml11(surface.detail)}</strong>
6818
+ const surfaces = model.surfaces.map((surface) => `<li class="absolute-voice-delivery-runtime__surface absolute-voice-delivery-runtime__surface--${escapeHtml12(surface.status)}">
6819
+ <span>${escapeHtml12(surface.label)}</span>
6820
+ <strong>${escapeHtml12(surface.detail)}</strong>
6684
6821
  <small>${String(surface.failed)} failed &middot; ${String(surface.deadLettered)} dead-lettered</small>
6685
6822
  </li>`).join("");
6686
6823
  const actions = options.includeActions === false ? "" : `<div class="absolute-voice-delivery-runtime__actions">
6687
6824
  <button type="button" data-absolute-voice-delivery-runtime-action="tick">${model.actionStatus === "running" ? "Working..." : "Tick workers"}</button>
6688
6825
  <button type="button" data-absolute-voice-delivery-runtime-action="requeue-dead-letters"${model.surfaces.some((surface) => surface.deadLettered > 0) ? "" : " disabled"}>Requeue dead letters</button>
6689
6826
  </div>`;
6690
- const actionError = model.actionError ? `<p class="absolute-voice-delivery-runtime__error">${escapeHtml11(model.actionError)}</p>` : "";
6691
- return `<section class="absolute-voice-delivery-runtime absolute-voice-delivery-runtime--${escapeHtml11(model.status)}">
6827
+ const actionError = model.actionError ? `<p class="absolute-voice-delivery-runtime__error">${escapeHtml12(model.actionError)}</p>` : "";
6828
+ return `<section class="absolute-voice-delivery-runtime absolute-voice-delivery-runtime--${escapeHtml12(model.status)}">
6692
6829
  <header class="absolute-voice-delivery-runtime__header">
6693
- <span class="absolute-voice-delivery-runtime__eyebrow">${escapeHtml11(model.title)}</span>
6694
- <strong class="absolute-voice-delivery-runtime__label">${escapeHtml11(model.label)}</strong>
6830
+ <span class="absolute-voice-delivery-runtime__eyebrow">${escapeHtml12(model.title)}</span>
6831
+ <strong class="absolute-voice-delivery-runtime__label">${escapeHtml12(model.label)}</strong>
6695
6832
  </header>
6696
- <p class="absolute-voice-delivery-runtime__description">${escapeHtml11(model.description)}</p>
6833
+ <p class="absolute-voice-delivery-runtime__description">${escapeHtml12(model.description)}</p>
6697
6834
  <ul class="absolute-voice-delivery-runtime__surfaces">${surfaces}</ul>
6698
6835
  ${actions}
6699
6836
  ${actionError}
6700
- ${model.error ? `<p class="absolute-voice-delivery-runtime__error">${escapeHtml11(model.error)}</p>` : ""}
6837
+ ${model.error ? `<p class="absolute-voice-delivery-runtime__error">${escapeHtml12(model.error)}</p>` : ""}
6701
6838
  </section>`;
6702
6839
  };
6703
6840
  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}`;
@@ -6833,9 +6970,9 @@ var createVoiceRoutingStatusStore = (path = "/api/routing/latest", options = {})
6833
6970
  };
6834
6971
  };
6835
6972
  // src/client/routingStatusWidget.ts
6836
- var DEFAULT_TITLE8 = "Voice Routing";
6837
- var DEFAULT_DESCRIPTION8 = "Latest provider routing decision from the self-hosted trace store.";
6838
- var escapeHtml12 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
6973
+ var DEFAULT_TITLE9 = "Voice Routing";
6974
+ var DEFAULT_DESCRIPTION9 = "Latest provider routing decision from the self-hosted trace store.";
6975
+ var escapeHtml13 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
6839
6976
  var formatValue = (value, fallback = "None") => typeof value === "string" && value.trim() ? value : typeof value === "number" && Number.isFinite(value) ? String(value) : fallback;
6840
6977
  var formatProviderRoutes2 = (routes) => routes && typeof routes === "object" ? Object.entries(routes).map(([role, provider]) => `${role}: ${formatValue(provider)}`).join(", ") || "None" : "None";
6841
6978
  var getProviderRoute = (routes, role) => routes && typeof routes === "object" ? formatValue(routes[role], "Not configured") : "Not configured";
@@ -6904,35 +7041,35 @@ var createVoiceRoutingStatusViewModel = (snapshot, options = {}) => {
6904
7041
  return {
6905
7042
  activeStack,
6906
7043
  decision,
6907
- description: options.description ?? DEFAULT_DESCRIPTION8,
7044
+ description: options.description ?? DEFAULT_DESCRIPTION9,
6908
7045
  error: snapshot.error,
6909
7046
  isLoading: snapshot.isLoading,
6910
7047
  label: snapshot.error ? "Unavailable" : decision ? `${formatValue(decision.kind).toUpperCase()} ${formatValue(decision.status, "unknown")}` : snapshot.isLoading ? "Checking" : "No routing yet",
6911
7048
  rows,
6912
7049
  status: snapshot.error ? "error" : decision ? "ready" : snapshot.isLoading ? "loading" : "empty",
6913
- title: options.title ?? DEFAULT_TITLE8,
7050
+ title: options.title ?? DEFAULT_TITLE9,
6914
7051
  updatedAt: snapshot.updatedAt
6915
7052
  };
6916
7053
  };
6917
7054
  var renderVoiceRoutingStatusHTML = (snapshot, options = {}) => {
6918
7055
  const model = createVoiceRoutingStatusViewModel(snapshot, options);
6919
7056
  const activeStack = model.activeStack.length ? `<div class="absolute-voice-routing-status__stack" aria-label="Active voice stack">${model.activeStack.map((item) => `<div>
6920
- <span>${escapeHtml12(item.label)}</span>
6921
- <strong>${escapeHtml12(item.value)}</strong>
7057
+ <span>${escapeHtml13(item.label)}</span>
7058
+ <strong>${escapeHtml13(item.value)}</strong>
6922
7059
  </div>`).join("")}</div>` : "";
6923
7060
  const rows = model.rows.length ? `<div class="absolute-voice-routing-status__grid">${model.rows.map((row) => `<div>
6924
- <span>${escapeHtml12(row.label)}</span>
6925
- <strong>${escapeHtml12(row.value)}</strong>
7061
+ <span>${escapeHtml13(row.label)}</span>
7062
+ <strong>${escapeHtml13(row.value)}</strong>
6926
7063
  </div>`).join("")}</div>` : '<p class="absolute-voice-routing-status__empty">Start a voice session to see the selected provider.</p>';
6927
- return `<section class="absolute-voice-routing-status absolute-voice-routing-status--${escapeHtml12(model.status)}">
7064
+ return `<section class="absolute-voice-routing-status absolute-voice-routing-status--${escapeHtml13(model.status)}">
6928
7065
  <header class="absolute-voice-routing-status__header">
6929
- <span class="absolute-voice-routing-status__eyebrow">${escapeHtml12(model.title)}</span>
6930
- <strong class="absolute-voice-routing-status__label">${escapeHtml12(model.label)}</strong>
7066
+ <span class="absolute-voice-routing-status__eyebrow">${escapeHtml13(model.title)}</span>
7067
+ <strong class="absolute-voice-routing-status__label">${escapeHtml13(model.label)}</strong>
6931
7068
  </header>
6932
- <p class="absolute-voice-routing-status__description">${escapeHtml12(model.description)}</p>
7069
+ <p class="absolute-voice-routing-status__description">${escapeHtml13(model.description)}</p>
6933
7070
  ${activeStack}
6934
7071
  ${rows}
6935
- ${model.error ? `<p class="absolute-voice-routing-status__error">${escapeHtml12(model.error)}</p>` : ""}
7072
+ ${model.error ? `<p class="absolute-voice-routing-status__error">${escapeHtml13(model.error)}</p>` : ""}
6936
7073
  </section>`;
6937
7074
  };
6938
7075
  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}}`;
@@ -7731,7 +7868,7 @@ var createVoiceProviderSimulationControlsStore = (options) => {
7731
7868
  };
7732
7869
  };
7733
7870
  // src/client/providerSimulationControlsWidget.ts
7734
- var escapeHtml13 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
7871
+ var escapeHtml14 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
7735
7872
  var formatKind = (kind) => (kind ?? "stt").toUpperCase();
7736
7873
  var createVoiceProviderSimulationControlsViewModel = (snapshot, options) => {
7737
7874
  const configuredProviders = options.providers.filter((provider) => provider.configured !== false);
@@ -7751,18 +7888,18 @@ var createVoiceProviderSimulationControlsViewModel = (snapshot, options) => {
7751
7888
  };
7752
7889
  var renderVoiceProviderSimulationControlsHTML = (snapshot, options) => {
7753
7890
  const model = createVoiceProviderSimulationControlsViewModel(snapshot, options);
7754
- const failureButtons = model.failureProviders.map((provider) => `<button type="button" data-voice-provider-fail="${escapeHtml13(provider.provider)}"${!model.canSimulateFailure || snapshot.isRunning ? " disabled" : ""}>Simulate ${escapeHtml13(provider.provider)} ${escapeHtml13(formatKind(options.kind))} failure</button>`).join("");
7755
- const recoveryButtons = model.providers.map((provider) => `<button type="button" data-voice-provider-recover="${escapeHtml13(provider.provider)}"${snapshot.isRunning ? " disabled" : ""}>Mark ${escapeHtml13(provider.provider)} recovered</button>`).join("");
7891
+ const failureButtons = model.failureProviders.map((provider) => `<button type="button" data-voice-provider-fail="${escapeHtml14(provider.provider)}"${!model.canSimulateFailure || snapshot.isRunning ? " disabled" : ""}>Simulate ${escapeHtml14(provider.provider)} ${escapeHtml14(formatKind(options.kind))} failure</button>`).join("");
7892
+ const recoveryButtons = model.providers.map((provider) => `<button type="button" data-voice-provider-recover="${escapeHtml14(provider.provider)}"${snapshot.isRunning ? " disabled" : ""}>Mark ${escapeHtml14(provider.provider)} recovered</button>`).join("");
7756
7893
  return `<section class="absolute-voice-provider-simulation absolute-voice-provider-simulation--${snapshot.error ? "error" : snapshot.isRunning ? "running" : "ready"}">
7757
7894
  <header class="absolute-voice-provider-simulation__header">
7758
- <span class="absolute-voice-provider-simulation__eyebrow">${escapeHtml13(model.title)}</span>
7759
- <strong class="absolute-voice-provider-simulation__label">${escapeHtml13(model.label)}</strong>
7895
+ <span class="absolute-voice-provider-simulation__eyebrow">${escapeHtml14(model.title)}</span>
7896
+ <strong class="absolute-voice-provider-simulation__label">${escapeHtml14(model.label)}</strong>
7760
7897
  </header>
7761
- <p class="absolute-voice-provider-simulation__description">${escapeHtml13(model.description)}</p>
7762
- ${model.canSimulateFailure ? "" : `<p class="absolute-voice-provider-simulation__empty">${escapeHtml13(options.fallbackRequiredMessage ?? "Configure fallback providers before simulating failure.")}</p>`}
7898
+ <p class="absolute-voice-provider-simulation__description">${escapeHtml14(model.description)}</p>
7899
+ ${model.canSimulateFailure ? "" : `<p class="absolute-voice-provider-simulation__empty">${escapeHtml14(options.fallbackRequiredMessage ?? "Configure fallback providers before simulating failure.")}</p>`}
7763
7900
  <div class="absolute-voice-provider-simulation__actions">${failureButtons}${recoveryButtons}</div>
7764
- ${snapshot.error ? `<p class="absolute-voice-provider-simulation__error">${escapeHtml13(snapshot.error)}</p>` : ""}
7765
- ${model.resultText ? `<pre class="absolute-voice-provider-simulation__result">${escapeHtml13(model.resultText)}</pre>` : ""}
7901
+ ${snapshot.error ? `<p class="absolute-voice-provider-simulation__error">${escapeHtml14(snapshot.error)}</p>` : ""}
7902
+ ${model.resultText ? `<pre class="absolute-voice-provider-simulation__result">${escapeHtml14(model.resultText)}</pre>` : ""}
7766
7903
  </section>`;
7767
7904
  };
7768
7905
  var bindVoiceProviderSimulationControls = (element, store) => {
@@ -7827,9 +7964,9 @@ var defineVoiceProviderSimulationControlsElement = (tagName = "absolute-voice-pr
7827
7964
  });
7828
7965
  };
7829
7966
  // src/client/providerStatusWidget.ts
7830
- var DEFAULT_TITLE9 = "Voice Providers";
7831
- var DEFAULT_DESCRIPTION9 = "Live provider health, fallback counts, latency, and suppression state from your self-hosted trace store.";
7832
- var escapeHtml14 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
7967
+ var DEFAULT_TITLE10 = "Voice Providers";
7968
+ var DEFAULT_DESCRIPTION10 = "Live provider health, fallback counts, latency, and suppression state from your self-hosted trace store.";
7969
+ var escapeHtml15 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
7833
7970
  var formatProvider = (provider) => provider.split(/[-_\s]+/).filter(Boolean).map((part) => `${part[0]?.toUpperCase() ?? ""}${part.slice(1)}`).join(" ") || provider;
7834
7971
  var formatStatus2 = (status) => status.split("-").map((part) => `${part[0]?.toUpperCase() ?? ""}${part.slice(1)}`).join(" ");
7835
7972
  var formatLatency = (value) => typeof value === "number" ? `${value}ms` : "No samples";
@@ -7873,37 +8010,37 @@ var createVoiceProviderStatusViewModel = (snapshot, options = {}) => {
7873
8010
  const warningCount = providers.filter((provider) => isWarningStatus(provider.status)).length;
7874
8011
  const healthyCount = providers.filter((provider) => provider.status === "healthy").length;
7875
8012
  return {
7876
- description: options.description ?? DEFAULT_DESCRIPTION9,
8013
+ description: options.description ?? DEFAULT_DESCRIPTION10,
7877
8014
  error: snapshot.error,
7878
8015
  isLoading: snapshot.isLoading,
7879
8016
  label: snapshot.error ? "Unavailable" : providers.length ? warningCount > 0 ? `${warningCount} needs attention` : `${healthyCount} healthy` : snapshot.isLoading ? "Checking" : "No provider traffic",
7880
8017
  providers,
7881
8018
  status: snapshot.error ? "error" : providers.length ? warningCount > 0 ? "warning" : "ready" : snapshot.isLoading ? "loading" : "empty",
7882
- title: options.title ?? DEFAULT_TITLE9,
8019
+ title: options.title ?? DEFAULT_TITLE10,
7883
8020
  updatedAt: snapshot.updatedAt
7884
8021
  };
7885
8022
  };
7886
8023
  var renderVoiceProviderStatusHTML = (snapshot, options = {}) => {
7887
8024
  const model = createVoiceProviderStatusViewModel(snapshot, options);
7888
- 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--${escapeHtml14(provider.status)}">
8025
+ 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--${escapeHtml15(provider.status)}">
7889
8026
  <header>
7890
- <strong>${escapeHtml14(provider.label)}</strong>
7891
- <span>${escapeHtml14(formatStatus2(provider.status))}</span>
8027
+ <strong>${escapeHtml15(provider.label)}</strong>
8028
+ <span>${escapeHtml15(formatStatus2(provider.status))}</span>
7892
8029
  </header>
7893
- <p>${escapeHtml14(provider.detail)}</p>
8030
+ <p>${escapeHtml15(provider.detail)}</p>
7894
8031
  <dl>${provider.rows.map((row) => `<div>
7895
- <dt>${escapeHtml14(row.label)}</dt>
7896
- <dd>${escapeHtml14(row.value)}</dd>
8032
+ <dt>${escapeHtml15(row.label)}</dt>
8033
+ <dd>${escapeHtml15(row.value)}</dd>
7897
8034
  </div>`).join("")}</dl>
7898
8035
  </article>`).join("")}</div>` : '<p class="absolute-voice-provider-status__empty">Run voice traffic to see provider health.</p>';
7899
- return `<section class="absolute-voice-provider-status absolute-voice-provider-status--${escapeHtml14(model.status)}">
8036
+ return `<section class="absolute-voice-provider-status absolute-voice-provider-status--${escapeHtml15(model.status)}">
7900
8037
  <header class="absolute-voice-provider-status__header">
7901
- <span class="absolute-voice-provider-status__eyebrow">${escapeHtml14(model.title)}</span>
7902
- <strong class="absolute-voice-provider-status__label">${escapeHtml14(model.label)}</strong>
8038
+ <span class="absolute-voice-provider-status__eyebrow">${escapeHtml15(model.title)}</span>
8039
+ <strong class="absolute-voice-provider-status__label">${escapeHtml15(model.label)}</strong>
7903
8040
  </header>
7904
- <p class="absolute-voice-provider-status__description">${escapeHtml14(model.description)}</p>
8041
+ <p class="absolute-voice-provider-status__description">${escapeHtml15(model.description)}</p>
7905
8042
  ${providers}
7906
- ${model.error ? `<p class="absolute-voice-provider-status__error">${escapeHtml14(model.error)}</p>` : ""}
8043
+ ${model.error ? `<p class="absolute-voice-provider-status__error">${escapeHtml15(model.error)}</p>` : ""}
7907
8044
  </section>`;
7908
8045
  };
7909
8046
  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}`;
@@ -7944,9 +8081,9 @@ var defineVoiceProviderStatusElement = (tagName = "absolute-voice-provider-statu
7944
8081
  });
7945
8082
  };
7946
8083
  // src/client/providerCapabilitiesWidget.ts
7947
- var DEFAULT_TITLE10 = "Provider Capabilities";
7948
- var DEFAULT_DESCRIPTION10 = "Configured, selected, and healthy voice providers for this deployment.";
7949
- var escapeHtml15 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
8084
+ var DEFAULT_TITLE11 = "Provider Capabilities";
8085
+ var DEFAULT_DESCRIPTION11 = "Configured, selected, and healthy voice providers for this deployment.";
8086
+ var escapeHtml16 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
7950
8087
  var formatProvider2 = (provider) => provider.split(/[-_\s]+/).filter(Boolean).map((part) => `${part[0]?.toUpperCase() ?? ""}${part.slice(1)}`).join(" ") || provider;
7951
8088
  var formatKind2 = (kind) => kind.toUpperCase();
7952
8089
  var formatStatus3 = (status) => status.split("-").map((part) => `${part[0]?.toUpperCase() ?? ""}${part.slice(1)}`).join(" ");
@@ -7990,36 +8127,36 @@ var createVoiceProviderCapabilitiesViewModel = (snapshot, options = {}) => {
7990
8127
  const selectedCount = snapshot.report?.selected ?? capabilities.filter((capability) => capability.selected).length;
7991
8128
  return {
7992
8129
  capabilities,
7993
- description: options.description ?? DEFAULT_DESCRIPTION10,
8130
+ description: options.description ?? DEFAULT_DESCRIPTION11,
7994
8131
  error: snapshot.error,
7995
8132
  isLoading: snapshot.isLoading,
7996
8133
  label: snapshot.error ? "Unavailable" : capabilities.length ? warningCount > 0 ? `${warningCount} needs attention` : `${selectedCount} selected` : snapshot.isLoading ? "Checking" : "No capabilities",
7997
8134
  status: snapshot.error ? "error" : capabilities.length ? warningCount > 0 ? "warning" : "ready" : snapshot.isLoading ? "loading" : "empty",
7998
- title: options.title ?? DEFAULT_TITLE10,
8135
+ title: options.title ?? DEFAULT_TITLE11,
7999
8136
  updatedAt: snapshot.updatedAt
8000
8137
  };
8001
8138
  };
8002
8139
  var renderVoiceProviderCapabilitiesHTML = (snapshot, options = {}) => {
8003
8140
  const model = createVoiceProviderCapabilitiesViewModel(snapshot, options);
8004
- 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--${escapeHtml15(capability.status)}">
8141
+ 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--${escapeHtml16(capability.status)}">
8005
8142
  <header>
8006
- <strong>${escapeHtml15(capability.label)}</strong>
8007
- <span>${escapeHtml15(formatStatus3(capability.status))}</span>
8143
+ <strong>${escapeHtml16(capability.label)}</strong>
8144
+ <span>${escapeHtml16(formatStatus3(capability.status))}</span>
8008
8145
  </header>
8009
- <p>${escapeHtml15(capability.detail)}</p>
8146
+ <p>${escapeHtml16(capability.detail)}</p>
8010
8147
  <dl>${capability.rows.map((row) => `<div>
8011
- <dt>${escapeHtml15(row.label)}</dt>
8012
- <dd>${escapeHtml15(row.value)}</dd>
8148
+ <dt>${escapeHtml16(row.label)}</dt>
8149
+ <dd>${escapeHtml16(row.value)}</dd>
8013
8150
  </div>`).join("")}</dl>
8014
8151
  </article>`).join("")}</div>` : '<p class="absolute-voice-provider-capabilities__empty">Configure provider capabilities to see deployment coverage.</p>';
8015
- return `<section class="absolute-voice-provider-capabilities absolute-voice-provider-capabilities--${escapeHtml15(model.status)}">
8152
+ return `<section class="absolute-voice-provider-capabilities absolute-voice-provider-capabilities--${escapeHtml16(model.status)}">
8016
8153
  <header class="absolute-voice-provider-capabilities__header">
8017
- <span class="absolute-voice-provider-capabilities__eyebrow">${escapeHtml15(model.title)}</span>
8018
- <strong class="absolute-voice-provider-capabilities__label">${escapeHtml15(model.label)}</strong>
8154
+ <span class="absolute-voice-provider-capabilities__eyebrow">${escapeHtml16(model.title)}</span>
8155
+ <strong class="absolute-voice-provider-capabilities__label">${escapeHtml16(model.label)}</strong>
8019
8156
  </header>
8020
- <p class="absolute-voice-provider-capabilities__description">${escapeHtml15(model.description)}</p>
8157
+ <p class="absolute-voice-provider-capabilities__description">${escapeHtml16(model.description)}</p>
8021
8158
  ${capabilities}
8022
- ${model.error ? `<p class="absolute-voice-provider-capabilities__error">${escapeHtml15(model.error)}</p>` : ""}
8159
+ ${model.error ? `<p class="absolute-voice-provider-capabilities__error">${escapeHtml16(model.error)}</p>` : ""}
8023
8160
  </section>`;
8024
8161
  };
8025
8162
  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}`;
@@ -8060,9 +8197,9 @@ var defineVoiceProviderCapabilitiesElement = (tagName = "absolute-voice-provider
8060
8197
  });
8061
8198
  };
8062
8199
  // src/client/providerContractsWidget.ts
8063
- var DEFAULT_TITLE11 = "Provider Contracts";
8064
- var DEFAULT_DESCRIPTION11 = "Production contract coverage for provider env, latency, fallback, streaming, and capabilities.";
8065
- var escapeHtml16 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
8200
+ var DEFAULT_TITLE12 = "Provider Contracts";
8201
+ var DEFAULT_DESCRIPTION12 = "Production contract coverage for provider env, latency, fallback, streaming, and capabilities.";
8202
+ var escapeHtml17 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
8066
8203
  var formatProvider3 = (provider) => provider.split(/[-_\s]+/).filter(Boolean).map((part) => `${part[0]?.toUpperCase() ?? ""}${part.slice(1)}`).join(" ") || provider;
8067
8204
  var formatStatus4 = (status) => status.split("-").map((part) => `${part[0]?.toUpperCase() ?? ""}${part.slice(1)}`).join(" ");
8068
8205
  var contractDetail = (row) => {
@@ -8094,38 +8231,38 @@ var createVoiceProviderContractsViewModel = (snapshot, options = {}) => {
8094
8231
  }));
8095
8232
  const warningCount = snapshot.report ? snapshot.report.failed + snapshot.report.warned : rows.filter((row) => row.status !== "pass").length;
8096
8233
  return {
8097
- description: options.description ?? DEFAULT_DESCRIPTION11,
8234
+ description: options.description ?? DEFAULT_DESCRIPTION12,
8098
8235
  error: snapshot.error,
8099
8236
  isLoading: snapshot.isLoading,
8100
8237
  label: snapshot.error ? "Unavailable" : rows.length ? warningCount > 0 ? `${warningCount} needs attention` : `${rows.length} passing` : snapshot.isLoading ? "Checking" : "No contracts",
8101
8238
  rows,
8102
8239
  status: snapshot.error ? "error" : rows.length ? warningCount > 0 ? "warning" : "ready" : snapshot.isLoading ? "loading" : "empty",
8103
- title: options.title ?? DEFAULT_TITLE11,
8240
+ title: options.title ?? DEFAULT_TITLE12,
8104
8241
  updatedAt: snapshot.updatedAt
8105
8242
  };
8106
8243
  };
8107
8244
  var renderVoiceProviderContractsHTML = (snapshot, options = {}) => {
8108
8245
  const model = createVoiceProviderContractsViewModel(snapshot, options);
8109
- 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--${escapeHtml16(row.status)}">
8246
+ 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--${escapeHtml17(row.status)}">
8110
8247
  <header>
8111
- <strong>${escapeHtml16(row.label)}</strong>
8112
- <span>${escapeHtml16(formatStatus4(row.status))}</span>
8248
+ <strong>${escapeHtml17(row.label)}</strong>
8249
+ <span>${escapeHtml17(formatStatus4(row.status))}</span>
8113
8250
  </header>
8114
- <p>${escapeHtml16(row.detail)}</p>
8115
- ${row.remediations.length ? `<ul class="absolute-voice-provider-contracts__remediations">${row.remediations.map((remediation) => `<li>${remediation.href ? `<a href="${escapeHtml16(remediation.href)}">${escapeHtml16(remediation.label)}</a>` : `<strong>${escapeHtml16(remediation.label)}</strong>`}<span>${escapeHtml16(remediation.detail)}</span></li>`).join("")}</ul>` : ""}
8251
+ <p>${escapeHtml17(row.detail)}</p>
8252
+ ${row.remediations.length ? `<ul class="absolute-voice-provider-contracts__remediations">${row.remediations.map((remediation) => `<li>${remediation.href ? `<a href="${escapeHtml17(remediation.href)}">${escapeHtml17(remediation.label)}</a>` : `<strong>${escapeHtml17(remediation.label)}</strong>`}<span>${escapeHtml17(remediation.detail)}</span></li>`).join("")}</ul>` : ""}
8116
8253
  <dl>${row.rows.map((item) => `<div>
8117
- <dt>${escapeHtml16(item.label)}</dt>
8118
- <dd>${escapeHtml16(item.value)}</dd>
8254
+ <dt>${escapeHtml17(item.label)}</dt>
8255
+ <dd>${escapeHtml17(item.value)}</dd>
8119
8256
  </div>`).join("")}</dl>
8120
8257
  </article>`).join("")}</div>` : '<p class="absolute-voice-provider-contracts__empty">Configure provider contracts to see production coverage.</p>';
8121
- return `<section class="absolute-voice-provider-contracts absolute-voice-provider-contracts--${escapeHtml16(model.status)}">
8258
+ return `<section class="absolute-voice-provider-contracts absolute-voice-provider-contracts--${escapeHtml17(model.status)}">
8122
8259
  <header class="absolute-voice-provider-contracts__header">
8123
- <span class="absolute-voice-provider-contracts__eyebrow">${escapeHtml16(model.title)}</span>
8124
- <strong class="absolute-voice-provider-contracts__label">${escapeHtml16(model.label)}</strong>
8260
+ <span class="absolute-voice-provider-contracts__eyebrow">${escapeHtml17(model.title)}</span>
8261
+ <strong class="absolute-voice-provider-contracts__label">${escapeHtml17(model.label)}</strong>
8125
8262
  </header>
8126
- <p class="absolute-voice-provider-contracts__description">${escapeHtml16(model.description)}</p>
8263
+ <p class="absolute-voice-provider-contracts__description">${escapeHtml17(model.description)}</p>
8127
8264
  ${rows}
8128
- ${model.error ? `<p class="absolute-voice-provider-contracts__error">${escapeHtml16(model.error)}</p>` : ""}
8265
+ ${model.error ? `<p class="absolute-voice-provider-contracts__error">${escapeHtml17(model.error)}</p>` : ""}
8129
8266
  </section>`;
8130
8267
  };
8131
8268
  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}`;
@@ -8166,9 +8303,9 @@ var defineVoiceProviderContractsElement = (tagName = "absolute-voice-provider-co
8166
8303
  });
8167
8304
  };
8168
8305
  // src/client/turnQualityWidget.ts
8169
- var DEFAULT_TITLE12 = "Turn Quality";
8170
- var DEFAULT_DESCRIPTION12 = "Per-turn STT confidence, fallback selection, corrections, and transcript coverage.";
8171
- var escapeHtml17 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
8306
+ var DEFAULT_TITLE13 = "Turn Quality";
8307
+ var DEFAULT_DESCRIPTION13 = "Per-turn STT confidence, fallback selection, corrections, and transcript coverage.";
8308
+ var escapeHtml18 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
8172
8309
  var formatConfidence = (value) => typeof value === "number" ? `${Math.round(value * 100)}%` : "n/a";
8173
8310
  var formatMaybe = (value) => value === undefined || value === "" ? "n/a" : String(value);
8174
8311
  var getTurnDetail = (turn) => {
@@ -8206,37 +8343,37 @@ var createVoiceTurnQualityViewModel = (snapshot, options = {}) => {
8206
8343
  const warningCount = snapshot.report?.warnings ?? turns.filter((turn) => turn.status === "warn").length;
8207
8344
  const failedCount = snapshot.report?.failed ?? turns.filter((turn) => turn.status === "fail").length;
8208
8345
  return {
8209
- description: options.description ?? DEFAULT_DESCRIPTION12,
8346
+ description: options.description ?? DEFAULT_DESCRIPTION13,
8210
8347
  error: snapshot.error,
8211
8348
  isLoading: snapshot.isLoading,
8212
8349
  label: snapshot.error ? "Unavailable" : turns.length ? failedCount > 0 ? `${failedCount} failed` : warningCount > 0 ? `${warningCount} warnings` : `${turns.length} healthy` : snapshot.isLoading ? "Checking" : "No turns",
8213
8350
  status: snapshot.error ? "error" : turns.length ? failedCount > 0 || warningCount > 0 ? "warning" : "ready" : snapshot.isLoading ? "loading" : "empty",
8214
- title: options.title ?? DEFAULT_TITLE12,
8351
+ title: options.title ?? DEFAULT_TITLE13,
8215
8352
  turns,
8216
8353
  updatedAt: snapshot.updatedAt
8217
8354
  };
8218
8355
  };
8219
8356
  var renderVoiceTurnQualityHTML = (snapshot, options = {}) => {
8220
8357
  const model = createVoiceTurnQualityViewModel(snapshot, options);
8221
- const turns = model.turns.length ? `<div class="absolute-voice-turn-quality__turns">${model.turns.map((turn) => `<article class="absolute-voice-turn-quality__turn absolute-voice-turn-quality__turn--${escapeHtml17(turn.status)}">
8358
+ 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--${escapeHtml18(turn.status)}">
8222
8359
  <header>
8223
- <strong>${escapeHtml17(turn.label)}</strong>
8224
- <span>${escapeHtml17(turn.status)}</span>
8360
+ <strong>${escapeHtml18(turn.label)}</strong>
8361
+ <span>${escapeHtml18(turn.status)}</span>
8225
8362
  </header>
8226
- <p>${escapeHtml17(turn.detail)}</p>
8363
+ <p>${escapeHtml18(turn.detail)}</p>
8227
8364
  <dl>${turn.rows.map((row) => `<div>
8228
- <dt>${escapeHtml17(row.label)}</dt>
8229
- <dd>${escapeHtml17(row.value)}</dd>
8365
+ <dt>${escapeHtml18(row.label)}</dt>
8366
+ <dd>${escapeHtml18(row.value)}</dd>
8230
8367
  </div>`).join("")}</dl>
8231
8368
  </article>`).join("")}</div>` : '<p class="absolute-voice-turn-quality__empty">Complete a voice turn to see STT quality diagnostics.</p>';
8232
- return `<section class="absolute-voice-turn-quality absolute-voice-turn-quality--${escapeHtml17(model.status)}">
8369
+ return `<section class="absolute-voice-turn-quality absolute-voice-turn-quality--${escapeHtml18(model.status)}">
8233
8370
  <header class="absolute-voice-turn-quality__header">
8234
- <span class="absolute-voice-turn-quality__eyebrow">${escapeHtml17(model.title)}</span>
8235
- <strong class="absolute-voice-turn-quality__label">${escapeHtml17(model.label)}</strong>
8371
+ <span class="absolute-voice-turn-quality__eyebrow">${escapeHtml18(model.title)}</span>
8372
+ <strong class="absolute-voice-turn-quality__label">${escapeHtml18(model.label)}</strong>
8236
8373
  </header>
8237
- <p class="absolute-voice-turn-quality__description">${escapeHtml17(model.description)}</p>
8374
+ <p class="absolute-voice-turn-quality__description">${escapeHtml18(model.description)}</p>
8238
8375
  ${turns}
8239
- ${model.error ? `<p class="absolute-voice-turn-quality__error">${escapeHtml17(model.error)}</p>` : ""}
8376
+ ${model.error ? `<p class="absolute-voice-turn-quality__error">${escapeHtml18(model.error)}</p>` : ""}
8240
8377
  </section>`;
8241
8378
  };
8242
8379
  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}`;
@@ -8277,10 +8414,10 @@ var defineVoiceTurnQualityElement = (tagName = "absolute-voice-turn-quality") =>
8277
8414
  });
8278
8415
  };
8279
8416
  // src/client/turnLatencyWidget.ts
8280
- var DEFAULT_TITLE13 = "Turn Latency";
8281
- var DEFAULT_DESCRIPTION13 = "Per-turn timing from first transcript to commit and assistant response start.";
8417
+ var DEFAULT_TITLE14 = "Turn Latency";
8418
+ var DEFAULT_DESCRIPTION14 = "Per-turn timing from first transcript to commit and assistant response start.";
8282
8419
  var DEFAULT_PROOF_LABEL = "Run latency proof";
8283
- var escapeHtml18 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
8420
+ var escapeHtml19 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
8284
8421
  var formatMs3 = (value) => typeof value === "number" ? `${Math.round(value)}ms` : "n/a";
8285
8422
  var createVoiceTurnLatencyViewModel = (snapshot, options = {}) => {
8286
8423
  const turns = (snapshot.report?.turns ?? []).map((turn) => ({
@@ -8294,39 +8431,39 @@ var createVoiceTurnLatencyViewModel = (snapshot, options = {}) => {
8294
8431
  const warningCount = snapshot.report?.warnings ?? turns.filter((turn) => turn.status === "warn").length;
8295
8432
  const failedCount = snapshot.report?.failed ?? turns.filter((turn) => turn.status === "fail").length;
8296
8433
  return {
8297
- description: options.description ?? DEFAULT_DESCRIPTION13,
8434
+ description: options.description ?? DEFAULT_DESCRIPTION14,
8298
8435
  error: snapshot.error,
8299
8436
  isLoading: snapshot.isLoading,
8300
8437
  label: snapshot.error ? "Unavailable" : turns.length ? failedCount > 0 ? `${failedCount} slow` : warningCount > 0 ? `${warningCount} warnings` : `avg ${formatMs3(snapshot.report?.averageTotalMs)}` : snapshot.isLoading ? "Checking" : "No turns",
8301
8438
  proofLabel: options.proofPath ? options.proofLabel ?? DEFAULT_PROOF_LABEL : undefined,
8302
8439
  showProofAction: Boolean(options.proofPath),
8303
8440
  status: snapshot.error ? "error" : turns.length ? failedCount > 0 || warningCount > 0 ? "warning" : "ready" : snapshot.isLoading ? "loading" : "empty",
8304
- title: options.title ?? DEFAULT_TITLE13,
8441
+ title: options.title ?? DEFAULT_TITLE14,
8305
8442
  turns,
8306
8443
  updatedAt: snapshot.updatedAt
8307
8444
  };
8308
8445
  };
8309
8446
  var renderVoiceTurnLatencyHTML = (snapshot, options = {}) => {
8310
8447
  const model = createVoiceTurnLatencyViewModel(snapshot, options);
8311
- 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--${escapeHtml18(turn.status)}">
8448
+ 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--${escapeHtml19(turn.status)}">
8312
8449
  <header>
8313
- <strong>${escapeHtml18(turn.label)}</strong>
8314
- <span>${escapeHtml18(turn.status)}</span>
8450
+ <strong>${escapeHtml19(turn.label)}</strong>
8451
+ <span>${escapeHtml19(turn.status)}</span>
8315
8452
  </header>
8316
8453
  <dl>${turn.rows.map((row) => `<div>
8317
- <dt>${escapeHtml18(row.label)}</dt>
8318
- <dd>${escapeHtml18(row.value)}</dd>
8454
+ <dt>${escapeHtml19(row.label)}</dt>
8455
+ <dd>${escapeHtml19(row.value)}</dd>
8319
8456
  </div>`).join("")}</dl>
8320
8457
  </article>`).join("")}</div>` : '<p class="absolute-voice-turn-latency__empty">Complete a voice turn to see latency diagnostics.</p>';
8321
- return `<section class="absolute-voice-turn-latency absolute-voice-turn-latency--${escapeHtml18(model.status)}">
8458
+ return `<section class="absolute-voice-turn-latency absolute-voice-turn-latency--${escapeHtml19(model.status)}">
8322
8459
  <header class="absolute-voice-turn-latency__header">
8323
- <span class="absolute-voice-turn-latency__eyebrow">${escapeHtml18(model.title)}</span>
8324
- <strong class="absolute-voice-turn-latency__label">${escapeHtml18(model.label)}</strong>
8460
+ <span class="absolute-voice-turn-latency__eyebrow">${escapeHtml19(model.title)}</span>
8461
+ <strong class="absolute-voice-turn-latency__label">${escapeHtml19(model.label)}</strong>
8325
8462
  </header>
8326
- <p class="absolute-voice-turn-latency__description">${escapeHtml18(model.description)}</p>
8327
- ${model.showProofAction ? `<button class="absolute-voice-turn-latency__proof" data-absolute-voice-turn-latency-proof type="button">${escapeHtml18(model.proofLabel ?? DEFAULT_PROOF_LABEL)}</button>` : ""}
8463
+ <p class="absolute-voice-turn-latency__description">${escapeHtml19(model.description)}</p>
8464
+ ${model.showProofAction ? `<button class="absolute-voice-turn-latency__proof" data-absolute-voice-turn-latency-proof type="button">${escapeHtml19(model.proofLabel ?? DEFAULT_PROOF_LABEL)}</button>` : ""}
8328
8465
  ${turns}
8329
- ${model.error ? `<p class="absolute-voice-turn-latency__error">${escapeHtml18(model.error)}</p>` : ""}
8466
+ ${model.error ? `<p class="absolute-voice-turn-latency__error">${escapeHtml19(model.error)}</p>` : ""}
8330
8467
  </section>`;
8331
8468
  };
8332
8469
  var mountVoiceTurnLatency = (element, path = "/api/turn-latency", options = {}) => {
@@ -8376,9 +8513,9 @@ var defineVoiceTurnLatencyElement = (tagName = "absolute-voice-turn-latency") =>
8376
8513
  });
8377
8514
  };
8378
8515
  // src/client/traceTimelineWidget.ts
8379
- var DEFAULT_TITLE14 = "Voice Traces";
8380
- var DEFAULT_DESCRIPTION14 = "Latest call timelines with provider latency, fallbacks, handoffs, and errors from your self-hosted trace store.";
8381
- var escapeHtml19 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
8516
+ var DEFAULT_TITLE15 = "Voice Traces";
8517
+ var DEFAULT_DESCRIPTION15 = "Latest call timelines with provider latency, fallbacks, handoffs, and errors from your self-hosted trace store.";
8518
+ var escapeHtml20 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
8382
8519
  var formatMs4 = (value) => typeof value === "number" ? `${value}ms` : "n/a";
8383
8520
  var formatProviders = (session) => session.providers.length ? session.providers.map((provider) => provider.provider).join(", ") : "No providers";
8384
8521
  var createVoiceTraceTimelineViewModel = (snapshot, options = {}) => {
@@ -8394,13 +8531,13 @@ var createVoiceTraceTimelineViewModel = (snapshot, options = {}) => {
8394
8531
  const failed = sessions.filter((session) => session.status === "failed").length;
8395
8532
  const warnings = sessions.filter((session) => session.status === "warning").length;
8396
8533
  return {
8397
- description: options.description ?? DEFAULT_DESCRIPTION14,
8534
+ description: options.description ?? DEFAULT_DESCRIPTION15,
8398
8535
  error: snapshot.error,
8399
8536
  isLoading: snapshot.isLoading,
8400
8537
  label: snapshot.error ? "Unavailable" : failed > 0 ? `${failed} failed` : warnings > 0 ? `${warnings} warning` : sessions.length ? `${sessions.length} recent` : snapshot.isLoading ? "Checking" : "No traces yet",
8401
8538
  sessions,
8402
8539
  status: snapshot.error ? "error" : failed > 0 ? "failed" : warnings > 0 ? "warning" : sessions.length ? "ready" : snapshot.isLoading ? "loading" : "empty",
8403
- title: options.title ?? DEFAULT_TITLE14,
8540
+ title: options.title ?? DEFAULT_TITLE15,
8404
8541
  updatedAt: snapshot.updatedAt
8405
8542
  };
8406
8543
  };
@@ -8408,27 +8545,27 @@ var renderVoiceTraceTimelineWidgetHTML = (snapshot, options = {}) => {
8408
8545
  const model = createVoiceTraceTimelineViewModel(snapshot, options);
8409
8546
  const sessions = model.sessions.length ? `<div class="absolute-voice-trace-timeline__sessions">${model.sessions.map((session) => {
8410
8547
  const supportLinks = [
8411
- `<a href="${escapeHtml19(session.detailHref)}">Open timeline</a>`,
8412
- session.operationsRecordHref ? `<a href="${escapeHtml19(session.operationsRecordHref)}">Open operations record</a>` : undefined,
8413
- session.incidentBundleHref ? `<a href="${escapeHtml19(session.incidentBundleHref)}">Export incident bundle</a>` : undefined
8548
+ `<a href="${escapeHtml20(session.detailHref)}">Open timeline</a>`,
8549
+ session.operationsRecordHref ? `<a href="${escapeHtml20(session.operationsRecordHref)}">Open operations record</a>` : undefined,
8550
+ session.incidentBundleHref ? `<a href="${escapeHtml20(session.incidentBundleHref)}">Export incident bundle</a>` : undefined
8414
8551
  ].filter(Boolean).join("");
8415
- return `<article class="absolute-voice-trace-timeline__session absolute-voice-trace-timeline__session--${escapeHtml19(session.status)}">
8552
+ return `<article class="absolute-voice-trace-timeline__session absolute-voice-trace-timeline__session--${escapeHtml20(session.status)}">
8416
8553
  <header>
8417
- <strong>${escapeHtml19(session.sessionId)}</strong>
8418
- <span>${escapeHtml19(session.status)}</span>
8554
+ <strong>${escapeHtml20(session.sessionId)}</strong>
8555
+ <span>${escapeHtml20(session.status)}</span>
8419
8556
  </header>
8420
- <p>${escapeHtml19(session.label)} \xB7 ${escapeHtml19(session.durationLabel)} \xB7 ${escapeHtml19(session.providerLabel)}</p>
8557
+ <p>${escapeHtml20(session.label)} \xB7 ${escapeHtml20(session.durationLabel)} \xB7 ${escapeHtml20(session.providerLabel)}</p>
8421
8558
  <p class="absolute-voice-trace-timeline__actions">${supportLinks}</p>
8422
8559
  </article>`;
8423
8560
  }).join("")}</div>` : '<p class="absolute-voice-trace-timeline__empty">Run a voice session to see call timelines.</p>';
8424
- return `<section class="absolute-voice-trace-timeline absolute-voice-trace-timeline--${escapeHtml19(model.status)}">
8561
+ return `<section class="absolute-voice-trace-timeline absolute-voice-trace-timeline--${escapeHtml20(model.status)}">
8425
8562
  <header class="absolute-voice-trace-timeline__header">
8426
- <span class="absolute-voice-trace-timeline__eyebrow">${escapeHtml19(model.title)}</span>
8427
- <strong class="absolute-voice-trace-timeline__label">${escapeHtml19(model.label)}</strong>
8563
+ <span class="absolute-voice-trace-timeline__eyebrow">${escapeHtml20(model.title)}</span>
8564
+ <strong class="absolute-voice-trace-timeline__label">${escapeHtml20(model.label)}</strong>
8428
8565
  </header>
8429
- <p class="absolute-voice-trace-timeline__description">${escapeHtml19(model.description)}</p>
8566
+ <p class="absolute-voice-trace-timeline__description">${escapeHtml20(model.description)}</p>
8430
8567
  ${sessions}
8431
- ${model.error ? `<p class="absolute-voice-trace-timeline__error">${escapeHtml19(model.error)}</p>` : ""}
8568
+ ${model.error ? `<p class="absolute-voice-trace-timeline__error">${escapeHtml20(model.error)}</p>` : ""}
8432
8569
  </section>`;
8433
8570
  };
8434
8571
  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}`;
@@ -8474,9 +8611,9 @@ var defineVoiceTraceTimelineElement = (tagName = "absolute-voice-trace-timeline"
8474
8611
  });
8475
8612
  };
8476
8613
  // src/client/agentSquadStatusWidget.ts
8477
- var DEFAULT_TITLE15 = "Voice Agent Squad";
8478
- var DEFAULT_DESCRIPTION15 = "Current specialist and recent handoffs from your self-hosted voice traces.";
8479
- var escapeHtml20 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
8614
+ var DEFAULT_TITLE16 = "Voice Agent Squad";
8615
+ var DEFAULT_DESCRIPTION16 = "Current specialist and recent handoffs from your self-hosted voice traces.";
8616
+ var escapeHtml21 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
8480
8617
  var labelFor = (current) => {
8481
8618
  if (!current)
8482
8619
  return "Waiting for specialist activity";
@@ -8490,37 +8627,37 @@ var labelFor = (current) => {
8490
8627
  };
8491
8628
  var createVoiceAgentSquadStatusViewModel = (snapshot, options = {}) => ({
8492
8629
  current: snapshot.report.current,
8493
- description: options.description ?? DEFAULT_DESCRIPTION15,
8630
+ description: options.description ?? DEFAULT_DESCRIPTION16,
8494
8631
  error: snapshot.error,
8495
8632
  isLoading: snapshot.isLoading,
8496
8633
  label: snapshot.error ? "Unavailable" : labelFor(snapshot.report.current),
8497
8634
  sessionCount: snapshot.report.sessionCount,
8498
8635
  sessions: snapshot.report.sessions,
8499
- title: options.title ?? DEFAULT_TITLE15,
8636
+ title: options.title ?? DEFAULT_TITLE16,
8500
8637
  updatedAt: snapshot.updatedAt
8501
8638
  });
8502
8639
  var renderVoiceAgentSquadStatusHTML = (snapshot, options = {}) => {
8503
8640
  const model = createVoiceAgentSquadStatusViewModel(snapshot, options);
8504
8641
  const current = model.current;
8505
8642
  const rows = model.sessions.length ? model.sessions.slice(0, 5).map((session) => `<li>
8506
- <span>${escapeHtml20(session.sessionId)}</span>
8507
- <strong>${escapeHtml20(session.targetAgentId ?? "none")}</strong>
8508
- <em>${escapeHtml20(session.status)}</em>
8509
- ${session.summary || session.reason ? `<p>${escapeHtml20(session.summary ?? session.reason ?? "")}</p>` : ""}
8643
+ <span>${escapeHtml21(session.sessionId)}</span>
8644
+ <strong>${escapeHtml21(session.targetAgentId ?? "none")}</strong>
8645
+ <em>${escapeHtml21(session.status)}</em>
8646
+ ${session.summary || session.reason ? `<p>${escapeHtml21(session.summary ?? session.reason ?? "")}</p>` : ""}
8510
8647
  </li>`).join("") : "<li><span>No squad traces yet.</span><strong>Waiting</strong></li>";
8511
8648
  return `<section class="absolute-voice-agent-squad-status">
8512
8649
  <header>
8513
- <span>${escapeHtml20(model.title)}</span>
8514
- <strong>${escapeHtml20(model.label)}</strong>
8650
+ <span>${escapeHtml21(model.title)}</span>
8651
+ <strong>${escapeHtml21(model.label)}</strong>
8515
8652
  </header>
8516
- <p>${escapeHtml20(model.description)}</p>
8653
+ <p>${escapeHtml21(model.description)}</p>
8517
8654
  <div>
8518
- <span>Session</span><strong>${escapeHtml20(current?.sessionId ?? "n/a")}</strong>
8519
- <span>From</span><strong>${escapeHtml20(current?.fromAgentId ?? "n/a")}</strong>
8520
- <span>Status</span><strong>${escapeHtml20(current?.status ?? "idle")}</strong>
8655
+ <span>Session</span><strong>${escapeHtml21(current?.sessionId ?? "n/a")}</strong>
8656
+ <span>From</span><strong>${escapeHtml21(current?.fromAgentId ?? "n/a")}</strong>
8657
+ <span>Status</span><strong>${escapeHtml21(current?.status ?? "idle")}</strong>
8521
8658
  </div>
8522
8659
  <ul>${rows}</ul>
8523
- ${model.error ? `<p class="absolute-voice-agent-squad-status__error">${escapeHtml20(model.error)}</p>` : ""}
8660
+ ${model.error ? `<p class="absolute-voice-agent-squad-status__error">${escapeHtml21(model.error)}</p>` : ""}
8524
8661
  </section>`;
8525
8662
  };
8526
8663
  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}`;
@@ -8656,6 +8793,7 @@ export {
8656
8793
  renderVoiceProviderContractsHTML,
8657
8794
  renderVoiceProviderCapabilitiesHTML,
8658
8795
  renderVoiceProofTrendsHTML,
8796
+ renderVoiceProfileSwitchRecommendationHTML,
8659
8797
  renderVoiceProfileComparisonHTML,
8660
8798
  renderVoicePlatformCoverageHTML,
8661
8799
  renderVoiceOpsStatusHTML,
@@ -8676,6 +8814,7 @@ export {
8676
8814
  mountVoiceProviderContracts,
8677
8815
  mountVoiceProviderCapabilities,
8678
8816
  mountVoiceProofTrends,
8817
+ mountVoiceProfileSwitchRecommendation,
8679
8818
  mountVoiceProfileComparison,
8680
8819
  mountVoicePlatformCoverage,
8681
8820
  mountVoiceOpsStatus,
@@ -8692,6 +8831,7 @@ export {
8692
8831
  getVoiceProviderContractsCSS,
8693
8832
  getVoiceProviderCapabilitiesCSS,
8694
8833
  getVoiceProofTrendsCSS,
8834
+ getVoiceProfileSwitchRecommendationCSS,
8695
8835
  getVoiceProfileComparisonCSS,
8696
8836
  getVoicePlatformCoverageCSS,
8697
8837
  getVoiceOpsStatusLabel,
@@ -8711,6 +8851,7 @@ export {
8711
8851
  fetchVoiceProviderContracts,
8712
8852
  fetchVoiceProviderCapabilities,
8713
8853
  fetchVoiceProofTrends,
8854
+ fetchVoiceProfileSwitchRecommendation,
8714
8855
  fetchVoiceProfileComparison,
8715
8856
  fetchVoicePlatformCoverage,
8716
8857
  fetchVoiceOpsStatus,
@@ -8727,6 +8868,7 @@ export {
8727
8868
  defineVoiceProviderContractsElement,
8728
8869
  defineVoiceProviderCapabilitiesElement,
8729
8870
  defineVoiceProofTrendsElement,
8871
+ defineVoiceProfileSwitchRecommendationElement,
8730
8872
  defineVoiceProfileComparisonElement,
8731
8873
  defineVoicePlatformCoverageElement,
8732
8874
  defineVoiceOpsStatusElement,
@@ -8757,6 +8899,7 @@ export {
8757
8899
  createVoiceProviderCapabilitiesStore,
8758
8900
  createVoiceProofTrendsViewModel,
8759
8901
  createVoiceProofTrendsStore,
8902
+ createVoiceProfileSwitchRecommendationStore,
8760
8903
  createVoiceProfileComparisonViewModel,
8761
8904
  createVoiceProfileComparisonStore,
8762
8905
  createVoicePlatformCoverageViewModel,