@absolutejs/voice 0.0.22-beta.242 → 0.0.22-beta.243

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.
@@ -2140,6 +2140,84 @@ var createVoicePlatformCoverageStore = (path = "/api/voice/platform-coverage", o
2140
2140
  }
2141
2141
  };
2142
2142
  };
2143
+ // src/client/proofTrends.ts
2144
+ var fetchVoiceProofTrends = async (path = "/api/voice/proof-trends", options = {}) => {
2145
+ const fetchImpl = options.fetch ?? globalThis.fetch;
2146
+ const response = await fetchImpl(path);
2147
+ if (!response.ok) {
2148
+ throw new Error(`Voice proof trends failed: HTTP ${response.status}`);
2149
+ }
2150
+ return await response.json();
2151
+ };
2152
+ var createVoiceProofTrendsStore = (path = "/api/voice/proof-trends", options = {}) => {
2153
+ const listeners = new Set;
2154
+ let closed = false;
2155
+ let timer;
2156
+ let snapshot = {
2157
+ error: null,
2158
+ isLoading: false
2159
+ };
2160
+ const emit = () => {
2161
+ for (const listener of listeners) {
2162
+ listener();
2163
+ }
2164
+ };
2165
+ const refresh = async () => {
2166
+ if (closed) {
2167
+ return snapshot.report;
2168
+ }
2169
+ snapshot = {
2170
+ ...snapshot,
2171
+ error: null,
2172
+ isLoading: true
2173
+ };
2174
+ emit();
2175
+ try {
2176
+ const report = await fetchVoiceProofTrends(path, options);
2177
+ snapshot = {
2178
+ error: null,
2179
+ isLoading: false,
2180
+ report,
2181
+ updatedAt: Date.now()
2182
+ };
2183
+ emit();
2184
+ return report;
2185
+ } catch (error) {
2186
+ snapshot = {
2187
+ ...snapshot,
2188
+ error: error instanceof Error ? error.message : String(error),
2189
+ isLoading: false
2190
+ };
2191
+ emit();
2192
+ throw error;
2193
+ }
2194
+ };
2195
+ const close = () => {
2196
+ closed = true;
2197
+ if (timer) {
2198
+ clearInterval(timer);
2199
+ timer = undefined;
2200
+ }
2201
+ listeners.clear();
2202
+ };
2203
+ if (typeof window !== "undefined" && options.intervalMs && options.intervalMs > 0) {
2204
+ timer = setInterval(() => {
2205
+ refresh().catch(() => {});
2206
+ }, options.intervalMs);
2207
+ }
2208
+ return {
2209
+ close,
2210
+ getServerSnapshot: () => snapshot,
2211
+ getSnapshot: () => snapshot,
2212
+ refresh,
2213
+ subscribe: (listener) => {
2214
+ listeners.add(listener);
2215
+ return () => {
2216
+ listeners.delete(listener);
2217
+ };
2218
+ }
2219
+ };
2220
+ };
2143
2221
  // src/client/opsActionCenter.ts
2144
2222
  var recordVoiceOpsActionResult = async (result, options = {}) => {
2145
2223
  if (options.auditPath === false) {
@@ -2850,10 +2928,225 @@ var defineVoicePlatformCoverageElement = (tagName = "absolute-voice-platform-cov
2850
2928
  }
2851
2929
  });
2852
2930
  };
2853
- // src/client/opsActionCenterWidget.ts
2854
- var DEFAULT_TITLE3 = "Voice Ops Action Center";
2855
- var DEFAULT_DESCRIPTION3 = "Run production voice proofs and operator actions from one primitive panel.";
2931
+ // src/proofTrends.ts
2932
+ import { Elysia } from "elysia";
2933
+ var DEFAULT_VOICE_PROOF_TRENDS_MAX_AGE_MS = 24 * 60 * 60 * 1000;
2934
+ var normalizeMaxAgeMs = (value) => typeof value === "number" && Number.isFinite(value) && value > 0 ? value : DEFAULT_VOICE_PROOF_TRENDS_MAX_AGE_MS;
2935
+ var toTimeMs = (value) => {
2936
+ if (value instanceof Date) {
2937
+ return value.getTime();
2938
+ }
2939
+ if (typeof value === "number") {
2940
+ return value;
2941
+ }
2942
+ if (typeof value === "string") {
2943
+ return Date.parse(value);
2944
+ }
2945
+ return Date.now();
2946
+ };
2947
+ var buildVoiceProofTrendReport = (input = {}) => {
2948
+ const maxAgeMs = normalizeMaxAgeMs(input.maxAgeMs);
2949
+ const nowMs = toTimeMs(input.now);
2950
+ const generatedAtMs = typeof input.generatedAt === "string" ? Date.parse(input.generatedAt) : Number.NaN;
2951
+ const ageMs = Number.isFinite(generatedAtMs) && Number.isFinite(nowMs) ? Math.max(0, nowMs - generatedAtMs) : undefined;
2952
+ const freshUntil = Number.isFinite(generatedAtMs) && Number.isFinite(maxAgeMs) ? new Date(generatedAtMs + maxAgeMs).toISOString() : undefined;
2953
+ const isFresh = ageMs !== undefined && ageMs <= maxAgeMs;
2954
+ const status = input.status === "empty" ? "empty" : !isFresh ? "stale" : input.ok === true ? "pass" : "fail";
2955
+ return {
2956
+ ageMs,
2957
+ baseUrl: input.baseUrl,
2958
+ cycles: input.cycles ?? [],
2959
+ freshUntil,
2960
+ generatedAt: input.generatedAt,
2961
+ maxAgeMs,
2962
+ ok: input.ok === true && status === "pass",
2963
+ outputDir: input.outputDir,
2964
+ runId: input.runId,
2965
+ source: input.source ?? "",
2966
+ status,
2967
+ summary: input.summary ?? {}
2968
+ };
2969
+ };
2970
+ var buildEmptyVoiceProofTrendReport = (source = "", maxAgeMs) => buildVoiceProofTrendReport({
2971
+ maxAgeMs,
2972
+ source,
2973
+ status: "empty"
2974
+ });
2975
+ var normalizeVoiceProofTrendReport = (value, options = {}) => {
2976
+ if ("status" in value && value.status === "empty") {
2977
+ return buildEmptyVoiceProofTrendReport(value.source || options.source || "", options.maxAgeMs ?? value.maxAgeMs);
2978
+ }
2979
+ return buildVoiceProofTrendReport({
2980
+ ...value,
2981
+ maxAgeMs: options.maxAgeMs ?? value.maxAgeMs,
2982
+ source: value.source ?? options.source
2983
+ });
2984
+ };
2985
+ var readVoiceProofTrendReportFile = async (path, options = {}) => {
2986
+ const file = Bun.file(path);
2987
+ if (!await file.exists()) {
2988
+ return buildEmptyVoiceProofTrendReport(path, options.maxAgeMs);
2989
+ }
2990
+ try {
2991
+ const parsed = await file.json();
2992
+ return normalizeVoiceProofTrendReport(parsed, {
2993
+ maxAgeMs: options.maxAgeMs,
2994
+ source: path
2995
+ });
2996
+ } catch {
2997
+ return buildVoiceProofTrendReport({
2998
+ maxAgeMs: options.maxAgeMs,
2999
+ source: path
3000
+ });
3001
+ }
3002
+ };
3003
+ var createVoiceProofTrendRoutes = (options) => {
3004
+ const path = options.path ?? "/api/voice/proof-trends";
3005
+ const routes = new Elysia({
3006
+ name: options.name ?? "absolutejs-voice-proof-trends"
3007
+ });
3008
+ routes.get(path, async () => {
3009
+ const value = options.source !== undefined ? typeof options.source === "function" ? await options.source() : options.source : options.jsonPath ? await readVoiceProofTrendReportFile(options.jsonPath, {
3010
+ maxAgeMs: options.maxAgeMs
3011
+ }) : buildEmptyVoiceProofTrendReport("", options.maxAgeMs);
3012
+ return Response.json(normalizeVoiceProofTrendReport(value, {
3013
+ maxAgeMs: options.maxAgeMs,
3014
+ source: options.jsonPath
3015
+ }), { headers: options.headers });
3016
+ });
3017
+ return routes;
3018
+ };
3019
+ var formatVoiceProofTrendAge = (ageMs) => {
3020
+ if (typeof ageMs !== "number" || !Number.isFinite(ageMs)) {
3021
+ return "unknown";
3022
+ }
3023
+ const minutes = Math.floor(ageMs / 60000);
3024
+ if (minutes < 1) {
3025
+ return "less than 1m";
3026
+ }
3027
+ if (minutes < 60) {
3028
+ return `${minutes}m`;
3029
+ }
3030
+ const hours = Math.floor(minutes / 60);
3031
+ if (hours < 48) {
3032
+ return `${hours}h ${minutes % 60}m`;
3033
+ }
3034
+ const days = Math.floor(hours / 24);
3035
+ return `${days}d ${hours % 24}h`;
3036
+ };
3037
+
3038
+ // src/client/proofTrendsWidget.ts
3039
+ var DEFAULT_TITLE3 = "Sustained Proof Trends";
3040
+ var DEFAULT_DESCRIPTION3 = "Repeated-cycle provider, latency, recovery, and readiness evidence with freshness gating.";
3041
+ var DEFAULT_LINKS2 = [
3042
+ { href: "/voice/proof-trends", label: "Trend page" },
3043
+ { href: "/api/voice/proof-trends", label: "Trend JSON" }
3044
+ ];
2856
3045
  var escapeHtml3 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
3046
+ var formatMs = (value) => typeof value === "number" && Number.isFinite(value) ? `${Math.round(value)}ms` : "n/a";
3047
+ var statusLabel = (report) => {
3048
+ if (!report) {
3049
+ return "No trend report";
3050
+ }
3051
+ if (report.status === "pass") {
3052
+ return `${report.summary.cycles ?? report.cycles.length} cycles passing`;
3053
+ }
3054
+ return report.status;
3055
+ };
3056
+ var createVoiceProofTrendsViewModel = (snapshot, options = {}) => {
3057
+ const report = snapshot.report;
3058
+ const metrics = report ? [
3059
+ { label: "Status", value: report.status.toUpperCase() },
3060
+ {
3061
+ label: "Cycles",
3062
+ value: String(report.summary.cycles ?? report.cycles.length)
3063
+ },
3064
+ {
3065
+ label: "Provider p95",
3066
+ value: formatMs(report.summary.maxProviderP95Ms)
3067
+ },
3068
+ { label: "Turn p95", value: formatMs(report.summary.maxTurnP95Ms) },
3069
+ { label: "Live p95", value: formatMs(report.summary.maxLiveP95Ms) },
3070
+ {
3071
+ label: "Artifact age",
3072
+ value: formatVoiceProofTrendAge(report.ageMs)
3073
+ },
3074
+ {
3075
+ label: "Stale after",
3076
+ value: formatVoiceProofTrendAge(report.maxAgeMs)
3077
+ }
3078
+ ] : [];
3079
+ return {
3080
+ description: options.description ?? DEFAULT_DESCRIPTION3,
3081
+ error: snapshot.error,
3082
+ isLoading: snapshot.isLoading,
3083
+ label: snapshot.error ? "Unavailable" : report ? statusLabel(report) : snapshot.isLoading ? "Checking" : "No trend report",
3084
+ links: options.links ?? DEFAULT_LINKS2,
3085
+ metrics,
3086
+ report,
3087
+ status: snapshot.error ? "error" : report ? report.status === "pass" ? "ready" : "warning" : snapshot.isLoading ? "loading" : "empty",
3088
+ title: options.title ?? DEFAULT_TITLE3,
3089
+ updatedAt: snapshot.updatedAt
3090
+ };
3091
+ };
3092
+ var renderVoiceProofTrendsHTML = (snapshot, options = {}) => {
3093
+ const model = createVoiceProofTrendsViewModel(snapshot, options);
3094
+ const metrics = model.metrics.length ? `<div class="absolute-voice-proof-trends__metrics">${model.metrics.map((metric) => `<article>
3095
+ <span>${escapeHtml3(metric.label)}</span>
3096
+ <strong>${escapeHtml3(metric.value)}</strong>
3097
+ </article>`).join("")}</div>` : `<p class="absolute-voice-proof-trends__empty">${model.error ? escapeHtml3(model.error) : "Run the sustained proof trends script to populate evidence."}</p>`;
3098
+ const links = model.links.length ? `<p class="absolute-voice-proof-trends__links">${model.links.map((link) => `<a href="${escapeHtml3(link.href)}">${escapeHtml3(link.label)}</a>`).join("")}</p>` : "";
3099
+ return `<section class="absolute-voice-proof-trends absolute-voice-proof-trends--${escapeHtml3(model.status)}">
3100
+ <header class="absolute-voice-proof-trends__header">
3101
+ <span class="absolute-voice-proof-trends__eyebrow">${escapeHtml3(model.title)}</span>
3102
+ <strong class="absolute-voice-proof-trends__label">${escapeHtml3(model.label)}</strong>
3103
+ </header>
3104
+ <p class="absolute-voice-proof-trends__description">${escapeHtml3(model.description)}</p>
3105
+ ${metrics}
3106
+ ${links}
3107
+ ${model.error ? `<p class="absolute-voice-proof-trends__error">${escapeHtml3(model.error)}</p>` : ""}
3108
+ </section>`;
3109
+ };
3110
+ var getVoiceProofTrendsCSS = () => `.absolute-voice-proof-trends{border:1px solid #99f6e4;border-radius:20px;background:#f0fdfa;color:#0f172a;padding:18px;box-shadow:0 18px 40px rgba(13,148,136,.12);font-family:inherit}.absolute-voice-proof-trends--warning,.absolute-voice-proof-trends--error{border-color:#f2a7a7;background:#fff7f4}.absolute-voice-proof-trends__header{align-items:start;display:flex;gap:12px;justify-content:space-between}.absolute-voice-proof-trends__eyebrow{color:#0f766e;font-size:12px;font-weight:800;letter-spacing:.08em;text-transform:uppercase}.absolute-voice-proof-trends__label{font-size:24px;line-height:1}.absolute-voice-proof-trends__description,.absolute-voice-proof-trends__empty{color:#475569}.absolute-voice-proof-trends__metrics{display:grid;gap:10px;grid-template-columns:repeat(auto-fit,minmax(130px,1fr));margin-top:14px}.absolute-voice-proof-trends__metrics article{background:#fff;border:1px solid #ccfbf1;border-radius:16px;padding:12px}.absolute-voice-proof-trends__metrics span{color:#64748b;display:block;font-size:12px;font-weight:800;text-transform:uppercase}.absolute-voice-proof-trends__metrics strong{display:block;font-size:20px;margin-top:4px}.absolute-voice-proof-trends__links{display:flex;flex-wrap:wrap;gap:8px;margin:14px 0 0}.absolute-voice-proof-trends__links a{border:1px solid #99f6e4;border-radius:999px;color:#0f766e;font-weight:800;padding:6px 10px;text-decoration:none}.absolute-voice-proof-trends__error{color:#9f1239;font-weight:700}`;
3111
+ var mountVoiceProofTrends = (element, path = "/api/voice/proof-trends", options = {}) => {
3112
+ const store = createVoiceProofTrendsStore(path, options);
3113
+ const render = () => {
3114
+ element.innerHTML = renderVoiceProofTrendsHTML(store.getSnapshot(), options);
3115
+ };
3116
+ const unsubscribe = store.subscribe(render);
3117
+ render();
3118
+ store.refresh().catch(() => {});
3119
+ return {
3120
+ close: () => {
3121
+ unsubscribe();
3122
+ store.close();
3123
+ },
3124
+ refresh: store.refresh
3125
+ };
3126
+ };
3127
+ var defineVoiceProofTrendsElement = (tagName = "absolute-voice-proof-trends") => {
3128
+ if (typeof window === "undefined" || typeof customElements === "undefined" || customElements.get(tagName)) {
3129
+ return;
3130
+ }
3131
+ customElements.define(tagName, class AbsoluteVoiceProofTrendsElement extends HTMLElement {
3132
+ mounted;
3133
+ connectedCallback() {
3134
+ this.mounted = mountVoiceProofTrends(this, this.getAttribute("path") ?? "/api/voice/proof-trends", {
3135
+ description: this.getAttribute("description") ?? undefined,
3136
+ intervalMs: Number(this.getAttribute("interval-ms") ?? 0) || undefined,
3137
+ title: this.getAttribute("title") ?? undefined
3138
+ });
3139
+ }
3140
+ disconnectedCallback() {
3141
+ this.mounted?.close();
3142
+ this.mounted = undefined;
3143
+ }
3144
+ });
3145
+ };
3146
+ // src/client/opsActionCenterWidget.ts
3147
+ var DEFAULT_TITLE4 = "Voice Ops Action Center";
3148
+ var DEFAULT_DESCRIPTION4 = "Run production voice proofs and operator actions from one primitive panel.";
3149
+ var escapeHtml4 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
2857
3150
  var createVoiceOpsActionCenterViewModel = (snapshot, options = {}) => {
2858
3151
  const status = snapshot.error ? "error" : snapshot.isRunning ? "running" : snapshot.lastResult ? "completed" : "ready";
2859
3152
  return {
@@ -2864,29 +3157,29 @@ var createVoiceOpsActionCenterViewModel = (snapshot, options = {}) => {
2864
3157
  isRunning: snapshot.runningActionId === action.id,
2865
3158
  label: action.label
2866
3159
  })),
2867
- description: options.description ?? DEFAULT_DESCRIPTION3,
3160
+ description: options.description ?? DEFAULT_DESCRIPTION4,
2868
3161
  error: snapshot.error,
2869
3162
  isRunning: snapshot.isRunning,
2870
3163
  label: status === "error" ? "Needs attention" : status === "running" ? "Running" : status === "completed" ? "Action completed" : "Ready",
2871
3164
  lastResultLabel: snapshot.lastResult ? `${snapshot.lastResult.actionId} returned HTTP ${snapshot.lastResult.status}` : "No action has run yet.",
2872
3165
  status,
2873
- title: options.title ?? DEFAULT_TITLE3
3166
+ title: options.title ?? DEFAULT_TITLE4
2874
3167
  };
2875
3168
  };
2876
3169
  var renderVoiceOpsActionCenterHTML = (snapshot, options = {}) => {
2877
3170
  const model = createVoiceOpsActionCenterViewModel(snapshot, options);
2878
- const actions = model.actions.map((action) => `<button type="button" data-absolute-voice-ops-action="${escapeHtml3(action.id)}"${action.disabled ? " disabled" : ""}>
2879
- ${escapeHtml3(action.isRunning ? "Working..." : action.label)}
3171
+ const actions = model.actions.map((action) => `<button type="button" data-absolute-voice-ops-action="${escapeHtml4(action.id)}"${action.disabled ? " disabled" : ""}>
3172
+ ${escapeHtml4(action.isRunning ? "Working..." : action.label)}
2880
3173
  </button>`).join("");
2881
- return `<section class="absolute-voice-ops-action-center absolute-voice-ops-action-center--${escapeHtml3(model.status)}">
3174
+ return `<section class="absolute-voice-ops-action-center absolute-voice-ops-action-center--${escapeHtml4(model.status)}">
2882
3175
  <header class="absolute-voice-ops-action-center__header">
2883
- <span class="absolute-voice-ops-action-center__eyebrow">${escapeHtml3(model.title)}</span>
2884
- <strong class="absolute-voice-ops-action-center__label">${escapeHtml3(model.label)}</strong>
3176
+ <span class="absolute-voice-ops-action-center__eyebrow">${escapeHtml4(model.title)}</span>
3177
+ <strong class="absolute-voice-ops-action-center__label">${escapeHtml4(model.label)}</strong>
2885
3178
  </header>
2886
- <p class="absolute-voice-ops-action-center__description">${escapeHtml3(model.description)}</p>
3179
+ <p class="absolute-voice-ops-action-center__description">${escapeHtml4(model.description)}</p>
2887
3180
  <div class="absolute-voice-ops-action-center__actions">${actions}</div>
2888
- <p class="absolute-voice-ops-action-center__result">${escapeHtml3(model.lastResultLabel)}</p>
2889
- ${model.error ? `<p class="absolute-voice-ops-action-center__error">${escapeHtml3(model.error)}</p>` : ""}
3181
+ <p class="absolute-voice-ops-action-center__result">${escapeHtml4(model.lastResultLabel)}</p>
3182
+ ${model.error ? `<p class="absolute-voice-ops-action-center__error">${escapeHtml4(model.error)}</p>` : ""}
2890
3183
  </section>`;
2891
3184
  };
2892
3185
  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}`;
@@ -2938,7 +3231,7 @@ var defineVoiceOpsActionCenterElement = (tagName = "absolute-voice-ops-action-ce
2938
3231
  });
2939
3232
  };
2940
3233
  // src/liveOps.ts
2941
- import { Elysia } from "elysia";
3234
+ import { Elysia as Elysia2 } from "elysia";
2942
3235
 
2943
3236
  // src/audit.ts
2944
3237
  var includes = (filter, value) => {
@@ -3487,7 +3780,7 @@ var exportVoiceTrace = async (input) => {
3487
3780
  };
3488
3781
  };
3489
3782
  var toNumber = (value) => typeof value === "number" && Number.isFinite(value) ? value : 0;
3490
- var escapeHtml4 = (value) => value.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;");
3783
+ var escapeHtml5 = (value) => value.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;");
3491
3784
  var formatTraceValue = (value) => {
3492
3785
  if (value === undefined || value === null) {
3493
3786
  return "";
@@ -3767,10 +4060,10 @@ var renderVoiceTraceHTML = (events, options = {}) => {
3767
4060
  const offset = summary.startedAt === undefined ? event.at : Math.max(0, event.at - summary.startedAt);
3768
4061
  return [
3769
4062
  "<tr>",
3770
- `<td>${escapeHtml4(String(offset))}</td>`,
3771
- `<td>${escapeHtml4(event.type)}</td>`,
3772
- `<td>${escapeHtml4(event.turnId ?? "")}</td>`,
3773
- `<td><code>${escapeHtml4(JSON.stringify(event.payload))}</code></td>`,
4063
+ `<td>${escapeHtml5(String(offset))}</td>`,
4064
+ `<td>${escapeHtml5(event.type)}</td>`,
4065
+ `<td>${escapeHtml5(event.turnId ?? "")}</td>`,
4066
+ `<td><code>${escapeHtml5(JSON.stringify(event.payload))}</code></td>`,
3774
4067
  "</tr>"
3775
4068
  ].join("");
3776
4069
  }).join(`
@@ -3781,7 +4074,7 @@ var renderVoiceTraceHTML = (events, options = {}) => {
3781
4074
  "<head>",
3782
4075
  '<meta charset="utf-8" />',
3783
4076
  '<meta name="viewport" content="width=device-width, initial-scale=1" />',
3784
- `<title>${escapeHtml4(options.title ?? "Voice Trace")}</title>`,
4077
+ `<title>${escapeHtml5(options.title ?? "Voice Trace")}</title>`,
3785
4078
  "<style>",
3786
4079
  "body{font-family:ui-sans-serif,system-ui,sans-serif;margin:2rem;line-height:1.45;background:#f8f7f2;color:#181713}",
3787
4080
  "main{max-width:1100px;margin:auto}",
@@ -3795,7 +4088,7 @@ var renderVoiceTraceHTML = (events, options = {}) => {
3795
4088
  "</style>",
3796
4089
  "</head>",
3797
4090
  "<body><main>",
3798
- `<h1>${escapeHtml4(options.title ?? `Voice Trace ${summary.sessionId ?? ""}`.trim())}</h1>`,
4091
+ `<h1>${escapeHtml5(options.title ?? `Voice Trace ${summary.sessionId ?? ""}`.trim())}</h1>`,
3799
4092
  `<p class="${evaluation.pass ? "pass" : "fail"}">QA: ${evaluation.pass ? "pass" : "fail"}</p>`,
3800
4093
  '<section class="summary">',
3801
4094
  `<div class="card"><strong>Events</strong><br>${summary.eventCount}</div>`,
@@ -3809,7 +4102,7 @@ var renderVoiceTraceHTML = (events, options = {}) => {
3809
4102
  eventRows,
3810
4103
  "</tbody></table>",
3811
4104
  "<h2>Markdown Export</h2>",
3812
- `<pre>${escapeHtml4(markdown)}</pre>`,
4105
+ `<pre>${escapeHtml5(markdown)}</pre>`,
3813
4106
  "</main></body></html>"
3814
4107
  ].join(`
3815
4108
  `);
@@ -3986,7 +4279,7 @@ var createVoiceLiveOpsRoutes = (options = {}) => {
3986
4279
  const controller = createVoiceLiveOpsController(options);
3987
4280
  const path = options.path ?? "/api/voice/live-ops/action";
3988
4281
  const controlPath = options.controlPath ?? "/api/voice/live-ops/control/:sessionId";
3989
- return new Elysia({
4282
+ return new Elysia2({
3990
4283
  name: options.name ?? "absolutejs-voice-live-ops"
3991
4284
  }).post(path, async ({ request, set }) => {
3992
4285
  try {
@@ -4020,7 +4313,7 @@ var ACTION_LABELS = {
4020
4313
  "resume-assistant": "Resume assistant",
4021
4314
  tag: "Tag"
4022
4315
  };
4023
- var escapeHtml5 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
4316
+ var escapeHtml6 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
4024
4317
  var createVoiceLiveOpsInput = (action, input) => ({
4025
4318
  action,
4026
4319
  assignee: input.assignee,
@@ -4031,17 +4324,17 @@ var createVoiceLiveOpsInput = (action, input) => ({
4031
4324
  var renderVoiceLiveOpsHTML = (snapshot, options = {}) => {
4032
4325
  const sessionId = options.getSessionId?.() ?? "";
4033
4326
  const disabled = snapshot.isRunning || !sessionId;
4034
- const actions = VOICE_LIVE_OPS_ACTIONS.map((action) => `<button type="button" data-absolute-voice-live-ops-action="${escapeHtml5(action)}"${disabled ? " disabled" : ""}>${escapeHtml5(snapshot.runningAction === action ? "Running..." : ACTION_LABELS[action])}</button>`).join("");
4035
- const result = snapshot.error ? `<p class="absolute-voice-live-ops__error">${escapeHtml5(snapshot.error)}</p>` : snapshot.lastResult ? `<p class="absolute-voice-live-ops__result">Recorded ${escapeHtml5(snapshot.lastResult.action)}. Control: ${escapeHtml5(snapshot.lastResult.control.status)}.</p>` : '<p class="absolute-voice-live-ops__result">No live ops action has run yet.</p>';
4327
+ const actions = VOICE_LIVE_OPS_ACTIONS.map((action) => `<button type="button" data-absolute-voice-live-ops-action="${escapeHtml6(action)}"${disabled ? " disabled" : ""}>${escapeHtml6(snapshot.runningAction === action ? "Running..." : ACTION_LABELS[action])}</button>`).join("");
4328
+ const result = snapshot.error ? `<p class="absolute-voice-live-ops__error">${escapeHtml6(snapshot.error)}</p>` : snapshot.lastResult ? `<p class="absolute-voice-live-ops__result">Recorded ${escapeHtml6(snapshot.lastResult.action)}. Control: ${escapeHtml6(snapshot.lastResult.control.status)}.</p>` : '<p class="absolute-voice-live-ops__result">No live ops action has run yet.</p>';
4036
4329
  return `<section class="absolute-voice-live-ops">
4037
4330
  <header class="absolute-voice-live-ops__header">
4038
- <span>${escapeHtml5(options.title ?? "Live Ops")}</span>
4039
- <strong>${escapeHtml5(sessionId || "No active session")}</strong>
4331
+ <span>${escapeHtml6(options.title ?? "Live Ops")}</span>
4332
+ <strong>${escapeHtml6(sessionId || "No active session")}</strong>
4040
4333
  </header>
4041
- <p class="absolute-voice-live-ops__description">${escapeHtml5(options.description ?? "Pause, resume, take over, force handoff, or inject operator instructions during a live voice session.")}</p>
4042
- <label><span>Operator</span><input data-absolute-voice-live-ops-assignee value="${escapeHtml5(options.defaultAssignee ?? "operator")}" /></label>
4043
- <label><span>Tag / handoff target</span><input data-absolute-voice-live-ops-tag value="${escapeHtml5(options.defaultTag ?? "live-ops")}" /></label>
4044
- <label><span>Detail / instruction</span><input data-absolute-voice-live-ops-detail value="${escapeHtml5(options.defaultDetail ?? "Operator marked this live session.")}" /></label>
4334
+ <p class="absolute-voice-live-ops__description">${escapeHtml6(options.description ?? "Pause, resume, take over, force handoff, or inject operator instructions during a live voice session.")}</p>
4335
+ <label><span>Operator</span><input data-absolute-voice-live-ops-assignee value="${escapeHtml6(options.defaultAssignee ?? "operator")}" /></label>
4336
+ <label><span>Tag / handoff target</span><input data-absolute-voice-live-ops-tag value="${escapeHtml6(options.defaultTag ?? "live-ops")}" /></label>
4337
+ <label><span>Detail / instruction</span><input data-absolute-voice-live-ops-detail value="${escapeHtml6(options.defaultDetail ?? "Operator marked this live session.")}" /></label>
4045
4338
  <div class="absolute-voice-live-ops__actions">${actions}</div>
4046
4339
  ${result}
4047
4340
  </section>`;
@@ -4128,16 +4421,16 @@ var defineVoiceLiveOpsElement = (tagName = "absolute-voice-live-ops", options =
4128
4421
  });
4129
4422
  };
4130
4423
  // src/client/opsActionHistoryWidget.ts
4131
- var escapeHtml6 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
4424
+ var escapeHtml7 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
4132
4425
  var renderVoiceOpsActionHistoryWidgetHTML = (snapshot, options = {}) => {
4133
4426
  const report = snapshot.report;
4134
4427
  const entries = (report?.entries ?? []).slice(0, options.limit ?? 5);
4135
- const rows = entries.map((entry) => `<li class="absolute-voice-ops-action-history__entry absolute-voice-ops-action-history__entry--${entry.ok ? "success" : "error"}"><span>${escapeHtml6(entry.actionId)}</span><strong>${escapeHtml6(entry.ok ? "Success" : "Failed")}</strong><small>${escapeHtml6(new Date(entry.at).toLocaleString())}${entry.status ? ` \xB7 HTTP ${String(entry.status)}` : ""}</small></li>`).join("");
4428
+ const rows = entries.map((entry) => `<li class="absolute-voice-ops-action-history__entry absolute-voice-ops-action-history__entry--${entry.ok ? "success" : "error"}"><span>${escapeHtml7(entry.actionId)}</span><strong>${escapeHtml7(entry.ok ? "Success" : "Failed")}</strong><small>${escapeHtml7(new Date(entry.at).toLocaleString())}${entry.status ? ` \xB7 HTTP ${String(entry.status)}` : ""}</small></li>`).join("");
4136
4429
  return `<section class="absolute-voice-ops-action-history">
4137
- <header><span>Operator proof</span><strong>${escapeHtml6(options.title ?? "Action History")}</strong></header>
4430
+ <header><span>Operator proof</span><strong>${escapeHtml7(options.title ?? "Action History")}</strong></header>
4138
4431
  <p>${String(report?.total ?? 0)} action(s), ${String(report?.failed ?? 0)} failed.</p>
4139
4432
  <ul>${rows || "<li>No operator actions recorded yet.</li>"}</ul>
4140
- ${snapshot.error ? `<p class="absolute-voice-ops-action-history__error">${escapeHtml6(snapshot.error)}</p>` : ""}
4433
+ ${snapshot.error ? `<p class="absolute-voice-ops-action-history__error">${escapeHtml7(snapshot.error)}</p>` : ""}
4141
4434
  </section>`;
4142
4435
  };
4143
4436
  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}`;
@@ -4158,9 +4451,9 @@ var mountVoiceOpsActionHistory = (element, path = "/api/voice/ops-actions/histor
4158
4451
  };
4159
4452
  };
4160
4453
  // src/client/deliveryRuntimeWidget.ts
4161
- var DEFAULT_TITLE4 = "Voice Delivery Runtime";
4162
- var DEFAULT_DESCRIPTION4 = "Audit and trace delivery worker health from your AbsoluteJS voice app.";
4163
- var escapeHtml7 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
4454
+ var DEFAULT_TITLE5 = "Voice Delivery Runtime";
4455
+ var DEFAULT_DESCRIPTION5 = "Audit and trace delivery worker health from your AbsoluteJS voice app.";
4456
+ var escapeHtml8 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
4164
4457
  var createSurface = (id, summary) => {
4165
4458
  if (!summary) {
4166
4459
  return {
@@ -4194,7 +4487,7 @@ var createVoiceDeliveryRuntimeViewModel = (snapshot, options = {}) => {
4194
4487
  ];
4195
4488
  const hasWarnings = surfaces.some((surface) => surface.status === "warn");
4196
4489
  return {
4197
- description: options.description ?? DEFAULT_DESCRIPTION4,
4490
+ description: options.description ?? DEFAULT_DESCRIPTION5,
4198
4491
  error: snapshot.error,
4199
4492
  actionError: snapshot.actionError,
4200
4493
  actionStatus: snapshot.actionStatus,
@@ -4203,32 +4496,32 @@ var createVoiceDeliveryRuntimeViewModel = (snapshot, options = {}) => {
4203
4496
  label: snapshot.error ? "Unavailable" : report ? report.isRunning ? "Running" : "Stopped" : "Checking",
4204
4497
  status: snapshot.error ? "error" : report ? hasWarnings ? "warn" : "pass" : "loading",
4205
4498
  surfaces,
4206
- title: options.title ?? DEFAULT_TITLE4,
4499
+ title: options.title ?? DEFAULT_TITLE5,
4207
4500
  updatedAt: snapshot.updatedAt
4208
4501
  };
4209
4502
  };
4210
4503
  var renderVoiceDeliveryRuntimeHTML = (snapshot, options = {}) => {
4211
4504
  const model = createVoiceDeliveryRuntimeViewModel(snapshot, options);
4212
- const surfaces = model.surfaces.map((surface) => `<li class="absolute-voice-delivery-runtime__surface absolute-voice-delivery-runtime__surface--${escapeHtml7(surface.status)}">
4213
- <span>${escapeHtml7(surface.label)}</span>
4214
- <strong>${escapeHtml7(surface.detail)}</strong>
4505
+ const surfaces = model.surfaces.map((surface) => `<li class="absolute-voice-delivery-runtime__surface absolute-voice-delivery-runtime__surface--${escapeHtml8(surface.status)}">
4506
+ <span>${escapeHtml8(surface.label)}</span>
4507
+ <strong>${escapeHtml8(surface.detail)}</strong>
4215
4508
  <small>${String(surface.failed)} failed &middot; ${String(surface.deadLettered)} dead-lettered</small>
4216
4509
  </li>`).join("");
4217
4510
  const actions = options.includeActions === false ? "" : `<div class="absolute-voice-delivery-runtime__actions">
4218
4511
  <button type="button" data-absolute-voice-delivery-runtime-action="tick">${model.actionStatus === "running" ? "Working..." : "Tick workers"}</button>
4219
4512
  <button type="button" data-absolute-voice-delivery-runtime-action="requeue-dead-letters"${model.surfaces.some((surface) => surface.deadLettered > 0) ? "" : " disabled"}>Requeue dead letters</button>
4220
4513
  </div>`;
4221
- const actionError = model.actionError ? `<p class="absolute-voice-delivery-runtime__error">${escapeHtml7(model.actionError)}</p>` : "";
4222
- return `<section class="absolute-voice-delivery-runtime absolute-voice-delivery-runtime--${escapeHtml7(model.status)}">
4514
+ const actionError = model.actionError ? `<p class="absolute-voice-delivery-runtime__error">${escapeHtml8(model.actionError)}</p>` : "";
4515
+ return `<section class="absolute-voice-delivery-runtime absolute-voice-delivery-runtime--${escapeHtml8(model.status)}">
4223
4516
  <header class="absolute-voice-delivery-runtime__header">
4224
- <span class="absolute-voice-delivery-runtime__eyebrow">${escapeHtml7(model.title)}</span>
4225
- <strong class="absolute-voice-delivery-runtime__label">${escapeHtml7(model.label)}</strong>
4517
+ <span class="absolute-voice-delivery-runtime__eyebrow">${escapeHtml8(model.title)}</span>
4518
+ <strong class="absolute-voice-delivery-runtime__label">${escapeHtml8(model.label)}</strong>
4226
4519
  </header>
4227
- <p class="absolute-voice-delivery-runtime__description">${escapeHtml7(model.description)}</p>
4520
+ <p class="absolute-voice-delivery-runtime__description">${escapeHtml8(model.description)}</p>
4228
4521
  <ul class="absolute-voice-delivery-runtime__surfaces">${surfaces}</ul>
4229
4522
  ${actions}
4230
4523
  ${actionError}
4231
- ${model.error ? `<p class="absolute-voice-delivery-runtime__error">${escapeHtml7(model.error)}</p>` : ""}
4524
+ ${model.error ? `<p class="absolute-voice-delivery-runtime__error">${escapeHtml8(model.error)}</p>` : ""}
4232
4525
  </section>`;
4233
4526
  };
4234
4527
  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}`;
@@ -4364,9 +4657,9 @@ var createVoiceRoutingStatusStore = (path = "/api/routing/latest", options = {})
4364
4657
  };
4365
4658
  };
4366
4659
  // src/client/routingStatusWidget.ts
4367
- var DEFAULT_TITLE5 = "Voice Routing";
4368
- var DEFAULT_DESCRIPTION5 = "Latest provider routing decision from the self-hosted trace store.";
4369
- var escapeHtml8 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
4660
+ var DEFAULT_TITLE6 = "Voice Routing";
4661
+ var DEFAULT_DESCRIPTION6 = "Latest provider routing decision from the self-hosted trace store.";
4662
+ var escapeHtml9 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
4370
4663
  var formatValue = (value, fallback = "None") => typeof value === "string" && value.trim() ? value : typeof value === "number" && Number.isFinite(value) ? String(value) : fallback;
4371
4664
  var createVoiceRoutingStatusViewModel = (snapshot, options = {}) => {
4372
4665
  const decision = snapshot.decision;
@@ -4390,30 +4683,30 @@ var createVoiceRoutingStatusViewModel = (snapshot, options = {}) => {
4390
4683
  ] : [];
4391
4684
  return {
4392
4685
  decision,
4393
- description: options.description ?? DEFAULT_DESCRIPTION5,
4686
+ description: options.description ?? DEFAULT_DESCRIPTION6,
4394
4687
  error: snapshot.error,
4395
4688
  isLoading: snapshot.isLoading,
4396
4689
  label: snapshot.error ? "Unavailable" : decision ? `${formatValue(decision.kind).toUpperCase()} ${formatValue(decision.status, "unknown")}` : snapshot.isLoading ? "Checking" : "No routing yet",
4397
4690
  rows,
4398
4691
  status: snapshot.error ? "error" : decision ? "ready" : snapshot.isLoading ? "loading" : "empty",
4399
- title: options.title ?? DEFAULT_TITLE5,
4692
+ title: options.title ?? DEFAULT_TITLE6,
4400
4693
  updatedAt: snapshot.updatedAt
4401
4694
  };
4402
4695
  };
4403
4696
  var renderVoiceRoutingStatusHTML = (snapshot, options = {}) => {
4404
4697
  const model = createVoiceRoutingStatusViewModel(snapshot, options);
4405
4698
  const rows = model.rows.length ? `<div class="absolute-voice-routing-status__grid">${model.rows.map((row) => `<div>
4406
- <span>${escapeHtml8(row.label)}</span>
4407
- <strong>${escapeHtml8(row.value)}</strong>
4699
+ <span>${escapeHtml9(row.label)}</span>
4700
+ <strong>${escapeHtml9(row.value)}</strong>
4408
4701
  </div>`).join("")}</div>` : '<p class="absolute-voice-routing-status__empty">Start a voice session to see the selected provider.</p>';
4409
- return `<section class="absolute-voice-routing-status absolute-voice-routing-status--${escapeHtml8(model.status)}">
4702
+ return `<section class="absolute-voice-routing-status absolute-voice-routing-status--${escapeHtml9(model.status)}">
4410
4703
  <header class="absolute-voice-routing-status__header">
4411
- <span class="absolute-voice-routing-status__eyebrow">${escapeHtml8(model.title)}</span>
4412
- <strong class="absolute-voice-routing-status__label">${escapeHtml8(model.label)}</strong>
4704
+ <span class="absolute-voice-routing-status__eyebrow">${escapeHtml9(model.title)}</span>
4705
+ <strong class="absolute-voice-routing-status__label">${escapeHtml9(model.label)}</strong>
4413
4706
  </header>
4414
- <p class="absolute-voice-routing-status__description">${escapeHtml8(model.description)}</p>
4707
+ <p class="absolute-voice-routing-status__description">${escapeHtml9(model.description)}</p>
4415
4708
  ${rows}
4416
- ${model.error ? `<p class="absolute-voice-routing-status__error">${escapeHtml8(model.error)}</p>` : ""}
4709
+ ${model.error ? `<p class="absolute-voice-routing-status__error">${escapeHtml9(model.error)}</p>` : ""}
4417
4710
  </section>`;
4418
4711
  };
4419
4712
  var getVoiceRoutingStatusCSS = () => `.absolute-voice-routing-status{border:1px solid #d8d2c4;border-radius:20px;background:#fffaf0;color:#16130d;padding:18px;box-shadow:0 18px 40px rgba(47,37,18,.12);font-family:inherit}.absolute-voice-routing-status--error{border-color:#f2a7a7;background:#fff5f3}.absolute-voice-routing-status__header{align-items:start;display:flex;gap:12px;justify-content:space-between}.absolute-voice-routing-status__eyebrow{color:#73664f;font-size:12px;font-weight:800;letter-spacing:.08em;text-transform:uppercase}.absolute-voice-routing-status__label{font-size:24px;line-height:1}.absolute-voice-routing-status__description{color:#514733;margin:12px 0 0}.absolute-voice-routing-status__grid{display:grid;gap:8px;grid-template-columns:repeat(2,minmax(0,1fr));margin-top:14px}.absolute-voice-routing-status__grid div{background:#fff;border:1px solid #eee4d2;border-radius:14px;padding:10px 12px}.absolute-voice-routing-status__grid span{color:#655944;display:block;font-size:12px;margin-bottom:4px}.absolute-voice-routing-status__grid strong{overflow-wrap:anywhere}.absolute-voice-routing-status__empty{color:#655944;margin:14px 0 0}.absolute-voice-routing-status__error{color:#9f1239;font-weight:700}`;
@@ -5212,7 +5505,7 @@ var createVoiceProviderSimulationControlsStore = (options) => {
5212
5505
  };
5213
5506
  };
5214
5507
  // src/client/providerSimulationControlsWidget.ts
5215
- var escapeHtml9 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
5508
+ var escapeHtml10 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
5216
5509
  var formatKind = (kind) => (kind ?? "stt").toUpperCase();
5217
5510
  var createVoiceProviderSimulationControlsViewModel = (snapshot, options) => {
5218
5511
  const configuredProviders = options.providers.filter((provider) => provider.configured !== false);
@@ -5232,18 +5525,18 @@ var createVoiceProviderSimulationControlsViewModel = (snapshot, options) => {
5232
5525
  };
5233
5526
  var renderVoiceProviderSimulationControlsHTML = (snapshot, options) => {
5234
5527
  const model = createVoiceProviderSimulationControlsViewModel(snapshot, options);
5235
- const failureButtons = model.failureProviders.map((provider) => `<button type="button" data-voice-provider-fail="${escapeHtml9(provider.provider)}"${!model.canSimulateFailure || snapshot.isRunning ? " disabled" : ""}>Simulate ${escapeHtml9(provider.provider)} ${escapeHtml9(formatKind(options.kind))} failure</button>`).join("");
5236
- const recoveryButtons = model.providers.map((provider) => `<button type="button" data-voice-provider-recover="${escapeHtml9(provider.provider)}"${snapshot.isRunning ? " disabled" : ""}>Mark ${escapeHtml9(provider.provider)} recovered</button>`).join("");
5528
+ const failureButtons = model.failureProviders.map((provider) => `<button type="button" data-voice-provider-fail="${escapeHtml10(provider.provider)}"${!model.canSimulateFailure || snapshot.isRunning ? " disabled" : ""}>Simulate ${escapeHtml10(provider.provider)} ${escapeHtml10(formatKind(options.kind))} failure</button>`).join("");
5529
+ const recoveryButtons = model.providers.map((provider) => `<button type="button" data-voice-provider-recover="${escapeHtml10(provider.provider)}"${snapshot.isRunning ? " disabled" : ""}>Mark ${escapeHtml10(provider.provider)} recovered</button>`).join("");
5237
5530
  return `<section class="absolute-voice-provider-simulation absolute-voice-provider-simulation--${snapshot.error ? "error" : snapshot.isRunning ? "running" : "ready"}">
5238
5531
  <header class="absolute-voice-provider-simulation__header">
5239
- <span class="absolute-voice-provider-simulation__eyebrow">${escapeHtml9(model.title)}</span>
5240
- <strong class="absolute-voice-provider-simulation__label">${escapeHtml9(model.label)}</strong>
5532
+ <span class="absolute-voice-provider-simulation__eyebrow">${escapeHtml10(model.title)}</span>
5533
+ <strong class="absolute-voice-provider-simulation__label">${escapeHtml10(model.label)}</strong>
5241
5534
  </header>
5242
- <p class="absolute-voice-provider-simulation__description">${escapeHtml9(model.description)}</p>
5243
- ${model.canSimulateFailure ? "" : `<p class="absolute-voice-provider-simulation__empty">${escapeHtml9(options.fallbackRequiredMessage ?? "Configure fallback providers before simulating failure.")}</p>`}
5535
+ <p class="absolute-voice-provider-simulation__description">${escapeHtml10(model.description)}</p>
5536
+ ${model.canSimulateFailure ? "" : `<p class="absolute-voice-provider-simulation__empty">${escapeHtml10(options.fallbackRequiredMessage ?? "Configure fallback providers before simulating failure.")}</p>`}
5244
5537
  <div class="absolute-voice-provider-simulation__actions">${failureButtons}${recoveryButtons}</div>
5245
- ${snapshot.error ? `<p class="absolute-voice-provider-simulation__error">${escapeHtml9(snapshot.error)}</p>` : ""}
5246
- ${model.resultText ? `<pre class="absolute-voice-provider-simulation__result">${escapeHtml9(model.resultText)}</pre>` : ""}
5538
+ ${snapshot.error ? `<p class="absolute-voice-provider-simulation__error">${escapeHtml10(snapshot.error)}</p>` : ""}
5539
+ ${model.resultText ? `<pre class="absolute-voice-provider-simulation__result">${escapeHtml10(model.resultText)}</pre>` : ""}
5247
5540
  </section>`;
5248
5541
  };
5249
5542
  var bindVoiceProviderSimulationControls = (element, store) => {
@@ -5308,9 +5601,9 @@ var defineVoiceProviderSimulationControlsElement = (tagName = "absolute-voice-pr
5308
5601
  });
5309
5602
  };
5310
5603
  // src/client/providerStatusWidget.ts
5311
- var DEFAULT_TITLE6 = "Voice Providers";
5312
- var DEFAULT_DESCRIPTION6 = "Live provider health, fallback counts, latency, and suppression state from your self-hosted trace store.";
5313
- var escapeHtml10 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
5604
+ var DEFAULT_TITLE7 = "Voice Providers";
5605
+ var DEFAULT_DESCRIPTION7 = "Live provider health, fallback counts, latency, and suppression state from your self-hosted trace store.";
5606
+ var escapeHtml11 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
5314
5607
  var formatProvider = (provider) => provider.split(/[-_\s]+/).filter(Boolean).map((part) => `${part[0]?.toUpperCase() ?? ""}${part.slice(1)}`).join(" ") || provider;
5315
5608
  var formatStatus2 = (status) => status.split("-").map((part) => `${part[0]?.toUpperCase() ?? ""}${part.slice(1)}`).join(" ");
5316
5609
  var formatLatency = (value) => typeof value === "number" ? `${value}ms` : "No samples";
@@ -5354,37 +5647,37 @@ var createVoiceProviderStatusViewModel = (snapshot, options = {}) => {
5354
5647
  const warningCount = providers.filter((provider) => isWarningStatus(provider.status)).length;
5355
5648
  const healthyCount = providers.filter((provider) => provider.status === "healthy").length;
5356
5649
  return {
5357
- description: options.description ?? DEFAULT_DESCRIPTION6,
5650
+ description: options.description ?? DEFAULT_DESCRIPTION7,
5358
5651
  error: snapshot.error,
5359
5652
  isLoading: snapshot.isLoading,
5360
5653
  label: snapshot.error ? "Unavailable" : providers.length ? warningCount > 0 ? `${warningCount} needs attention` : `${healthyCount} healthy` : snapshot.isLoading ? "Checking" : "No provider traffic",
5361
5654
  providers,
5362
5655
  status: snapshot.error ? "error" : providers.length ? warningCount > 0 ? "warning" : "ready" : snapshot.isLoading ? "loading" : "empty",
5363
- title: options.title ?? DEFAULT_TITLE6,
5656
+ title: options.title ?? DEFAULT_TITLE7,
5364
5657
  updatedAt: snapshot.updatedAt
5365
5658
  };
5366
5659
  };
5367
5660
  var renderVoiceProviderStatusHTML = (snapshot, options = {}) => {
5368
5661
  const model = createVoiceProviderStatusViewModel(snapshot, options);
5369
- const providers = model.providers.length ? `<div class="absolute-voice-provider-status__providers">${model.providers.map((provider) => `<article class="absolute-voice-provider-status__provider absolute-voice-provider-status__provider--${escapeHtml10(provider.status)}">
5662
+ const providers = model.providers.length ? `<div class="absolute-voice-provider-status__providers">${model.providers.map((provider) => `<article class="absolute-voice-provider-status__provider absolute-voice-provider-status__provider--${escapeHtml11(provider.status)}">
5370
5663
  <header>
5371
- <strong>${escapeHtml10(provider.label)}</strong>
5372
- <span>${escapeHtml10(formatStatus2(provider.status))}</span>
5664
+ <strong>${escapeHtml11(provider.label)}</strong>
5665
+ <span>${escapeHtml11(formatStatus2(provider.status))}</span>
5373
5666
  </header>
5374
- <p>${escapeHtml10(provider.detail)}</p>
5667
+ <p>${escapeHtml11(provider.detail)}</p>
5375
5668
  <dl>${provider.rows.map((row) => `<div>
5376
- <dt>${escapeHtml10(row.label)}</dt>
5377
- <dd>${escapeHtml10(row.value)}</dd>
5669
+ <dt>${escapeHtml11(row.label)}</dt>
5670
+ <dd>${escapeHtml11(row.value)}</dd>
5378
5671
  </div>`).join("")}</dl>
5379
5672
  </article>`).join("")}</div>` : '<p class="absolute-voice-provider-status__empty">Run voice traffic to see provider health.</p>';
5380
- return `<section class="absolute-voice-provider-status absolute-voice-provider-status--${escapeHtml10(model.status)}">
5673
+ return `<section class="absolute-voice-provider-status absolute-voice-provider-status--${escapeHtml11(model.status)}">
5381
5674
  <header class="absolute-voice-provider-status__header">
5382
- <span class="absolute-voice-provider-status__eyebrow">${escapeHtml10(model.title)}</span>
5383
- <strong class="absolute-voice-provider-status__label">${escapeHtml10(model.label)}</strong>
5675
+ <span class="absolute-voice-provider-status__eyebrow">${escapeHtml11(model.title)}</span>
5676
+ <strong class="absolute-voice-provider-status__label">${escapeHtml11(model.label)}</strong>
5384
5677
  </header>
5385
- <p class="absolute-voice-provider-status__description">${escapeHtml10(model.description)}</p>
5678
+ <p class="absolute-voice-provider-status__description">${escapeHtml11(model.description)}</p>
5386
5679
  ${providers}
5387
- ${model.error ? `<p class="absolute-voice-provider-status__error">${escapeHtml10(model.error)}</p>` : ""}
5680
+ ${model.error ? `<p class="absolute-voice-provider-status__error">${escapeHtml11(model.error)}</p>` : ""}
5388
5681
  </section>`;
5389
5682
  };
5390
5683
  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}`;
@@ -5425,9 +5718,9 @@ var defineVoiceProviderStatusElement = (tagName = "absolute-voice-provider-statu
5425
5718
  });
5426
5719
  };
5427
5720
  // src/client/providerCapabilitiesWidget.ts
5428
- var DEFAULT_TITLE7 = "Provider Capabilities";
5429
- var DEFAULT_DESCRIPTION7 = "Configured, selected, and healthy voice providers for this deployment.";
5430
- var escapeHtml11 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
5721
+ var DEFAULT_TITLE8 = "Provider Capabilities";
5722
+ var DEFAULT_DESCRIPTION8 = "Configured, selected, and healthy voice providers for this deployment.";
5723
+ var escapeHtml12 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
5431
5724
  var formatProvider2 = (provider) => provider.split(/[-_\s]+/).filter(Boolean).map((part) => `${part[0]?.toUpperCase() ?? ""}${part.slice(1)}`).join(" ") || provider;
5432
5725
  var formatKind2 = (kind) => kind.toUpperCase();
5433
5726
  var formatStatus3 = (status) => status.split("-").map((part) => `${part[0]?.toUpperCase() ?? ""}${part.slice(1)}`).join(" ");
@@ -5471,36 +5764,36 @@ var createVoiceProviderCapabilitiesViewModel = (snapshot, options = {}) => {
5471
5764
  const selectedCount = snapshot.report?.selected ?? capabilities.filter((capability) => capability.selected).length;
5472
5765
  return {
5473
5766
  capabilities,
5474
- description: options.description ?? DEFAULT_DESCRIPTION7,
5767
+ description: options.description ?? DEFAULT_DESCRIPTION8,
5475
5768
  error: snapshot.error,
5476
5769
  isLoading: snapshot.isLoading,
5477
5770
  label: snapshot.error ? "Unavailable" : capabilities.length ? warningCount > 0 ? `${warningCount} needs attention` : `${selectedCount} selected` : snapshot.isLoading ? "Checking" : "No capabilities",
5478
5771
  status: snapshot.error ? "error" : capabilities.length ? warningCount > 0 ? "warning" : "ready" : snapshot.isLoading ? "loading" : "empty",
5479
- title: options.title ?? DEFAULT_TITLE7,
5772
+ title: options.title ?? DEFAULT_TITLE8,
5480
5773
  updatedAt: snapshot.updatedAt
5481
5774
  };
5482
5775
  };
5483
5776
  var renderVoiceProviderCapabilitiesHTML = (snapshot, options = {}) => {
5484
5777
  const model = createVoiceProviderCapabilitiesViewModel(snapshot, options);
5485
- 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--${escapeHtml11(capability.status)}">
5778
+ 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--${escapeHtml12(capability.status)}">
5486
5779
  <header>
5487
- <strong>${escapeHtml11(capability.label)}</strong>
5488
- <span>${escapeHtml11(formatStatus3(capability.status))}</span>
5780
+ <strong>${escapeHtml12(capability.label)}</strong>
5781
+ <span>${escapeHtml12(formatStatus3(capability.status))}</span>
5489
5782
  </header>
5490
- <p>${escapeHtml11(capability.detail)}</p>
5783
+ <p>${escapeHtml12(capability.detail)}</p>
5491
5784
  <dl>${capability.rows.map((row) => `<div>
5492
- <dt>${escapeHtml11(row.label)}</dt>
5493
- <dd>${escapeHtml11(row.value)}</dd>
5785
+ <dt>${escapeHtml12(row.label)}</dt>
5786
+ <dd>${escapeHtml12(row.value)}</dd>
5494
5787
  </div>`).join("")}</dl>
5495
5788
  </article>`).join("")}</div>` : '<p class="absolute-voice-provider-capabilities__empty">Configure provider capabilities to see deployment coverage.</p>';
5496
- return `<section class="absolute-voice-provider-capabilities absolute-voice-provider-capabilities--${escapeHtml11(model.status)}">
5789
+ return `<section class="absolute-voice-provider-capabilities absolute-voice-provider-capabilities--${escapeHtml12(model.status)}">
5497
5790
  <header class="absolute-voice-provider-capabilities__header">
5498
- <span class="absolute-voice-provider-capabilities__eyebrow">${escapeHtml11(model.title)}</span>
5499
- <strong class="absolute-voice-provider-capabilities__label">${escapeHtml11(model.label)}</strong>
5791
+ <span class="absolute-voice-provider-capabilities__eyebrow">${escapeHtml12(model.title)}</span>
5792
+ <strong class="absolute-voice-provider-capabilities__label">${escapeHtml12(model.label)}</strong>
5500
5793
  </header>
5501
- <p class="absolute-voice-provider-capabilities__description">${escapeHtml11(model.description)}</p>
5794
+ <p class="absolute-voice-provider-capabilities__description">${escapeHtml12(model.description)}</p>
5502
5795
  ${capabilities}
5503
- ${model.error ? `<p class="absolute-voice-provider-capabilities__error">${escapeHtml11(model.error)}</p>` : ""}
5796
+ ${model.error ? `<p class="absolute-voice-provider-capabilities__error">${escapeHtml12(model.error)}</p>` : ""}
5504
5797
  </section>`;
5505
5798
  };
5506
5799
  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}`;
@@ -5541,9 +5834,9 @@ var defineVoiceProviderCapabilitiesElement = (tagName = "absolute-voice-provider
5541
5834
  });
5542
5835
  };
5543
5836
  // src/client/providerContractsWidget.ts
5544
- var DEFAULT_TITLE8 = "Provider Contracts";
5545
- var DEFAULT_DESCRIPTION8 = "Production contract coverage for provider env, latency, fallback, streaming, and capabilities.";
5546
- var escapeHtml12 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
5837
+ var DEFAULT_TITLE9 = "Provider Contracts";
5838
+ var DEFAULT_DESCRIPTION9 = "Production contract coverage for provider env, latency, fallback, streaming, and capabilities.";
5839
+ var escapeHtml13 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
5547
5840
  var formatProvider3 = (provider) => provider.split(/[-_\s]+/).filter(Boolean).map((part) => `${part[0]?.toUpperCase() ?? ""}${part.slice(1)}`).join(" ") || provider;
5548
5841
  var formatStatus4 = (status) => status.split("-").map((part) => `${part[0]?.toUpperCase() ?? ""}${part.slice(1)}`).join(" ");
5549
5842
  var contractDetail = (row) => {
@@ -5575,38 +5868,38 @@ var createVoiceProviderContractsViewModel = (snapshot, options = {}) => {
5575
5868
  }));
5576
5869
  const warningCount = snapshot.report ? snapshot.report.failed + snapshot.report.warned : rows.filter((row) => row.status !== "pass").length;
5577
5870
  return {
5578
- description: options.description ?? DEFAULT_DESCRIPTION8,
5871
+ description: options.description ?? DEFAULT_DESCRIPTION9,
5579
5872
  error: snapshot.error,
5580
5873
  isLoading: snapshot.isLoading,
5581
5874
  label: snapshot.error ? "Unavailable" : rows.length ? warningCount > 0 ? `${warningCount} needs attention` : `${rows.length} passing` : snapshot.isLoading ? "Checking" : "No contracts",
5582
5875
  rows,
5583
5876
  status: snapshot.error ? "error" : rows.length ? warningCount > 0 ? "warning" : "ready" : snapshot.isLoading ? "loading" : "empty",
5584
- title: options.title ?? DEFAULT_TITLE8,
5877
+ title: options.title ?? DEFAULT_TITLE9,
5585
5878
  updatedAt: snapshot.updatedAt
5586
5879
  };
5587
5880
  };
5588
5881
  var renderVoiceProviderContractsHTML = (snapshot, options = {}) => {
5589
5882
  const model = createVoiceProviderContractsViewModel(snapshot, options);
5590
- 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--${escapeHtml12(row.status)}">
5883
+ 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--${escapeHtml13(row.status)}">
5591
5884
  <header>
5592
- <strong>${escapeHtml12(row.label)}</strong>
5593
- <span>${escapeHtml12(formatStatus4(row.status))}</span>
5885
+ <strong>${escapeHtml13(row.label)}</strong>
5886
+ <span>${escapeHtml13(formatStatus4(row.status))}</span>
5594
5887
  </header>
5595
- <p>${escapeHtml12(row.detail)}</p>
5596
- ${row.remediations.length ? `<ul class="absolute-voice-provider-contracts__remediations">${row.remediations.map((remediation) => `<li>${remediation.href ? `<a href="${escapeHtml12(remediation.href)}">${escapeHtml12(remediation.label)}</a>` : `<strong>${escapeHtml12(remediation.label)}</strong>`}<span>${escapeHtml12(remediation.detail)}</span></li>`).join("")}</ul>` : ""}
5888
+ <p>${escapeHtml13(row.detail)}</p>
5889
+ ${row.remediations.length ? `<ul class="absolute-voice-provider-contracts__remediations">${row.remediations.map((remediation) => `<li>${remediation.href ? `<a href="${escapeHtml13(remediation.href)}">${escapeHtml13(remediation.label)}</a>` : `<strong>${escapeHtml13(remediation.label)}</strong>`}<span>${escapeHtml13(remediation.detail)}</span></li>`).join("")}</ul>` : ""}
5597
5890
  <dl>${row.rows.map((item) => `<div>
5598
- <dt>${escapeHtml12(item.label)}</dt>
5599
- <dd>${escapeHtml12(item.value)}</dd>
5891
+ <dt>${escapeHtml13(item.label)}</dt>
5892
+ <dd>${escapeHtml13(item.value)}</dd>
5600
5893
  </div>`).join("")}</dl>
5601
5894
  </article>`).join("")}</div>` : '<p class="absolute-voice-provider-contracts__empty">Configure provider contracts to see production coverage.</p>';
5602
- return `<section class="absolute-voice-provider-contracts absolute-voice-provider-contracts--${escapeHtml12(model.status)}">
5895
+ return `<section class="absolute-voice-provider-contracts absolute-voice-provider-contracts--${escapeHtml13(model.status)}">
5603
5896
  <header class="absolute-voice-provider-contracts__header">
5604
- <span class="absolute-voice-provider-contracts__eyebrow">${escapeHtml12(model.title)}</span>
5605
- <strong class="absolute-voice-provider-contracts__label">${escapeHtml12(model.label)}</strong>
5897
+ <span class="absolute-voice-provider-contracts__eyebrow">${escapeHtml13(model.title)}</span>
5898
+ <strong class="absolute-voice-provider-contracts__label">${escapeHtml13(model.label)}</strong>
5606
5899
  </header>
5607
- <p class="absolute-voice-provider-contracts__description">${escapeHtml12(model.description)}</p>
5900
+ <p class="absolute-voice-provider-contracts__description">${escapeHtml13(model.description)}</p>
5608
5901
  ${rows}
5609
- ${model.error ? `<p class="absolute-voice-provider-contracts__error">${escapeHtml12(model.error)}</p>` : ""}
5902
+ ${model.error ? `<p class="absolute-voice-provider-contracts__error">${escapeHtml13(model.error)}</p>` : ""}
5610
5903
  </section>`;
5611
5904
  };
5612
5905
  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}`;
@@ -5647,9 +5940,9 @@ var defineVoiceProviderContractsElement = (tagName = "absolute-voice-provider-co
5647
5940
  });
5648
5941
  };
5649
5942
  // src/client/turnQualityWidget.ts
5650
- var DEFAULT_TITLE9 = "Turn Quality";
5651
- var DEFAULT_DESCRIPTION9 = "Per-turn STT confidence, fallback selection, corrections, and transcript coverage.";
5652
- var escapeHtml13 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
5943
+ var DEFAULT_TITLE10 = "Turn Quality";
5944
+ var DEFAULT_DESCRIPTION10 = "Per-turn STT confidence, fallback selection, corrections, and transcript coverage.";
5945
+ var escapeHtml14 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
5653
5946
  var formatConfidence = (value) => typeof value === "number" ? `${Math.round(value * 100)}%` : "n/a";
5654
5947
  var formatMaybe = (value) => value === undefined || value === "" ? "n/a" : String(value);
5655
5948
  var getTurnDetail = (turn) => {
@@ -5687,37 +5980,37 @@ var createVoiceTurnQualityViewModel = (snapshot, options = {}) => {
5687
5980
  const warningCount = snapshot.report?.warnings ?? turns.filter((turn) => turn.status === "warn").length;
5688
5981
  const failedCount = snapshot.report?.failed ?? turns.filter((turn) => turn.status === "fail").length;
5689
5982
  return {
5690
- description: options.description ?? DEFAULT_DESCRIPTION9,
5983
+ description: options.description ?? DEFAULT_DESCRIPTION10,
5691
5984
  error: snapshot.error,
5692
5985
  isLoading: snapshot.isLoading,
5693
5986
  label: snapshot.error ? "Unavailable" : turns.length ? failedCount > 0 ? `${failedCount} failed` : warningCount > 0 ? `${warningCount} warnings` : `${turns.length} healthy` : snapshot.isLoading ? "Checking" : "No turns",
5694
5987
  status: snapshot.error ? "error" : turns.length ? failedCount > 0 || warningCount > 0 ? "warning" : "ready" : snapshot.isLoading ? "loading" : "empty",
5695
- title: options.title ?? DEFAULT_TITLE9,
5988
+ title: options.title ?? DEFAULT_TITLE10,
5696
5989
  turns,
5697
5990
  updatedAt: snapshot.updatedAt
5698
5991
  };
5699
5992
  };
5700
5993
  var renderVoiceTurnQualityHTML = (snapshot, options = {}) => {
5701
5994
  const model = createVoiceTurnQualityViewModel(snapshot, options);
5702
- 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--${escapeHtml13(turn.status)}">
5995
+ 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--${escapeHtml14(turn.status)}">
5703
5996
  <header>
5704
- <strong>${escapeHtml13(turn.label)}</strong>
5705
- <span>${escapeHtml13(turn.status)}</span>
5997
+ <strong>${escapeHtml14(turn.label)}</strong>
5998
+ <span>${escapeHtml14(turn.status)}</span>
5706
5999
  </header>
5707
- <p>${escapeHtml13(turn.detail)}</p>
6000
+ <p>${escapeHtml14(turn.detail)}</p>
5708
6001
  <dl>${turn.rows.map((row) => `<div>
5709
- <dt>${escapeHtml13(row.label)}</dt>
5710
- <dd>${escapeHtml13(row.value)}</dd>
6002
+ <dt>${escapeHtml14(row.label)}</dt>
6003
+ <dd>${escapeHtml14(row.value)}</dd>
5711
6004
  </div>`).join("")}</dl>
5712
6005
  </article>`).join("")}</div>` : '<p class="absolute-voice-turn-quality__empty">Complete a voice turn to see STT quality diagnostics.</p>';
5713
- return `<section class="absolute-voice-turn-quality absolute-voice-turn-quality--${escapeHtml13(model.status)}">
6006
+ return `<section class="absolute-voice-turn-quality absolute-voice-turn-quality--${escapeHtml14(model.status)}">
5714
6007
  <header class="absolute-voice-turn-quality__header">
5715
- <span class="absolute-voice-turn-quality__eyebrow">${escapeHtml13(model.title)}</span>
5716
- <strong class="absolute-voice-turn-quality__label">${escapeHtml13(model.label)}</strong>
6008
+ <span class="absolute-voice-turn-quality__eyebrow">${escapeHtml14(model.title)}</span>
6009
+ <strong class="absolute-voice-turn-quality__label">${escapeHtml14(model.label)}</strong>
5717
6010
  </header>
5718
- <p class="absolute-voice-turn-quality__description">${escapeHtml13(model.description)}</p>
6011
+ <p class="absolute-voice-turn-quality__description">${escapeHtml14(model.description)}</p>
5719
6012
  ${turns}
5720
- ${model.error ? `<p class="absolute-voice-turn-quality__error">${escapeHtml13(model.error)}</p>` : ""}
6013
+ ${model.error ? `<p class="absolute-voice-turn-quality__error">${escapeHtml14(model.error)}</p>` : ""}
5721
6014
  </section>`;
5722
6015
  };
5723
6016
  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}`;
@@ -5758,56 +6051,56 @@ var defineVoiceTurnQualityElement = (tagName = "absolute-voice-turn-quality") =>
5758
6051
  });
5759
6052
  };
5760
6053
  // src/client/turnLatencyWidget.ts
5761
- var DEFAULT_TITLE10 = "Turn Latency";
5762
- var DEFAULT_DESCRIPTION10 = "Per-turn timing from first transcript to commit and assistant response start.";
6054
+ var DEFAULT_TITLE11 = "Turn Latency";
6055
+ var DEFAULT_DESCRIPTION11 = "Per-turn timing from first transcript to commit and assistant response start.";
5763
6056
  var DEFAULT_PROOF_LABEL = "Run latency proof";
5764
- var escapeHtml14 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
5765
- var formatMs = (value) => typeof value === "number" ? `${Math.round(value)}ms` : "n/a";
6057
+ var escapeHtml15 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
6058
+ var formatMs2 = (value) => typeof value === "number" ? `${Math.round(value)}ms` : "n/a";
5766
6059
  var createVoiceTurnLatencyViewModel = (snapshot, options = {}) => {
5767
6060
  const turns = (snapshot.report?.turns ?? []).map((turn) => ({
5768
6061
  ...turn,
5769
6062
  label: turn.text || "Empty turn",
5770
6063
  rows: turn.stages.map((stage) => ({
5771
6064
  label: stage.label,
5772
- value: formatMs(stage.valueMs)
6065
+ value: formatMs2(stage.valueMs)
5773
6066
  }))
5774
6067
  }));
5775
6068
  const warningCount = snapshot.report?.warnings ?? turns.filter((turn) => turn.status === "warn").length;
5776
6069
  const failedCount = snapshot.report?.failed ?? turns.filter((turn) => turn.status === "fail").length;
5777
6070
  return {
5778
- description: options.description ?? DEFAULT_DESCRIPTION10,
6071
+ description: options.description ?? DEFAULT_DESCRIPTION11,
5779
6072
  error: snapshot.error,
5780
6073
  isLoading: snapshot.isLoading,
5781
- label: snapshot.error ? "Unavailable" : turns.length ? failedCount > 0 ? `${failedCount} slow` : warningCount > 0 ? `${warningCount} warnings` : `avg ${formatMs(snapshot.report?.averageTotalMs)}` : snapshot.isLoading ? "Checking" : "No turns",
6074
+ label: snapshot.error ? "Unavailable" : turns.length ? failedCount > 0 ? `${failedCount} slow` : warningCount > 0 ? `${warningCount} warnings` : `avg ${formatMs2(snapshot.report?.averageTotalMs)}` : snapshot.isLoading ? "Checking" : "No turns",
5782
6075
  proofLabel: options.proofPath ? options.proofLabel ?? DEFAULT_PROOF_LABEL : undefined,
5783
6076
  showProofAction: Boolean(options.proofPath),
5784
6077
  status: snapshot.error ? "error" : turns.length ? failedCount > 0 || warningCount > 0 ? "warning" : "ready" : snapshot.isLoading ? "loading" : "empty",
5785
- title: options.title ?? DEFAULT_TITLE10,
6078
+ title: options.title ?? DEFAULT_TITLE11,
5786
6079
  turns,
5787
6080
  updatedAt: snapshot.updatedAt
5788
6081
  };
5789
6082
  };
5790
6083
  var renderVoiceTurnLatencyHTML = (snapshot, options = {}) => {
5791
6084
  const model = createVoiceTurnLatencyViewModel(snapshot, options);
5792
- const turns = model.turns.length ? `<div class="absolute-voice-turn-latency__turns">${model.turns.map((turn) => `<article class="absolute-voice-turn-latency__turn absolute-voice-turn-latency__turn--${escapeHtml14(turn.status)}">
6085
+ const turns = model.turns.length ? `<div class="absolute-voice-turn-latency__turns">${model.turns.map((turn) => `<article class="absolute-voice-turn-latency__turn absolute-voice-turn-latency__turn--${escapeHtml15(turn.status)}">
5793
6086
  <header>
5794
- <strong>${escapeHtml14(turn.label)}</strong>
5795
- <span>${escapeHtml14(turn.status)}</span>
6087
+ <strong>${escapeHtml15(turn.label)}</strong>
6088
+ <span>${escapeHtml15(turn.status)}</span>
5796
6089
  </header>
5797
6090
  <dl>${turn.rows.map((row) => `<div>
5798
- <dt>${escapeHtml14(row.label)}</dt>
5799
- <dd>${escapeHtml14(row.value)}</dd>
6091
+ <dt>${escapeHtml15(row.label)}</dt>
6092
+ <dd>${escapeHtml15(row.value)}</dd>
5800
6093
  </div>`).join("")}</dl>
5801
6094
  </article>`).join("")}</div>` : '<p class="absolute-voice-turn-latency__empty">Complete a voice turn to see latency diagnostics.</p>';
5802
- return `<section class="absolute-voice-turn-latency absolute-voice-turn-latency--${escapeHtml14(model.status)}">
6095
+ return `<section class="absolute-voice-turn-latency absolute-voice-turn-latency--${escapeHtml15(model.status)}">
5803
6096
  <header class="absolute-voice-turn-latency__header">
5804
- <span class="absolute-voice-turn-latency__eyebrow">${escapeHtml14(model.title)}</span>
5805
- <strong class="absolute-voice-turn-latency__label">${escapeHtml14(model.label)}</strong>
6097
+ <span class="absolute-voice-turn-latency__eyebrow">${escapeHtml15(model.title)}</span>
6098
+ <strong class="absolute-voice-turn-latency__label">${escapeHtml15(model.label)}</strong>
5806
6099
  </header>
5807
- <p class="absolute-voice-turn-latency__description">${escapeHtml14(model.description)}</p>
5808
- ${model.showProofAction ? `<button class="absolute-voice-turn-latency__proof" data-absolute-voice-turn-latency-proof type="button">${escapeHtml14(model.proofLabel ?? DEFAULT_PROOF_LABEL)}</button>` : ""}
6100
+ <p class="absolute-voice-turn-latency__description">${escapeHtml15(model.description)}</p>
6101
+ ${model.showProofAction ? `<button class="absolute-voice-turn-latency__proof" data-absolute-voice-turn-latency-proof type="button">${escapeHtml15(model.proofLabel ?? DEFAULT_PROOF_LABEL)}</button>` : ""}
5809
6102
  ${turns}
5810
- ${model.error ? `<p class="absolute-voice-turn-latency__error">${escapeHtml14(model.error)}</p>` : ""}
6103
+ ${model.error ? `<p class="absolute-voice-turn-latency__error">${escapeHtml15(model.error)}</p>` : ""}
5811
6104
  </section>`;
5812
6105
  };
5813
6106
  var mountVoiceTurnLatency = (element, path = "/api/turn-latency", options = {}) => {
@@ -5857,16 +6150,16 @@ var defineVoiceTurnLatencyElement = (tagName = "absolute-voice-turn-latency") =>
5857
6150
  });
5858
6151
  };
5859
6152
  // src/client/traceTimelineWidget.ts
5860
- var DEFAULT_TITLE11 = "Voice Traces";
5861
- var DEFAULT_DESCRIPTION11 = "Latest call timelines with provider latency, fallbacks, handoffs, and errors from your self-hosted trace store.";
5862
- var escapeHtml15 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
5863
- var formatMs2 = (value) => typeof value === "number" ? `${value}ms` : "n/a";
6153
+ var DEFAULT_TITLE12 = "Voice Traces";
6154
+ var DEFAULT_DESCRIPTION12 = "Latest call timelines with provider latency, fallbacks, handoffs, and errors from your self-hosted trace store.";
6155
+ var escapeHtml16 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
6156
+ var formatMs3 = (value) => typeof value === "number" ? `${value}ms` : "n/a";
5864
6157
  var formatProviders = (session) => session.providers.length ? session.providers.map((provider) => provider.provider).join(", ") : "No providers";
5865
6158
  var createVoiceTraceTimelineViewModel = (snapshot, options = {}) => {
5866
6159
  const sessions = (snapshot.report?.sessions ?? []).slice(0, options.limit ?? 3).map((session) => ({
5867
6160
  ...session,
5868
6161
  detailHref: `${options.detailBasePath ?? "/traces"}/${encodeURIComponent(session.sessionId)}`,
5869
- durationLabel: formatMs2(session.summary.callDurationMs),
6162
+ durationLabel: formatMs3(session.summary.callDurationMs),
5870
6163
  incidentBundleHref: options.incidentBundleBasePath === false ? undefined : `${options.incidentBundleBasePath ?? "/voice-incidents"}/${encodeURIComponent(session.sessionId)}/markdown`,
5871
6164
  label: `${session.summary.eventCount} events / ${session.summary.turnCount} turns`,
5872
6165
  operationsRecordHref: options.operationsRecordBasePath === false ? undefined : `${options.operationsRecordBasePath ?? "/voice-operations"}/${encodeURIComponent(session.sessionId)}`,
@@ -5875,13 +6168,13 @@ var createVoiceTraceTimelineViewModel = (snapshot, options = {}) => {
5875
6168
  const failed = sessions.filter((session) => session.status === "failed").length;
5876
6169
  const warnings = sessions.filter((session) => session.status === "warning").length;
5877
6170
  return {
5878
- description: options.description ?? DEFAULT_DESCRIPTION11,
6171
+ description: options.description ?? DEFAULT_DESCRIPTION12,
5879
6172
  error: snapshot.error,
5880
6173
  isLoading: snapshot.isLoading,
5881
6174
  label: snapshot.error ? "Unavailable" : failed > 0 ? `${failed} failed` : warnings > 0 ? `${warnings} warning` : sessions.length ? `${sessions.length} recent` : snapshot.isLoading ? "Checking" : "No traces yet",
5882
6175
  sessions,
5883
6176
  status: snapshot.error ? "error" : failed > 0 ? "failed" : warnings > 0 ? "warning" : sessions.length ? "ready" : snapshot.isLoading ? "loading" : "empty",
5884
- title: options.title ?? DEFAULT_TITLE11,
6177
+ title: options.title ?? DEFAULT_TITLE12,
5885
6178
  updatedAt: snapshot.updatedAt
5886
6179
  };
5887
6180
  };
@@ -5889,27 +6182,27 @@ var renderVoiceTraceTimelineWidgetHTML = (snapshot, options = {}) => {
5889
6182
  const model = createVoiceTraceTimelineViewModel(snapshot, options);
5890
6183
  const sessions = model.sessions.length ? `<div class="absolute-voice-trace-timeline__sessions">${model.sessions.map((session) => {
5891
6184
  const supportLinks = [
5892
- `<a href="${escapeHtml15(session.detailHref)}">Open timeline</a>`,
5893
- session.operationsRecordHref ? `<a href="${escapeHtml15(session.operationsRecordHref)}">Open operations record</a>` : undefined,
5894
- session.incidentBundleHref ? `<a href="${escapeHtml15(session.incidentBundleHref)}">Export incident bundle</a>` : undefined
6185
+ `<a href="${escapeHtml16(session.detailHref)}">Open timeline</a>`,
6186
+ session.operationsRecordHref ? `<a href="${escapeHtml16(session.operationsRecordHref)}">Open operations record</a>` : undefined,
6187
+ session.incidentBundleHref ? `<a href="${escapeHtml16(session.incidentBundleHref)}">Export incident bundle</a>` : undefined
5895
6188
  ].filter(Boolean).join("");
5896
- return `<article class="absolute-voice-trace-timeline__session absolute-voice-trace-timeline__session--${escapeHtml15(session.status)}">
6189
+ return `<article class="absolute-voice-trace-timeline__session absolute-voice-trace-timeline__session--${escapeHtml16(session.status)}">
5897
6190
  <header>
5898
- <strong>${escapeHtml15(session.sessionId)}</strong>
5899
- <span>${escapeHtml15(session.status)}</span>
6191
+ <strong>${escapeHtml16(session.sessionId)}</strong>
6192
+ <span>${escapeHtml16(session.status)}</span>
5900
6193
  </header>
5901
- <p>${escapeHtml15(session.label)} \xB7 ${escapeHtml15(session.durationLabel)} \xB7 ${escapeHtml15(session.providerLabel)}</p>
6194
+ <p>${escapeHtml16(session.label)} \xB7 ${escapeHtml16(session.durationLabel)} \xB7 ${escapeHtml16(session.providerLabel)}</p>
5902
6195
  <p class="absolute-voice-trace-timeline__actions">${supportLinks}</p>
5903
6196
  </article>`;
5904
6197
  }).join("")}</div>` : '<p class="absolute-voice-trace-timeline__empty">Run a voice session to see call timelines.</p>';
5905
- return `<section class="absolute-voice-trace-timeline absolute-voice-trace-timeline--${escapeHtml15(model.status)}">
6198
+ return `<section class="absolute-voice-trace-timeline absolute-voice-trace-timeline--${escapeHtml16(model.status)}">
5906
6199
  <header class="absolute-voice-trace-timeline__header">
5907
- <span class="absolute-voice-trace-timeline__eyebrow">${escapeHtml15(model.title)}</span>
5908
- <strong class="absolute-voice-trace-timeline__label">${escapeHtml15(model.label)}</strong>
6200
+ <span class="absolute-voice-trace-timeline__eyebrow">${escapeHtml16(model.title)}</span>
6201
+ <strong class="absolute-voice-trace-timeline__label">${escapeHtml16(model.label)}</strong>
5909
6202
  </header>
5910
- <p class="absolute-voice-trace-timeline__description">${escapeHtml15(model.description)}</p>
6203
+ <p class="absolute-voice-trace-timeline__description">${escapeHtml16(model.description)}</p>
5911
6204
  ${sessions}
5912
- ${model.error ? `<p class="absolute-voice-trace-timeline__error">${escapeHtml15(model.error)}</p>` : ""}
6205
+ ${model.error ? `<p class="absolute-voice-trace-timeline__error">${escapeHtml16(model.error)}</p>` : ""}
5913
6206
  </section>`;
5914
6207
  };
5915
6208
  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}`;
@@ -5955,9 +6248,9 @@ var defineVoiceTraceTimelineElement = (tagName = "absolute-voice-trace-timeline"
5955
6248
  });
5956
6249
  };
5957
6250
  // src/client/agentSquadStatusWidget.ts
5958
- var DEFAULT_TITLE12 = "Voice Agent Squad";
5959
- var DEFAULT_DESCRIPTION12 = "Current specialist and recent handoffs from your self-hosted voice traces.";
5960
- var escapeHtml16 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
6251
+ var DEFAULT_TITLE13 = "Voice Agent Squad";
6252
+ var DEFAULT_DESCRIPTION13 = "Current specialist and recent handoffs from your self-hosted voice traces.";
6253
+ var escapeHtml17 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
5961
6254
  var labelFor = (current) => {
5962
6255
  if (!current)
5963
6256
  return "Waiting for specialist activity";
@@ -5971,37 +6264,37 @@ var labelFor = (current) => {
5971
6264
  };
5972
6265
  var createVoiceAgentSquadStatusViewModel = (snapshot, options = {}) => ({
5973
6266
  current: snapshot.report.current,
5974
- description: options.description ?? DEFAULT_DESCRIPTION12,
6267
+ description: options.description ?? DEFAULT_DESCRIPTION13,
5975
6268
  error: snapshot.error,
5976
6269
  isLoading: snapshot.isLoading,
5977
6270
  label: snapshot.error ? "Unavailable" : labelFor(snapshot.report.current),
5978
6271
  sessionCount: snapshot.report.sessionCount,
5979
6272
  sessions: snapshot.report.sessions,
5980
- title: options.title ?? DEFAULT_TITLE12,
6273
+ title: options.title ?? DEFAULT_TITLE13,
5981
6274
  updatedAt: snapshot.updatedAt
5982
6275
  });
5983
6276
  var renderVoiceAgentSquadStatusHTML = (snapshot, options = {}) => {
5984
6277
  const model = createVoiceAgentSquadStatusViewModel(snapshot, options);
5985
6278
  const current = model.current;
5986
6279
  const rows = model.sessions.length ? model.sessions.slice(0, 5).map((session) => `<li>
5987
- <span>${escapeHtml16(session.sessionId)}</span>
5988
- <strong>${escapeHtml16(session.targetAgentId ?? "none")}</strong>
5989
- <em>${escapeHtml16(session.status)}</em>
5990
- ${session.summary || session.reason ? `<p>${escapeHtml16(session.summary ?? session.reason ?? "")}</p>` : ""}
6280
+ <span>${escapeHtml17(session.sessionId)}</span>
6281
+ <strong>${escapeHtml17(session.targetAgentId ?? "none")}</strong>
6282
+ <em>${escapeHtml17(session.status)}</em>
6283
+ ${session.summary || session.reason ? `<p>${escapeHtml17(session.summary ?? session.reason ?? "")}</p>` : ""}
5991
6284
  </li>`).join("") : "<li><span>No squad traces yet.</span><strong>Waiting</strong></li>";
5992
6285
  return `<section class="absolute-voice-agent-squad-status">
5993
6286
  <header>
5994
- <span>${escapeHtml16(model.title)}</span>
5995
- <strong>${escapeHtml16(model.label)}</strong>
6287
+ <span>${escapeHtml17(model.title)}</span>
6288
+ <strong>${escapeHtml17(model.label)}</strong>
5996
6289
  </header>
5997
- <p>${escapeHtml16(model.description)}</p>
6290
+ <p>${escapeHtml17(model.description)}</p>
5998
6291
  <div>
5999
- <span>Session</span><strong>${escapeHtml16(current?.sessionId ?? "n/a")}</strong>
6000
- <span>From</span><strong>${escapeHtml16(current?.fromAgentId ?? "n/a")}</strong>
6001
- <span>Status</span><strong>${escapeHtml16(current?.status ?? "idle")}</strong>
6292
+ <span>Session</span><strong>${escapeHtml17(current?.sessionId ?? "n/a")}</strong>
6293
+ <span>From</span><strong>${escapeHtml17(current?.fromAgentId ?? "n/a")}</strong>
6294
+ <span>Status</span><strong>${escapeHtml17(current?.status ?? "idle")}</strong>
6002
6295
  </div>
6003
6296
  <ul>${rows}</ul>
6004
- ${model.error ? `<p class="absolute-voice-agent-squad-status__error">${escapeHtml16(model.error)}</p>` : ""}
6297
+ ${model.error ? `<p class="absolute-voice-agent-squad-status__error">${escapeHtml17(model.error)}</p>` : ""}
6005
6298
  </section>`;
6006
6299
  };
6007
6300
  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}`;
@@ -6135,6 +6428,7 @@ export {
6135
6428
  renderVoiceProviderSimulationControlsHTML,
6136
6429
  renderVoiceProviderContractsHTML,
6137
6430
  renderVoiceProviderCapabilitiesHTML,
6431
+ renderVoiceProofTrendsHTML,
6138
6432
  renderVoicePlatformCoverageHTML,
6139
6433
  renderVoiceOpsStatusHTML,
6140
6434
  renderVoiceOpsActionHistoryWidgetHTML,
@@ -6152,6 +6446,7 @@ export {
6152
6446
  mountVoiceProviderSimulationControls,
6153
6447
  mountVoiceProviderContracts,
6154
6448
  mountVoiceProviderCapabilities,
6449
+ mountVoiceProofTrends,
6155
6450
  mountVoicePlatformCoverage,
6156
6451
  mountVoiceOpsStatus,
6157
6452
  mountVoiceOpsActionHistory,
@@ -6165,6 +6460,7 @@ export {
6165
6460
  getVoiceProviderStatusCSS,
6166
6461
  getVoiceProviderContractsCSS,
6167
6462
  getVoiceProviderCapabilitiesCSS,
6463
+ getVoiceProofTrendsCSS,
6168
6464
  getVoicePlatformCoverageCSS,
6169
6465
  getVoiceOpsStatusLabel,
6170
6466
  getVoiceOpsStatusCSS,
@@ -6181,6 +6477,7 @@ export {
6181
6477
  fetchVoiceProviderStatus,
6182
6478
  fetchVoiceProviderContracts,
6183
6479
  fetchVoiceProviderCapabilities,
6480
+ fetchVoiceProofTrends,
6184
6481
  fetchVoicePlatformCoverage,
6185
6482
  fetchVoiceOpsStatus,
6186
6483
  fetchVoiceOpsActionHistory,
@@ -6194,6 +6491,7 @@ export {
6194
6491
  defineVoiceProviderSimulationControlsElement,
6195
6492
  defineVoiceProviderContractsElement,
6196
6493
  defineVoiceProviderCapabilitiesElement,
6494
+ defineVoiceProofTrendsElement,
6197
6495
  defineVoicePlatformCoverageElement,
6198
6496
  defineVoiceOpsStatusElement,
6199
6497
  defineVoiceOpsActionCenterElement,
@@ -6219,6 +6517,8 @@ export {
6219
6517
  createVoiceProviderContractsStore,
6220
6518
  createVoiceProviderCapabilitiesViewModel,
6221
6519
  createVoiceProviderCapabilitiesStore,
6520
+ createVoiceProofTrendsViewModel,
6521
+ createVoiceProofTrendsStore,
6222
6522
  createVoicePlatformCoverageViewModel,
6223
6523
  createVoicePlatformCoverageStore,
6224
6524
  createVoiceOpsStatusViewModel,