@absolutejs/voice 0.0.22-beta.286 → 0.0.22-beta.288

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.
package/dist/index.js CHANGED
@@ -12790,7 +12790,76 @@ var createVoiceSloThresholdProfile = (input, options = {}) => {
12790
12790
  status: report.status
12791
12791
  };
12792
12792
  };
12793
+ var createVoiceSloReadinessThresholdOptions = (input, options = {}) => {
12794
+ const profile = "providerSlo" in input ? input : createVoiceSloThresholdProfile(input, options);
12795
+ return {
12796
+ liveLatencyFailAfterMs: profile.liveLatency.failAfterMs,
12797
+ liveLatencyWarnAfterMs: profile.liveLatency.warnAfterMs,
12798
+ monitoringNotifierDeliveryFailAfterMs: profile.monitoring.notifierDeliveryFailAfterMs,
12799
+ monitoringRunFailAfterMs: profile.monitoring.monitorRunFailAfterMs,
12800
+ reconnectResumeFailAfterMs: profile.reconnect.failAfterMs
12801
+ };
12802
+ };
12803
+ var buildVoiceSloReadinessThresholdReport = (input, options = {}) => {
12804
+ const report = Array.isArray(input) ? buildVoiceSloCalibrationReport(input, options) : ("thresholds" in input) ? input : undefined;
12805
+ const profile = report === undefined ? input : createVoiceSloThresholdProfile(report, options);
12806
+ return {
12807
+ bargeIn: profile.bargeIn,
12808
+ generatedAt: new Date().toISOString(),
12809
+ issues: profile.issues,
12810
+ liveLatencyMaxAgeMs: options.liveLatencyMaxAgeMs,
12811
+ ok: profile.status !== "fail",
12812
+ providerSlo: profile.providerSlo,
12813
+ readinessOptions: createVoiceSloReadinessThresholdOptions(profile),
12814
+ sources: report?.sources ?? [],
12815
+ status: profile.status
12816
+ };
12817
+ };
12793
12818
  var escapeMarkdown = (value) => value.replaceAll("|", "\\|");
12819
+ var escapeHtml16 = (value) => String(value).replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
12820
+ var formatMs = (value) => value === undefined ? "n/a" : `${value.toLocaleString()} ms`;
12821
+ var readinessThresholdRows = (report) => [
12822
+ {
12823
+ control: "Provider SLO p95",
12824
+ value: report.providerSlo.llm?.maxP95ElapsedMs,
12825
+ usedBy: "Provider SLO gates for STT, LLM, and TTS"
12826
+ },
12827
+ {
12828
+ control: "Live latency warn",
12829
+ value: report.readinessOptions.liveLatencyWarnAfterMs,
12830
+ usedBy: "Production readiness live latency warning gate"
12831
+ },
12832
+ {
12833
+ control: "Live latency fail",
12834
+ value: report.readinessOptions.liveLatencyFailAfterMs,
12835
+ usedBy: "Production readiness live latency fail gate"
12836
+ },
12837
+ {
12838
+ control: "Live latency freshness",
12839
+ value: report.liveLatencyMaxAgeMs,
12840
+ usedBy: "Maximum age for latency evidence before readiness ignores it"
12841
+ },
12842
+ {
12843
+ control: "Barge-in interruption",
12844
+ value: report.bargeIn.thresholdMs,
12845
+ usedBy: "Runtime interruption classification threshold"
12846
+ },
12847
+ {
12848
+ control: "Reconnect resume p95",
12849
+ value: report.readinessOptions.reconnectResumeFailAfterMs,
12850
+ usedBy: "Production readiness reconnect-resume gate"
12851
+ },
12852
+ {
12853
+ control: "Monitor run elapsed",
12854
+ value: report.readinessOptions.monitoringRunFailAfterMs,
12855
+ usedBy: "Production readiness monitoring run gate"
12856
+ },
12857
+ {
12858
+ control: "Notifier delivery elapsed",
12859
+ value: report.readinessOptions.monitoringNotifierDeliveryFailAfterMs,
12860
+ usedBy: "Production readiness notifier delivery gate"
12861
+ }
12862
+ ];
12794
12863
  var renderVoiceSloCalibrationMarkdown = (report, options = {}) => {
12795
12864
  const rows = Object.values(report.thresholds).map((threshold) => `| ${escapeMarkdown(threshold.metric)} | ${threshold.status} | ${threshold.samples} | ${threshold.baselineP95Ms ?? "n/a"} | ${threshold.warnAfterMs ?? "n/a"} | ${threshold.failAfterMs ?? "n/a"} |`).join(`
12796
12865
  `);
@@ -12812,6 +12881,37 @@ ${report.issues.map((issue) => `- ${issue}`).join(`
12812
12881
  `) || "- None"}
12813
12882
  `;
12814
12883
  };
12884
+ var renderVoiceSloReadinessThresholdMarkdown = (report, options = {}) => {
12885
+ const rows = readinessThresholdRows(report).map((row) => `| ${escapeMarkdown(row.control)} | ${formatMs(row.value)} | ${escapeMarkdown(row.usedBy)} |`).join(`
12886
+ `);
12887
+ return `# ${options.title ?? "Calibration -> Active Readiness Gate"}
12888
+
12889
+ Generated: ${report.generatedAt}
12890
+
12891
+ Status: **${report.status}**
12892
+
12893
+ | Threshold | Active value | Used by |
12894
+ | --- | ---: | --- |
12895
+ ${rows}
12896
+
12897
+ Sources:
12898
+
12899
+ ${report.sources.map((source) => `- ${source}`).join(`
12900
+ `) || "- n/a"}
12901
+
12902
+ Issues:
12903
+
12904
+ ${report.issues.map((issue) => `- ${issue}`).join(`
12905
+ `) || "- None"}
12906
+ `;
12907
+ };
12908
+ var renderVoiceSloReadinessThresholdHTML = (report, options = {}) => {
12909
+ const title = options.title ?? "Calibration -> Active Readiness Gate";
12910
+ const rows = readinessThresholdRows(report).map((row) => `<tr><td>${escapeHtml16(row.control)}</td><td>${escapeHtml16(formatMs(row.value))}</td><td>${escapeHtml16(row.usedBy)}</td></tr>`).join("");
12911
+ const issues = report.issues.length === 0 ? "<li>None</li>" : report.issues.map((issue) => `<li>${escapeHtml16(issue)}</li>`).join("");
12912
+ const sources = report.sources.length === 0 ? "<li>n/a</li>" : report.sources.map((source) => `<li><code>${escapeHtml16(source)}</code></li>`).join("");
12913
+ return `<!doctype html><html lang="en"><head><meta charset="utf-8" /><meta name="viewport" content="width=device-width,initial-scale=1" /><title>${escapeHtml16(title)}</title><style>body{background:#f8f7f2;color:#181713;font-family:ui-sans-serif,system-ui,sans-serif;line-height:1.45;margin:2rem}main{max-width:1040px;margin:auto}.summary{display:grid;gap:1rem;grid-template-columns:repeat(auto-fit,minmax(180px,1fr));margin:1rem 0}.card,table{background:white;border:1px solid #ddd6c8;border-radius:14px}.card{padding:1rem}table{border-collapse:collapse;width:100%;overflow:hidden}td,th{border-bottom:1px solid #eee8dc;padding:.7rem;text-align:left;vertical-align:top}code{white-space:pre-wrap;word-break:break-word}.status{font-size:1.6rem;font-weight:800;text-transform:uppercase}</style></head><body><main><h1>${escapeHtml16(title)}</h1><p>This page shows the calibrated thresholds currently driving production readiness gates.</p><section class="summary"><div class="card"><strong>Status</strong><br><span class="status">${escapeHtml16(report.status)}</span></div><div class="card"><strong>Live evidence max age</strong><br>${escapeHtml16(formatMs(report.liveLatencyMaxAgeMs))}</div><div class="card"><strong>Provider p95 gate</strong><br>${escapeHtml16(formatMs(report.providerSlo.llm?.maxP95ElapsedMs))}</div><div class="card"><strong>Barge-in gate</strong><br>${escapeHtml16(formatMs(report.bargeIn.thresholdMs))}</div></section><h2>Active Readiness Thresholds</h2><table><thead><tr><th>Threshold</th><th>Active value</th><th>Used by</th></tr></thead><tbody>${rows}</tbody></table><h2>Sources</h2><ul>${sources}</ul><h2>Issues</h2><ul>${issues}</ul></main></body></html>`;
12914
+ };
12815
12915
  var createVoiceSloCalibrationRoutes = (options) => {
12816
12916
  const path = options.path ?? "/api/voice/slo-calibration";
12817
12917
  const markdownPath = options.markdownPath === undefined ? "/voice/slo-calibration.md" : options.markdownPath;
@@ -12835,6 +12935,43 @@ var createVoiceSloCalibrationRoutes = (options) => {
12835
12935
  }
12836
12936
  return routes;
12837
12937
  };
12938
+ var createVoiceSloReadinessThresholdRoutes = (options) => {
12939
+ const path = options.path ?? "/api/voice/slo-readiness-thresholds";
12940
+ const htmlPath = options.htmlPath === undefined ? "/voice/slo-readiness-thresholds" : options.htmlPath;
12941
+ const markdownPath = options.markdownPath === undefined ? "/voice/slo-readiness-thresholds.md" : options.markdownPath;
12942
+ const routes = new Elysia15({
12943
+ name: options.name ?? "absolutejs-voice-slo-readiness-thresholds"
12944
+ });
12945
+ const loadReport = async () => buildVoiceSloReadinessThresholdReport(typeof options.source === "function" ? await options.source() : options.source, options);
12946
+ routes.get(path, async () => Response.json(await loadReport(), { headers: options.headers }));
12947
+ if (htmlPath !== false) {
12948
+ routes.get(htmlPath, async () => {
12949
+ const report = await loadReport();
12950
+ return new Response(renderVoiceSloReadinessThresholdHTML(report, {
12951
+ title: options.title
12952
+ }), {
12953
+ headers: {
12954
+ "content-type": "text/html; charset=utf-8",
12955
+ ...Object.fromEntries(new Headers(options.headers))
12956
+ }
12957
+ });
12958
+ });
12959
+ }
12960
+ if (markdownPath !== false) {
12961
+ routes.get(markdownPath, async () => {
12962
+ const report = await loadReport();
12963
+ return new Response(renderVoiceSloReadinessThresholdMarkdown(report, {
12964
+ title: options.title
12965
+ }), {
12966
+ headers: {
12967
+ "content-type": "text/markdown; charset=utf-8",
12968
+ ...Object.fromEntries(new Headers(options.headers))
12969
+ }
12970
+ });
12971
+ });
12972
+ }
12973
+ return routes;
12974
+ };
12838
12975
  // src/liveOps.ts
12839
12976
  import { Elysia as Elysia16 } from "elysia";
12840
12977
  var VOICE_LIVE_OPS_ACTIONS = [
@@ -13171,12 +13308,12 @@ var createVoiceLiveOpsRoutes = (options = {}) => {
13171
13308
  import { Elysia as Elysia17 } from "elysia";
13172
13309
  import { mkdir } from "fs/promises";
13173
13310
  import { dirname, join } from "path";
13174
- var escapeHtml16 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
13311
+ var escapeHtml17 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
13175
13312
  var renderSummaryCard = (label, summary) => {
13176
13313
  if (!summary) {
13177
- return `<article><span>${escapeHtml16(label)}</span><strong>Disabled</strong><p class="muted">No worker configured.</p></article>`;
13314
+ return `<article><span>${escapeHtml17(label)}</span><strong>Disabled</strong><p class="muted">No worker configured.</p></article>`;
13178
13315
  }
13179
- return `<article><span>${escapeHtml16(label)}</span><strong>${String(summary.delivered)}/${String(summary.total)}</strong><p class="muted">${String(summary.pending)} pending &middot; ${String(summary.failed)} failed &middot; ${String(summary.deadLettered)} dead-lettered</p></article>`;
13316
+ return `<article><span>${escapeHtml17(label)}</span><strong>${String(summary.delivered)}/${String(summary.total)}</strong><p class="muted">${String(summary.pending)} pending &middot; ${String(summary.failed)} failed &middot; ${String(summary.deadLettered)} dead-lettered</p></article>`;
13180
13317
  };
13181
13318
  var resolvePresetLeases = (leases) => ("claim" in leases) ? {
13182
13319
  audit: leases,
@@ -13387,9 +13524,9 @@ var buildVoiceDeliveryRuntimeReport = async (runtime) => ({
13387
13524
  });
13388
13525
  var renderVoiceDeliveryRuntimeHTML = (report, options = {}) => {
13389
13526
  const title = options.title ?? "AbsoluteJS Voice Delivery Runtime";
13390
- const tickForm = options.tickPath === false ? "" : `<form method="post" action="${escapeHtml16(options.tickPath ?? "/api/voice-delivery-runtime/tick")}"><button type="submit">Tick delivery workers</button></form>`;
13391
- const requeueForm = options.requeueDeadLettersPath === false ? "" : `<form method="post" action="${escapeHtml16(options.requeueDeadLettersPath ?? "/api/voice-delivery-runtime/requeue-dead-letters")}"><button type="submit">Requeue dead letters</button></form>`;
13392
- const snippet = escapeHtml16(`const deliveryRuntime = createVoiceDeliveryRuntime(
13527
+ const tickForm = options.tickPath === false ? "" : `<form method="post" action="${escapeHtml17(options.tickPath ?? "/api/voice-delivery-runtime/tick")}"><button type="submit">Tick delivery workers</button></form>`;
13528
+ const requeueForm = options.requeueDeadLettersPath === false ? "" : `<form method="post" action="${escapeHtml17(options.requeueDeadLettersPath ?? "/api/voice-delivery-runtime/requeue-dead-letters")}"><button type="submit">Requeue dead letters</button></form>`;
13529
+ const snippet = escapeHtml17(`const deliveryRuntime = createVoiceDeliveryRuntime(
13393
13530
  createVoiceDeliveryRuntimePresetConfig({
13394
13531
  audit: {
13395
13532
  deliveries: runtimeStorage.auditDeliveries,
@@ -13415,7 +13552,7 @@ app.use(
13415
13552
  traceDeliveries: runtimeStorage.traceDeliveries
13416
13553
  })
13417
13554
  );`);
13418
- return `<!doctype html><html lang="en"><head><meta charset="utf-8" /><meta name="viewport" content="width=device-width, initial-scale=1" /><title>${escapeHtml16(title)}</title><style>body{background:#0f1411;color:#f7f2df;font-family:ui-sans-serif,system-ui,sans-serif;margin:0}main{margin:auto;max-width:1080px;padding:32px}a{color:#86efac;text-decoration:none}.hero{background:linear-gradient(135deg,rgba(34,197,94,.18),rgba(14,165,233,.13));border:1px solid #263a30;border-radius:28px;margin-bottom:18px;padding:28px}.eyebrow{color:#86efac;font-weight:900;letter-spacing:.12em;text-transform:uppercase}h1{font-size:clamp(2.2rem,5vw,4.8rem);line-height:.92;margin:.2rem 0 1rem}.status{border:1px solid #64748b;border-radius:999px;display:inline-flex;font-weight:900;padding:8px 12px}.status.running{border-color:rgba(34,197,94,.7);color:#bbf7d0}.muted{color:#b9c3b4}.grid{display:grid;gap:14px;grid-template-columns:repeat(auto-fit,minmax(220px,1fr));margin:18px 0}article,.card{background:#151d18;border:1px solid #263a30;border-radius:22px;padding:18px}.primitive{background:#111a15;border-color:#41604a}article span{color:#b9c3b4;display:block;font-weight:800}article strong{display:block;font-size:2.3rem;margin-top:8px}.actions{display:flex;flex-wrap:wrap;gap:10px}button{background:#86efac;border:0;border-radius:999px;color:#07120b;cursor:pointer;font-weight:900;margin-top:12px;padding:10px 14px}pre{background:#09100c;border:1px solid #263a30;border-radius:18px;color:#dcfce7;overflow:auto;padding:16px}.primitive p{color:#c8d8ca;line-height:1.55}.primitive code{color:#bbf7d0}</style></head><body><main><p><a href="/delivery-sinks">Delivery sinks</a></p><section class="hero"><p class="eyebrow">Worker control plane</p><h1>${escapeHtml16(title)}</h1><p class="muted">Inspect queue summaries, manually tick failed/pending audit and trace deliveries, and requeue dead letters after operator review.</p><p class="status ${report.isRunning ? "running" : ""}">${report.isRunning ? "Running" : "Stopped"}</p><p class="muted">Checked ${escapeHtml16(new Date(report.checkedAt).toLocaleString())}</p><div class="actions">${tickForm}${requeueForm}</div></section><section class="grid">${renderSummaryCard("Audit", report.summary.audit)}${renderSummaryCard("Trace", report.summary.trace)}</section><section class="card primitive"><p class="eyebrow">Copy into your app</p><h2><code>createVoiceDeliveryRuntimeRoutes(...)</code> builds this control plane</h2><p>Own the audit and trace delivery queues in your app, mount one runtime route group, and pass the same runtime into production readiness so failed or dead-lettered exports block deploys.</p><pre><code>${snippet}</code></pre></section></main></body></html>`;
13555
+ return `<!doctype html><html lang="en"><head><meta charset="utf-8" /><meta name="viewport" content="width=device-width, initial-scale=1" /><title>${escapeHtml17(title)}</title><style>body{background:#0f1411;color:#f7f2df;font-family:ui-sans-serif,system-ui,sans-serif;margin:0}main{margin:auto;max-width:1080px;padding:32px}a{color:#86efac;text-decoration:none}.hero{background:linear-gradient(135deg,rgba(34,197,94,.18),rgba(14,165,233,.13));border:1px solid #263a30;border-radius:28px;margin-bottom:18px;padding:28px}.eyebrow{color:#86efac;font-weight:900;letter-spacing:.12em;text-transform:uppercase}h1{font-size:clamp(2.2rem,5vw,4.8rem);line-height:.92;margin:.2rem 0 1rem}.status{border:1px solid #64748b;border-radius:999px;display:inline-flex;font-weight:900;padding:8px 12px}.status.running{border-color:rgba(34,197,94,.7);color:#bbf7d0}.muted{color:#b9c3b4}.grid{display:grid;gap:14px;grid-template-columns:repeat(auto-fit,minmax(220px,1fr));margin:18px 0}article,.card{background:#151d18;border:1px solid #263a30;border-radius:22px;padding:18px}.primitive{background:#111a15;border-color:#41604a}article span{color:#b9c3b4;display:block;font-weight:800}article strong{display:block;font-size:2.3rem;margin-top:8px}.actions{display:flex;flex-wrap:wrap;gap:10px}button{background:#86efac;border:0;border-radius:999px;color:#07120b;cursor:pointer;font-weight:900;margin-top:12px;padding:10px 14px}pre{background:#09100c;border:1px solid #263a30;border-radius:18px;color:#dcfce7;overflow:auto;padding:16px}.primitive p{color:#c8d8ca;line-height:1.55}.primitive code{color:#bbf7d0}</style></head><body><main><p><a href="/delivery-sinks">Delivery sinks</a></p><section class="hero"><p class="eyebrow">Worker control plane</p><h1>${escapeHtml17(title)}</h1><p class="muted">Inspect queue summaries, manually tick failed/pending audit and trace deliveries, and requeue dead letters after operator review.</p><p class="status ${report.isRunning ? "running" : ""}">${report.isRunning ? "Running" : "Stopped"}</p><p class="muted">Checked ${escapeHtml17(new Date(report.checkedAt).toLocaleString())}</p><div class="actions">${tickForm}${requeueForm}</div></section><section class="grid">${renderSummaryCard("Audit", report.summary.audit)}${renderSummaryCard("Trace", report.summary.trace)}</section><section class="card primitive"><p class="eyebrow">Copy into your app</p><h2><code>createVoiceDeliveryRuntimeRoutes(...)</code> builds this control plane</h2><p>Own the audit and trace delivery queues in your app, mount one runtime route group, and pass the same runtime into production readiness so failed or dead-lettered exports block deploys.</p><pre><code>${snippet}</code></pre></section></main></body></html>`;
13419
13556
  };
13420
13557
  var createVoiceDeliveryRuntimeRoutes = (options) => {
13421
13558
  const path = options.path ?? "/api/voice-delivery-runtime";
@@ -13697,7 +13834,7 @@ var parseRetentionScopes = (value) => {
13697
13834
  const allowed = new Set(allRetentionScopes);
13698
13835
  return value.split(",").map((entry) => entry.trim()).filter((entry) => allowed.has(entry));
13699
13836
  };
13700
- var escapeHtml17 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
13837
+ var escapeHtml18 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
13701
13838
  var buildStorageSurfaces = (options) => [
13702
13839
  {
13703
13840
  configured: Boolean(options.session ?? options.sessions),
@@ -13934,12 +14071,12 @@ var buildVoiceDataControlReport = async (options) => {
13934
14071
  zeroRetentionAvailable: true
13935
14072
  };
13936
14073
  };
13937
- var renderDataRetentionReportRows = (report) => report.scopes.map((scope) => `<tr><td>${escapeHtml17(scope.scope)}</td><td>${scope.scannedCount}</td><td>${scope.deletedCount}</td><td>${escapeHtml17(scope.skippedReason ?? "")}</td><td><code>${escapeHtml17(scope.deletedIds.join(", "))}</code></td></tr>`).join("");
14074
+ var renderDataRetentionReportRows = (report) => report.scopes.map((scope) => `<tr><td>${escapeHtml18(scope.scope)}</td><td>${scope.scannedCount}</td><td>${scope.deletedCount}</td><td>${escapeHtml18(scope.skippedReason ?? "")}</td><td><code>${escapeHtml18(scope.deletedIds.join(", "))}</code></td></tr>`).join("");
13938
14075
  var renderVoiceDataControlHTML = (report, options = {}) => {
13939
14076
  const title = options.title ?? "Voice Data Control";
13940
- const storageRows = report.storage.map((surface) => `<tr><td>${escapeHtml17(surface.name)}</td><td>${surface.configured ? "Configured" : "Missing"}</td><td>${escapeHtml17(surface.control)}</td><td>${surface.selfHosted ? "Yes" : "No"}</td></tr>`).join("");
13941
- const keyRows = report.providerKeys.map((key) => `<tr><td>${escapeHtml17(key.name)}</td><td><code>${escapeHtml17(key.env ?? "n/a")}</code></td><td>${key.required ? "Required" : "Optional"}</td><td>${escapeHtml17(key.recommendation)}</td></tr>`).join("");
13942
- return `<!doctype html><html lang="en"><head><meta charset="utf-8" /><meta name="viewport" content="width=device-width,initial-scale=1" /><title>${escapeHtml17(title)}</title><style>body{background:#f8f7f2;color:#181713;font-family:ui-sans-serif,system-ui,sans-serif;line-height:1.45;margin:2rem}main{max-width:1120px;margin:auto}.summary{display:grid;gap:1rem;grid-template-columns:repeat(auto-fit,minmax(180px,1fr));margin:1rem 0}.card,table{background:white;border:1px solid #ddd6c8;border-radius:14px}.card{padding:1rem}table{border-collapse:collapse;width:100%;overflow:hidden}td,th{border-bottom:1px solid #eee8dc;padding:.7rem;text-align:left;vertical-align:top}code{white-space:pre-wrap;word-break:break-word}a{color:#9a3412}</style></head><body><main><h1>${escapeHtml17(title)}</h1><p>Self-hosted data-control proof for retention, redaction, audit export, deletion planning, customer-owned storage, and provider key handling.</p><section class="summary"><div class="card"><strong>Redaction</strong><br>${report.redaction.enabled ? "enabled" : "disabled"}</div><div class="card"><strong>Retention dry-run deletes</strong><br>${report.retentionPlan.deletedCount}</div><div class="card"><strong>Audit export events</strong><br>${report.auditExport?.events.length ?? 0}</div><div class="card"><strong>Zero retention recipe</strong><br>${report.zeroRetentionAvailable ? "available" : "missing"}</div></section><h2>Customer-Owned Storage</h2><table><thead><tr><th>Surface</th><th>Status</th><th>Control</th><th>Self-hosted</th></tr></thead><tbody>${storageRows}</tbody></table><h2>Retention Plan</h2><table><thead><tr><th>Scope</th><th>Scanned</th><th>Would delete</th><th>Skipped</th><th>Ids</th></tr></thead><tbody>${renderDataRetentionReportRows(report.retentionPlan)}</tbody></table><h2>Provider Keys</h2><table><thead><tr><th>Provider</th><th>Env</th><th>Required</th><th>Recommendation</th></tr></thead><tbody>${keyRows}</tbody></table><p><a href="./data-control/audit.md">Redacted audit Markdown</a> \xB7 <a href="./data-control/audit.html">Redacted audit HTML</a></p></main></body></html>`;
14077
+ const storageRows = report.storage.map((surface) => `<tr><td>${escapeHtml18(surface.name)}</td><td>${surface.configured ? "Configured" : "Missing"}</td><td>${escapeHtml18(surface.control)}</td><td>${surface.selfHosted ? "Yes" : "No"}</td></tr>`).join("");
14078
+ const keyRows = report.providerKeys.map((key) => `<tr><td>${escapeHtml18(key.name)}</td><td><code>${escapeHtml18(key.env ?? "n/a")}</code></td><td>${key.required ? "Required" : "Optional"}</td><td>${escapeHtml18(key.recommendation)}</td></tr>`).join("");
14079
+ return `<!doctype html><html lang="en"><head><meta charset="utf-8" /><meta name="viewport" content="width=device-width,initial-scale=1" /><title>${escapeHtml18(title)}</title><style>body{background:#f8f7f2;color:#181713;font-family:ui-sans-serif,system-ui,sans-serif;line-height:1.45;margin:2rem}main{max-width:1120px;margin:auto}.summary{display:grid;gap:1rem;grid-template-columns:repeat(auto-fit,minmax(180px,1fr));margin:1rem 0}.card,table{background:white;border:1px solid #ddd6c8;border-radius:14px}.card{padding:1rem}table{border-collapse:collapse;width:100%;overflow:hidden}td,th{border-bottom:1px solid #eee8dc;padding:.7rem;text-align:left;vertical-align:top}code{white-space:pre-wrap;word-break:break-word}a{color:#9a3412}</style></head><body><main><h1>${escapeHtml18(title)}</h1><p>Self-hosted data-control proof for retention, redaction, audit export, deletion planning, customer-owned storage, and provider key handling.</p><section class="summary"><div class="card"><strong>Redaction</strong><br>${report.redaction.enabled ? "enabled" : "disabled"}</div><div class="card"><strong>Retention dry-run deletes</strong><br>${report.retentionPlan.deletedCount}</div><div class="card"><strong>Audit export events</strong><br>${report.auditExport?.events.length ?? 0}</div><div class="card"><strong>Zero retention recipe</strong><br>${report.zeroRetentionAvailable ? "available" : "missing"}</div></section><h2>Customer-Owned Storage</h2><table><thead><tr><th>Surface</th><th>Status</th><th>Control</th><th>Self-hosted</th></tr></thead><tbody>${storageRows}</tbody></table><h2>Retention Plan</h2><table><thead><tr><th>Scope</th><th>Scanned</th><th>Would delete</th><th>Skipped</th><th>Ids</th></tr></thead><tbody>${renderDataRetentionReportRows(report.retentionPlan)}</tbody></table><h2>Provider Keys</h2><table><thead><tr><th>Provider</th><th>Env</th><th>Required</th><th>Recommendation</th></tr></thead><tbody>${keyRows}</tbody></table><p><a href="./data-control/audit.md">Redacted audit Markdown</a> \xB7 <a href="./data-control/audit.html">Redacted audit HTML</a></p></main></body></html>`;
13943
14080
  };
13944
14081
  var renderVoiceDataControlMarkdown = (report, options = {}) => [
13945
14082
  `# ${options.title ?? "Voice Data Control"}`,
@@ -14082,7 +14219,7 @@ import { Elysia as Elysia20 } from "elysia";
14082
14219
 
14083
14220
  // src/handoffHealth.ts
14084
14221
  import { Elysia as Elysia19 } from "elysia";
14085
- var escapeHtml18 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
14222
+ var escapeHtml19 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
14086
14223
  var getString7 = (value) => typeof value === "string" && value.length > 0 ? value : undefined;
14087
14224
  var isStatus = (value) => value === "delivered" || value === "failed" || value === "skipped";
14088
14225
  var increment3 = (record, key) => {
@@ -14200,10 +14337,10 @@ var renderActionSummary = (summary) => {
14200
14337
  return [
14201
14338
  '<section class="voice-handoff-health-columns">',
14202
14339
  "<article><h3>Actions</h3>",
14203
- actions.length === 0 ? "<p>No handoff actions yet.</p>" : `<ul>${actions.map(([action, count]) => `<li>${escapeHtml18(action)}: ${String(count)}</li>`).join("")}</ul>`,
14340
+ actions.length === 0 ? "<p>No handoff actions yet.</p>" : `<ul>${actions.map(([action, count]) => `<li>${escapeHtml19(action)}: ${String(count)}</li>`).join("")}</ul>`,
14204
14341
  "</article>",
14205
14342
  "<article><h3>Adapters</h3>",
14206
- adapters.length === 0 ? "<p>No adapter deliveries yet.</p>" : `<ul>${adapters.map(([adapterId, counts]) => `<li>${escapeHtml18(adapterId)}: ${String(counts.delivered)} delivered / ${String(counts.failed)} failed / ${String(counts.skipped)} skipped</li>`).join("")}</ul>`,
14343
+ adapters.length === 0 ? "<p>No adapter deliveries yet.</p>" : `<ul>${adapters.map(([adapterId, counts]) => `<li>${escapeHtml19(adapterId)}: ${String(counts.delivered)} delivered / ${String(counts.failed)} failed / ${String(counts.skipped)} skipped</li>`).join("")}</ul>`,
14207
14344
  "</article>",
14208
14345
  "</section>"
14209
14346
  ].join("");
@@ -14217,22 +14354,22 @@ var renderVoiceHandoffHealthHTML = (summary) => [
14217
14354
  summary.events.length === 0 ? '<p class="voice-handoff-health-empty">No handoffs found.</p>' : [
14218
14355
  '<div class="voice-handoff-health-events">',
14219
14356
  ...summary.events.map((event) => [
14220
- `<article class="${escapeHtml18(event.status)}">`,
14357
+ `<article class="${escapeHtml19(event.status)}">`,
14221
14358
  '<div class="voice-handoff-health-event-header">',
14222
- `<strong>${escapeHtml18(event.action ?? "handoff")}</strong>`,
14223
- `<span>${escapeHtml18(event.status)}</span>`,
14359
+ `<strong>${escapeHtml19(event.action ?? "handoff")}</strong>`,
14360
+ `<span>${escapeHtml19(event.status)}</span>`,
14224
14361
  "</div>",
14225
- `<p><small>${escapeHtml18(event.sessionId)}</small></p>`,
14226
- event.target ? `<p>Target: ${escapeHtml18(event.target)}</p>` : "",
14227
- event.reason ? `<p>Reason: ${escapeHtml18(event.reason)}</p>` : "",
14362
+ `<p><small>${escapeHtml19(event.sessionId)}</small></p>`,
14363
+ event.target ? `<p>Target: ${escapeHtml19(event.target)}</p>` : "",
14364
+ event.reason ? `<p>Reason: ${escapeHtml19(event.reason)}</p>` : "",
14228
14365
  event.deliveries.length ? `<ul>${event.deliveries.map((delivery) => [
14229
14366
  "<li>",
14230
- `${escapeHtml18(delivery.adapterId)}: ${escapeHtml18(delivery.status)}`,
14231
- delivery.deliveredTo ? ` to ${escapeHtml18(delivery.deliveredTo)}` : "",
14232
- delivery.error ? ` (${escapeHtml18(delivery.error)})` : "",
14367
+ `${escapeHtml19(delivery.adapterId)}: ${escapeHtml19(delivery.status)}`,
14368
+ delivery.deliveredTo ? ` to ${escapeHtml19(delivery.deliveredTo)}` : "",
14369
+ delivery.error ? ` (${escapeHtml19(delivery.error)})` : "",
14233
14370
  "</li>"
14234
14371
  ].join("")).join("")}</ul>` : "",
14235
- event.replayHref ? `<p><a href="${escapeHtml18(event.replayHref)}">Open replay</a></p>` : "",
14372
+ event.replayHref ? `<p><a href="${escapeHtml19(event.replayHref)}">Open replay</a></p>` : "",
14236
14373
  "</article>"
14237
14374
  ].join("")),
14238
14375
  "</div>"
@@ -14385,12 +14522,12 @@ var evaluateVoiceQuality = async (input) => {
14385
14522
  thresholds
14386
14523
  };
14387
14524
  };
14388
- var escapeHtml19 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
14525
+ var escapeHtml20 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
14389
14526
  var formatMetricValue = (metric) => metric.unit === "rate" ? `${(metric.actual * 100).toFixed(2)}%` : metric.unit === "ms" ? `${Math.round(metric.actual)}ms` : String(metric.actual);
14390
14527
  var formatThreshold = (metric) => metric.unit === "rate" ? `${(metric.threshold * 100).toFixed(2)}%` : metric.unit === "ms" ? `${Math.round(metric.threshold)}ms` : String(metric.threshold);
14391
14528
  var renderVoiceQualityHTML = (report, options = {}) => {
14392
- const rows = Object.entries(report.metrics).map(([key, metric]) => `<tr class="${metric.pass ? "pass" : "fail"}"><td>${escapeHtml19(metric.label)}</td><td>${escapeHtml19(formatMetricValue(metric))}</td><td>${escapeHtml19(formatThreshold(metric))}</td><td>${metric.pass ? "pass" : "fail"}</td><td><code>${escapeHtml19(key)}</code></td></tr>`).join("");
14393
- const links = options.links?.length ? `<nav>${options.links.map((link) => `<a href="${escapeHtml19(link.href)}">${escapeHtml19(link.label)}</a>`).join("")}</nav>` : "";
14529
+ const rows = Object.entries(report.metrics).map(([key, metric]) => `<tr class="${metric.pass ? "pass" : "fail"}"><td>${escapeHtml20(metric.label)}</td><td>${escapeHtml20(formatMetricValue(metric))}</td><td>${escapeHtml20(formatThreshold(metric))}</td><td>${metric.pass ? "pass" : "fail"}</td><td><code>${escapeHtml20(key)}</code></td></tr>`).join("");
14530
+ const links = options.links?.length ? `<nav>${options.links.map((link) => `<a href="${escapeHtml20(link.href)}">${escapeHtml20(link.label)}</a>`).join("")}</nav>` : "";
14394
14531
  return `<!doctype html><html lang="en"><head><meta charset="utf-8" /><meta name="viewport" content="width=device-width, initial-scale=1" /><title>AbsoluteJS Voice Quality</title><style>body{font-family:ui-sans-serif,system-ui,sans-serif;margin:2rem;background:#f8f7f2;color:#181713}main{max-width:1100px;margin:auto}nav{display:flex;flex-wrap:wrap;gap:.5rem;margin:0 0 1.25rem}nav a{background:#181713;border-radius:999px;color:white;padding:.35rem .7rem;text-decoration:none}.status{border-radius:999px;display:inline-flex;padding:.35rem .75rem;font-weight:800}.status.pass{background:#dcfce7;color:#166534}.status.fail{background:#fee2e2;color:#991b1b}table{border-collapse:collapse;width:100%;background:white;margin-top:1rem}td,th{border-bottom:1px solid #eee;padding:.75rem;text-align:left}.pass td{border-left:4px solid #16a34a}.fail td{border-left:4px solid #dc2626}code{background:#f3f4f6;padding:.15rem .3rem;border-radius:.3rem}</style></head><body><main>${links}<h1>Voice quality gates</h1><p class="status ${report.status}">${report.status}</p><p>${report.eventCount} event(s) checked.</p><table><thead><tr><th>Metric</th><th>Actual</th><th>Threshold</th><th>Status</th><th>Key</th></tr></thead><tbody>${rows}</tbody></table></main></body></html>`;
14395
14532
  };
14396
14533
  var createVoiceQualityRoutes = (options) => {
@@ -14424,7 +14561,7 @@ var createVoiceQualityRoutes = (options) => {
14424
14561
  };
14425
14562
 
14426
14563
  // src/evalRoutes.ts
14427
- var escapeHtml20 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
14564
+ var escapeHtml21 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
14428
14565
  var rate2 = (count, total) => count / Math.max(1, total);
14429
14566
  var normalizeSearchText = (value) => value.trim().toLowerCase();
14430
14567
  var getString9 = (value) => typeof value === "string" ? value : undefined;
@@ -14746,7 +14883,7 @@ var createVoiceFileScenarioFixtureStore = (filePath) => ({
14746
14883
  var formatTime = (value) => value === undefined ? "unknown" : new Date(value).toLocaleString();
14747
14884
  var formatPercent = (value) => `${(value * 100).toFixed(2)}%`;
14748
14885
  var renderVoiceEvalPrimitiveCopy = () => {
14749
- const snippet = escapeHtml20(`app.use(
14886
+ const snippet = escapeHtml21(`app.use(
14750
14887
  createVoiceEvalRoutes({
14751
14888
  path: '/evals',
14752
14889
  store: traceStore,
@@ -14767,44 +14904,44 @@ var renderVoiceEvalPrimitiveCopy = () => {
14767
14904
  };
14768
14905
  var renderVoiceEvalHTML = (report, options = {}) => {
14769
14906
  const title = options.title ?? "AbsoluteJS Voice Evals";
14770
- const links = options.links?.length ? `<nav>${options.links.map((link) => `<a href="${escapeHtml20(link.href)}">${escapeHtml20(link.label)}</a>`).join("")}</nav>` : "";
14771
- const trend = report.trend.length ? report.trend.map((bucket) => `<tr><td>${escapeHtml20(bucket.key)}</td><td>${bucket.total}</td><td>${bucket.passed}</td><td>${bucket.failed}</td></tr>`).join("") : '<tr><td colspan="4">No eval buckets yet.</td></tr>';
14907
+ const links = options.links?.length ? `<nav>${options.links.map((link) => `<a href="${escapeHtml21(link.href)}">${escapeHtml21(link.label)}</a>`).join("")}</nav>` : "";
14908
+ const trend = report.trend.length ? report.trend.map((bucket) => `<tr><td>${escapeHtml21(bucket.key)}</td><td>${bucket.total}</td><td>${bucket.passed}</td><td>${bucket.failed}</td></tr>`).join("") : '<tr><td colspan="4">No eval buckets yet.</td></tr>';
14772
14909
  const sessions = report.sessions.length ? report.sessions.map((session) => {
14773
14910
  const failedMetrics = Object.entries(session.quality.metrics).filter(([, metric]) => !metric.pass).map(([, metric]) => metric.label).join(", ");
14774
- const sessionLabel = session.operationsRecordHref ? `<a href="${escapeHtml20(session.operationsRecordHref)}">${escapeHtml20(session.sessionId)}</a>` : escapeHtml20(session.sessionId);
14775
- return `<tr class="${session.status}"><td>${sessionLabel}</td><td>${escapeHtml20(session.status)}</td><td>${session.eventCount}</td><td>${session.summary.turnCount}</td><td>${session.summary.errorCount}</td><td>${escapeHtml20(formatTime(session.endedAt))}</td><td>${escapeHtml20(failedMetrics || "none")}</td></tr>`;
14911
+ const sessionLabel = session.operationsRecordHref ? `<a href="${escapeHtml21(session.operationsRecordHref)}">${escapeHtml21(session.sessionId)}</a>` : escapeHtml21(session.sessionId);
14912
+ return `<tr class="${session.status}"><td>${sessionLabel}</td><td>${escapeHtml21(session.status)}</td><td>${session.eventCount}</td><td>${session.summary.turnCount}</td><td>${session.summary.errorCount}</td><td>${escapeHtml21(formatTime(session.endedAt))}</td><td>${escapeHtml21(failedMetrics || "none")}</td></tr>`;
14776
14913
  }).join("") : '<tr><td colspan="7">No sessions found.</td></tr>';
14777
- return `<!doctype html><html lang="en"><head><meta charset="utf-8" /><meta name="viewport" content="width=device-width, initial-scale=1" /><title>${escapeHtml20(title)}</title><style>body{font-family:ui-sans-serif,system-ui,sans-serif;margin:2rem;background:#f8f7f2;color:#181713}main{max-width:1180px;margin:auto}nav{display:flex;gap:.5rem;flex-wrap:wrap;margin-bottom:1rem}nav a{background:#181713;border-radius:999px;color:white;padding:.35rem .7rem;text-decoration:none}.eyebrow{font-size:.78rem;font-weight:900;letter-spacing:.08em;text-transform:uppercase}.status{border-radius:999px;display:inline-flex;font-weight:800;padding:.35rem .75rem}.pass{color:#166534}.fail{color:#991b1b}.status.pass{background:#dcfce7}.status.fail{background:#fee2e2}.grid{display:grid;gap:1rem;grid-template-columns:repeat(auto-fit,minmax(160px,1fr));margin:1rem 0}.card,.primitive{background:white;border:1px solid #e7e5e4;border-radius:1rem;padding:1rem}.primitive{background:#fffdf7;border-color:#d6c7a3;margin:1rem 0}.primitive p{line-height:1.55}.primitive pre{background:#181713;border-radius:.85rem;color:#fef3c7;overflow:auto;padding:1rem}.primitive code{color:#fef3c7}.card strong{display:block;font-size:2rem}table{border-collapse:collapse;background:white;width:100%;margin:1rem 0 2rem}td,th{border-bottom:1px solid #eee;padding:.75rem;text-align:left}tr.fail td{border-left:4px solid #dc2626}tr.pass td{border-left:4px solid #16a34a}</style></head><body><main>${links}<h1>${escapeHtml20(title)}</h1><p class="status ${report.status}">${report.status}</p><div class="grid"><article class="card"><span>Total</span><strong>${report.total}</strong></article><article class="card"><span>Passed</span><strong>${report.passed}</strong></article><article class="card"><span>Failed</span><strong>${report.failed}</strong></article></div>${renderVoiceEvalPrimitiveCopy()}<h2>Trend</h2><table><thead><tr><th>Day</th><th>Total</th><th>Passed</th><th>Failed</th></tr></thead><tbody>${trend}</tbody></table><h2>Session Eval Results</h2><table><thead><tr><th>Session</th><th>Status</th><th>Events</th><th>Turns</th><th>Errors</th><th>Last event</th><th>Failed metrics</th></tr></thead><tbody>${sessions}</tbody></table></main></body></html>`;
14914
+ return `<!doctype html><html lang="en"><head><meta charset="utf-8" /><meta name="viewport" content="width=device-width, initial-scale=1" /><title>${escapeHtml21(title)}</title><style>body{font-family:ui-sans-serif,system-ui,sans-serif;margin:2rem;background:#f8f7f2;color:#181713}main{max-width:1180px;margin:auto}nav{display:flex;gap:.5rem;flex-wrap:wrap;margin-bottom:1rem}nav a{background:#181713;border-radius:999px;color:white;padding:.35rem .7rem;text-decoration:none}.eyebrow{font-size:.78rem;font-weight:900;letter-spacing:.08em;text-transform:uppercase}.status{border-radius:999px;display:inline-flex;font-weight:800;padding:.35rem .75rem}.pass{color:#166534}.fail{color:#991b1b}.status.pass{background:#dcfce7}.status.fail{background:#fee2e2}.grid{display:grid;gap:1rem;grid-template-columns:repeat(auto-fit,minmax(160px,1fr));margin:1rem 0}.card,.primitive{background:white;border:1px solid #e7e5e4;border-radius:1rem;padding:1rem}.primitive{background:#fffdf7;border-color:#d6c7a3;margin:1rem 0}.primitive p{line-height:1.55}.primitive pre{background:#181713;border-radius:.85rem;color:#fef3c7;overflow:auto;padding:1rem}.primitive code{color:#fef3c7}.card strong{display:block;font-size:2rem}table{border-collapse:collapse;background:white;width:100%;margin:1rem 0 2rem}td,th{border-bottom:1px solid #eee;padding:.75rem;text-align:left}tr.fail td{border-left:4px solid #dc2626}tr.pass td{border-left:4px solid #16a34a}</style></head><body><main>${links}<h1>${escapeHtml21(title)}</h1><p class="status ${report.status}">${report.status}</p><div class="grid"><article class="card"><span>Total</span><strong>${report.total}</strong></article><article class="card"><span>Passed</span><strong>${report.passed}</strong></article><article class="card"><span>Failed</span><strong>${report.failed}</strong></article></div>${renderVoiceEvalPrimitiveCopy()}<h2>Trend</h2><table><thead><tr><th>Day</th><th>Total</th><th>Passed</th><th>Failed</th></tr></thead><tbody>${trend}</tbody></table><h2>Session Eval Results</h2><table><thead><tr><th>Session</th><th>Status</th><th>Events</th><th>Turns</th><th>Errors</th><th>Last event</th><th>Failed metrics</th></tr></thead><tbody>${sessions}</tbody></table></main></body></html>`;
14778
14915
  };
14779
14916
  var renderVoiceEvalBaselineHTML = (comparison, options = {}) => {
14780
14917
  const title = options.title ?? "AbsoluteJS Voice Eval Baseline";
14781
- const links = options.links?.length ? `<nav>${options.links.map((link) => `<a href="${escapeHtml20(link.href)}">${escapeHtml20(link.label)}</a>`).join("")}</nav>` : "";
14782
- const reasons = comparison.reasons.length ? comparison.reasons.map((reason) => `<li>${escapeHtml20(reason)}</li>`).join("") : "<li>No baseline regressions detected.</li>";
14783
- const newFailures = comparison.newFailedSessionIds.length ? comparison.newFailedSessionIds.map((id) => `<li>${escapeHtml20(id)}</li>`).join("") : "<li>none</li>";
14784
- const recovered = comparison.recoveredSessionIds.length ? comparison.recoveredSessionIds.map((id) => `<li>${escapeHtml20(id)}</li>`).join("") : "<li>none</li>";
14785
- return `<!doctype html><html lang="en"><head><meta charset="utf-8" /><meta name="viewport" content="width=device-width, initial-scale=1" /><title>${escapeHtml20(title)}</title><style>body{font-family:ui-sans-serif,system-ui,sans-serif;margin:2rem;background:#f8f7f2;color:#181713}main{max-width:1000px;margin:auto}nav{display:flex;gap:.5rem;flex-wrap:wrap;margin-bottom:1rem}nav a{background:#181713;border-radius:999px;color:white;padding:.35rem .7rem;text-decoration:none}.status{border-radius:999px;display:inline-flex;font-weight:800;padding:.35rem .75rem}.pass{background:#dcfce7;color:#166534}.fail{background:#fee2e2;color:#991b1b}.grid{display:grid;gap:1rem;grid-template-columns:repeat(auto-fit,minmax(180px,1fr));margin:1rem 0}.card{background:white;border:1px solid #e7e5e4;border-radius:1rem;padding:1rem}.card strong{display:block;font-size:2rem}section{background:white;border:1px solid #e7e5e4;border-radius:1rem;margin:1rem 0;padding:1rem}</style></head><body><main>${links}<h1>${escapeHtml20(title)}</h1><p class="status ${comparison.status}">${comparison.status}</p><div class="grid"><article class="card"><span>Baseline pass rate</span><strong>${escapeHtml20(formatPercent(comparison.baseline.passRate))}</strong></article><article class="card"><span>Current pass rate</span><strong>${escapeHtml20(formatPercent(comparison.current.passRate))}</strong></article><article class="card"><span>Failed delta</span><strong>${comparison.deltas.failed}</strong></article><article class="card"><span>Pass rate delta</span><strong>${escapeHtml20(formatPercent(comparison.deltas.passRate))}</strong></article></div><section><h2>Regression Reasons</h2><ul>${reasons}</ul></section><section><h2>New Failed Sessions</h2><ul>${newFailures}</ul></section><section><h2>Recovered Sessions</h2><ul>${recovered}</ul></section></main></body></html>`;
14918
+ const links = options.links?.length ? `<nav>${options.links.map((link) => `<a href="${escapeHtml21(link.href)}">${escapeHtml21(link.label)}</a>`).join("")}</nav>` : "";
14919
+ const reasons = comparison.reasons.length ? comparison.reasons.map((reason) => `<li>${escapeHtml21(reason)}</li>`).join("") : "<li>No baseline regressions detected.</li>";
14920
+ const newFailures = comparison.newFailedSessionIds.length ? comparison.newFailedSessionIds.map((id) => `<li>${escapeHtml21(id)}</li>`).join("") : "<li>none</li>";
14921
+ const recovered = comparison.recoveredSessionIds.length ? comparison.recoveredSessionIds.map((id) => `<li>${escapeHtml21(id)}</li>`).join("") : "<li>none</li>";
14922
+ return `<!doctype html><html lang="en"><head><meta charset="utf-8" /><meta name="viewport" content="width=device-width, initial-scale=1" /><title>${escapeHtml21(title)}</title><style>body{font-family:ui-sans-serif,system-ui,sans-serif;margin:2rem;background:#f8f7f2;color:#181713}main{max-width:1000px;margin:auto}nav{display:flex;gap:.5rem;flex-wrap:wrap;margin-bottom:1rem}nav a{background:#181713;border-radius:999px;color:white;padding:.35rem .7rem;text-decoration:none}.status{border-radius:999px;display:inline-flex;font-weight:800;padding:.35rem .75rem}.pass{background:#dcfce7;color:#166534}.fail{background:#fee2e2;color:#991b1b}.grid{display:grid;gap:1rem;grid-template-columns:repeat(auto-fit,minmax(180px,1fr));margin:1rem 0}.card{background:white;border:1px solid #e7e5e4;border-radius:1rem;padding:1rem}.card strong{display:block;font-size:2rem}section{background:white;border:1px solid #e7e5e4;border-radius:1rem;margin:1rem 0;padding:1rem}</style></head><body><main>${links}<h1>${escapeHtml21(title)}</h1><p class="status ${comparison.status}">${comparison.status}</p><div class="grid"><article class="card"><span>Baseline pass rate</span><strong>${escapeHtml21(formatPercent(comparison.baseline.passRate))}</strong></article><article class="card"><span>Current pass rate</span><strong>${escapeHtml21(formatPercent(comparison.current.passRate))}</strong></article><article class="card"><span>Failed delta</span><strong>${comparison.deltas.failed}</strong></article><article class="card"><span>Pass rate delta</span><strong>${escapeHtml21(formatPercent(comparison.deltas.passRate))}</strong></article></div><section><h2>Regression Reasons</h2><ul>${reasons}</ul></section><section><h2>New Failed Sessions</h2><ul>${newFailures}</ul></section><section><h2>Recovered Sessions</h2><ul>${recovered}</ul></section></main></body></html>`;
14786
14923
  };
14787
14924
  var renderVoiceScenarioEvalHTML = (report, options = {}) => {
14788
14925
  const title = options.title ?? "AbsoluteJS Voice Scenario Evals";
14789
- const links = options.links?.length ? `<nav>${options.links.map((link) => `<a href="${escapeHtml20(link.href)}">${escapeHtml20(link.label)}</a>`).join("")}</nav>` : "";
14926
+ const links = options.links?.length ? `<nav>${options.links.map((link) => `<a href="${escapeHtml21(link.href)}">${escapeHtml21(link.label)}</a>`).join("")}</nav>` : "";
14790
14927
  const scenarios = report.scenarios.length ? report.scenarios.map((scenario) => {
14791
- const scenarioIssues = scenario.issues.length ? `<ul>${scenario.issues.map((issue) => `<li>${escapeHtml20(issue)}</li>`).join("")}</ul>` : "";
14928
+ const scenarioIssues = scenario.issues.length ? `<ul>${scenario.issues.map((issue) => `<li>${escapeHtml21(issue)}</li>`).join("")}</ul>` : "";
14792
14929
  const sessions = scenario.sessions.length ? scenario.sessions.map((session) => {
14793
- const sessionLabel = session.operationsRecordHref ? `<a href="${escapeHtml20(session.operationsRecordHref)}">${escapeHtml20(session.sessionId)}</a>` : escapeHtml20(session.sessionId);
14794
- return `<tr class="${session.status}"><td>${sessionLabel}</td><td>${escapeHtml20(session.status)}</td><td>${session.eventCount}</td><td>${escapeHtml20(session.issues.join(", ") || "none")}</td></tr>`;
14930
+ const sessionLabel = session.operationsRecordHref ? `<a href="${escapeHtml21(session.operationsRecordHref)}">${escapeHtml21(session.sessionId)}</a>` : escapeHtml21(session.sessionId);
14931
+ return `<tr class="${session.status}"><td>${sessionLabel}</td><td>${escapeHtml21(session.status)}</td><td>${session.eventCount}</td><td>${escapeHtml21(session.issues.join(", ") || "none")}</td></tr>`;
14795
14932
  }).join("") : '<tr><td colspan="4">No matching sessions.</td></tr>';
14796
- return `<section class="scenario ${scenario.status}"><h2>${escapeHtml20(scenario.label)}</h2>${scenario.description ? `<p>${escapeHtml20(scenario.description)}</p>` : ""}<p class="status ${scenario.status}">${scenario.status}</p><p>${scenario.passed} passed, ${scenario.failed} failed, ${scenario.matchedSessions} matched.</p>${scenarioIssues}<table><thead><tr><th>Session</th><th>Status</th><th>Events</th><th>Issues</th></tr></thead><tbody>${sessions}</tbody></table></section>`;
14933
+ return `<section class="scenario ${scenario.status}"><h2>${escapeHtml21(scenario.label)}</h2>${scenario.description ? `<p>${escapeHtml21(scenario.description)}</p>` : ""}<p class="status ${scenario.status}">${scenario.status}</p><p>${scenario.passed} passed, ${scenario.failed} failed, ${scenario.matchedSessions} matched.</p>${scenarioIssues}<table><thead><tr><th>Session</th><th>Status</th><th>Events</th><th>Issues</th></tr></thead><tbody>${sessions}</tbody></table></section>`;
14797
14934
  }).join("") : "<section><p>No scenarios configured.</p></section>";
14798
- return `<!doctype html><html lang="en"><head><meta charset="utf-8" /><meta name="viewport" content="width=device-width, initial-scale=1" /><title>${escapeHtml20(title)}</title><style>body{font-family:ui-sans-serif,system-ui,sans-serif;margin:2rem;background:#f8f7f2;color:#181713}main{max-width:1180px;margin:auto}nav{display:flex;gap:.5rem;flex-wrap:wrap;margin-bottom:1rem}nav a{background:#181713;border-radius:999px;color:white;padding:.35rem .7rem;text-decoration:none}.eyebrow{font-size:.78rem;font-weight:900;letter-spacing:.08em;text-transform:uppercase}.status{border-radius:999px;display:inline-flex;font-weight:800;padding:.35rem .75rem}.status.pass{background:#dcfce7;color:#166534}.status.fail{background:#fee2e2;color:#991b1b}.grid{display:grid;gap:1rem;grid-template-columns:repeat(auto-fit,minmax(160px,1fr));margin:1rem 0}.card,section{background:white;border:1px solid #e7e5e4;border-radius:1rem;padding:1rem}.primitive{background:#fffdf7;border-color:#d6c7a3}.primitive p{line-height:1.55}.primitive pre{background:#181713;border-radius:.85rem;color:#fef3c7;overflow:auto;padding:1rem}.primitive code{color:#fef3c7}.card strong{display:block;font-size:2rem}section{margin:1rem 0}table{border-collapse:collapse;width:100%;margin-top:1rem}td,th{border-bottom:1px solid #eee;padding:.75rem;text-align:left}tr.fail td{border-left:4px solid #dc2626}tr.pass td{border-left:4px solid #16a34a}</style></head><body><main>${links}<h1>${escapeHtml20(title)}</h1><p class="status ${report.status}">${report.status}</p><div class="grid"><article class="card"><span>Total</span><strong>${report.total}</strong></article><article class="card"><span>Passed</span><strong>${report.passed}</strong></article><article class="card"><span>Failed</span><strong>${report.failed}</strong></article></div>${renderVoiceEvalPrimitiveCopy()}${scenarios}</main></body></html>`;
14935
+ return `<!doctype html><html lang="en"><head><meta charset="utf-8" /><meta name="viewport" content="width=device-width, initial-scale=1" /><title>${escapeHtml21(title)}</title><style>body{font-family:ui-sans-serif,system-ui,sans-serif;margin:2rem;background:#f8f7f2;color:#181713}main{max-width:1180px;margin:auto}nav{display:flex;gap:.5rem;flex-wrap:wrap;margin-bottom:1rem}nav a{background:#181713;border-radius:999px;color:white;padding:.35rem .7rem;text-decoration:none}.eyebrow{font-size:.78rem;font-weight:900;letter-spacing:.08em;text-transform:uppercase}.status{border-radius:999px;display:inline-flex;font-weight:800;padding:.35rem .75rem}.status.pass{background:#dcfce7;color:#166534}.status.fail{background:#fee2e2;color:#991b1b}.grid{display:grid;gap:1rem;grid-template-columns:repeat(auto-fit,minmax(160px,1fr));margin:1rem 0}.card,section{background:white;border:1px solid #e7e5e4;border-radius:1rem;padding:1rem}.primitive{background:#fffdf7;border-color:#d6c7a3}.primitive p{line-height:1.55}.primitive pre{background:#181713;border-radius:.85rem;color:#fef3c7;overflow:auto;padding:1rem}.primitive code{color:#fef3c7}.card strong{display:block;font-size:2rem}section{margin:1rem 0}table{border-collapse:collapse;width:100%;margin-top:1rem}td,th{border-bottom:1px solid #eee;padding:.75rem;text-align:left}tr.fail td{border-left:4px solid #dc2626}tr.pass td{border-left:4px solid #16a34a}</style></head><body><main>${links}<h1>${escapeHtml21(title)}</h1><p class="status ${report.status}">${report.status}</p><div class="grid"><article class="card"><span>Total</span><strong>${report.total}</strong></article><article class="card"><span>Passed</span><strong>${report.passed}</strong></article><article class="card"><span>Failed</span><strong>${report.failed}</strong></article></div>${renderVoiceEvalPrimitiveCopy()}${scenarios}</main></body></html>`;
14799
14936
  };
14800
14937
  var renderVoiceScenarioFixtureEvalHTML = (report, options = {}) => {
14801
14938
  const title = options.title ?? "AbsoluteJS Voice Fixture Evals";
14802
- const links = options.links?.length ? `<nav>${options.links.map((link) => `<a href="${escapeHtml20(link.href)}">${escapeHtml20(link.label)}</a>`).join("")}</nav>` : "";
14939
+ const links = options.links?.length ? `<nav>${options.links.map((link) => `<a href="${escapeHtml21(link.href)}">${escapeHtml21(link.label)}</a>`).join("")}</nav>` : "";
14803
14940
  const fixtures = report.fixtures.length ? report.fixtures.map((fixture) => {
14804
- const scenarios = fixture.report.scenarios.map((scenario) => `<tr class="${scenario.status}"><td>${escapeHtml20(scenario.label)}</td><td>${escapeHtml20(scenario.status)}</td><td>${scenario.matchedSessions}</td><td>${escapeHtml20([...scenario.issues, ...scenario.sessions.flatMap((session) => session.issues)].join(", ") || "none")}</td></tr>`).join("");
14805
- return `<section class="${fixture.status}"><h2>${escapeHtml20(fixture.label)}</h2>${fixture.description ? `<p>${escapeHtml20(fixture.description)}</p>` : ""}<p class="status ${fixture.status}">${fixture.status}</p><table><thead><tr><th>Scenario</th><th>Status</th><th>Sessions</th><th>Issues</th></tr></thead><tbody>${scenarios}</tbody></table></section>`;
14941
+ const scenarios = fixture.report.scenarios.map((scenario) => `<tr class="${scenario.status}"><td>${escapeHtml21(scenario.label)}</td><td>${escapeHtml21(scenario.status)}</td><td>${scenario.matchedSessions}</td><td>${escapeHtml21([...scenario.issues, ...scenario.sessions.flatMap((session) => session.issues)].join(", ") || "none")}</td></tr>`).join("");
14942
+ return `<section class="${fixture.status}"><h2>${escapeHtml21(fixture.label)}</h2>${fixture.description ? `<p>${escapeHtml21(fixture.description)}</p>` : ""}<p class="status ${fixture.status}">${fixture.status}</p><table><thead><tr><th>Scenario</th><th>Status</th><th>Sessions</th><th>Issues</th></tr></thead><tbody>${scenarios}</tbody></table></section>`;
14806
14943
  }).join("") : "<section><p>No scenario fixtures configured.</p></section>";
14807
- return `<!doctype html><html lang="en"><head><meta charset="utf-8" /><meta name="viewport" content="width=device-width, initial-scale=1" /><title>${escapeHtml20(title)}</title><style>body{font-family:ui-sans-serif,system-ui,sans-serif;margin:2rem;background:#f8f7f2;color:#181713}main{max-width:1180px;margin:auto}nav{display:flex;gap:.5rem;flex-wrap:wrap;margin-bottom:1rem}nav a{background:#181713;border-radius:999px;color:white;padding:.35rem .7rem;text-decoration:none}.eyebrow{font-size:.78rem;font-weight:900;letter-spacing:.08em;text-transform:uppercase}.status{border-radius:999px;display:inline-flex;font-weight:800;padding:.35rem .75rem}.status.pass{background:#dcfce7;color:#166534}.status.fail{background:#fee2e2;color:#991b1b}.grid{display:grid;gap:1rem;grid-template-columns:repeat(auto-fit,minmax(160px,1fr));margin:1rem 0}.card,section{background:white;border:1px solid #e7e5e4;border-radius:1rem;padding:1rem}.primitive{background:#fffdf7;border-color:#d6c7a3}.primitive p{line-height:1.55}.primitive pre{background:#181713;border-radius:.85rem;color:#fef3c7;overflow:auto;padding:1rem}.primitive code{color:#fef3c7}.card strong{display:block;font-size:2rem}section{margin:1rem 0}table{border-collapse:collapse;width:100%;margin-top:1rem}td,th{border-bottom:1px solid #eee;padding:.75rem;text-align:left}tr.fail td{border-left:4px solid #dc2626}tr.pass td{border-left:4px solid #16a34a}</style></head><body><main>${links}<h1>${escapeHtml20(title)}</h1><p class="status ${report.status}">${report.status}</p><div class="grid"><article class="card"><span>Total</span><strong>${report.total}</strong></article><article class="card"><span>Passed</span><strong>${report.passed}</strong></article><article class="card"><span>Failed</span><strong>${report.failed}</strong></article></div>${renderVoiceEvalPrimitiveCopy()}${fixtures}</main></body></html>`;
14944
+ return `<!doctype html><html lang="en"><head><meta charset="utf-8" /><meta name="viewport" content="width=device-width, initial-scale=1" /><title>${escapeHtml21(title)}</title><style>body{font-family:ui-sans-serif,system-ui,sans-serif;margin:2rem;background:#f8f7f2;color:#181713}main{max-width:1180px;margin:auto}nav{display:flex;gap:.5rem;flex-wrap:wrap;margin-bottom:1rem}nav a{background:#181713;border-radius:999px;color:white;padding:.35rem .7rem;text-decoration:none}.eyebrow{font-size:.78rem;font-weight:900;letter-spacing:.08em;text-transform:uppercase}.status{border-radius:999px;display:inline-flex;font-weight:800;padding:.35rem .75rem}.status.pass{background:#dcfce7;color:#166534}.status.fail{background:#fee2e2;color:#991b1b}.grid{display:grid;gap:1rem;grid-template-columns:repeat(auto-fit,minmax(160px,1fr));margin:1rem 0}.card,section{background:white;border:1px solid #e7e5e4;border-radius:1rem;padding:1rem}.primitive{background:#fffdf7;border-color:#d6c7a3}.primitive p{line-height:1.55}.primitive pre{background:#181713;border-radius:.85rem;color:#fef3c7;overflow:auto;padding:1rem}.primitive code{color:#fef3c7}.card strong{display:block;font-size:2rem}section{margin:1rem 0}table{border-collapse:collapse;width:100%;margin-top:1rem}td,th{border-bottom:1px solid #eee;padding:.75rem;text-align:left}tr.fail td{border-left:4px solid #dc2626}tr.pass td{border-left:4px solid #16a34a}</style></head><body><main>${links}<h1>${escapeHtml21(title)}</h1><p class="status ${report.status}">${report.status}</p><div class="grid"><article class="card"><span>Total</span><strong>${report.total}</strong></article><article class="card"><span>Passed</span><strong>${report.passed}</strong></article><article class="card"><span>Failed</span><strong>${report.failed}</strong></article></div>${renderVoiceEvalPrimitiveCopy()}${fixtures}</main></body></html>`;
14808
14945
  };
14809
14946
  var createVoiceEvalRoutes = (options) => {
14810
14947
  const path = options.path ?? "/evals";
@@ -14949,7 +15086,7 @@ import { Elysia as Elysia24 } from "elysia";
14949
15086
 
14950
15087
  // src/outcomeContract.ts
14951
15088
  import { Elysia as Elysia22 } from "elysia";
14952
- var escapeHtml21 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
15089
+ var escapeHtml22 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
14953
15090
  var resolveSessionHref2 = (value, sessionId) => {
14954
15091
  if (value === false) {
14955
15092
  return;
@@ -15160,13 +15297,13 @@ var assertVoiceOutcomeContractEvidence = (report, input = {}) => {
15160
15297
  var renderVoiceOutcomeContractHTML = (report, options = {}) => {
15161
15298
  const title = options.title ?? "Voice Outcome Contracts";
15162
15299
  const contracts = report.contracts.map((contract) => {
15163
- const sessionLinks = contract.operationsRecordHrefs.length ? `<p>${contract.operationsRecordHrefs.map((href, index) => `<a href="${escapeHtml21(href)}">${escapeHtml21(contract.sessionIds[index] ?? href)}</a>`).join(" \xB7 ")}</p>` : "";
15300
+ const sessionLinks = contract.operationsRecordHrefs.length ? `<p>${contract.operationsRecordHrefs.map((href, index) => `<a href="${escapeHtml22(href)}">${escapeHtml22(contract.sessionIds[index] ?? href)}</a>`).join(" \xB7 ")}</p>` : "";
15164
15301
  return `<section class="contract ${contract.pass ? "pass" : "fail"}">
15165
15302
  <div class="contract-header">
15166
15303
  <div>
15167
- <p class="eyebrow">${escapeHtml21(contract.contractId)}</p>
15168
- <h2>${escapeHtml21(contract.label ?? contract.contractId)}</h2>
15169
- ${contract.description ? `<p>${escapeHtml21(contract.description)}</p>` : ""}
15304
+ <p class="eyebrow">${escapeHtml22(contract.contractId)}</p>
15305
+ <h2>${escapeHtml22(contract.label ?? contract.contractId)}</h2>
15306
+ ${contract.description ? `<p>${escapeHtml22(contract.description)}</p>` : ""}
15170
15307
  ${sessionLinks}
15171
15308
  </div>
15172
15309
  <strong>${contract.pass ? "pass" : "fail"}</strong>
@@ -15178,10 +15315,10 @@ var renderVoiceOutcomeContractHTML = (report, options = {}) => {
15178
15315
  <span>handoffs ${String(contract.matched.handoffs)}</span>
15179
15316
  <span>events ${String(contract.matched.integrationEvents)}</span>
15180
15317
  </div>
15181
- ${contract.issues.length ? `<ul>${contract.issues.map((issue) => `<li>${escapeHtml21(issue.message)}</li>`).join("")}</ul>` : ""}
15318
+ ${contract.issues.length ? `<ul>${contract.issues.map((issue) => `<li>${escapeHtml22(issue.message)}</li>`).join("")}</ul>` : ""}
15182
15319
  </section>`;
15183
15320
  }).join("");
15184
- return `<!doctype html><html lang="en"><head><meta charset="utf-8" /><meta name="viewport" content="width=device-width, initial-scale=1" /><title>${escapeHtml21(title)}</title><style>body{background:#101316;color:#f6f2e8;font-family:ui-sans-serif,system-ui,sans-serif;margin:0}main{margin:auto;max-width:1180px;padding:32px}.hero,.contract{background:#181d22;border:1px solid #2a323a;border-radius:20px;margin-bottom:16px;padding:20px}.hero{background:linear-gradient(135deg,rgba(34,197,94,.14),rgba(14,165,233,.12))}.eyebrow{color:#7dd3fc;font-size:.78rem;font-weight:900;letter-spacing:.08em;text-transform:uppercase}h1{font-size:clamp(2.3rem,6vw,5rem);letter-spacing:-.06em;line-height:.9;margin:.2rem 0 1rem}h2{margin:.2rem 0}.summary,.grid{display:flex;flex-wrap:wrap;gap:10px}.pill,.grid span{background:#0f1217;border:1px solid #3f3f46;border-radius:999px;padding:7px 10px}.contract-header{display:flex;gap:16px;justify-content:space-between}.pass{color:#86efac}.fail{color:#fca5a5}.contract.fail{border-color:rgba(248,113,113,.45)}li{margin:8px 0}@media(max-width:800px){main{padding:18px}.contract-header{display:block}}</style></head><body><main><section class="hero"><p class="eyebrow">Business Outcome Verification</p><h1>${escapeHtml21(title)}</h1><div class="summary"><span class="pill ${report.status}">${report.status}</span><span class="pill">${String(report.passed)} passing</span><span class="pill">${String(report.failed)} failing</span><span class="pill">${String(report.total)} contracts</span></div></section>${contracts || '<section class="contract"><p>No outcome contracts configured.</p></section>'}</main></body></html>`;
15321
+ return `<!doctype html><html lang="en"><head><meta charset="utf-8" /><meta name="viewport" content="width=device-width, initial-scale=1" /><title>${escapeHtml22(title)}</title><style>body{background:#101316;color:#f6f2e8;font-family:ui-sans-serif,system-ui,sans-serif;margin:0}main{margin:auto;max-width:1180px;padding:32px}.hero,.contract{background:#181d22;border:1px solid #2a323a;border-radius:20px;margin-bottom:16px;padding:20px}.hero{background:linear-gradient(135deg,rgba(34,197,94,.14),rgba(14,165,233,.12))}.eyebrow{color:#7dd3fc;font-size:.78rem;font-weight:900;letter-spacing:.08em;text-transform:uppercase}h1{font-size:clamp(2.3rem,6vw,5rem);letter-spacing:-.06em;line-height:.9;margin:.2rem 0 1rem}h2{margin:.2rem 0}.summary,.grid{display:flex;flex-wrap:wrap;gap:10px}.pill,.grid span{background:#0f1217;border:1px solid #3f3f46;border-radius:999px;padding:7px 10px}.contract-header{display:flex;gap:16px;justify-content:space-between}.pass{color:#86efac}.fail{color:#fca5a5}.contract.fail{border-color:rgba(248,113,113,.45)}li{margin:8px 0}@media(max-width:800px){main{padding:18px}.contract-header{display:block}}</style></head><body><main><section class="hero"><p class="eyebrow">Business Outcome Verification</p><h1>${escapeHtml22(title)}</h1><div class="summary"><span class="pill ${report.status}">${report.status}</span><span class="pill">${String(report.passed)} passing</span><span class="pill">${String(report.failed)} failing</span><span class="pill">${String(report.total)} contracts</span></div></section>${contracts || '<section class="contract"><p>No outcome contracts configured.</p></section>'}</main></body></html>`;
15185
15322
  };
15186
15323
  var createVoiceOutcomeContractJSONHandler = (options) => async () => runVoiceOutcomeContractSuite(options);
15187
15324
  var createVoiceOutcomeContractHTMLHandler = (options) => async () => {
@@ -15416,7 +15553,7 @@ var createDefaultTurn = (caseId) => ({
15416
15553
  });
15417
15554
  var defaultApi = {};
15418
15555
  var sameJSON = (left, right) => JSON.stringify(left) === JSON.stringify(right);
15419
- var escapeHtml22 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
15556
+ var escapeHtml23 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
15420
15557
  var resolveSessionHref3 = (value, sessionId) => {
15421
15558
  if (value === false) {
15422
15559
  return;
@@ -15665,7 +15802,7 @@ var assertVoiceToolContractEvidence = (report, input = {}) => {
15665
15802
  };
15666
15803
  var renderVoiceToolContractHTML = (report, options = {}) => {
15667
15804
  const title = options.title ?? "Voice Tool Contracts";
15668
- const snippet = escapeHtml22(`app.use(
15805
+ const snippet = escapeHtml23(`app.use(
15669
15806
  createVoiceToolContractRoutes({
15670
15807
  htmlPath: '/tool-contracts',
15671
15808
  path: '/api/tool-contracts',
@@ -15691,20 +15828,20 @@ var renderVoiceToolContractHTML = (report, options = {}) => {
15691
15828
  );`);
15692
15829
  const contracts = report.contracts.map((contract) => {
15693
15830
  const cases = contract.cases.map((testCase) => `<tr>
15694
- <td>${testCase.operationsRecordHref ? `<a href="${escapeHtml22(testCase.operationsRecordHref)}">${escapeHtml22(testCase.label ?? testCase.caseId)}</a>` : escapeHtml22(testCase.label ?? testCase.caseId)}</td>
15831
+ <td>${testCase.operationsRecordHref ? `<a href="${escapeHtml23(testCase.operationsRecordHref)}">${escapeHtml23(testCase.label ?? testCase.caseId)}</a>` : escapeHtml23(testCase.label ?? testCase.caseId)}</td>
15695
15832
  <td class="${testCase.pass ? "pass" : "fail"}">${testCase.pass ? "pass" : "fail"}</td>
15696
- <td>${escapeHtml22(testCase.status)}</td>
15697
- <td>${escapeHtml22(testCase.sessionId)}</td>
15833
+ <td>${escapeHtml23(testCase.status)}</td>
15834
+ <td>${escapeHtml23(testCase.sessionId)}</td>
15698
15835
  <td>${String(testCase.attempts)}</td>
15699
15836
  <td>${String(testCase.elapsedMs)}ms</td>
15700
15837
  <td>${testCase.timedOut ? "yes" : "no"}</td>
15701
- <td>${escapeHtml22(testCase.issues.map((issue) => issue.message).join(" ") || testCase.error || "")}</td>
15838
+ <td>${escapeHtml23(testCase.issues.map((issue) => issue.message).join(" ") || testCase.error || "")}</td>
15702
15839
  </tr>`).join("");
15703
15840
  return `<section class="contract ${contract.pass ? "pass" : "fail"}">
15704
15841
  <div class="contract-header">
15705
15842
  <div>
15706
- <p class="eyebrow">${escapeHtml22(contract.toolName)}</p>
15707
- <h2>${escapeHtml22(contract.label ?? contract.contractId)}</h2>
15843
+ <p class="eyebrow">${escapeHtml23(contract.toolName)}</p>
15844
+ <h2>${escapeHtml23(contract.label ?? contract.contractId)}</h2>
15708
15845
  </div>
15709
15846
  <strong class="${contract.pass ? "pass" : "fail"}">${contract.pass ? "Passing" : "Failing"}</strong>
15710
15847
  </div>
@@ -15714,7 +15851,7 @@ var renderVoiceToolContractHTML = (report, options = {}) => {
15714
15851
  </table>
15715
15852
  </section>`;
15716
15853
  }).join("");
15717
- return `<!doctype html><html lang="en"><head><meta charset="utf-8" /><meta name="viewport" content="width=device-width, initial-scale=1" /><title>${escapeHtml22(title)}</title><style>body{background:#101316;color:#f6f2e8;font-family:ui-sans-serif,system-ui,sans-serif;margin:0}main{margin:auto;max-width:1180px;padding:32px}.hero,.primitive,.contract{background:#181d22;border:1px solid #2a323a;border-radius:20px;margin-bottom:16px;padding:20px}.hero{background:linear-gradient(135deg,rgba(34,197,94,.14),rgba(245,158,11,.12))}.primitive{background:#151b20;border-color:#5a4421}.eyebrow{color:#fbbf24;font-size:.78rem;font-weight:900;letter-spacing:.08em;text-transform:uppercase}h1{font-size:clamp(2.3rem,6vw,5rem);letter-spacing:-.06em;line-height:.9;margin:.2rem 0 1rem}.summary{display:flex;flex-wrap:wrap;gap:10px}.pill{background:#0f1217;border:1px solid #3f3f46;border-radius:999px;padding:7px 10px}.contract-header{align-items:flex-start;display:flex;gap:16px;justify-content:space-between}h2{margin:.2rem 0 1rem}.pass{color:#86efac}.fail{color:#fca5a5}.contract.fail{border-color:rgba(248,113,113,.45)}.primitive p{color:#d8dee6;line-height:1.55}.primitive pre{background:#0f1217;border:1px solid #2a323a;border-radius:16px;color:#fef3c7;overflow:auto;padding:14px}.primitive code{color:#fef3c7}table{border-collapse:collapse;width:100%}td,th{border-bottom:1px solid #2a323a;padding:12px;text-align:left;vertical-align:top}th{color:#a8b0b8;font-size:.82rem}@media(max-width:800px){main{padding:18px}table{display:block;overflow:auto}.contract-header{display:block}}</style></head><body><main><section class="hero"><p class="eyebrow">Tool Reliability</p><h1>${escapeHtml22(title)}</h1><div class="summary"><span class="pill ${report.status === "pass" ? "pass" : "fail"}">${escapeHtml22(report.status)}</span><span class="pill">${String(report.passed)} passing</span><span class="pill">${String(report.failed)} failing</span><span class="pill">${String(report.total)} contracts</span></div></section><section class="primitive"><p class="eyebrow">Copy into your app</p><h2><code>createVoiceToolContractRoutes(...)</code> certifies tool behavior</h2><p>Define deterministic tool cases for retries, idempotency, timeouts, result shape, and error handling so assistant tools fail in pre-production instead of live calls.</p><pre><code>${snippet}</code></pre></section>${contracts || '<section class="contract"><p>No tool contracts configured.</p></section>'}</main></body></html>`;
15854
+ return `<!doctype html><html lang="en"><head><meta charset="utf-8" /><meta name="viewport" content="width=device-width, initial-scale=1" /><title>${escapeHtml23(title)}</title><style>body{background:#101316;color:#f6f2e8;font-family:ui-sans-serif,system-ui,sans-serif;margin:0}main{margin:auto;max-width:1180px;padding:32px}.hero,.primitive,.contract{background:#181d22;border:1px solid #2a323a;border-radius:20px;margin-bottom:16px;padding:20px}.hero{background:linear-gradient(135deg,rgba(34,197,94,.14),rgba(245,158,11,.12))}.primitive{background:#151b20;border-color:#5a4421}.eyebrow{color:#fbbf24;font-size:.78rem;font-weight:900;letter-spacing:.08em;text-transform:uppercase}h1{font-size:clamp(2.3rem,6vw,5rem);letter-spacing:-.06em;line-height:.9;margin:.2rem 0 1rem}.summary{display:flex;flex-wrap:wrap;gap:10px}.pill{background:#0f1217;border:1px solid #3f3f46;border-radius:999px;padding:7px 10px}.contract-header{align-items:flex-start;display:flex;gap:16px;justify-content:space-between}h2{margin:.2rem 0 1rem}.pass{color:#86efac}.fail{color:#fca5a5}.contract.fail{border-color:rgba(248,113,113,.45)}.primitive p{color:#d8dee6;line-height:1.55}.primitive pre{background:#0f1217;border:1px solid #2a323a;border-radius:16px;color:#fef3c7;overflow:auto;padding:14px}.primitive code{color:#fef3c7}table{border-collapse:collapse;width:100%}td,th{border-bottom:1px solid #2a323a;padding:12px;text-align:left;vertical-align:top}th{color:#a8b0b8;font-size:.82rem}@media(max-width:800px){main{padding:18px}table{display:block;overflow:auto}.contract-header{display:block}}</style></head><body><main><section class="hero"><p class="eyebrow">Tool Reliability</p><h1>${escapeHtml23(title)}</h1><div class="summary"><span class="pill ${report.status === "pass" ? "pass" : "fail"}">${escapeHtml23(report.status)}</span><span class="pill">${String(report.passed)} passing</span><span class="pill">${String(report.failed)} failing</span><span class="pill">${String(report.total)} contracts</span></div></section><section class="primitive"><p class="eyebrow">Copy into your app</p><h2><code>createVoiceToolContractRoutes(...)</code> certifies tool behavior</h2><p>Define deterministic tool cases for retries, idempotency, timeouts, result shape, and error handling so assistant tools fail in pre-production instead of live calls.</p><pre><code>${snippet}</code></pre></section>${contracts || '<section class="contract"><p>No tool contracts configured.</p></section>'}</main></body></html>`;
15718
15855
  };
15719
15856
  var createVoiceToolContractJSONHandler = (options) => () => runVoiceToolContractSuite(options);
15720
15857
  var createVoiceToolContractHTMLHandler = (options) => async () => {
@@ -15741,7 +15878,7 @@ var createVoiceToolContractRoutes = (options) => {
15741
15878
  };
15742
15879
 
15743
15880
  // src/simulationSuite.ts
15744
- var escapeHtml23 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
15881
+ var escapeHtml24 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
15745
15882
  var summarizeSection = (report) => ({
15746
15883
  failed: report.failed,
15747
15884
  passed: report.passed,
@@ -15937,15 +16074,15 @@ var renderSection = (label, summary) => {
15937
16074
  if (!summary) {
15938
16075
  return "";
15939
16076
  }
15940
- return `<article class="${escapeHtml23(summary.status)}"><span>${escapeHtml23(label)}</span><strong>${escapeHtml23(summary.status)}</strong><p>${summary.passed}/${summary.total} passed, ${summary.failed} failed.</p></article>`;
16077
+ return `<article class="${escapeHtml24(summary.status)}"><span>${escapeHtml24(label)}</span><strong>${escapeHtml24(summary.status)}</strong><p>${summary.passed}/${summary.total} passed, ${summary.failed} failed.</p></article>`;
15941
16078
  };
15942
16079
  var renderAction = (action) => {
15943
- const content = `<strong>${escapeHtml23(action.label)}</strong><p>${escapeHtml23(action.description)}</p><span>${escapeHtml23(action.section)} / ${escapeHtml23(action.severity)}</span>`;
15944
- return action.href ? `<a class="action" href="${escapeHtml23(action.href)}">${content}</a>` : `<article class="action">${content}</article>`;
16080
+ const content = `<strong>${escapeHtml24(action.label)}</strong><p>${escapeHtml24(action.description)}</p><span>${escapeHtml24(action.section)} / ${escapeHtml24(action.severity)}</span>`;
16081
+ return action.href ? `<a class="action" href="${escapeHtml24(action.href)}">${content}</a>` : `<article class="action">${content}</article>`;
15945
16082
  };
15946
16083
  var renderVoiceSimulationSuiteHTML = (report, options = {}) => {
15947
16084
  const title = options.title ?? "Voice Simulation Suite";
15948
- const snippet = escapeHtml23(`app.use(
16085
+ const snippet = escapeHtml24(`app.use(
15949
16086
  createVoiceSimulationSuiteRoutes({
15950
16087
  htmlPath: '/voice/simulations',
15951
16088
  path: '/api/voice/simulations',
@@ -15978,7 +16115,7 @@ app.use(
15978
16115
  store: traceStore
15979
16116
  })
15980
16117
  );`);
15981
- return `<!doctype html><html lang="en"><head><meta charset="utf-8" /><meta name="viewport" content="width=device-width, initial-scale=1" /><title>${escapeHtml23(title)}</title><style>body{background:#10151c;color:#f8f3e7;font-family:ui-sans-serif,system-ui,sans-serif;margin:0}main{margin:auto;max-width:1080px;padding:32px}.hero,.primitive{background:linear-gradient(135deg,rgba(34,197,94,.18),rgba(59,130,246,.12));border:1px solid #283544;border-radius:28px;margin-bottom:18px;padding:28px}.primitive{background:#151d27;border-color:#355078}.eyebrow{color:#93c5fd;font-weight:900;letter-spacing:.12em;text-transform:uppercase}h1{font-size:clamp(2.4rem,6vw,5rem);line-height:.9;margin:.2rem 0 1rem}.badge{border:1px solid #3f3f46;border-radius:999px;display:inline-flex;padding:8px 12px}.pass{color:#86efac}.fail{color:#fca5a5}.grid,.actions{display:grid;gap:14px;grid-template-columns:repeat(auto-fit,minmax(190px,1fr));margin:18px 0}.grid article,.action{background:#151d27;border:1px solid #283544;border-radius:18px;color:inherit;padding:16px;text-decoration:none}.grid span,.action span{color:#aab5c0}.grid strong{display:block;font-size:2rem;margin:.25rem 0;text-transform:uppercase}.action strong{display:block;color:#f8f3e7;margin-bottom:.35rem}.action p,.primitive p{color:#d8dee6;line-height:1.55;margin:.3rem 0 .6rem}pre{background:#151d27;border:1px solid #283544;border-radius:18px;overflow:auto;padding:16px}.primitive pre{background:#0b1118;color:#dbeafe}.primitive code{color:#bfdbfe}</style></head><body><main><section class="hero"><p class="eyebrow">Pre-production proof</p><h1>${escapeHtml23(title)}</h1><p>One report for session quality, scenario evals, fixture simulations, tool contracts, and outcome contracts.</p><p class="badge ${escapeHtml23(report.status)}">Status: ${escapeHtml23(report.status)}</p><section class="grid">${renderSection("Sessions", report.summary.sessions)}${renderSection("Scenarios", report.summary.scenarios)}${renderSection("Fixtures", report.summary.fixtures)}${renderSection("Tools", report.summary.tools)}${renderSection("Outcomes", report.summary.outcomes)}</section></section><section class="primitive"><p class="eyebrow">Copy into your app</p><h2><code>createVoiceSimulationSuiteRoutes(...)</code> builds this pre-production proof surface</h2><p>Run session quality checks, scenario evals, fixture-backed simulations, tool contracts, and outcome contracts from one route group before live traffic sees a regression.</p><pre><code>${snippet}</code></pre></section><h2>Actions</h2><section class="actions">${report.actions.length > 0 ? report.actions.map(renderAction).join("") : '<article class="action"><strong>No action required</strong><p>All enabled simulation sections are passing.</p></article>'}</section><pre>${escapeHtml23(JSON.stringify({ summary: report.summary, actions: report.actions }, null, 2))}</pre></main></body></html>`;
16118
+ return `<!doctype html><html lang="en"><head><meta charset="utf-8" /><meta name="viewport" content="width=device-width, initial-scale=1" /><title>${escapeHtml24(title)}</title><style>body{background:#10151c;color:#f8f3e7;font-family:ui-sans-serif,system-ui,sans-serif;margin:0}main{margin:auto;max-width:1080px;padding:32px}.hero,.primitive{background:linear-gradient(135deg,rgba(34,197,94,.18),rgba(59,130,246,.12));border:1px solid #283544;border-radius:28px;margin-bottom:18px;padding:28px}.primitive{background:#151d27;border-color:#355078}.eyebrow{color:#93c5fd;font-weight:900;letter-spacing:.12em;text-transform:uppercase}h1{font-size:clamp(2.4rem,6vw,5rem);line-height:.9;margin:.2rem 0 1rem}.badge{border:1px solid #3f3f46;border-radius:999px;display:inline-flex;padding:8px 12px}.pass{color:#86efac}.fail{color:#fca5a5}.grid,.actions{display:grid;gap:14px;grid-template-columns:repeat(auto-fit,minmax(190px,1fr));margin:18px 0}.grid article,.action{background:#151d27;border:1px solid #283544;border-radius:18px;color:inherit;padding:16px;text-decoration:none}.grid span,.action span{color:#aab5c0}.grid strong{display:block;font-size:2rem;margin:.25rem 0;text-transform:uppercase}.action strong{display:block;color:#f8f3e7;margin-bottom:.35rem}.action p,.primitive p{color:#d8dee6;line-height:1.55;margin:.3rem 0 .6rem}pre{background:#151d27;border:1px solid #283544;border-radius:18px;overflow:auto;padding:16px}.primitive pre{background:#0b1118;color:#dbeafe}.primitive code{color:#bfdbfe}</style></head><body><main><section class="hero"><p class="eyebrow">Pre-production proof</p><h1>${escapeHtml24(title)}</h1><p>One report for session quality, scenario evals, fixture simulations, tool contracts, and outcome contracts.</p><p class="badge ${escapeHtml24(report.status)}">Status: ${escapeHtml24(report.status)}</p><section class="grid">${renderSection("Sessions", report.summary.sessions)}${renderSection("Scenarios", report.summary.scenarios)}${renderSection("Fixtures", report.summary.fixtures)}${renderSection("Tools", report.summary.tools)}${renderSection("Outcomes", report.summary.outcomes)}</section></section><section class="primitive"><p class="eyebrow">Copy into your app</p><h2><code>createVoiceSimulationSuiteRoutes(...)</code> builds this pre-production proof surface</h2><p>Run session quality checks, scenario evals, fixture-backed simulations, tool contracts, and outcome contracts from one route group before live traffic sees a regression.</p><pre><code>${snippet}</code></pre></section><h2>Actions</h2><section class="actions">${report.actions.length > 0 ? report.actions.map(renderAction).join("") : '<article class="action"><strong>No action required</strong><p>All enabled simulation sections are passing.</p></article>'}</section><pre>${escapeHtml24(JSON.stringify({ summary: report.summary, actions: report.actions }, null, 2))}</pre></main></body></html>`;
15982
16119
  };
15983
16120
  var createVoiceSimulationSuiteRoutes = (options) => {
15984
16121
  const path = options.path ?? "/api/voice/simulations";
@@ -16297,7 +16434,7 @@ var createVoiceWorkflowContractHandler = (input) => {
16297
16434
  // src/sessionReplay.ts
16298
16435
  import { Elysia as Elysia25 } from "elysia";
16299
16436
  var getString10 = (value) => typeof value === "string" ? value : undefined;
16300
- var escapeHtml24 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
16437
+ var escapeHtml25 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
16301
16438
  var increment4 = (record, key) => {
16302
16439
  record[key] = (record[key] ?? 0) + 1;
16303
16440
  };
@@ -16491,10 +16628,10 @@ var summarizeVoiceSessions = async (options = {}) => {
16491
16628
  var renderVoiceSessionsHTML = (sessions) => sessions.length === 0 ? '<p class="voice-sessions-empty">No voice sessions found.</p>' : [
16492
16629
  '<div class="voice-sessions-list">',
16493
16630
  ...sessions.map((session) => [
16494
- `<article class="voice-session-card ${escapeHtml24(session.status)}">`,
16631
+ `<article class="voice-session-card ${escapeHtml25(session.status)}">`,
16495
16632
  '<div class="voice-session-card-header">',
16496
- `<strong>${escapeHtml24(session.sessionId)}</strong>`,
16497
- `<span>${escapeHtml24(session.status)}</span>`,
16633
+ `<strong>${escapeHtml25(session.sessionId)}</strong>`,
16634
+ `<span>${escapeHtml25(session.status)}</span>`,
16498
16635
  "</div>",
16499
16636
  "<dl>",
16500
16637
  `<div><dt>Events</dt><dd>${String(session.eventCount)}</dd></div>`,
@@ -16502,9 +16639,9 @@ var renderVoiceSessionsHTML = (sessions) => sessions.length === 0 ? '<p class="v
16502
16639
  `<div><dt>Transcripts</dt><dd>${String(session.transcriptCount)}</dd></div>`,
16503
16640
  `<div><dt>Errors</dt><dd>${String(session.errorCount)}</dd></div>`,
16504
16641
  "</dl>",
16505
- session.latestOutcome ? `<p>Outcome: ${escapeHtml24(session.latestOutcome)}</p>` : "",
16506
- session.providers.length ? `<p>Providers: ${session.providers.map(escapeHtml24).join(", ")}</p>` : "",
16507
- session.replayHref ? `<p>${session.operationsRecordHref ? `<a href="${escapeHtml24(session.operationsRecordHref)}">Open operations record</a> \xB7 ` : ""}<a href="${escapeHtml24(session.replayHref)}">Open replay</a></p>` : "",
16642
+ session.latestOutcome ? `<p>Outcome: ${escapeHtml25(session.latestOutcome)}</p>` : "",
16643
+ session.providers.length ? `<p>Providers: ${session.providers.map(escapeHtml25).join(", ")}</p>` : "",
16644
+ session.replayHref ? `<p>${session.operationsRecordHref ? `<a href="${escapeHtml25(session.operationsRecordHref)}">Open operations record</a> \xB7 ` : ""}<a href="${escapeHtml25(session.replayHref)}">Open replay</a></p>` : "",
16508
16645
  "</article>"
16509
16646
  ].join("")),
16510
16647
  "</div>"
@@ -16880,7 +17017,7 @@ var assertVoiceAgentSquadContractEvidence = (reports, input = {}) => {
16880
17017
  import { Elysia as Elysia26 } from "elysia";
16881
17018
  var DEFAULT_WARN_AFTER_MS = 1800;
16882
17019
  var DEFAULT_FAIL_AFTER_MS = 3200;
16883
- var escapeHtml25 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
17020
+ var escapeHtml26 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
16884
17021
  var firstNumber = (values) => values.filter((value) => typeof value === "number").sort((left, right) => left - right)[0];
16885
17022
  var getString11 = (value) => typeof value === "string" && value.trim() ? value : undefined;
16886
17023
  var createTraceStageIndex = (events) => {
@@ -16991,7 +17128,7 @@ var summarizeVoiceTurnLatency = async (options) => {
16991
17128
  warnings
16992
17129
  };
16993
17130
  };
16994
- var formatMs = (value) => typeof value === "number" ? `${Math.round(value)}ms` : "n/a";
17131
+ var formatMs2 = (value) => typeof value === "number" ? `${Math.round(value)}ms` : "n/a";
16995
17132
  var renderVoiceTurnLatencyHTML = (report, options = {}) => {
16996
17133
  const title = options.title ?? "Voice Turn Latency";
16997
17134
  const snippet = `app.use(
@@ -17012,11 +17149,11 @@ await traceStore.append({
17012
17149
  turnId,
17013
17150
  type: 'turn_latency.stage'
17014
17151
  });`;
17015
- const turns = report.turns.map((turn) => `<article class="turn ${escapeHtml25(turn.status)}">
17016
- <header><div><p class="eyebrow">${escapeHtml25(turn.sessionId)} \xB7 ${escapeHtml25(turn.turnId)}</p><h2>${escapeHtml25(turn.text || "Empty turn")}</h2></div><strong>${escapeHtml25(turn.status)}</strong></header>
17017
- <dl>${turn.stages.map((stage) => `<div><dt>${escapeHtml25(stage.label)}</dt><dd>${escapeHtml25(formatMs(stage.valueMs))}</dd></div>`).join("")}</dl>
17152
+ const turns = report.turns.map((turn) => `<article class="turn ${escapeHtml26(turn.status)}">
17153
+ <header><div><p class="eyebrow">${escapeHtml26(turn.sessionId)} \xB7 ${escapeHtml26(turn.turnId)}</p><h2>${escapeHtml26(turn.text || "Empty turn")}</h2></div><strong>${escapeHtml26(turn.status)}</strong></header>
17154
+ <dl>${turn.stages.map((stage) => `<div><dt>${escapeHtml26(stage.label)}</dt><dd>${escapeHtml26(formatMs2(stage.valueMs))}</dd></div>`).join("")}</dl>
17018
17155
  </article>`).join("");
17019
- return `<!doctype html><html lang="en"><head><meta charset="utf-8" /><meta name="viewport" content="width=device-width, initial-scale=1" /><title>${escapeHtml25(title)}</title><style>body{background:#101316;color:#f6f2e8;font-family:ui-sans-serif,system-ui,sans-serif;margin:0}main{margin:auto;max-width:1180px;padding:32px}.hero,.turn,.primitive{background:#181d22;border:1px solid #2a323a;border-radius:20px;margin-bottom:16px;padding:20px}.hero{background:linear-gradient(135deg,rgba(94,234,212,.16),rgba(251,191,36,.1))}.eyebrow{color:#5eead4;font-size:.78rem;font-weight:900;letter-spacing:.08em;text-transform:uppercase}h1{font-size:clamp(2.3rem,6vw,5rem);letter-spacing:-.06em;line-height:.9;margin:.2rem 0 1rem}h2{margin:.2rem 0 1rem}.summary{display:flex;flex-wrap:wrap;gap:10px}.pill{background:#0f1217;border:1px solid #3f3f46;border-radius:999px;padding:7px 10px}.primitive p{color:#cbd5e1}.primitive pre{background:#0a0d10;border:1px solid #2a323a;border-radius:16px;color:#d9fff7;overflow:auto;padding:16px}.turn header{align-items:flex-start;display:flex;gap:16px;justify-content:space-between}.pass{color:#86efac}.warn,.empty{color:#fde68a}.fail{color:#fca5a5}.turn.fail{border-color:rgba(248,113,113,.45)}dl{display:grid;gap:8px;grid-template-columns:repeat(auto-fit,minmax(160px,1fr))}dt{color:#a8b0b8;font-size:.8rem}dd{font-weight:900;margin:0}@media(max-width:800px){main{padding:18px}.turn header{display:block}}</style></head><body><main><section class="hero"><p class="eyebrow">End-to-end responsiveness</p><h1>${escapeHtml25(title)}</h1><div class="summary"><span class="pill ${escapeHtml25(report.status)}">${escapeHtml25(report.status)}</span><span class="pill">${String(report.total)} turns</span><span class="pill">avg ${escapeHtml25(formatMs(report.averageTotalMs))}</span><span class="pill">${String(report.warnings)} warnings</span><span class="pill">${String(report.failed)} failed</span></div></section><section class="primitive"><p class="eyebrow">Copy into your app</p><h2><code>createVoiceTurnLatencyRoutes(...)</code> exposes the full turn waterfall</h2><p>Attach stage traces for speech detection, commit, model response, TTS send, and first audio so teams can prove where latency actually comes from.</p><pre><code>${escapeHtml25(snippet)}</code></pre></section>${turns || '<section class="turn"><p>No committed turns found.</p></section>'}</main></body></html>`;
17156
+ return `<!doctype html><html lang="en"><head><meta charset="utf-8" /><meta name="viewport" content="width=device-width, initial-scale=1" /><title>${escapeHtml26(title)}</title><style>body{background:#101316;color:#f6f2e8;font-family:ui-sans-serif,system-ui,sans-serif;margin:0}main{margin:auto;max-width:1180px;padding:32px}.hero,.turn,.primitive{background:#181d22;border:1px solid #2a323a;border-radius:20px;margin-bottom:16px;padding:20px}.hero{background:linear-gradient(135deg,rgba(94,234,212,.16),rgba(251,191,36,.1))}.eyebrow{color:#5eead4;font-size:.78rem;font-weight:900;letter-spacing:.08em;text-transform:uppercase}h1{font-size:clamp(2.3rem,6vw,5rem);letter-spacing:-.06em;line-height:.9;margin:.2rem 0 1rem}h2{margin:.2rem 0 1rem}.summary{display:flex;flex-wrap:wrap;gap:10px}.pill{background:#0f1217;border:1px solid #3f3f46;border-radius:999px;padding:7px 10px}.primitive p{color:#cbd5e1}.primitive pre{background:#0a0d10;border:1px solid #2a323a;border-radius:16px;color:#d9fff7;overflow:auto;padding:16px}.turn header{align-items:flex-start;display:flex;gap:16px;justify-content:space-between}.pass{color:#86efac}.warn,.empty{color:#fde68a}.fail{color:#fca5a5}.turn.fail{border-color:rgba(248,113,113,.45)}dl{display:grid;gap:8px;grid-template-columns:repeat(auto-fit,minmax(160px,1fr))}dt{color:#a8b0b8;font-size:.8rem}dd{font-weight:900;margin:0}@media(max-width:800px){main{padding:18px}.turn header{display:block}}</style></head><body><main><section class="hero"><p class="eyebrow">End-to-end responsiveness</p><h1>${escapeHtml26(title)}</h1><div class="summary"><span class="pill ${escapeHtml26(report.status)}">${escapeHtml26(report.status)}</span><span class="pill">${String(report.total)} turns</span><span class="pill">avg ${escapeHtml26(formatMs2(report.averageTotalMs))}</span><span class="pill">${String(report.warnings)} warnings</span><span class="pill">${String(report.failed)} failed</span></div></section><section class="primitive"><p class="eyebrow">Copy into your app</p><h2><code>createVoiceTurnLatencyRoutes(...)</code> exposes the full turn waterfall</h2><p>Attach stage traces for speech detection, commit, model response, TTS send, and first audio so teams can prove where latency actually comes from.</p><pre><code>${escapeHtml26(snippet)}</code></pre></section>${turns || '<section class="turn"><p>No committed turns found.</p></section>'}</main></body></html>`;
17020
17157
  };
17021
17158
  var createVoiceTurnLatencyJSONHandler = (options) => async () => summarizeVoiceTurnLatency(options);
17022
17159
  var createVoiceTurnLatencyHTMLHandler = (options) => async () => {
@@ -17043,7 +17180,7 @@ var createVoiceTurnLatencyRoutes = (options) => {
17043
17180
  };
17044
17181
  // src/liveLatency.ts
17045
17182
  import { Elysia as Elysia27 } from "elysia";
17046
- var escapeHtml26 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
17183
+ var escapeHtml27 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
17047
17184
  var percentile3 = (values, percentileValue) => {
17048
17185
  if (values.length === 0) {
17049
17186
  return;
@@ -17088,7 +17225,7 @@ var summarizeVoiceLiveLatency = async (options) => {
17088
17225
  warnings
17089
17226
  };
17090
17227
  };
17091
- var formatMs2 = (value) => typeof value === "number" ? `${Math.round(value)}ms` : "n/a";
17228
+ var formatMs3 = (value) => typeof value === "number" ? `${Math.round(value)}ms` : "n/a";
17092
17229
  var renderVoiceLiveLatencyHTML = (report, options = {}) => {
17093
17230
  const title = options.title ?? "Voice Live Latency";
17094
17231
  const snippet = `app.use(
@@ -17110,8 +17247,8 @@ await traceStore.append({
17110
17247
  sessionId,
17111
17248
  type: 'client.live_latency'
17112
17249
  });`;
17113
- const rows = report.recent.map((sample) => `<tr><td>${escapeHtml26(sample.sessionId)}</td><td>${escapeHtml26(formatMs2(sample.latencyMs))}</td><td>${escapeHtml26(sample.status ?? "unknown")}</td><td>${escapeHtml26(new Date(sample.at).toLocaleString())}</td></tr>`).join("");
17114
- return `<!doctype html><html lang="en"><head><meta charset="utf-8" /><meta name="viewport" content="width=device-width, initial-scale=1" /><title>${escapeHtml26(title)}</title><style>body{background:#0c0f14;color:#f6f2e8;font-family:ui-sans-serif,system-ui,sans-serif;margin:0}main{margin:auto;max-width:1060px;padding:32px}.hero{background:linear-gradient(135deg,rgba(94,234,212,.16),rgba(245,158,11,.1));border:1px solid #26313d;border-radius:28px;margin-bottom:18px;padding:28px}.eyebrow{color:#5eead4;font-weight:900;letter-spacing:.12em;text-transform:uppercase}h1{font-size:clamp(2.4rem,6vw,5rem);line-height:.9;margin:.2rem 0 1rem}.status{border:1px solid #3f3f46;border-radius:999px;display:inline-flex;padding:8px 12px}.pass{color:#86efac}.warn,.empty{color:#fbbf24}.fail{color:#fca5a5}.metrics{display:grid;gap:14px;grid-template-columns:repeat(auto-fit,minmax(160px,1fr));margin:18px 0}.metrics article,table,.primitive{background:#141922;border:1px solid #26313d;border-radius:18px}.metrics article,.primitive{padding:16px}.metrics span{color:#a8b0b8}.metrics strong{display:block;font-size:2rem;margin-top:.25rem}.primitive{margin:0 0 18px}.primitive h2{margin:.2rem 0 .5rem}.primitive p{color:#cbd5e1}.primitive pre{background:#080b10;border:1px solid #26313d;border-radius:16px;color:#d9fff7;overflow:auto;padding:16px}table{border-collapse:collapse;overflow:hidden;width:100%}td,th{border-bottom:1px solid #26313d;padding:12px;text-align:left}@media(max-width:760px){main{padding:20px}}</style></head><body><main><section class="hero"><p class="eyebrow">Browser proof</p><h1>${escapeHtml26(title)}</h1><p>Recent real browser speech-to-assistant response measurements from persisted <code>client.live_latency</code> traces.</p><p class="status ${escapeHtml26(report.status)}">Status: ${escapeHtml26(report.status)}</p><section class="metrics"><article><span>p50</span><strong>${escapeHtml26(formatMs2(report.p50LatencyMs))}</strong></article><article><span>p95</span><strong>${escapeHtml26(formatMs2(report.p95LatencyMs))}</strong></article><article><span>Average</span><strong>${escapeHtml26(formatMs2(report.averageLatencyMs))}</strong></article><article><span>Samples</span><strong>${String(report.total)}</strong></article></section></section><section class="primitive"><p class="eyebrow">Copy into your app</p><h2><code>createVoiceLiveLatencyRoutes(...)</code> turns real browser timing into a release gate</h2><p>Persist live timing samples into the trace store so readiness, simulations, and trace timelines all point at the same self-hosted proof.</p><pre><code>${escapeHtml26(snippet)}</code></pre></section><table><thead><tr><th>Session</th><th>Latency</th><th>Status</th><th>Measured</th></tr></thead><tbody>${rows || '<tr><td colspan="4">No live latency samples yet.</td></tr>'}</tbody></table></main></body></html>`;
17250
+ const rows = report.recent.map((sample) => `<tr><td>${escapeHtml27(sample.sessionId)}</td><td>${escapeHtml27(formatMs3(sample.latencyMs))}</td><td>${escapeHtml27(sample.status ?? "unknown")}</td><td>${escapeHtml27(new Date(sample.at).toLocaleString())}</td></tr>`).join("");
17251
+ return `<!doctype html><html lang="en"><head><meta charset="utf-8" /><meta name="viewport" content="width=device-width, initial-scale=1" /><title>${escapeHtml27(title)}</title><style>body{background:#0c0f14;color:#f6f2e8;font-family:ui-sans-serif,system-ui,sans-serif;margin:0}main{margin:auto;max-width:1060px;padding:32px}.hero{background:linear-gradient(135deg,rgba(94,234,212,.16),rgba(245,158,11,.1));border:1px solid #26313d;border-radius:28px;margin-bottom:18px;padding:28px}.eyebrow{color:#5eead4;font-weight:900;letter-spacing:.12em;text-transform:uppercase}h1{font-size:clamp(2.4rem,6vw,5rem);line-height:.9;margin:.2rem 0 1rem}.status{border:1px solid #3f3f46;border-radius:999px;display:inline-flex;padding:8px 12px}.pass{color:#86efac}.warn,.empty{color:#fbbf24}.fail{color:#fca5a5}.metrics{display:grid;gap:14px;grid-template-columns:repeat(auto-fit,minmax(160px,1fr));margin:18px 0}.metrics article,table,.primitive{background:#141922;border:1px solid #26313d;border-radius:18px}.metrics article,.primitive{padding:16px}.metrics span{color:#a8b0b8}.metrics strong{display:block;font-size:2rem;margin-top:.25rem}.primitive{margin:0 0 18px}.primitive h2{margin:.2rem 0 .5rem}.primitive p{color:#cbd5e1}.primitive pre{background:#080b10;border:1px solid #26313d;border-radius:16px;color:#d9fff7;overflow:auto;padding:16px}table{border-collapse:collapse;overflow:hidden;width:100%}td,th{border-bottom:1px solid #26313d;padding:12px;text-align:left}@media(max-width:760px){main{padding:20px}}</style></head><body><main><section class="hero"><p class="eyebrow">Browser proof</p><h1>${escapeHtml27(title)}</h1><p>Recent real browser speech-to-assistant response measurements from persisted <code>client.live_latency</code> traces.</p><p class="status ${escapeHtml27(report.status)}">Status: ${escapeHtml27(report.status)}</p><section class="metrics"><article><span>p50</span><strong>${escapeHtml27(formatMs3(report.p50LatencyMs))}</strong></article><article><span>p95</span><strong>${escapeHtml27(formatMs3(report.p95LatencyMs))}</strong></article><article><span>Average</span><strong>${escapeHtml27(formatMs3(report.averageLatencyMs))}</strong></article><article><span>Samples</span><strong>${String(report.total)}</strong></article></section></section><section class="primitive"><p class="eyebrow">Copy into your app</p><h2><code>createVoiceLiveLatencyRoutes(...)</code> turns real browser timing into a release gate</h2><p>Persist live timing samples into the trace store so readiness, simulations, and trace timelines all point at the same self-hosted proof.</p><pre><code>${escapeHtml27(snippet)}</code></pre></section><table><thead><tr><th>Session</th><th>Latency</th><th>Status</th><th>Measured</th></tr></thead><tbody>${rows || '<tr><td colspan="4">No live latency samples yet.</td></tr>'}</tbody></table></main></body></html>`;
17115
17252
  };
17116
17253
  var createVoiceLiveLatencyRoutes = (options) => {
17117
17254
  const path = options.path ?? "/api/live-latency";
@@ -17437,7 +17574,7 @@ None.
17437
17574
  // src/turnQuality.ts
17438
17575
  import { Elysia as Elysia28 } from "elysia";
17439
17576
  var DEFAULT_CONFIDENCE_WARN_THRESHOLD = 0.72;
17440
- var escapeHtml27 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
17577
+ var escapeHtml28 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
17441
17578
  var getTurnLatencyMs = (turn) => {
17442
17579
  const firstTranscriptAt = turn.transcripts.map((transcript) => transcript.endedAtMs ?? transcript.startedAtMs).filter((value) => typeof value === "number").sort((left, right) => left - right)[0];
17443
17580
  if (firstTranscriptAt === undefined) {
@@ -17508,24 +17645,24 @@ var summarizeVoiceTurnQuality = async (options) => {
17508
17645
  };
17509
17646
  var renderVoiceTurnQualityHTML = (report, options = {}) => {
17510
17647
  const title = options.title ?? "Voice Turn Quality";
17511
- const turns = report.turns.map((turn) => `<article class="turn ${escapeHtml27(turn.status)}">
17648
+ const turns = report.turns.map((turn) => `<article class="turn ${escapeHtml28(turn.status)}">
17512
17649
  <div class="turn-header">
17513
17650
  <div>
17514
- <p class="eyebrow">${escapeHtml27(turn.sessionId)} \xB7 ${escapeHtml27(turn.turnId)}</p>
17515
- <h2>${escapeHtml27(turn.text || "Empty turn")}</h2>
17651
+ <p class="eyebrow">${escapeHtml28(turn.sessionId)} \xB7 ${escapeHtml28(turn.turnId)}</p>
17652
+ <h2>${escapeHtml28(turn.text || "Empty turn")}</h2>
17516
17653
  </div>
17517
- <strong>${escapeHtml27(turn.status)}</strong>
17654
+ <strong>${escapeHtml28(turn.status)}</strong>
17518
17655
  </div>
17519
17656
  <dl>
17520
- <div><dt>Source</dt><dd>${escapeHtml27(turn.source ?? "unknown")}</dd></div>
17657
+ <div><dt>Source</dt><dd>${escapeHtml28(turn.source ?? "unknown")}</dd></div>
17521
17658
  <div><dt>Confidence</dt><dd>${turn.averageConfidence === undefined ? "n/a" : `${Math.round(turn.averageConfidence * 100)}%`}</dd></div>
17522
- <div><dt>Fallback</dt><dd>${turn.fallbackUsed ? `yes (${escapeHtml27(turn.fallbackSelectionReason ?? "selected")})` : "no"}</dd></div>
17523
- <div><dt>Correction</dt><dd>${turn.correctionChanged ? `changed${turn.correctionProvider ? ` by ${escapeHtml27(turn.correctionProvider)}` : ""}` : "none"}</dd></div>
17659
+ <div><dt>Fallback</dt><dd>${turn.fallbackUsed ? `yes (${escapeHtml28(turn.fallbackSelectionReason ?? "selected")})` : "no"}</dd></div>
17660
+ <div><dt>Correction</dt><dd>${turn.correctionChanged ? `changed${turn.correctionProvider ? ` by ${escapeHtml28(turn.correctionProvider)}` : ""}` : "none"}</dd></div>
17524
17661
  <div><dt>Transcripts</dt><dd>${String(turn.selectedTranscriptCount)} selected \xB7 ${String(turn.finalTranscriptCount)} final \xB7 ${String(turn.partialTranscriptCount)} partial</dd></div>
17525
17662
  <div><dt>Cost</dt><dd>${turn.costUnits === undefined ? "n/a" : String(turn.costUnits)}</dd></div>
17526
17663
  </dl>
17527
17664
  </article>`).join("");
17528
- return `<!doctype html><html lang="en"><head><meta charset="utf-8" /><meta name="viewport" content="width=device-width, initial-scale=1" /><title>${escapeHtml27(title)}</title><style>body{background:#101316;color:#f6f2e8;font-family:ui-sans-serif,system-ui,sans-serif;margin:0}main{margin:auto;max-width:1180px;padding:32px}.hero,.turn{background:#181d22;border:1px solid #2a323a;border-radius:20px;margin-bottom:16px;padding:20px}.hero{background:linear-gradient(135deg,rgba(251,191,36,.16),rgba(34,197,94,.1))}.eyebrow{color:#fbbf24;font-size:.78rem;font-weight:900;letter-spacing:.08em;text-transform:uppercase}h1{font-size:clamp(2.3rem,6vw,5rem);letter-spacing:-.06em;line-height:.9;margin:.2rem 0 1rem}h2{margin:.2rem 0 1rem}.summary{display:flex;flex-wrap:wrap;gap:10px}.pill{background:#0f1217;border:1px solid #3f3f46;border-radius:999px;padding:7px 10px}.turn-header{align-items:flex-start;display:flex;gap:16px;justify-content:space-between}.pass{color:#86efac}.warn,.unknown{color:#fde68a}.fail{color:#fca5a5}.turn.fail{border-color:rgba(248,113,113,.45)}dl{display:grid;gap:8px;grid-template-columns:repeat(auto-fit,minmax(160px,1fr))}dt{color:#a8b0b8;font-size:.8rem}dd{margin:0}@media(max-width:800px){main{padding:18px}.turn-header{display:block}}</style></head><body><main><section class="hero"><p class="eyebrow">Realtime STT Debugging</p><h1>${escapeHtml27(title)}</h1><div class="summary"><span class="pill ${escapeHtml27(report.status)}">${escapeHtml27(report.status)}</span><span class="pill">${String(report.total)} turns</span><span class="pill">${String(report.warnings)} warnings</span><span class="pill">${String(report.failed)} failed</span><span class="pill">${String(report.sessions)} sessions</span></div></section>${turns || '<section class="turn"><p>No committed turns found.</p></section>'}</main></body></html>`;
17665
+ return `<!doctype html><html lang="en"><head><meta charset="utf-8" /><meta name="viewport" content="width=device-width, initial-scale=1" /><title>${escapeHtml28(title)}</title><style>body{background:#101316;color:#f6f2e8;font-family:ui-sans-serif,system-ui,sans-serif;margin:0}main{margin:auto;max-width:1180px;padding:32px}.hero,.turn{background:#181d22;border:1px solid #2a323a;border-radius:20px;margin-bottom:16px;padding:20px}.hero{background:linear-gradient(135deg,rgba(251,191,36,.16),rgba(34,197,94,.1))}.eyebrow{color:#fbbf24;font-size:.78rem;font-weight:900;letter-spacing:.08em;text-transform:uppercase}h1{font-size:clamp(2.3rem,6vw,5rem);letter-spacing:-.06em;line-height:.9;margin:.2rem 0 1rem}h2{margin:.2rem 0 1rem}.summary{display:flex;flex-wrap:wrap;gap:10px}.pill{background:#0f1217;border:1px solid #3f3f46;border-radius:999px;padding:7px 10px}.turn-header{align-items:flex-start;display:flex;gap:16px;justify-content:space-between}.pass{color:#86efac}.warn,.unknown{color:#fde68a}.fail{color:#fca5a5}.turn.fail{border-color:rgba(248,113,113,.45)}dl{display:grid;gap:8px;grid-template-columns:repeat(auto-fit,minmax(160px,1fr))}dt{color:#a8b0b8;font-size:.8rem}dd{margin:0}@media(max-width:800px){main{padding:18px}.turn-header{display:block}}</style></head><body><main><section class="hero"><p class="eyebrow">Realtime STT Debugging</p><h1>${escapeHtml28(title)}</h1><div class="summary"><span class="pill ${escapeHtml28(report.status)}">${escapeHtml28(report.status)}</span><span class="pill">${String(report.total)} turns</span><span class="pill">${String(report.warnings)} warnings</span><span class="pill">${String(report.failed)} failed</span><span class="pill">${String(report.sessions)} sessions</span></div></section>${turns || '<section class="turn"><p>No committed turns found.</p></section>'}</main></body></html>`;
17529
17666
  };
17530
17667
  var createVoiceTurnQualityJSONHandler = (options) => async () => summarizeVoiceTurnQuality(options);
17531
17668
  var createVoiceTurnQualityHTMLHandler = (options) => async () => {
@@ -18452,7 +18589,7 @@ var resolveTwilioStreamParameters = async (parameters, input) => {
18452
18589
  return parameters;
18453
18590
  };
18454
18591
  var joinUrlPath2 = (origin, path) => `${origin.replace(/\/$/, "")}${path.startsWith("/") ? path : `/${path}`}`;
18455
- var escapeHtml28 = (value) => value.replaceAll("&", "&amp;").replaceAll('"', "&quot;").replaceAll("'", "&#39;").replaceAll("<", "&lt;").replaceAll(">", "&gt;");
18592
+ var escapeHtml29 = (value) => value.replaceAll("&", "&amp;").replaceAll('"', "&quot;").replaceAll("'", "&#39;").replaceAll("<", "&lt;").replaceAll(">", "&gt;");
18456
18593
  var getWebhookVerificationUrl = (webhook, input) => {
18457
18594
  if (!webhook?.verificationUrl) {
18458
18595
  return;
@@ -18495,23 +18632,23 @@ var buildTwilioVoiceSetupStatus = async (options, input) => {
18495
18632
  };
18496
18633
  var renderTwilioVoiceSetupHTML = (status, title) => `<main style="font-family: ui-sans-serif, system-ui; max-width: 860px; margin: 40px auto; padding: 0 20px;">
18497
18634
  <p style="letter-spacing: .12em; text-transform: uppercase; color: #52606d;">Twilio setup</p>
18498
- <h1>${escapeHtml28(title)}</h1>
18635
+ <h1>${escapeHtml29(title)}</h1>
18499
18636
  <p><strong>Status:</strong> ${status.ready ? "Ready" : "Needs attention"}</p>
18500
18637
  <section>
18501
18638
  <h2>URLs</h2>
18502
18639
  <ul>
18503
- <li><strong>TwiML:</strong> <code>${escapeHtml28(status.urls.twiml)}</code></li>
18504
- <li><strong>Media stream:</strong> <code>${escapeHtml28(status.urls.stream)}</code></li>
18505
- <li><strong>Status webhook:</strong> <code>${escapeHtml28(status.urls.webhook)}</code></li>
18640
+ <li><strong>TwiML:</strong> <code>${escapeHtml29(status.urls.twiml)}</code></li>
18641
+ <li><strong>Media stream:</strong> <code>${escapeHtml29(status.urls.stream)}</code></li>
18642
+ <li><strong>Status webhook:</strong> <code>${escapeHtml29(status.urls.webhook)}</code></li>
18506
18643
  </ul>
18507
18644
  </section>
18508
18645
  <section>
18509
18646
  <h2>Signing</h2>
18510
18647
  <p>Mode: <code>${status.signing.mode}</code></p>
18511
- ${status.signing.verificationUrl ? `<p>Verification URL: <code>${escapeHtml28(status.signing.verificationUrl)}</code></p>` : ""}
18648
+ ${status.signing.verificationUrl ? `<p>Verification URL: <code>${escapeHtml29(status.signing.verificationUrl)}</code></p>` : ""}
18512
18649
  </section>
18513
- ${status.missing.length ? `<section><h2>Missing env</h2><ul>${status.missing.map((name) => `<li><code>${escapeHtml28(name)}</code></li>`).join("")}</ul></section>` : ""}
18514
- ${status.warnings.length ? `<section><h2>Warnings</h2><ul>${status.warnings.map((warning) => `<li>${escapeHtml28(warning)}</li>`).join("")}</ul></section>` : ""}
18650
+ ${status.missing.length ? `<section><h2>Missing env</h2><ul>${status.missing.map((name) => `<li><code>${escapeHtml29(name)}</code></li>`).join("")}</ul></section>` : ""}
18651
+ ${status.warnings.length ? `<section><h2>Warnings</h2><ul>${status.warnings.map((warning) => `<li>${escapeHtml29(warning)}</li>`).join("")}</ul></section>` : ""}
18515
18652
  </main>`;
18516
18653
  var extractTwilioStreamUrl = (twiml) => twiml.match(/<Stream\b[^>]*\surl="([^"]+)"/i)?.[1]?.replaceAll("&amp;", "&");
18517
18654
  var createSmokeCheck = (name, status, message, details) => ({
@@ -18522,20 +18659,20 @@ var createSmokeCheck = (name, status, message, details) => ({
18522
18659
  });
18523
18660
  var renderTwilioVoiceSmokeHTML = (report, title) => `<main style="font-family: ui-sans-serif, system-ui; max-width: 860px; margin: 40px auto; padding: 0 20px;">
18524
18661
  <p style="letter-spacing: .12em; text-transform: uppercase; color: #52606d;">Twilio smoke test</p>
18525
- <h1>${escapeHtml28(title)}</h1>
18662
+ <h1>${escapeHtml29(title)}</h1>
18526
18663
  <p><strong>Status:</strong> ${report.pass ? "Pass" : "Fail"}</p>
18527
18664
  <section>
18528
18665
  <h2>Checks</h2>
18529
18666
  <ul>
18530
- ${report.checks.map((check) => `<li><strong>${escapeHtml28(check.name)}</strong>: ${escapeHtml28(check.status)}${check.message ? ` - ${escapeHtml28(check.message)}` : ""}</li>`).join("")}
18667
+ ${report.checks.map((check) => `<li><strong>${escapeHtml29(check.name)}</strong>: ${escapeHtml29(check.status)}${check.message ? ` - ${escapeHtml29(check.message)}` : ""}</li>`).join("")}
18531
18668
  </ul>
18532
18669
  </section>
18533
18670
  <section>
18534
18671
  <h2>Observed URLs</h2>
18535
18672
  <ul>
18536
- <li><strong>TwiML:</strong> <code>${escapeHtml28(report.setup.urls.twiml)}</code></li>
18537
- <li><strong>Stream:</strong> <code>${escapeHtml28(report.twiml?.streamUrl ?? report.setup.urls.stream)}</code></li>
18538
- <li><strong>Webhook:</strong> <code>${escapeHtml28(report.setup.urls.webhook)}</code></li>
18673
+ <li><strong>TwiML:</strong> <code>${escapeHtml29(report.setup.urls.twiml)}</code></li>
18674
+ <li><strong>Stream:</strong> <code>${escapeHtml29(report.twiml?.streamUrl ?? report.setup.urls.stream)}</code></li>
18675
+ <li><strong>Webhook:</strong> <code>${escapeHtml29(report.setup.urls.webhook)}</code></li>
18539
18676
  </ul>
18540
18677
  </section>
18541
18678
  </main>`;
@@ -19132,7 +19269,7 @@ var createTwilioVoiceRoutes = (options) => {
19132
19269
 
19133
19270
  // src/telephony/plivo.ts
19134
19271
  var escapeXml3 = (value) => value.replaceAll("&", "&amp;").replaceAll('"', "&quot;").replaceAll("'", "&apos;").replaceAll("<", "&lt;").replaceAll(">", "&gt;");
19135
- var escapeHtml29 = (value) => value.replaceAll("&", "&amp;").replaceAll('"', "&quot;").replaceAll("'", "&#39;").replaceAll("<", "&lt;").replaceAll(">", "&gt;");
19272
+ var escapeHtml30 = (value) => value.replaceAll("&", "&amp;").replaceAll('"', "&quot;").replaceAll("'", "&#39;").replaceAll("<", "&lt;").replaceAll(">", "&gt;");
19136
19273
  var joinUrlPath3 = (origin, path) => `${origin.replace(/\/$/, "")}${path.startsWith("/") ? path : `/${path}`}`;
19137
19274
  var resolveRequestOrigin2 = (request) => {
19138
19275
  const url = new URL(request.url);
@@ -19562,21 +19699,21 @@ var buildPlivoVoiceSetupStatus = async (options, input) => {
19562
19699
  };
19563
19700
  var renderPlivoSetupHTML = (status, title) => `<main style="font-family: ui-sans-serif, system-ui; max-width: 860px; margin: 40px auto; padding: 0 20px;">
19564
19701
  <p style="letter-spacing: .12em; text-transform: uppercase; color: #52606d;">Plivo setup</p>
19565
- <h1>${escapeHtml29(title)}</h1>
19702
+ <h1>${escapeHtml30(title)}</h1>
19566
19703
  <p><strong>Status:</strong> ${status.ready ? "Ready" : "Needs attention"}</p>
19567
19704
  <ul>
19568
- <li><strong>Answer XML:</strong> <code>${escapeHtml29(status.urls.answer)}</code></li>
19569
- <li><strong>Audio stream:</strong> <code>${escapeHtml29(status.urls.stream)}</code></li>
19570
- <li><strong>Status webhook:</strong> <code>${escapeHtml29(status.urls.webhook)}</code></li>
19705
+ <li><strong>Answer XML:</strong> <code>${escapeHtml30(status.urls.answer)}</code></li>
19706
+ <li><strong>Audio stream:</strong> <code>${escapeHtml30(status.urls.stream)}</code></li>
19707
+ <li><strong>Status webhook:</strong> <code>${escapeHtml30(status.urls.webhook)}</code></li>
19571
19708
  </ul>
19572
- ${status.missing.length ? `<h2>Missing env</h2><ul>${status.missing.map((name) => `<li><code>${escapeHtml29(name)}</code></li>`).join("")}</ul>` : ""}
19573
- ${status.warnings.length ? `<h2>Warnings</h2><ul>${status.warnings.map((warning) => `<li>${escapeHtml29(warning)}</li>`).join("")}</ul>` : ""}
19709
+ ${status.missing.length ? `<h2>Missing env</h2><ul>${status.missing.map((name) => `<li><code>${escapeHtml30(name)}</code></li>`).join("")}</ul>` : ""}
19710
+ ${status.warnings.length ? `<h2>Warnings</h2><ul>${status.warnings.map((warning) => `<li>${escapeHtml30(warning)}</li>`).join("")}</ul>` : ""}
19574
19711
  </main>`;
19575
19712
  var renderPlivoSmokeHTML = (report, title) => `<main style="font-family: ui-sans-serif, system-ui; max-width: 860px; margin: 40px auto; padding: 0 20px;">
19576
19713
  <p style="letter-spacing: .12em; text-transform: uppercase; color: #52606d;">Plivo smoke test</p>
19577
- <h1>${escapeHtml29(title)}</h1>
19714
+ <h1>${escapeHtml30(title)}</h1>
19578
19715
  <p><strong>Status:</strong> ${report.pass ? "Pass" : "Fail"}</p>
19579
- <ul>${report.checks.map((check) => `<li><strong>${escapeHtml29(check.name)}</strong>: ${escapeHtml29(check.status)}${check.message ? ` - ${escapeHtml29(check.message)}` : ""}</li>`).join("")}</ul>
19716
+ <ul>${report.checks.map((check) => `<li><strong>${escapeHtml30(check.name)}</strong>: ${escapeHtml30(check.status)}${check.message ? ` - ${escapeHtml30(check.message)}` : ""}</li>`).join("")}</ul>
19580
19717
  </main>`;
19581
19718
  var runPlivoSmokeTest = async (input) => {
19582
19719
  const setup = await buildPlivoVoiceSetupStatus(input.options, input);
@@ -19780,7 +19917,7 @@ import { Buffer as Buffer6 } from "buffer";
19780
19917
  import { Database as Database2 } from "bun:sqlite";
19781
19918
  import { Elysia as Elysia32 } from "elysia";
19782
19919
  var escapeXml4 = (value) => value.replaceAll("&", "&amp;").replaceAll('"', "&quot;").replaceAll("'", "&apos;").replaceAll("<", "&lt;").replaceAll(">", "&gt;");
19783
- var escapeHtml30 = (value) => value.replaceAll("&", "&amp;").replaceAll('"', "&quot;").replaceAll("'", "&#39;").replaceAll("<", "&lt;").replaceAll(">", "&gt;");
19920
+ var escapeHtml31 = (value) => value.replaceAll("&", "&amp;").replaceAll('"', "&quot;").replaceAll("'", "&#39;").replaceAll("<", "&lt;").replaceAll(">", "&gt;");
19784
19921
  var joinUrlPath4 = (origin, path) => `${origin.replace(/\/$/, "")}${path.startsWith("/") ? path : `/${path}`}`;
19785
19922
  var resolveRequestOrigin3 = (request) => {
19786
19923
  const url = new URL(request.url);
@@ -20173,21 +20310,21 @@ var buildTelnyxVoiceSetupStatus = async (options, input) => {
20173
20310
  };
20174
20311
  var renderTelnyxSetupHTML = (status, title) => `<main style="font-family: ui-sans-serif, system-ui; max-width: 860px; margin: 40px auto; padding: 0 20px;">
20175
20312
  <p style="letter-spacing: .12em; text-transform: uppercase; color: #52606d;">Telnyx setup</p>
20176
- <h1>${escapeHtml30(title)}</h1>
20313
+ <h1>${escapeHtml31(title)}</h1>
20177
20314
  <p><strong>Status:</strong> ${status.ready ? "Ready" : "Needs attention"}</p>
20178
20315
  <ul>
20179
- <li><strong>TeXML:</strong> <code>${escapeHtml30(status.urls.texml)}</code></li>
20180
- <li><strong>Media stream:</strong> <code>${escapeHtml30(status.urls.stream)}</code></li>
20181
- <li><strong>Status webhook:</strong> <code>${escapeHtml30(status.urls.webhook)}</code></li>
20316
+ <li><strong>TeXML:</strong> <code>${escapeHtml31(status.urls.texml)}</code></li>
20317
+ <li><strong>Media stream:</strong> <code>${escapeHtml31(status.urls.stream)}</code></li>
20318
+ <li><strong>Status webhook:</strong> <code>${escapeHtml31(status.urls.webhook)}</code></li>
20182
20319
  </ul>
20183
- ${status.missing.length ? `<h2>Missing env</h2><ul>${status.missing.map((name) => `<li><code>${escapeHtml30(name)}</code></li>`).join("")}</ul>` : ""}
20184
- ${status.warnings.length ? `<h2>Warnings</h2><ul>${status.warnings.map((warning) => `<li>${escapeHtml30(warning)}</li>`).join("")}</ul>` : ""}
20320
+ ${status.missing.length ? `<h2>Missing env</h2><ul>${status.missing.map((name) => `<li><code>${escapeHtml31(name)}</code></li>`).join("")}</ul>` : ""}
20321
+ ${status.warnings.length ? `<h2>Warnings</h2><ul>${status.warnings.map((warning) => `<li>${escapeHtml31(warning)}</li>`).join("")}</ul>` : ""}
20185
20322
  </main>`;
20186
20323
  var renderTelnyxSmokeHTML = (report, title) => `<main style="font-family: ui-sans-serif, system-ui; max-width: 860px; margin: 40px auto; padding: 0 20px;">
20187
20324
  <p style="letter-spacing: .12em; text-transform: uppercase; color: #52606d;">Telnyx smoke test</p>
20188
- <h1>${escapeHtml30(title)}</h1>
20325
+ <h1>${escapeHtml31(title)}</h1>
20189
20326
  <p><strong>Status:</strong> ${report.pass ? "Pass" : "Fail"}</p>
20190
- <ul>${report.checks.map((check) => `<li><strong>${escapeHtml30(check.name)}</strong>: ${escapeHtml30(check.status)}${check.message ? ` - ${escapeHtml30(check.message)}` : ""}</li>`).join("")}</ul>
20327
+ <ul>${report.checks.map((check) => `<li><strong>${escapeHtml31(check.name)}</strong>: ${escapeHtml31(check.status)}${check.message ? ` - ${escapeHtml31(check.message)}` : ""}</li>`).join("")}</ul>
20191
20328
  </main>`;
20192
20329
  var runTelnyxSmokeTest = async (input) => {
20193
20330
  const setup = await buildTelnyxVoiceSetupStatus(input.options, input);
@@ -20391,7 +20528,7 @@ var createTelnyxVoiceRoutes = (options = {}) => {
20391
20528
 
20392
20529
  // src/telephony/matrix.ts
20393
20530
  import { Elysia as Elysia33 } from "elysia";
20394
- var escapeHtml31 = (value) => value.replaceAll("&", "&amp;").replaceAll('"', "&quot;").replaceAll("'", "&#39;").replaceAll("<", "&lt;").replaceAll(">", "&gt;");
20531
+ var escapeHtml32 = (value) => value.replaceAll("&", "&amp;").replaceAll('"', "&quot;").replaceAll("'", "&#39;").replaceAll("<", "&lt;").replaceAll(">", "&gt;");
20395
20532
  var labelForProvider = (provider) => provider.split("-").map((part) => `${part.slice(0, 1).toUpperCase()}${part.slice(1)}`).join(" ");
20396
20533
  var resolveEntryStatus = (contract, setup, smoke) => {
20397
20534
  if (!contract.pass || !setup.ready || smoke?.pass === false) {
@@ -20452,13 +20589,13 @@ var badgeStyles = {
20452
20589
  };
20453
20590
  var renderVoiceTelephonyCarrierMatrixHTML = (matrix, options = {}) => `<main style="font-family: ui-sans-serif, system-ui; max-width: 1040px; margin: 40px auto; padding: 0 20px; color: #172033;">
20454
20591
  <p style="letter-spacing: .12em; text-transform: uppercase; color: #52606d;">Carrier matrix</p>
20455
- <h1 style="font-size: 34px; margin: 0 0 8px;">${escapeHtml31(options.title ?? "AbsoluteJS Voice Carrier Matrix")}</h1>
20592
+ <h1 style="font-size: 34px; margin: 0 0 8px;">${escapeHtml32(options.title ?? "AbsoluteJS Voice Carrier Matrix")}</h1>
20456
20593
  <p style="color:#52606d; margin: 0 0 24px;">${matrix.summary.ready}/${matrix.summary.providers} ready, ${matrix.summary.contractsPassing}/${matrix.summary.providers} contract passing, ${matrix.summary.smokePassing}/${matrix.summary.providers} smoke passing.</p>
20457
20594
  <section style="display:grid; grid-template-columns: repeat(auto-fit, minmax(260px, 1fr)); gap: 16px;">
20458
20595
  ${matrix.entries.map((entry) => `<article style="border:1px solid #d9e2ec; border-radius:18px; padding:18px; background:#fff; box-shadow:0 18px 48px rgba(15,23,42,.08);">
20459
20596
  <div style="display:flex; justify-content:space-between; gap:12px; align-items:center;">
20460
- <h2 style="margin:0; font-size:20px;">${escapeHtml31(entry.name)}</h2>
20461
- <span style="border:1px solid; border-radius:999px; padding:4px 10px; font-size:12px; font-weight:700; ${badgeStyles[entry.status]}">${escapeHtml31(entry.status.toUpperCase())}</span>
20597
+ <h2 style="margin:0; font-size:20px;">${escapeHtml32(entry.name)}</h2>
20598
+ <span style="border:1px solid; border-radius:999px; padding:4px 10px; font-size:12px; font-weight:700; ${badgeStyles[entry.status]}">${escapeHtml32(entry.status.toUpperCase())}</span>
20462
20599
  </div>
20463
20600
  <dl style="display:grid; grid-template-columns: 1fr 1fr; gap:8px 12px; margin:16px 0;">
20464
20601
  <dt style="color:#64748b;">Setup</dt><dd style="margin:0; font-weight:700;">${entry.ready ? "Ready" : "Needs attention"}</dd>
@@ -20466,9 +20603,9 @@ ${matrix.entries.map((entry) => `<article style="border:1px solid #d9e2ec; borde
20466
20603
  <dt style="color:#64748b;">Smoke</dt><dd style="margin:0; font-weight:700;">${entry.smoke ? entry.smoke.pass ? "Pass" : "Fail" : "Missing"}</dd>
20467
20604
  <dt style="color:#64748b;">Contract</dt><dd style="margin:0; font-weight:700;">${entry.contract.pass ? "Pass" : "Fail"}</dd>
20468
20605
  </dl>
20469
- <p style="margin:0 0 8px; color:#475569;"><strong>Stream:</strong> <code>${escapeHtml31(entry.setup.urls.stream || "missing")}</code></p>
20470
- <p style="margin:0 0 12px; color:#475569;"><strong>Webhook:</strong> <code>${escapeHtml31(entry.setup.urls.webhook || "missing")}</code></p>
20471
- ${entry.issues.length ? `<ul style="margin:12px 0 0; padding-left:18px;">${entry.issues.map((issue) => `<li>${escapeHtml31(issue.severity)}: ${escapeHtml31(issue.message)}</li>`).join("")}</ul>` : '<p style="margin:12px 0 0; color:#166534;">No contract issues.</p>'}
20606
+ <p style="margin:0 0 8px; color:#475569;"><strong>Stream:</strong> <code>${escapeHtml32(entry.setup.urls.stream || "missing")}</code></p>
20607
+ <p style="margin:0 0 12px; color:#475569;"><strong>Webhook:</strong> <code>${escapeHtml32(entry.setup.urls.webhook || "missing")}</code></p>
20608
+ ${entry.issues.length ? `<ul style="margin:12px 0 0; padding-left:18px;">${entry.issues.map((issue) => `<li>${escapeHtml32(issue.severity)}: ${escapeHtml32(issue.message)}</li>`).join("")}</ul>` : '<p style="margin:12px 0 0; color:#166534;">No contract issues.</p>'}
20472
20609
  </article>`).join("")}
20473
20610
  </section>
20474
20611
  </main>`;
@@ -20504,7 +20641,7 @@ var defaultRequirements = [
20504
20641
  "lifecycle-outcome",
20505
20642
  "no-session-error"
20506
20643
  ];
20507
- var escapeHtml32 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
20644
+ var escapeHtml33 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
20508
20645
  var payloadType = (event) => typeof event.payload.type === "string" ? event.payload.type : undefined;
20509
20646
  var hasTextPayload = (event) => ["text", "assistantText", "transcript"].some((key) => {
20510
20647
  const value = event.payload[key];
@@ -20613,10 +20750,10 @@ var resolveHandlerOptions = async (options, input) => ({
20613
20750
  });
20614
20751
  var renderVoicePhoneAgentProductionSmokeHTML = (report, options = {}) => {
20615
20752
  const title = options.title ?? "AbsoluteJS Voice Phone Smoke Contract";
20616
- const issues = report.issues.map((issue) => `<li><strong>${escapeHtml32(issue.requirement)}</strong>: ${escapeHtml32(issue.message)}</li>`).join("");
20617
- const outcomes = report.observed.lifecycleOutcomes.map((outcome) => `<span class="pill">${escapeHtml32(outcome)}</span>`).join("");
20618
- const requirements = report.required.map((requirement) => `<span class="pill">${escapeHtml32(requirement)}</span>`).join("");
20619
- return `<!doctype html><html lang="en"><head><meta charset="utf-8" /><meta name="viewport" content="width=device-width, initial-scale=1" /><title>${escapeHtml32(title)}</title><style>body{background:#0e141b;color:#f8f3e7;font-family:ui-sans-serif,system-ui,sans-serif;margin:0}main{margin:auto;max-width:1050px;padding:32px}.hero,.panel{background:#151d26;border:1px solid #283544;border-radius:24px;margin-bottom:16px;padding:22px}.hero{background:linear-gradient(135deg,rgba(20,184,166,.18),rgba(245,158,11,.12))}.eyebrow{color:#5eead4;font-weight:900;letter-spacing:.12em;text-transform:uppercase}h1{font-size:clamp(2.2rem,6vw,4.8rem);line-height:.92;margin:.2rem 0 1rem}.status{border:1px solid #3f3f46;border-radius:999px;display:inline-flex;font-weight:900;padding:8px 12px}.pass{color:#86efac}.fail{color:#fca5a5}.grid{display:grid;gap:12px;grid-template-columns:repeat(auto-fit,minmax(180px,1fr))}.metric{background:#0f151d;border:1px solid #283544;border-radius:16px;padding:14px}.metric strong{display:block;font-size:1.8rem}.pill{background:#0f151d;border:1px solid #3f3f46;border-radius:999px;display:inline-flex;margin:4px;padding:7px 10px}.issues{color:#fca5a5}code{color:#fde68a}@media(max-width:720px){main{padding:18px}}</style></head><body><main><section class="hero"><p class="eyebrow">Phone agent production smoke</p><h1>${escapeHtml32(title)}</h1><p class="status ${report.pass ? "pass" : "fail"}">${report.pass ? "PASS" : "FAIL"}</p><p>Contract <code>${escapeHtml32(report.contractId)}</code>${report.provider ? ` for <code>${escapeHtml32(report.provider)}</code>` : ""}${report.sessionId ? ` on session <code>${escapeHtml32(report.sessionId)}</code>` : ""}.</p></section><section class="panel"><h2>Observed Trace Evidence</h2><div class="grid"><div class="metric"><span>Media starts</span><strong>${String(report.observed.mediaStarts)}</strong></div><div class="metric"><span>Transcripts</span><strong>${String(report.observed.transcripts)}</strong></div><div class="metric"><span>Assistant responses</span><strong>${String(report.observed.assistantResponses)}</strong></div><div class="metric"><span>Session errors</span><strong>${String(report.observed.sessionErrors)}</strong></div></div><p>${outcomes || '<span class="pill">No lifecycle outcome</span>'}</p></section><section class="panel"><h2>Requirements</h2><p>${requirements}</p>${issues ? `<ul class="issues">${issues}</ul>` : '<p class="pass">All required phone-agent smoke evidence is present.</p>'}</section></main></body></html>`;
20753
+ const issues = report.issues.map((issue) => `<li><strong>${escapeHtml33(issue.requirement)}</strong>: ${escapeHtml33(issue.message)}</li>`).join("");
20754
+ const outcomes = report.observed.lifecycleOutcomes.map((outcome) => `<span class="pill">${escapeHtml33(outcome)}</span>`).join("");
20755
+ const requirements = report.required.map((requirement) => `<span class="pill">${escapeHtml33(requirement)}</span>`).join("");
20756
+ return `<!doctype html><html lang="en"><head><meta charset="utf-8" /><meta name="viewport" content="width=device-width, initial-scale=1" /><title>${escapeHtml33(title)}</title><style>body{background:#0e141b;color:#f8f3e7;font-family:ui-sans-serif,system-ui,sans-serif;margin:0}main{margin:auto;max-width:1050px;padding:32px}.hero,.panel{background:#151d26;border:1px solid #283544;border-radius:24px;margin-bottom:16px;padding:22px}.hero{background:linear-gradient(135deg,rgba(20,184,166,.18),rgba(245,158,11,.12))}.eyebrow{color:#5eead4;font-weight:900;letter-spacing:.12em;text-transform:uppercase}h1{font-size:clamp(2.2rem,6vw,4.8rem);line-height:.92;margin:.2rem 0 1rem}.status{border:1px solid #3f3f46;border-radius:999px;display:inline-flex;font-weight:900;padding:8px 12px}.pass{color:#86efac}.fail{color:#fca5a5}.grid{display:grid;gap:12px;grid-template-columns:repeat(auto-fit,minmax(180px,1fr))}.metric{background:#0f151d;border:1px solid #283544;border-radius:16px;padding:14px}.metric strong{display:block;font-size:1.8rem}.pill{background:#0f151d;border:1px solid #3f3f46;border-radius:999px;display:inline-flex;margin:4px;padding:7px 10px}.issues{color:#fca5a5}code{color:#fde68a}@media(max-width:720px){main{padding:18px}}</style></head><body><main><section class="hero"><p class="eyebrow">Phone agent production smoke</p><h1>${escapeHtml33(title)}</h1><p class="status ${report.pass ? "pass" : "fail"}">${report.pass ? "PASS" : "FAIL"}</p><p>Contract <code>${escapeHtml33(report.contractId)}</code>${report.provider ? ` for <code>${escapeHtml33(report.provider)}</code>` : ""}${report.sessionId ? ` on session <code>${escapeHtml33(report.sessionId)}</code>` : ""}.</p></section><section class="panel"><h2>Observed Trace Evidence</h2><div class="grid"><div class="metric"><span>Media starts</span><strong>${String(report.observed.mediaStarts)}</strong></div><div class="metric"><span>Transcripts</span><strong>${String(report.observed.transcripts)}</strong></div><div class="metric"><span>Assistant responses</span><strong>${String(report.observed.assistantResponses)}</strong></div><div class="metric"><span>Session errors</span><strong>${String(report.observed.sessionErrors)}</strong></div></div><p>${outcomes || '<span class="pill">No lifecycle outcome</span>'}</p></section><section class="panel"><h2>Requirements</h2><p>${requirements}</p>${issues ? `<ul class="issues">${issues}</ul>` : '<p class="pass">All required phone-agent smoke evidence is present.</p>'}</section></main></body></html>`;
20620
20757
  };
20621
20758
  var createVoicePhoneAgentProductionSmokeJSONHandler = (options) => async ({
20622
20759
  query,
@@ -20682,7 +20819,7 @@ var PHONE_AGENT_LIFECYCLE_STAGES = [
20682
20819
  "completed",
20683
20820
  "failed"
20684
20821
  ];
20685
- var escapeHtml33 = (value) => value.replaceAll("&", "&amp;").replaceAll('"', "&quot;").replaceAll("'", "&#39;").replaceAll("<", "&lt;").replaceAll(">", "&gt;");
20822
+ var escapeHtml34 = (value) => value.replaceAll("&", "&amp;").replaceAll('"', "&quot;").replaceAll("'", "&#39;").replaceAll("<", "&lt;").replaceAll(">", "&gt;");
20686
20823
  var loadRouteJson = async (input) => {
20687
20824
  const response = await input.app.handle(new Request(new URL(input.path, input.origin).toString(), {
20688
20825
  headers: {
@@ -20920,10 +21057,10 @@ var renderVoicePhoneAgentSetupHTML = (report) => {
20920
21057
  const entry = findCarrierMatrixEntry(report.matrix, carrier);
20921
21058
  const urls = entry?.setup.urls;
20922
21059
  const primaryUrl = carrier.provider === "plivo" ? urls?.twiml : urls?.twiml;
20923
- return `<tr><td>${escapeHtml33(carrier.name ?? carrier.provider)}</td><td>${escapeHtml33(carrier.provider)}</td><td><code>${escapeHtml33(carrier.setupPath || "disabled")}</code></td><td><code>${escapeHtml33(carrier.smokePath || "disabled")}</code></td><td>${entry ? `<span class="${escapeHtml33(entry.status)}">${escapeHtml33(entry.status.toUpperCase())}</span>` : "unknown"}</td><td>${primaryUrl ? `<code>${escapeHtml33(primaryUrl)}</code>` : '<span class="muted">missing</span>'}</td><td>${urls?.webhook ? `<code>${escapeHtml33(urls.webhook)}</code>` : '<span class="muted">missing</span>'}</td><td>${urls?.stream ? `<code>${escapeHtml33(urls.stream)}</code>` : '<span class="muted">missing</span>'}</td></tr>`;
21060
+ return `<tr><td>${escapeHtml34(carrier.name ?? carrier.provider)}</td><td>${escapeHtml34(carrier.provider)}</td><td><code>${escapeHtml34(carrier.setupPath || "disabled")}</code></td><td><code>${escapeHtml34(carrier.smokePath || "disabled")}</code></td><td>${entry ? `<span class="${escapeHtml34(entry.status)}">${escapeHtml34(entry.status.toUpperCase())}</span>` : "unknown"}</td><td>${primaryUrl ? `<code>${escapeHtml34(primaryUrl)}</code>` : '<span class="muted">missing</span>'}</td><td>${urls?.webhook ? `<code>${escapeHtml34(urls.webhook)}</code>` : '<span class="muted">missing</span>'}</td><td>${urls?.stream ? `<code>${escapeHtml34(urls.stream)}</code>` : '<span class="muted">missing</span>'}</td></tr>`;
20924
21061
  }).join("");
20925
- const stageList = report.lifecycleStages.map((stage) => `<li><code>${escapeHtml33(stage)}</code></li>`).join("");
20926
- const snippet = escapeHtml33(`const phoneAgent = createVoicePhoneAgent({
21062
+ const stageList = report.lifecycleStages.map((stage) => `<li><code>${escapeHtml34(stage)}</code></li>`).join("");
21063
+ const snippet = escapeHtml34(`const phoneAgent = createVoicePhoneAgent({
20927
21064
  carriers: [
20928
21065
  {
20929
21066
  provider: 'twilio',
@@ -20957,11 +21094,11 @@ app.use(
20957
21094
  );`);
20958
21095
  const checklist = report.carriers.map((carrier) => {
20959
21096
  const instruction = report.setupInstructions.find((candidate) => candidate.provider === carrier.provider && candidate.carrierName === (carrier.name ?? carrier.provider));
20960
- const issueList = instruction?.issues.map((issue) => `<li>${escapeHtml33(issue)}</li>`).join("") ?? "";
20961
- const steps = instruction?.steps.map((step) => `<li>${escapeHtml33(step)}</li>`).join("") ?? "";
20962
- return `<article><h3>${escapeHtml33(carrier.name ?? carrier.provider)}</h3><ol>${steps}</ol>${issueList ? `<ul class="issues">${issueList}</ul>` : '<p class="pass">No carrier contract issues.</p>'}</article>`;
21097
+ const issueList = instruction?.issues.map((issue) => `<li>${escapeHtml34(issue)}</li>`).join("") ?? "";
21098
+ const steps = instruction?.steps.map((step) => `<li>${escapeHtml34(step)}</li>`).join("") ?? "";
21099
+ return `<article><h3>${escapeHtml34(carrier.name ?? carrier.provider)}</h3><ol>${steps}</ol>${issueList ? `<ul class="issues">${issueList}</ul>` : '<p class="pass">No carrier contract issues.</p>'}</article>`;
20963
21100
  }).join("");
20964
- return `<!doctype html><html lang="en"><head><meta charset="utf-8" /><meta name="viewport" content="width=device-width, initial-scale=1" /><title>${escapeHtml33(report.title)}</title><style>body{background:#10151c;color:#f8f3e7;font-family:ui-sans-serif,system-ui,sans-serif;margin:0}main{margin:auto;max-width:1180px;padding:32px}.hero,.primitive{background:linear-gradient(135deg,rgba(20,184,166,.2),rgba(245,158,11,.12));border:1px solid #283544;border-radius:28px;margin-bottom:18px;padding:28px}.primitive{background:#151d27;border-color:#365a60}.eyebrow{color:#5eead4;font-weight:900;letter-spacing:.12em;text-transform:uppercase}h1{font-size:clamp(2.3rem,6vw,4.8rem);line-height:.92;margin:.2rem 0 1rem}.badge{border:1px solid #3f3f46;border-radius:999px;display:inline-flex;padding:8px 12px}.pass{color:#86efac}.fail{color:#fca5a5}.warn{color:#fde68a}.muted{color:#aab5c0}table{background:#151d27;border:1px solid #283544;border-collapse:collapse;border-radius:18px;display:block;overflow:auto;width:100%}td,th{border-bottom:1px solid #283544;padding:12px;text-align:left;vertical-align:top}code{color:#fde68a;overflow-wrap:anywhere}.primitive p{color:#cbd5de;line-height:1.55}.primitive pre{background:#0b1118;border:1px solid #283544;border-radius:18px;color:#fef3c7;overflow:auto;padding:16px}.checklist{display:grid;gap:14px;grid-template-columns:repeat(auto-fit,minmax(280px,1fr));margin:18px 0}.checklist article{background:#151d27;border:1px solid #283544;border-radius:18px;padding:18px}.checklist ol{padding-left:20px}.issues{color:#fca5a5}.stages{display:grid;gap:8px;grid-template-columns:repeat(auto-fit,minmax(180px,1fr));padding-left:18px}a{color:#5eead4}</style></head><body><main><section class="hero"><p class="eyebrow">Phone agent setup</p><h1>${escapeHtml33(report.title)}</h1><p>One self-hosted entrypoint for carrier routes, setup reports, smoke checks, and normalized call lifecycle stages.</p><p class="badge ${report.ready ? "pass" : "fail"}">Ready: ${String(report.ready)}</p>${report.matrixPath ? `<p><a href="${escapeHtml33(report.matrixPath)}?format=html">Open carrier matrix</a></p>` : ""}</section><section class="primitive"><p class="eyebrow">Copy into your app</p><h2><code>createVoicePhoneAgent(...)</code> builds this carrier control plane</h2><p>Mount carrier routes once, expose setup and smoke proof, then feed the same carrier matrix and phone-agent smoke reports into production readiness so carrier regressions block deploys.</p><pre><code>${snippet}</code></pre></section><h2>Carrier Setup Checklist</h2><section class="checklist">${checklist}</section><h2>Carrier URLs</h2><table><thead><tr><th>Name</th><th>Provider</th><th>Setup</th><th>Smoke</th><th>Status</th><th>Answer/TwiML/TeXML</th><th>Webhook</th><th>Stream</th></tr></thead><tbody>${carrierRows}</tbody></table><h2>Lifecycle Schema</h2><ul class="stages">${stageList}</ul></main></body></html>`;
21101
+ return `<!doctype html><html lang="en"><head><meta charset="utf-8" /><meta name="viewport" content="width=device-width, initial-scale=1" /><title>${escapeHtml34(report.title)}</title><style>body{background:#10151c;color:#f8f3e7;font-family:ui-sans-serif,system-ui,sans-serif;margin:0}main{margin:auto;max-width:1180px;padding:32px}.hero,.primitive{background:linear-gradient(135deg,rgba(20,184,166,.2),rgba(245,158,11,.12));border:1px solid #283544;border-radius:28px;margin-bottom:18px;padding:28px}.primitive{background:#151d27;border-color:#365a60}.eyebrow{color:#5eead4;font-weight:900;letter-spacing:.12em;text-transform:uppercase}h1{font-size:clamp(2.3rem,6vw,4.8rem);line-height:.92;margin:.2rem 0 1rem}.badge{border:1px solid #3f3f46;border-radius:999px;display:inline-flex;padding:8px 12px}.pass{color:#86efac}.fail{color:#fca5a5}.warn{color:#fde68a}.muted{color:#aab5c0}table{background:#151d27;border:1px solid #283544;border-collapse:collapse;border-radius:18px;display:block;overflow:auto;width:100%}td,th{border-bottom:1px solid #283544;padding:12px;text-align:left;vertical-align:top}code{color:#fde68a;overflow-wrap:anywhere}.primitive p{color:#cbd5de;line-height:1.55}.primitive pre{background:#0b1118;border:1px solid #283544;border-radius:18px;color:#fef3c7;overflow:auto;padding:16px}.checklist{display:grid;gap:14px;grid-template-columns:repeat(auto-fit,minmax(280px,1fr));margin:18px 0}.checklist article{background:#151d27;border:1px solid #283544;border-radius:18px;padding:18px}.checklist ol{padding-left:20px}.issues{color:#fca5a5}.stages{display:grid;gap:8px;grid-template-columns:repeat(auto-fit,minmax(180px,1fr));padding-left:18px}a{color:#5eead4}</style></head><body><main><section class="hero"><p class="eyebrow">Phone agent setup</p><h1>${escapeHtml34(report.title)}</h1><p>One self-hosted entrypoint for carrier routes, setup reports, smoke checks, and normalized call lifecycle stages.</p><p class="badge ${report.ready ? "pass" : "fail"}">Ready: ${String(report.ready)}</p>${report.matrixPath ? `<p><a href="${escapeHtml34(report.matrixPath)}?format=html">Open carrier matrix</a></p>` : ""}</section><section class="primitive"><p class="eyebrow">Copy into your app</p><h2><code>createVoicePhoneAgent(...)</code> builds this carrier control plane</h2><p>Mount carrier routes once, expose setup and smoke proof, then feed the same carrier matrix and phone-agent smoke reports into production readiness so carrier regressions block deploys.</p><pre><code>${snippet}</code></pre></section><h2>Carrier Setup Checklist</h2><section class="checklist">${checklist}</section><h2>Carrier URLs</h2><table><thead><tr><th>Name</th><th>Provider</th><th>Setup</th><th>Smoke</th><th>Status</th><th>Answer/TwiML/TeXML</th><th>Webhook</th><th>Stream</th></tr></thead><tbody>${carrierRows}</tbody></table><h2>Lifecycle Schema</h2><ul class="stages">${stageList}</ul></main></body></html>`;
20965
21102
  };
20966
21103
  var createVoicePhoneAgent = (options) => {
20967
21104
  const carrierSummaries = options.carriers.map((carrier) => ({
@@ -23030,7 +23167,7 @@ var createOpenAIVoiceTTS = (options) => {
23030
23167
  };
23031
23168
  // src/providerCapabilities.ts
23032
23169
  import { Elysia as Elysia36 } from "elysia";
23033
- var escapeHtml34 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
23170
+ var escapeHtml35 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
23034
23171
  var fromProviderList = (kind, providers, options) => (providers ?? []).map((provider) => ({
23035
23172
  configured: true,
23036
23173
  features: options.features?.[provider],
@@ -23093,27 +23230,27 @@ var summarizeVoiceProviderCapabilities = async (options) => {
23093
23230
  var renderVoiceProviderCapabilityHTML = (report, options = {}) => {
23094
23231
  const title = options.title ?? "Voice Provider Capabilities";
23095
23232
  const cards = report.capabilities.map((capability) => {
23096
- const features = (capability.features ?? []).map((feature) => `<span class="pill">${escapeHtml34(feature)}</span>`).join("");
23097
- return `<article class="card ${escapeHtml34(capability.status)}">
23233
+ const features = (capability.features ?? []).map((feature) => `<span class="pill">${escapeHtml35(feature)}</span>`).join("");
23234
+ return `<article class="card ${escapeHtml35(capability.status)}">
23098
23235
  <div class="card-header">
23099
23236
  <div>
23100
- <p class="eyebrow">${escapeHtml34(capability.kind)}</p>
23101
- <h2>${escapeHtml34(capability.label ?? capability.provider)}</h2>
23237
+ <p class="eyebrow">${escapeHtml35(capability.kind)}</p>
23238
+ <h2>${escapeHtml35(capability.label ?? capability.provider)}</h2>
23102
23239
  </div>
23103
- <strong>${escapeHtml34(capability.status)}</strong>
23240
+ <strong>${escapeHtml35(capability.status)}</strong>
23104
23241
  </div>
23105
- ${capability.description ? `<p>${escapeHtml34(capability.description)}</p>` : ""}
23242
+ ${capability.description ? `<p>${escapeHtml35(capability.description)}</p>` : ""}
23106
23243
  <dl>
23107
23244
  <div><dt>Configured</dt><dd>${capability.configured ? "yes" : "no"}</dd></div>
23108
23245
  <div><dt>Selected</dt><dd>${capability.selected ? "yes" : "no"}</dd></div>
23109
- <div><dt>Model</dt><dd>${escapeHtml34(capability.model ?? "default")}</dd></div>
23246
+ <div><dt>Model</dt><dd>${escapeHtml35(capability.model ?? "default")}</dd></div>
23110
23247
  <div><dt>Runs</dt><dd>${String(capability.health?.runCount ?? 0)}</dd></div>
23111
23248
  <div><dt>Errors</dt><dd>${String(capability.health?.errorCount ?? 0)}</dd></div>
23112
23249
  </dl>
23113
23250
  ${features ? `<div class="features">${features}</div>` : ""}
23114
23251
  </article>`;
23115
23252
  }).join("");
23116
- return `<!doctype html><html lang="en"><head><meta charset="utf-8" /><meta name="viewport" content="width=device-width, initial-scale=1" /><title>${escapeHtml34(title)}</title><style>body{background:#101316;color:#f6f2e8;font-family:ui-sans-serif,system-ui,sans-serif;margin:0}main{margin:auto;max-width:1180px;padding:32px}.hero,.card{background:#181d22;border:1px solid #2a323a;border-radius:20px;margin-bottom:16px;padding:20px}.hero{background:linear-gradient(135deg,rgba(14,165,233,.16),rgba(34,197,94,.12))}.eyebrow{color:#7dd3fc;font-size:.78rem;font-weight:900;letter-spacing:.08em;text-transform:uppercase}h1{font-size:clamp(2.3rem,6vw,5rem);letter-spacing:-.06em;line-height:.9;margin:.2rem 0 1rem}h2{margin:.2rem 0 1rem}.summary,.features{display:flex;flex-wrap:wrap;gap:10px}.pill{background:#0f1217;border:1px solid #3f3f46;border-radius:999px;padding:7px 10px}.grid{display:grid;gap:16px;grid-template-columns:repeat(auto-fit,minmax(260px,1fr))}.card-header{align-items:flex-start;display:flex;gap:16px;justify-content:space-between}.selected,.healthy{color:#86efac}.unconfigured,.degraded,.rate-limited,.suppressed{color:#fca5a5}.idle,.recoverable{color:#fde68a}dl{display:grid;gap:8px;grid-template-columns:repeat(2,minmax(0,1fr))}dt{color:#a8b0b8;font-size:.8rem}dd{margin:0}@media(max-width:800px){main{padding:18px}.card-header{display:block}}</style></head><body><main><section class="hero"><p class="eyebrow">Provider Discovery</p><h1>${escapeHtml34(title)}</h1><div class="summary"><span class="pill">${String(report.configured)} configured</span><span class="pill">${String(report.selected)} selected</span><span class="pill">${String(report.unconfigured)} missing</span><span class="pill">${String(report.total)} total</span></div></section><section class="grid">${cards || '<article class="card"><p>No provider capabilities configured.</p></article>'}</section></main></body></html>`;
23253
+ return `<!doctype html><html lang="en"><head><meta charset="utf-8" /><meta name="viewport" content="width=device-width, initial-scale=1" /><title>${escapeHtml35(title)}</title><style>body{background:#101316;color:#f6f2e8;font-family:ui-sans-serif,system-ui,sans-serif;margin:0}main{margin:auto;max-width:1180px;padding:32px}.hero,.card{background:#181d22;border:1px solid #2a323a;border-radius:20px;margin-bottom:16px;padding:20px}.hero{background:linear-gradient(135deg,rgba(14,165,233,.16),rgba(34,197,94,.12))}.eyebrow{color:#7dd3fc;font-size:.78rem;font-weight:900;letter-spacing:.08em;text-transform:uppercase}h1{font-size:clamp(2.3rem,6vw,5rem);letter-spacing:-.06em;line-height:.9;margin:.2rem 0 1rem}h2{margin:.2rem 0 1rem}.summary,.features{display:flex;flex-wrap:wrap;gap:10px}.pill{background:#0f1217;border:1px solid #3f3f46;border-radius:999px;padding:7px 10px}.grid{display:grid;gap:16px;grid-template-columns:repeat(auto-fit,minmax(260px,1fr))}.card-header{align-items:flex-start;display:flex;gap:16px;justify-content:space-between}.selected,.healthy{color:#86efac}.unconfigured,.degraded,.rate-limited,.suppressed{color:#fca5a5}.idle,.recoverable{color:#fde68a}dl{display:grid;gap:8px;grid-template-columns:repeat(2,minmax(0,1fr))}dt{color:#a8b0b8;font-size:.8rem}dd{margin:0}@media(max-width:800px){main{padding:18px}.card-header{display:block}}</style></head><body><main><section class="hero"><p class="eyebrow">Provider Discovery</p><h1>${escapeHtml35(title)}</h1><div class="summary"><span class="pill">${String(report.configured)} configured</span><span class="pill">${String(report.selected)} selected</span><span class="pill">${String(report.unconfigured)} missing</span><span class="pill">${String(report.total)} total</span></div></section><section class="grid">${cards || '<article class="card"><p>No provider capabilities configured.</p></article>'}</section></main></body></html>`;
23117
23254
  };
23118
23255
  var createVoiceProviderCapabilityJSONHandler = (options) => async () => summarizeVoiceProviderCapabilities(options);
23119
23256
  var createVoiceProviderCapabilityHTMLHandler = (options) => async () => {
@@ -23140,7 +23277,7 @@ var createVoiceProviderCapabilityRoutes = (options) => {
23140
23277
  };
23141
23278
  // src/resilienceRoutes.ts
23142
23279
  import { Elysia as Elysia37 } from "elysia";
23143
- var escapeHtml35 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
23280
+ var escapeHtml36 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
23144
23281
  var getString13 = (value) => typeof value === "string" ? value : undefined;
23145
23282
  var getNumber7 = (value) => typeof value === "number" && Number.isFinite(value) ? value : undefined;
23146
23283
  var getBoolean2 = (value) => value === true;
@@ -23288,13 +23425,13 @@ var summarizeRoutingEvents = (events) => {
23288
23425
  };
23289
23426
  var renderProviderCards = (title, providers) => {
23290
23427
  if (providers.length === 0) {
23291
- return `<p class="muted">No ${escapeHtml35(title)} provider health yet.</p>`;
23428
+ return `<p class="muted">No ${escapeHtml36(title)} provider health yet.</p>`;
23292
23429
  }
23293
23430
  return `<div class="provider-grid">${providers.map((provider) => `
23294
- <article class="card provider ${escapeHtml35(provider.status)}">
23431
+ <article class="card provider ${escapeHtml36(provider.status)}">
23295
23432
  <div class="card-header">
23296
- <strong>${escapeHtml35(provider.provider)}</strong>
23297
- <span>${escapeHtml35(provider.status)}${provider.recommended ? " \xB7 recommended" : ""}</span>
23433
+ <strong>${escapeHtml36(provider.provider)}</strong>
23434
+ <span>${escapeHtml36(provider.status)}${provider.recommended ? " \xB7 recommended" : ""}</span>
23298
23435
  </div>
23299
23436
  <dl>
23300
23437
  <div><dt>Runs</dt><dd>${provider.runCount}</dd></div>
@@ -23303,7 +23440,7 @@ var renderProviderCards = (title, providers) => {
23303
23440
  <div><dt>Timeouts</dt><dd>${provider.timeoutCount}</dd></div>
23304
23441
  <div><dt>Fallbacks</dt><dd>${provider.fallbackCount}</dd></div>
23305
23442
  </dl>
23306
- ${provider.lastError ? `<p class="muted">${escapeHtml35(provider.lastError)}</p>` : ""}
23443
+ ${provider.lastError ? `<p class="muted">${escapeHtml36(provider.lastError)}</p>` : ""}
23307
23444
  </article>
23308
23445
  `).join("")}</div>`;
23309
23446
  };
@@ -23312,24 +23449,24 @@ var renderTimeline2 = (events) => {
23312
23449
  return '<p class="muted">No provider routing events yet. Run the app or simulate provider failover.</p>';
23313
23450
  }
23314
23451
  return `<div class="timeline">${events.slice(0, 40).map((event) => `
23315
- <article class="card event ${escapeHtml35(event.status ?? "unknown")}">
23452
+ <article class="card event ${escapeHtml36(event.status ?? "unknown")}">
23316
23453
  <div class="card-header">
23317
- <strong>${escapeHtml35(event.kind.toUpperCase())} ${escapeHtml35(event.operation ?? "generate")}</strong>
23454
+ <strong>${escapeHtml36(event.kind.toUpperCase())} ${escapeHtml36(event.operation ?? "generate")}</strong>
23318
23455
  <span>${new Date(event.at).toLocaleString()}</span>
23319
23456
  </div>
23320
23457
  <p>
23321
- <span class="pill">${escapeHtml35(event.status ?? "unknown")}</span>
23322
- <span class="pill">provider: ${escapeHtml35(event.provider ?? "unknown")}</span>
23323
- ${event.fallbackProvider ? `<span class="pill">fallback: ${escapeHtml35(event.fallbackProvider)}</span>` : ""}
23458
+ <span class="pill">${escapeHtml36(event.status ?? "unknown")}</span>
23459
+ <span class="pill">provider: ${escapeHtml36(event.provider ?? "unknown")}</span>
23460
+ ${event.fallbackProvider ? `<span class="pill">fallback: ${escapeHtml36(event.fallbackProvider)}</span>` : ""}
23324
23461
  ${event.timedOut ? '<span class="pill danger">timed out</span>' : ""}
23325
23462
  </p>
23326
23463
  <dl>
23327
23464
  <div><dt>Attempt</dt><dd>${event.attempt ?? 0}</dd></div>
23328
23465
  <div><dt>Elapsed</dt><dd>${event.elapsedMs ?? 0}ms</dd></div>
23329
23466
  <div><dt>Budget</dt><dd>${event.latencyBudgetMs ?? 0}ms</dd></div>
23330
- <div><dt>Session</dt><dd>${escapeHtml35(event.sessionId)}</dd></div>
23467
+ <div><dt>Session</dt><dd>${escapeHtml36(event.sessionId)}</dd></div>
23331
23468
  </dl>
23332
- ${event.error ? `<p class="muted">${escapeHtml35(event.error)}</p>` : ""}
23469
+ ${event.error ? `<p class="muted">${escapeHtml36(event.error)}</p>` : ""}
23333
23470
  </article>
23334
23471
  `).join("")}</div>`;
23335
23472
  };
@@ -23339,9 +23476,9 @@ var renderSessionKind = (kind, summary) => {
23339
23476
  const status = latest?.status ?? "idle";
23340
23477
  const fallback = latest?.fallbackProvider && latest.fallbackProvider !== provider ? ` -> ${latest.fallbackProvider}` : "";
23341
23478
  return `<div>
23342
- <dt>${escapeHtml35(kind.toUpperCase())}</dt>
23343
- <dd>${escapeHtml35(provider)}${escapeHtml35(fallback)}</dd>
23344
- <small>${escapeHtml35(status)} \xB7 ${summary.runCount} event${summary.runCount === 1 ? "" : "s"} \xB7 ${summary.errorCount} error${summary.errorCount === 1 ? "" : "s"} \xB7 ${summary.fallbackCount} fallback${summary.fallbackCount === 1 ? "" : "s"}</small>
23479
+ <dt>${escapeHtml36(kind.toUpperCase())}</dt>
23480
+ <dd>${escapeHtml36(provider)}${escapeHtml36(fallback)}</dd>
23481
+ <small>${escapeHtml36(status)} \xB7 ${summary.runCount} event${summary.runCount === 1 ? "" : "s"} \xB7 ${summary.errorCount} error${summary.errorCount === 1 ? "" : "s"} \xB7 ${summary.fallbackCount} fallback${summary.fallbackCount === 1 ? "" : "s"}</small>
23345
23482
  </div>`;
23346
23483
  };
23347
23484
  var renderSessionSummaries = (sessions) => {
@@ -23349,10 +23486,10 @@ var renderSessionSummaries = (sessions) => {
23349
23486
  return '<p class="muted">No call-level routing summaries yet. Run a voice session or provider simulation.</p>';
23350
23487
  }
23351
23488
  return `<div class="session-grid">${sessions.slice(0, 12).map((session) => `
23352
- <article class="card session ${escapeHtml35(session.status)}">
23489
+ <article class="card session ${escapeHtml36(session.status)}">
23353
23490
  <div class="card-header">
23354
- <strong>${escapeHtml35(session.sessionId)}</strong>
23355
- <span>${escapeHtml35(session.status)}</span>
23491
+ <strong>${escapeHtml36(session.sessionId)}</strong>
23492
+ <span>${escapeHtml36(session.status)}</span>
23356
23493
  </div>
23357
23494
  <p>
23358
23495
  <span class="pill">${session.eventCount} routing events</span>
@@ -23379,21 +23516,21 @@ var renderSimulationControls = (kind, simulation) => {
23379
23516
  const pathPrefix = simulation.pathPrefix ?? `/api/${kind}-simulate`;
23380
23517
  const failureProviders = simulation.failureProviders ?? configuredProviders.map(({ provider }) => provider);
23381
23518
  const canFail = (provider) => configuredProviders.some((entry) => entry.provider === provider) && (!simulation.fallbackRequiredProvider || configuredProviders.some((entry) => entry.provider === simulation.fallbackRequiredProvider));
23382
- return `<div class="simulate-panel" data-sim-kind="${kind}" data-sim-prefix="${escapeHtml35(pathPrefix)}">
23383
- <p class="muted">${escapeHtml35(simulation.failureMessage ?? `Simulate ${kind.toUpperCase()} provider failure without changing provider credentials.`)}</p>
23519
+ return `<div class="simulate-panel" data-sim-kind="${kind}" data-sim-prefix="${escapeHtml36(pathPrefix)}">
23520
+ <p class="muted">${escapeHtml36(simulation.failureMessage ?? `Simulate ${kind.toUpperCase()} provider failure without changing provider credentials.`)}</p>
23384
23521
  <div class="simulate-actions">
23385
- ${failureProviders.map((provider) => `<button type="button" data-provider-fail="${escapeHtml35(provider)}"${canFail(provider) ? "" : " disabled"}>Simulate ${escapeHtml35(provider)} ${kind.toUpperCase()} failure</button>`).join("")}
23386
- ${configuredProviders.map((provider) => `<button type="button" data-provider-recover="${escapeHtml35(provider.provider)}">Mark ${escapeHtml35(provider.provider)} recovered</button>`).join("")}
23522
+ ${failureProviders.map((provider) => `<button type="button" data-provider-fail="${escapeHtml36(provider)}"${canFail(provider) ? "" : " disabled"}>Simulate ${escapeHtml36(provider)} ${kind.toUpperCase()} failure</button>`).join("")}
23523
+ ${configuredProviders.map((provider) => `<button type="button" data-provider-recover="${escapeHtml36(provider.provider)}">Mark ${escapeHtml36(provider.provider)} recovered</button>`).join("")}
23387
23524
  </div>
23388
- ${simulation.fallbackRequiredProvider && !configuredProviders.some((entry) => entry.provider === simulation.fallbackRequiredProvider) ? `<p class="muted">${escapeHtml35(simulation.fallbackRequiredMessage ?? `Configure ${simulation.fallbackRequiredProvider} to enable fallback simulation.`)}</p>` : ""}
23525
+ ${simulation.fallbackRequiredProvider && !configuredProviders.some((entry) => entry.provider === simulation.fallbackRequiredProvider) ? `<p class="muted">${escapeHtml36(simulation.fallbackRequiredMessage ?? `Configure ${simulation.fallbackRequiredProvider} to enable fallback simulation.`)}</p>` : ""}
23389
23526
  <pre class="simulate-output" hidden></pre>
23390
23527
  </div>`;
23391
23528
  };
23392
23529
  var renderVoiceResilienceHTML = (input) => {
23393
23530
  const summary = summarizeRoutingEvents(input.routingEvents);
23394
- const kindCounts = [...summary.byKind.entries()].map(([kind, count]) => `<span class="pill">${escapeHtml35(kind)}: ${String(count)}</span>`).join("");
23395
- const links = input.links?.length ? input.links.map((link) => `<a href="${escapeHtml35(link.href)}">${escapeHtml35(link.label)}</a>`).join(" \xB7 ") : "";
23396
- const snippet = escapeHtml35(`const sttSimulator = createVoiceIOProviderFailureSimulator({
23531
+ const kindCounts = [...summary.byKind.entries()].map(([kind, count]) => `<span class="pill">${escapeHtml36(kind)}: ${String(count)}</span>`).join("");
23532
+ const links = input.links?.length ? input.links.map((link) => `<a href="${escapeHtml36(link.href)}">${escapeHtml36(link.label)}</a>`).join(" \xB7 ") : "";
23533
+ const snippet = escapeHtml36(`const sttSimulator = createVoiceIOProviderFailureSimulator({
23397
23534
  kind: 'stt',
23398
23535
  providers: ['deepgram', 'assemblyai'],
23399
23536
  fallback: ['deepgram', 'assemblyai'],
@@ -23431,7 +23568,7 @@ app.use(
23431
23568
  <head>
23432
23569
  <meta charset="utf-8" />
23433
23570
  <meta name="viewport" content="width=device-width, initial-scale=1" />
23434
- <title>${escapeHtml35(input.title ?? "AbsoluteJS Voice Resilience")}</title>
23571
+ <title>${escapeHtml36(input.title ?? "AbsoluteJS Voice Resilience")}</title>
23435
23572
  <style>
23436
23573
  :root { color-scheme: dark; }
23437
23574
  body { background: radial-gradient(circle at top left, #172554, #09090b 36%, #050505); color: #f4f4f5; font-family: ui-sans-serif, system-ui, sans-serif; margin: 0; padding: 24px; }
@@ -23798,7 +23935,7 @@ var statusRank = {
23798
23935
  warn: 1,
23799
23936
  fail: 2
23800
23937
  };
23801
- var escapeHtml36 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
23938
+ var escapeHtml37 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
23802
23939
  var roundMetric3 = (value) => Math.round(value * 1e4) / 1e4;
23803
23940
  var rate3 = (count, total) => count / Math.max(1, total);
23804
23941
  var uniqueSorted5 = (values) => [
@@ -24094,11 +24231,11 @@ var renderVoiceProviderSloHTML = (report, options = {}) => {
24094
24231
  const title = options.title ?? "AbsoluteJS Voice Provider SLOs";
24095
24232
  const kindCards = providerKinds.map((kind) => {
24096
24233
  const kindReport = report.kinds[kind];
24097
- const metrics = Object.values(kindReport.metrics).map((metric) => `<div><dt>${escapeHtml36(metric.label)}</dt><dd>${escapeHtml36(formatMetricValue2(metric))}</dd><small>budget ${escapeHtml36(formatMetricThreshold(metric))}</small></div>`).join("");
24234
+ const metrics = Object.values(kindReport.metrics).map((metric) => `<div><dt>${escapeHtml37(metric.label)}</dt><dd>${escapeHtml37(formatMetricValue2(metric))}</dd><small>budget ${escapeHtml37(formatMetricThreshold(metric))}</small></div>`).join("");
24098
24235
  const providers = kindReport.providers.length ? kindReport.providers.join(", ") : "none recorded";
24099
- return `<article class="${escapeHtml36(kindReport.status)}"><h2>${kind.toUpperCase()} <span>${escapeHtml36(kindReport.status)}</span></h2><p>${kindReport.events} routing event(s), ${kindReport.eventsWithLatency} latency sample(s), providers: ${escapeHtml36(providers)}.</p><dl>${metrics}</dl></article>`;
24236
+ return `<article class="${escapeHtml37(kindReport.status)}"><h2>${kind.toUpperCase()} <span>${escapeHtml37(kindReport.status)}</span></h2><p>${kindReport.events} routing event(s), ${kindReport.eventsWithLatency} latency sample(s), providers: ${escapeHtml37(providers)}.</p><dl>${metrics}</dl></article>`;
24100
24237
  }).join("");
24101
- const issues = report.issues.length > 0 ? `<ul>${report.issues.map((issue) => `<li class="${escapeHtml36(issue.status)}"><strong>${escapeHtml36(issue.kind ? `${issue.kind.toUpperCase()} ${issue.label}` : issue.label)}</strong><span>${escapeHtml36(issue.detail ?? "")}</span></li>`).join("")}</ul>` : "<p>No provider SLO issues.</p>";
24238
+ const issues = report.issues.length > 0 ? `<ul>${report.issues.map((issue) => `<li class="${escapeHtml37(issue.status)}"><strong>${escapeHtml37(issue.kind ? `${issue.kind.toUpperCase()} ${issue.label}` : issue.label)}</strong><span>${escapeHtml37(issue.detail ?? "")}</span></li>`).join("")}</ul>` : "<p>No provider SLO issues.</p>";
24102
24239
  const snippet = `createVoiceProviderSloRoutes({
24103
24240
  store: runtimeStorage.traces,
24104
24241
  requiredKinds: ['llm', 'stt', 'tts'],
@@ -24108,7 +24245,7 @@ var renderVoiceProviderSloHTML = (report, options = {}) => {
24108
24245
  tts: { maxAverageElapsedMs: 1200, maxP95ElapsedMs: 2200 }
24109
24246
  }
24110
24247
  })`;
24111
- return `<!doctype html><html lang="en"><head><meta charset="utf-8" /><meta name="viewport" content="width=device-width, initial-scale=1" /><title>${escapeHtml36(title)}</title><style>body{background:#101318;color:#f8f4e8;font-family:ui-sans-serif,system-ui,sans-serif;margin:0}main{margin:auto;max-width:1180px;padding:32px}.hero,article,.primitive{background:#171b22;border:1px solid #2c3340;border-radius:24px;margin-bottom:16px;padding:22px}.hero{background:linear-gradient(135deg,rgba(14,165,233,.2),rgba(245,158,11,.12))}.eyebrow{color:#7dd3fc;font-weight:900;letter-spacing:.12em;text-transform:uppercase}h1{font-size:clamp(2.3rem,6vw,4.9rem);letter-spacing:-.06em;line-height:.9;margin:.2rem 0 1rem}.status,article h2 span{border:1px solid #475569;border-radius:999px;display:inline-flex;font-size:.85rem;padding:6px 10px}.pass{border-color:rgba(34,197,94,.65)}.warn{border-color:rgba(245,158,11,.7)}.fail{border-color:rgba(239,68,68,.75)}.grid{display:grid;gap:14px;grid-template-columns:repeat(auto-fit,minmax(280px,1fr))}dl{display:grid;gap:10px;grid-template-columns:repeat(auto-fit,minmax(150px,1fr))}dt{color:#cbd5e1;font-size:.78rem;text-transform:uppercase}dd{font-size:1.7rem;font-weight:900;margin:0}small{color:#a8b3c2}ul{display:grid;gap:10px;list-style:none;padding:0}li{background:#101318;border:1px solid #2c3340;border-radius:16px;padding:12px}li span{color:#cbd5e1;display:block;margin-top:4px}.primitive{background:#11161d}.primitive code{color:#bae6fd}.primitive pre{background:#070b10;border:1px solid #243041;border-radius:16px;color:#e0f2fe;overflow:auto;padding:16px}</style></head><body><main><section class="hero"><p class="eyebrow">Provider latency and fallback proof</p><h1>${escapeHtml36(title)}</h1><p class="status ${escapeHtml36(report.status)}">${escapeHtml36(report.status)}</p><p>${report.events} provider routing event(s), ${report.eventsWithLatency} latency sample(s).</p></section><section class="grid">${kindCards}</section><section class="primitive"><p class="eyebrow">Copy into your app</p><h2><code>createVoiceProviderSloRoutes(...)</code> turns provider speed into release evidence</h2><p>Pair this report with production readiness so LLM/STT/TTS latency, timeout, fallback, and unresolved error regressions block deploys.</p><pre><code>${escapeHtml36(snippet)}</code></pre></section><section><h2>Issues</h2>${issues}</section></main></body></html>`;
24248
+ return `<!doctype html><html lang="en"><head><meta charset="utf-8" /><meta name="viewport" content="width=device-width, initial-scale=1" /><title>${escapeHtml37(title)}</title><style>body{background:#101318;color:#f8f4e8;font-family:ui-sans-serif,system-ui,sans-serif;margin:0}main{margin:auto;max-width:1180px;padding:32px}.hero,article,.primitive{background:#171b22;border:1px solid #2c3340;border-radius:24px;margin-bottom:16px;padding:22px}.hero{background:linear-gradient(135deg,rgba(14,165,233,.2),rgba(245,158,11,.12))}.eyebrow{color:#7dd3fc;font-weight:900;letter-spacing:.12em;text-transform:uppercase}h1{font-size:clamp(2.3rem,6vw,4.9rem);letter-spacing:-.06em;line-height:.9;margin:.2rem 0 1rem}.status,article h2 span{border:1px solid #475569;border-radius:999px;display:inline-flex;font-size:.85rem;padding:6px 10px}.pass{border-color:rgba(34,197,94,.65)}.warn{border-color:rgba(245,158,11,.7)}.fail{border-color:rgba(239,68,68,.75)}.grid{display:grid;gap:14px;grid-template-columns:repeat(auto-fit,minmax(280px,1fr))}dl{display:grid;gap:10px;grid-template-columns:repeat(auto-fit,minmax(150px,1fr))}dt{color:#cbd5e1;font-size:.78rem;text-transform:uppercase}dd{font-size:1.7rem;font-weight:900;margin:0}small{color:#a8b3c2}ul{display:grid;gap:10px;list-style:none;padding:0}li{background:#101318;border:1px solid #2c3340;border-radius:16px;padding:12px}li span{color:#cbd5e1;display:block;margin-top:4px}.primitive{background:#11161d}.primitive code{color:#bae6fd}.primitive pre{background:#070b10;border:1px solid #243041;border-radius:16px;color:#e0f2fe;overflow:auto;padding:16px}</style></head><body><main><section class="hero"><p class="eyebrow">Provider latency and fallback proof</p><h1>${escapeHtml37(title)}</h1><p class="status ${escapeHtml37(report.status)}">${escapeHtml37(report.status)}</p><p>${report.events} provider routing event(s), ${report.eventsWithLatency} latency sample(s).</p></section><section class="grid">${kindCards}</section><section class="primitive"><p class="eyebrow">Copy into your app</p><h2><code>createVoiceProviderSloRoutes(...)</code> turns provider speed into release evidence</h2><p>Pair this report with production readiness so LLM/STT/TTS latency, timeout, fallback, and unresolved error regressions block deploys.</p><pre><code>${escapeHtml37(snippet)}</code></pre></section><section><h2>Issues</h2>${issues}</section></main></body></html>`;
24112
24249
  };
24113
24250
  var createVoiceProviderSloRoutes = (options) => {
24114
24251
  const path = options.path ?? "/api/voice/provider-slos";
@@ -24948,7 +25085,7 @@ var createVoiceTelephonyWebhookSecurityPreset = (options = {}) => {
24948
25085
 
24949
25086
  // src/opsRecovery.ts
24950
25087
  import { Elysia as Elysia40 } from "elysia";
24951
- var escapeHtml37 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
25088
+ var escapeHtml38 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
24952
25089
  var getString14 = (value) => typeof value === "string" && value.trim() ? value.trim() : undefined;
24953
25090
  var hrefForSession = (value, sessionId) => {
24954
25091
  if (typeof value === "function") {
@@ -25162,13 +25299,13 @@ ${failedSessions || "None."}
25162
25299
  ${report.latency ? renderVoiceLatencySLOMarkdown(report.latency, { title: "Latency SLO" }) : "Latency SLO disabled."}
25163
25300
  `;
25164
25301
  };
25165
- var renderDeliverySummary = (label, summary) => summary ? `<article><span>${escapeHtml37(label)}</span><strong>${String(summary.failed + summary.deadLettered)} failed</strong><small>${String(summary.pending)} pending \xB7 ${String(summary.retryEligible)} retry eligible \xB7 ${String(summary.total)} total</small></article>` : `<article><span>${escapeHtml37(label)}</span><strong>not configured</strong></article>`;
25302
+ var renderDeliverySummary = (label, summary) => summary ? `<article><span>${escapeHtml38(label)}</span><strong>${String(summary.failed + summary.deadLettered)} failed</strong><small>${String(summary.pending)} pending \xB7 ${String(summary.retryEligible)} retry eligible \xB7 ${String(summary.total)} total</small></article>` : `<article><span>${escapeHtml38(label)}</span><strong>not configured</strong></article>`;
25166
25303
  var renderVoiceOpsRecoveryHTML = (report, options = {}) => {
25167
25304
  const title = options.title ?? "Voice Ops Recovery";
25168
- const issues = report.issues.map((issue) => `<tr><td>${escapeHtml37(issue.severity)}</td><td><code>${escapeHtml37(issue.code)}</code></td><td>${issue.href ? `<a href="${escapeHtml37(issue.href)}">${escapeHtml37(issue.label)}</a>` : escapeHtml37(issue.label)}</td><td>${escapeHtml37(String(issue.value ?? ""))}</td><td>${escapeHtml37(issue.detail ?? "")}</td></tr>`).join("");
25169
- const providers = report.providers.providers.map((provider) => `<tr><td>${escapeHtml37(provider.provider)}</td><td>${escapeHtml37(provider.status)}</td><td>${String(provider.runCount)}</td><td>${String(provider.errorCount)}</td><td>${String(provider.fallbackCount)}</td><td>${escapeHtml37(provider.lastError ?? "")}</td></tr>`).join("");
25170
- const failedSessions = report.failedSessions.map((session) => `<li>${session.operationsRecordHref ? `<a href="${escapeHtml37(session.operationsRecordHref)}">${escapeHtml37(session.sessionId)}</a>` : escapeHtml37(session.sessionId)}${session.provider ? ` via ${escapeHtml37(session.provider)}` : ""}${session.error ? `: ${escapeHtml37(session.error)}` : ""}</li>`).join("");
25171
- return `<!doctype html><html lang="en"><head><meta charset="utf-8" /><meta name="viewport" content="width=device-width, initial-scale=1" /><title>${escapeHtml37(title)}</title><style>body{font-family:ui-sans-serif,system-ui,sans-serif;background:#f8fafc;color:#172033;margin:2rem;line-height:1.45}main{max-width:1180px;margin:auto}.grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(190px,1fr));gap:.75rem;margin:1rem 0}article{background:white;border:1px solid #dbe3ef;border-radius:14px;padding:1rem;box-shadow:0 10px 28px rgba(15,23,42,.05)}article span{display:block;color:#64748b;font-size:.85rem}article strong{display:block;font-size:1.5rem;margin:.2rem 0}article small{color:#64748b}table{border-collapse:collapse;width:100%;background:white;border:1px solid #dbe3ef;border-radius:14px;overflow:hidden}th,td{border-bottom:1px solid #e2e8f0;padding:.7rem;text-align:left;vertical-align:top}code{font-size:.85em}.status{display:inline-flex;border-radius:999px;padding:.35rem .7rem;background:${report.status === "fail" ? "#fee2e2" : report.status === "warn" ? "#fef3c7" : "#dcfce7"};color:${report.status === "fail" ? "#991b1b" : report.status === "warn" ? "#92400e" : "#166534"};font-weight:700}</style></head><body><main><h1>${escapeHtml37(title)}</h1><p><span class="status">${escapeHtml37(report.status)}</span> Checked ${escapeHtml37(new Date(report.checkedAt).toLocaleString())}</p><section class="grid"><article><span>Recovered fallbacks</span><strong>${String(report.providers.recoveredFallbacks)}</strong></article><article><span>Unresolved providers</span><strong>${String(report.providers.unresolvedFailures)}</strong></article><article><span>Operator interventions</span><strong>${String(report.interventions.total)}</strong></article><article><span>Latency status</span><strong>${escapeHtml37(report.latency?.status ?? "disabled")}</strong></article>${renderDeliverySummary("Audit delivery", report.auditDeliveries)}${renderDeliverySummary("Trace delivery", report.traceDeliveries)}${renderDeliverySummary("Handoff delivery", report.handoffDeliveries)}</section><h2>Issues</h2><table><thead><tr><th>Severity</th><th>Code</th><th>Label</th><th>Value</th><th>Detail</th></tr></thead><tbody>${issues || '<tr><td colspan="5">No recovery issues.</td></tr>'}</tbody></table><h2>Providers</h2><table><thead><tr><th>Provider</th><th>Status</th><th>Runs</th><th>Errors</th><th>Fallbacks</th><th>Last error</th></tr></thead><tbody>${providers || '<tr><td colspan="6">No provider activity.</td></tr>'}</tbody></table><h2>Failed Sessions</h2><ul>${failedSessions || "<li>None.</li>"}</ul></main></body></html>`;
25305
+ const issues = report.issues.map((issue) => `<tr><td>${escapeHtml38(issue.severity)}</td><td><code>${escapeHtml38(issue.code)}</code></td><td>${issue.href ? `<a href="${escapeHtml38(issue.href)}">${escapeHtml38(issue.label)}</a>` : escapeHtml38(issue.label)}</td><td>${escapeHtml38(String(issue.value ?? ""))}</td><td>${escapeHtml38(issue.detail ?? "")}</td></tr>`).join("");
25306
+ const providers = report.providers.providers.map((provider) => `<tr><td>${escapeHtml38(provider.provider)}</td><td>${escapeHtml38(provider.status)}</td><td>${String(provider.runCount)}</td><td>${String(provider.errorCount)}</td><td>${String(provider.fallbackCount)}</td><td>${escapeHtml38(provider.lastError ?? "")}</td></tr>`).join("");
25307
+ const failedSessions = report.failedSessions.map((session) => `<li>${session.operationsRecordHref ? `<a href="${escapeHtml38(session.operationsRecordHref)}">${escapeHtml38(session.sessionId)}</a>` : escapeHtml38(session.sessionId)}${session.provider ? ` via ${escapeHtml38(session.provider)}` : ""}${session.error ? `: ${escapeHtml38(session.error)}` : ""}</li>`).join("");
25308
+ return `<!doctype html><html lang="en"><head><meta charset="utf-8" /><meta name="viewport" content="width=device-width, initial-scale=1" /><title>${escapeHtml38(title)}</title><style>body{font-family:ui-sans-serif,system-ui,sans-serif;background:#f8fafc;color:#172033;margin:2rem;line-height:1.45}main{max-width:1180px;margin:auto}.grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(190px,1fr));gap:.75rem;margin:1rem 0}article{background:white;border:1px solid #dbe3ef;border-radius:14px;padding:1rem;box-shadow:0 10px 28px rgba(15,23,42,.05)}article span{display:block;color:#64748b;font-size:.85rem}article strong{display:block;font-size:1.5rem;margin:.2rem 0}article small{color:#64748b}table{border-collapse:collapse;width:100%;background:white;border:1px solid #dbe3ef;border-radius:14px;overflow:hidden}th,td{border-bottom:1px solid #e2e8f0;padding:.7rem;text-align:left;vertical-align:top}code{font-size:.85em}.status{display:inline-flex;border-radius:999px;padding:.35rem .7rem;background:${report.status === "fail" ? "#fee2e2" : report.status === "warn" ? "#fef3c7" : "#dcfce7"};color:${report.status === "fail" ? "#991b1b" : report.status === "warn" ? "#92400e" : "#166534"};font-weight:700}</style></head><body><main><h1>${escapeHtml38(title)}</h1><p><span class="status">${escapeHtml38(report.status)}</span> Checked ${escapeHtml38(new Date(report.checkedAt).toLocaleString())}</p><section class="grid"><article><span>Recovered fallbacks</span><strong>${String(report.providers.recoveredFallbacks)}</strong></article><article><span>Unresolved providers</span><strong>${String(report.providers.unresolvedFailures)}</strong></article><article><span>Operator interventions</span><strong>${String(report.interventions.total)}</strong></article><article><span>Latency status</span><strong>${escapeHtml38(report.latency?.status ?? "disabled")}</strong></article>${renderDeliverySummary("Audit delivery", report.auditDeliveries)}${renderDeliverySummary("Trace delivery", report.traceDeliveries)}${renderDeliverySummary("Handoff delivery", report.handoffDeliveries)}</section><h2>Issues</h2><table><thead><tr><th>Severity</th><th>Code</th><th>Label</th><th>Value</th><th>Detail</th></tr></thead><tbody>${issues || '<tr><td colspan="5">No recovery issues.</td></tr>'}</tbody></table><h2>Providers</h2><table><thead><tr><th>Provider</th><th>Status</th><th>Runs</th><th>Errors</th><th>Fallbacks</th><th>Last error</th></tr></thead><tbody>${providers || '<tr><td colspan="6">No provider activity.</td></tr>'}</tbody></table><h2>Failed Sessions</h2><ul>${failedSessions || "<li>None.</li>"}</ul></main></body></html>`;
25172
25309
  };
25173
25310
  var createVoiceOpsRecoveryRoutes = (options = {}) => {
25174
25311
  const path = options.path ?? "/api/voice/ops-recovery";
@@ -25215,7 +25352,7 @@ import { Elysia as Elysia42 } from "elysia";
25215
25352
 
25216
25353
  // src/traceTimeline.ts
25217
25354
  import { Elysia as Elysia41 } from "elysia";
25218
- var escapeHtml38 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
25355
+ var escapeHtml39 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
25219
25356
  var getString15 = (value) => typeof value === "string" && value.trim() ? value : undefined;
25220
25357
  var getNumber8 = (value) => typeof value === "number" && Number.isFinite(value) ? value : undefined;
25221
25358
  var firstString3 = (payload, keys) => {
@@ -25397,18 +25534,18 @@ var summarizeVoiceTraceTimeline = (events, options = {}) => {
25397
25534
  warnings: sessions.filter((session) => session.status === "warning").length
25398
25535
  };
25399
25536
  };
25400
- var formatMs3 = (value) => value === undefined ? "n/a" : `${String(value)}ms`;
25401
- var renderProviderCards2 = (session) => session.providers.length === 0 ? '<p class="muted">No provider events recorded for this session.</p>' : `<div class="providers">${session.providers.map((provider) => `<article><strong>${escapeHtml38(provider.provider)}</strong><dl><div><dt>Events</dt><dd>${String(provider.eventCount)}</dd></div><div><dt>Avg</dt><dd>${formatMs3(provider.averageElapsedMs)}</dd></div><div><dt>Max</dt><dd>${formatMs3(provider.maxElapsedMs)}</dd></div><div><dt>Errors</dt><dd>${String(provider.errorCount)}</dd></div><div><dt>Fallbacks</dt><dd>${String(provider.fallbackCount)}</dd></div><div><dt>Timeouts</dt><dd>${String(provider.timeoutCount)}</dd></div></dl></article>`).join("")}</div>`;
25537
+ var formatMs4 = (value) => value === undefined ? "n/a" : `${String(value)}ms`;
25538
+ var renderProviderCards2 = (session) => session.providers.length === 0 ? '<p class="muted">No provider events recorded for this session.</p>' : `<div class="providers">${session.providers.map((provider) => `<article><strong>${escapeHtml39(provider.provider)}</strong><dl><div><dt>Events</dt><dd>${String(provider.eventCount)}</dd></div><div><dt>Avg</dt><dd>${formatMs4(provider.averageElapsedMs)}</dd></div><div><dt>Max</dt><dd>${formatMs4(provider.maxElapsedMs)}</dd></div><div><dt>Errors</dt><dd>${String(provider.errorCount)}</dd></div><div><dt>Fallbacks</dt><dd>${String(provider.fallbackCount)}</dd></div><div><dt>Timeouts</dt><dd>${String(provider.timeoutCount)}</dd></div></dl></article>`).join("")}</div>`;
25402
25539
  var renderVoiceTraceTimelineSessionHTML = (session, options = {}) => {
25403
- const events = session.events.map((event) => `<tr class="${escapeHtml38(event.status ?? "")}"><td>+${String(event.offsetMs)}ms</td><td>${escapeHtml38(event.type)}</td><td>${escapeHtml38(event.label)}</td><td>${escapeHtml38(event.provider ?? "")}</td><td>${escapeHtml38(event.status ?? "")}</td><td>${formatMs3(event.elapsedMs)}</td></tr>`).join("");
25404
- const issues = session.evaluation.issues.length ? session.evaluation.issues.map((issue) => `<li class="${escapeHtml38(issue.severity)}">${escapeHtml38(issue.code)}: ${escapeHtml38(issue.message)}</li>`).join("") : "<li>none</li>";
25405
- const supportLinks = session.operationsRecordHref ? `<p><a href="${escapeHtml38(session.operationsRecordHref)}">Open operations record</a></p>` : "";
25406
- return `<!doctype html><html lang="en"><head><meta charset="utf-8" /><meta name="viewport" content="width=device-width, initial-scale=1" /><title>${escapeHtml38(options.title ?? "Voice Trace Timeline")}</title><style>${timelineCSS}</style></head><body><main><a href="/traces">Back to traces</a><header><p class="eyebrow">Call timeline</p><h1>${escapeHtml38(session.sessionId)}</h1><p class="status ${escapeHtml38(session.status)}">${escapeHtml38(session.status)}</p>${supportLinks}</header><section class="metrics"><article><span>Events</span><strong>${String(session.summary.eventCount)}</strong></article><article><span>Turns</span><strong>${String(session.summary.turnCount)}</strong></article><article><span>Errors</span><strong>${String(session.summary.errorCount)}</strong></article><article><span>Duration</span><strong>${formatMs3(session.summary.callDurationMs)}</strong></article></section><section><h2>Providers</h2>${renderProviderCards2(session)}</section><section><h2>Issues</h2><ul>${issues}</ul></section><section><h2>Timeline</h2><table><thead><tr><th>Offset</th><th>Type</th><th>Event</th><th>Provider</th><th>Status</th><th>Latency</th></tr></thead><tbody>${events}</tbody></table></section></main></body></html>`;
25540
+ const events = session.events.map((event) => `<tr class="${escapeHtml39(event.status ?? "")}"><td>+${String(event.offsetMs)}ms</td><td>${escapeHtml39(event.type)}</td><td>${escapeHtml39(event.label)}</td><td>${escapeHtml39(event.provider ?? "")}</td><td>${escapeHtml39(event.status ?? "")}</td><td>${formatMs4(event.elapsedMs)}</td></tr>`).join("");
25541
+ const issues = session.evaluation.issues.length ? session.evaluation.issues.map((issue) => `<li class="${escapeHtml39(issue.severity)}">${escapeHtml39(issue.code)}: ${escapeHtml39(issue.message)}</li>`).join("") : "<li>none</li>";
25542
+ const supportLinks = session.operationsRecordHref ? `<p><a href="${escapeHtml39(session.operationsRecordHref)}">Open operations record</a></p>` : "";
25543
+ return `<!doctype html><html lang="en"><head><meta charset="utf-8" /><meta name="viewport" content="width=device-width, initial-scale=1" /><title>${escapeHtml39(options.title ?? "Voice Trace Timeline")}</title><style>${timelineCSS}</style></head><body><main><a href="/traces">Back to traces</a><header><p class="eyebrow">Call timeline</p><h1>${escapeHtml39(session.sessionId)}</h1><p class="status ${escapeHtml39(session.status)}">${escapeHtml39(session.status)}</p>${supportLinks}</header><section class="metrics"><article><span>Events</span><strong>${String(session.summary.eventCount)}</strong></article><article><span>Turns</span><strong>${String(session.summary.turnCount)}</strong></article><article><span>Errors</span><strong>${String(session.summary.errorCount)}</strong></article><article><span>Duration</span><strong>${formatMs4(session.summary.callDurationMs)}</strong></article></section><section><h2>Providers</h2>${renderProviderCards2(session)}</section><section><h2>Issues</h2><ul>${issues}</ul></section><section><h2>Timeline</h2><table><thead><tr><th>Offset</th><th>Type</th><th>Event</th><th>Provider</th><th>Status</th><th>Latency</th></tr></thead><tbody>${events}</tbody></table></section></main></body></html>`;
25407
25544
  };
25408
- var renderSessionRows = (report) => report.sessions.length === 0 ? '<tr><td colspan="7">No trace events recorded yet.</td></tr>' : report.sessions.map((session) => `<tr class="${escapeHtml38(session.status)}"><td>${session.operationsRecordHref ? `<a href="${escapeHtml38(session.operationsRecordHref)}">${escapeHtml38(session.sessionId)}</a>` : `<a href="/traces/${encodeURIComponent(session.sessionId)}">${escapeHtml38(session.sessionId)}</a>`}</td><td>${escapeHtml38(session.status)}</td><td>${String(session.summary.eventCount)}</td><td>${String(session.summary.turnCount)}</td><td>${String(session.summary.errorCount)}</td><td>${formatMs3(session.summary.callDurationMs)}</td><td>${session.providers.map((provider) => escapeHtml38(provider.provider)).join(", ")}</td></tr>`).join("");
25545
+ var renderSessionRows = (report) => report.sessions.length === 0 ? '<tr><td colspan="7">No trace events recorded yet.</td></tr>' : report.sessions.map((session) => `<tr class="${escapeHtml39(session.status)}"><td>${session.operationsRecordHref ? `<a href="${escapeHtml39(session.operationsRecordHref)}">${escapeHtml39(session.sessionId)}</a>` : `<a href="/traces/${encodeURIComponent(session.sessionId)}">${escapeHtml39(session.sessionId)}</a>`}</td><td>${escapeHtml39(session.status)}</td><td>${String(session.summary.eventCount)}</td><td>${String(session.summary.turnCount)}</td><td>${String(session.summary.errorCount)}</td><td>${formatMs4(session.summary.callDurationMs)}</td><td>${session.providers.map((provider) => escapeHtml39(provider.provider)).join(", ")}</td></tr>`).join("");
25409
25546
  var timelineCSS = "body{background:#0f1318;color:#f6f2e8;font-family:ui-sans-serif,system-ui,sans-serif;margin:0}main{margin:auto;max-width:1180px;padding:32px}a{color:#fbbf24}.eyebrow{color:#fbbf24;font-weight:900;letter-spacing:.12em;text-transform:uppercase}h1{font-size:clamp(2.4rem,6vw,4.5rem);line-height:.92;margin:.2rem 0 1rem}.status{border:1px solid #475569;border-radius:999px;display:inline-flex;padding:8px 12px}.healthy{color:#86efac}.warning{color:#fbbf24}.failed,.error{color:#fca5a5}.metrics,.providers{display:grid;gap:14px;grid-template-columns:repeat(auto-fit,minmax(170px,1fr));margin:20px 0}.metrics article,.providers article{background:#181f27;border:1px solid #2b3642;border-radius:20px;padding:16px}.metrics span,dt,.muted{color:#a8b0b8}.metrics strong{display:block;font-size:2rem}dl{display:grid;gap:8px;grid-template-columns:repeat(2,minmax(0,1fr));margin:12px 0 0}dd{font-weight:800;margin:4px 0 0}table{background:#181f27;border-collapse:collapse;border-radius:18px;overflow:hidden;width:100%}td,th{border-bottom:1px solid #2b3642;padding:12px;text-align:left}section{margin-top:28px}@media(max-width:760px){main{padding:20px}table{font-size:.9rem}}";
25410
25547
  var renderVoiceTraceTimelineHTML = (report, options = {}) => {
25411
- const snippet = escapeHtml38(`const traceStore = createVoiceTraceSinkStore({
25548
+ const snippet = escapeHtml39(`const traceStore = createVoiceTraceSinkStore({
25412
25549
  store: runtimeStorage.traces,
25413
25550
  sinks: [
25414
25551
  createVoiceTraceHTTPSink({
@@ -25434,7 +25571,7 @@ app.use(
25434
25571
  traceDeliveries: runtimeStorage.traceDeliveries
25435
25572
  })
25436
25573
  );`);
25437
- return `<!doctype html><html lang="en"><head><meta charset="utf-8" /><meta name="viewport" content="width=device-width, initial-scale=1" /><title>${escapeHtml38(options.title ?? "Voice Trace Timelines")}</title><style>${timelineCSS}.primitive{background:#181f27;border:1px solid #334155;border-radius:20px;margin:20px 0;padding:18px}.primitive p{line-height:1.55}.primitive pre{background:#0b1118;border:1px solid #2b3642;border-radius:16px;color:#dbeafe;overflow:auto;padding:14px}.primitive code{color:#bfdbfe}</style></head><body><main><header><p class="eyebrow">Self-hosted voice debugging</p><h1>${escapeHtml38(options.title ?? "Voice Trace Timelines")}</h1><p class="muted">Per-call event timelines with provider latency, fallback, timeout, handoff, and error context.</p></header><section class="metrics"><article><span>Sessions</span><strong>${String(report.total)}</strong></article><article><span>Failed</span><strong>${String(report.failed)}</strong></article><article><span>Warnings</span><strong>${String(report.warnings)}</strong></article></section><section class="primitive"><p class="eyebrow">Copy into your app</p><h2><code>createVoiceTraceTimelineRoutes(...)</code> makes traces the proof backbone</h2><p class="muted">Mount trace timelines from the same trace store used by readiness, simulations, provider recovery, delivery sinks, and phone-agent smoke proof.</p><pre><code>${snippet}</code></pre></section><table><thead><tr><th>Session</th><th>Status</th><th>Events</th><th>Turns</th><th>Errors</th><th>Duration</th><th>Providers</th></tr></thead><tbody>${renderSessionRows(report)}</tbody></table></main></body></html>`;
25574
+ return `<!doctype html><html lang="en"><head><meta charset="utf-8" /><meta name="viewport" content="width=device-width, initial-scale=1" /><title>${escapeHtml39(options.title ?? "Voice Trace Timelines")}</title><style>${timelineCSS}.primitive{background:#181f27;border:1px solid #334155;border-radius:20px;margin:20px 0;padding:18px}.primitive p{line-height:1.55}.primitive pre{background:#0b1118;border:1px solid #2b3642;border-radius:16px;color:#dbeafe;overflow:auto;padding:14px}.primitive code{color:#bfdbfe}</style></head><body><main><header><p class="eyebrow">Self-hosted voice debugging</p><h1>${escapeHtml39(options.title ?? "Voice Trace Timelines")}</h1><p class="muted">Per-call event timelines with provider latency, fallback, timeout, handoff, and error context.</p></header><section class="metrics"><article><span>Sessions</span><strong>${String(report.total)}</strong></article><article><span>Failed</span><strong>${String(report.failed)}</strong></article><article><span>Warnings</span><strong>${String(report.warnings)}</strong></article></section><section class="primitive"><p class="eyebrow">Copy into your app</p><h2><code>createVoiceTraceTimelineRoutes(...)</code> makes traces the proof backbone</h2><p class="muted">Mount trace timelines from the same trace store used by readiness, simulations, provider recovery, delivery sinks, and phone-agent smoke proof.</p><pre><code>${snippet}</code></pre></section><table><thead><tr><th>Session</th><th>Status</th><th>Events</th><th>Turns</th><th>Errors</th><th>Duration</th><th>Providers</th></tr></thead><tbody>${renderSessionRows(report)}</tbody></table></main></body></html>`;
25438
25575
  };
25439
25576
  var createVoiceTraceTimelineRoutes = (options) => {
25440
25577
  const path = options.path ?? "/api/voice-traces";
@@ -25748,8 +25885,8 @@ var assertVoiceOperationsRecordGuardrails = (record, input = {}) => {
25748
25885
  }
25749
25886
  return report;
25750
25887
  };
25751
- var escapeHtml39 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
25752
- var formatMs4 = (value) => value === undefined ? "n/a" : `${String(value)}ms`;
25888
+ var escapeHtml40 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
25889
+ var formatMs5 = (value) => value === undefined ? "n/a" : `${String(value)}ms`;
25753
25890
  var outcomeLabels = (outcome) => [
25754
25891
  outcome.complete ? "complete" : undefined,
25755
25892
  outcome.escalated ? "escalated" : undefined,
@@ -25765,7 +25902,7 @@ var renderVoiceOperationsRecordIncidentMarkdown = (record) => {
25765
25902
  `# Voice incident handoff: ${record.sessionId}`,
25766
25903
  "",
25767
25904
  `- Status: ${record.status}`,
25768
- `- Duration: ${formatMs4(record.summary.callDurationMs)}`,
25905
+ `- Duration: ${formatMs5(record.summary.callDurationMs)}`,
25769
25906
  `- Turns: ${String(record.summary.turnCount)}`,
25770
25907
  `- Errors: ${String(record.summary.errorCount)}`,
25771
25908
  `- Outcome: ${outcomes.join(", ") || "unknown"}`,
@@ -25803,19 +25940,19 @@ var renderVoiceOperationsRecordGuardrailMarkdown = (record) => {
25803
25940
  `);
25804
25941
  };
25805
25942
  var renderVoiceOperationsRecordHTML = (record, options = {}) => {
25806
- const providers = record.providers.length ? record.providers.map((provider) => `<article><strong>${escapeHtml39(provider.provider)}</strong><span>${String(provider.eventCount)} events</span><span>${formatMs4(provider.averageElapsedMs)} avg</span><span>${String(provider.errorCount)} errors</span></article>`).join("") : '<p class="muted">No provider events recorded.</p>';
25807
- const transcript = record.transcript.length ? record.transcript.map((turn) => `<li><strong>${escapeHtml39(turn.id)}</strong>${turn.committedText ? `<p><span class="label">Caller</span>${escapeHtml39(turn.committedText)}</p>` : ""}${turn.assistantReplies.map((reply) => `<p><span class="label">Assistant</span>${escapeHtml39(reply)}</p>`).join("")}${turn.errors.map((error) => `<p class="error"><span class="label">Error</span>${escapeHtml39(error)}</p>`).join("")}</li>`).join("") : "<li>No transcript turns recorded.</li>";
25808
- const providerDecisions = record.providerDecisions.length ? record.providerDecisions.map((decision) => `<li><strong>${escapeHtml39(decision.provider ?? decision.selectedProvider ?? decision.fallbackProvider ?? "provider")}</strong> <span>${escapeHtml39(decision.status ?? decision.type)}</span> ${formatMs4(decision.elapsedMs)}${decision.fallbackProvider ? `<p>Fallback: ${escapeHtml39(decision.fallbackProvider)}</p>` : ""}${decision.error ? `<p class="error">${escapeHtml39(decision.error)}</p>` : ""}${decision.reason ? `<p>${escapeHtml39(decision.reason)}</p>` : ""}</li>`).join("") : "<li>No provider decisions recorded.</li>";
25809
- const handoffs = record.handoffs.length ? record.handoffs.map((handoff) => `<li><strong>${escapeHtml39(handoff.fromAgentId ?? "unknown")}</strong> to <strong>${escapeHtml39(handoff.targetAgentId ?? "unknown")}</strong> <span>${escapeHtml39(handoff.status ?? "")}</span><p>${escapeHtml39(handoff.summary ?? handoff.reason ?? "")}</p></li>`).join("") : "<li>No agent handoffs recorded.</li>";
25810
- const tools = record.tools.length ? record.tools.map((tool) => `<li><strong>${escapeHtml39(tool.toolName ?? "tool")}</strong> <span>${escapeHtml39(tool.status ?? "")}</span> ${formatMs4(tool.elapsedMs)} ${tool.error ? `<p>${escapeHtml39(tool.error)}</p>` : ""}</li>`).join("") : "<li>No tool calls recorded.</li>";
25811
- const reviews = record.reviews?.reviews.length ? record.reviews.reviews.map((review) => `<li><strong>${escapeHtml39(review.title)}</strong> <span>${escapeHtml39(review.summary.outcome ?? "")}</span><p>${escapeHtml39(review.postCall?.summary ?? review.transcript.actual)}</p></li>`).join("") : "<li>No call reviews recorded.</li>";
25812
- const tasks = record.tasks?.tasks.length ? record.tasks.tasks.map((task) => `<li><strong>${escapeHtml39(task.title)}</strong> <span>${escapeHtml39(task.status)}</span><p>${escapeHtml39(task.recommendedAction)}</p></li>`).join("") : "<li>No ops tasks recorded.</li>";
25813
- const integrationEvents = record.integrationEvents?.events.length ? record.integrationEvents.events.map((event) => `<li><strong>${escapeHtml39(event.type)}</strong> <span>${escapeHtml39(event.deliveryStatus ?? "local")}</span><p>${escapeHtml39(event.deliveryError ?? event.deliveredTo ?? "")}</p></li>`).join("") : "<li>No integration events recorded.</li>";
25943
+ const providers = record.providers.length ? record.providers.map((provider) => `<article><strong>${escapeHtml40(provider.provider)}</strong><span>${String(provider.eventCount)} events</span><span>${formatMs5(provider.averageElapsedMs)} avg</span><span>${String(provider.errorCount)} errors</span></article>`).join("") : '<p class="muted">No provider events recorded.</p>';
25944
+ const transcript = record.transcript.length ? record.transcript.map((turn) => `<li><strong>${escapeHtml40(turn.id)}</strong>${turn.committedText ? `<p><span class="label">Caller</span>${escapeHtml40(turn.committedText)}</p>` : ""}${turn.assistantReplies.map((reply) => `<p><span class="label">Assistant</span>${escapeHtml40(reply)}</p>`).join("")}${turn.errors.map((error) => `<p class="error"><span class="label">Error</span>${escapeHtml40(error)}</p>`).join("")}</li>`).join("") : "<li>No transcript turns recorded.</li>";
25945
+ const providerDecisions = record.providerDecisions.length ? record.providerDecisions.map((decision) => `<li><strong>${escapeHtml40(decision.provider ?? decision.selectedProvider ?? decision.fallbackProvider ?? "provider")}</strong> <span>${escapeHtml40(decision.status ?? decision.type)}</span> ${formatMs5(decision.elapsedMs)}${decision.fallbackProvider ? `<p>Fallback: ${escapeHtml40(decision.fallbackProvider)}</p>` : ""}${decision.error ? `<p class="error">${escapeHtml40(decision.error)}</p>` : ""}${decision.reason ? `<p>${escapeHtml40(decision.reason)}</p>` : ""}</li>`).join("") : "<li>No provider decisions recorded.</li>";
25946
+ const handoffs = record.handoffs.length ? record.handoffs.map((handoff) => `<li><strong>${escapeHtml40(handoff.fromAgentId ?? "unknown")}</strong> to <strong>${escapeHtml40(handoff.targetAgentId ?? "unknown")}</strong> <span>${escapeHtml40(handoff.status ?? "")}</span><p>${escapeHtml40(handoff.summary ?? handoff.reason ?? "")}</p></li>`).join("") : "<li>No agent handoffs recorded.</li>";
25947
+ const tools = record.tools.length ? record.tools.map((tool) => `<li><strong>${escapeHtml40(tool.toolName ?? "tool")}</strong> <span>${escapeHtml40(tool.status ?? "")}</span> ${formatMs5(tool.elapsedMs)} ${tool.error ? `<p>${escapeHtml40(tool.error)}</p>` : ""}</li>`).join("") : "<li>No tool calls recorded.</li>";
25948
+ const reviews = record.reviews?.reviews.length ? record.reviews.reviews.map((review) => `<li><strong>${escapeHtml40(review.title)}</strong> <span>${escapeHtml40(review.summary.outcome ?? "")}</span><p>${escapeHtml40(review.postCall?.summary ?? review.transcript.actual)}</p></li>`).join("") : "<li>No call reviews recorded.</li>";
25949
+ const tasks = record.tasks?.tasks.length ? record.tasks.tasks.map((task) => `<li><strong>${escapeHtml40(task.title)}</strong> <span>${escapeHtml40(task.status)}</span><p>${escapeHtml40(task.recommendedAction)}</p></li>`).join("") : "<li>No ops tasks recorded.</li>";
25950
+ const integrationEvents = record.integrationEvents?.events.length ? record.integrationEvents.events.map((event) => `<li><strong>${escapeHtml40(event.type)}</strong> <span>${escapeHtml40(event.deliveryStatus ?? "local")}</span><p>${escapeHtml40(event.deliveryError ?? event.deliveredTo ?? "")}</p></li>`).join("") : "<li>No integration events recorded.</li>";
25814
25951
  const guardrails = record.guardrails.total ? record.guardrails.decisions.map((decision) => {
25815
25952
  const findings = decision.findings.map((finding) => finding.label ?? finding.ruleId ?? finding.action).filter((value) => typeof value === "string").join(", ") || "none";
25816
- return `<li><strong>assistant.guardrail ${escapeHtml39(decision.stage ?? "unknown")}</strong> <span>${escapeHtml39(decision.status ?? "")}</span><p>Allowed: ${escapeHtml39(String(decision.allowed ?? "unknown"))} \xB7 Proof: ${escapeHtml39(decision.proof ?? "runtime")}${decision.turnId ? ` \xB7 Turn: ${escapeHtml39(decision.turnId)}` : ""}</p><p>${escapeHtml39(findings)}</p></li>`;
25953
+ return `<li><strong>assistant.guardrail ${escapeHtml40(decision.stage ?? "unknown")}</strong> <span>${escapeHtml40(decision.status ?? "")}</span><p>Allowed: ${escapeHtml40(String(decision.allowed ?? "unknown"))} \xB7 Proof: ${escapeHtml40(decision.proof ?? "runtime")}${decision.turnId ? ` \xB7 Turn: ${escapeHtml40(decision.turnId)}` : ""}</p><p>${escapeHtml40(findings)}</p></li>`;
25817
25954
  }).join("") : "<li>No assistant.guardrail events recorded.</li>";
25818
- const snippet = escapeHtml39(`app.use(
25955
+ const snippet = escapeHtml40(`app.use(
25819
25956
  createVoiceOperationsRecordRoutes({
25820
25957
  audit: auditStore,
25821
25958
  integrationEvents: opsEvents,
@@ -25829,9 +25966,9 @@ var renderVoiceOperationsRecordHTML = (record, options = {}) => {
25829
25966
  tasks: opsTasks
25830
25967
  })
25831
25968
  );`);
25832
- const incidentMarkdown = escapeHtml39(renderVoiceOperationsRecordIncidentMarkdown(record));
25833
- const incidentLink = options.incidentHref ? `<a href="${escapeHtml39(options.incidentHref)}">Download incident.md</a>` : "";
25834
- return `<!doctype html><html lang="en"><head><meta charset="utf-8" /><meta name="viewport" content="width=device-width, initial-scale=1" /><title>${escapeHtml39(options.title ?? "Voice Operations Record")}</title><style>body{background:#101417;color:#f9f4e8;font-family:ui-sans-serif,system-ui,sans-serif;margin:0}main{margin:auto;max-width:1120px;padding:32px}.eyebrow{color:#fbbf24;font-size:.8rem;font-weight:900;letter-spacing:.14em;text-transform:uppercase}h1{font-size:clamp(2.4rem,6vw,4.8rem);line-height:.9;margin:.2rem 0 1rem}.status{border:1px solid #475569;border-radius:999px;display:inline-flex;padding:8px 12px}.healthy{color:#86efac}.warning{color:#fbbf24}.failed,.error{color:#fca5a5}.grid{display:grid;gap:14px;grid-template-columns:repeat(auto-fit,minmax(180px,1fr));margin:20px 0}.card,.primitive{background:#182025;border:1px solid #2d3a43;border-radius:20px;padding:16px}.card span,.muted,.label{color:#a9b4bd}.label{display:block;font-size:.72rem;font-weight:900;letter-spacing:.12em;text-transform:uppercase}.card strong{display:block;font-size:2rem}section{margin-top:28px}article{display:grid;gap:8px}ul{display:grid;gap:10px;list-style:none;padding:0}li{background:#182025;border:1px solid #2d3a43;border-radius:16px;padding:14px}pre{background:#080d10;border:1px solid #2d3a43;border-radius:16px;color:#dbeafe;overflow:auto;padding:14px}.hero-actions{display:flex;flex-wrap:wrap;gap:10px;margin-top:16px}.hero-actions a{background:#fbbf24;border-radius:999px;color:#111827;font-weight:900;padding:10px 14px;text-decoration:none}.two-column{display:grid;gap:18px;grid-template-columns:minmax(0,1.15fr) minmax(280px,.85fr)}@media(max-width:860px){main{padding:20px}.two-column{grid-template-columns:1fr}}</style></head><body><main><p class="eyebrow">Call log replacement</p><h1>${escapeHtml39(options.title ?? "Voice Operations Record")}</h1><p class="status ${escapeHtml39(record.status)}">${escapeHtml39(record.status)}</p><div class="hero-actions"><a href="#transcript">Transcript</a><a href="#provider-decisions">Provider decisions</a><a href="#guardrails">Guardrails</a><a href="#incident-handoff">Incident handoff</a>${incidentLink}</div><section class="grid"><div class="card"><span>Events</span><strong>${String(record.summary.eventCount)}</strong></div><div class="card"><span>Turns</span><strong>${String(record.summary.turnCount)}</strong></div><div class="card"><span>Errors</span><strong>${String(record.summary.errorCount)}</strong></div><div class="card"><span>Duration</span><strong>${formatMs4(record.summary.callDurationMs)}</strong></div><div class="card"><span>Guardrails</span><strong>${String(record.guardrails.blocked)}</strong></div><div class="card"><span>Audit</span><strong>${String(record.audit?.total ?? 0)}</strong></div><div class="card"><span>Reviews</span><strong>${String(record.reviews?.total ?? 0)}</strong></div><div class="card"><span>Tasks</span><strong>${String(record.tasks?.total ?? 0)}</strong></div><div class="card"><span>Integrations</span><strong>${String(record.integrationEvents?.total ?? 0)}</strong></div></section><section class="two-column"><div><h2 id="transcript">Transcript</h2><ul>${transcript}</ul></div><div><h2 id="provider-decisions">Provider Decisions</h2><ul>${providerDecisions}</ul></div></section><section id="guardrails"><h2>Guardrail Evidence</h2><p class="muted">Live <code>assistant.guardrail</code> decisions attached to this session.</p><ul>${guardrails}</ul></section><section id="incident-handoff"><h2>Copyable Incident Handoff</h2><p class="muted">Paste this into Slack, Linear, Zendesk, or an incident review. ${incidentLink}</p><pre><code>${incidentMarkdown}</code></pre></section><section class="primitive"><p class="eyebrow">Copy into your app</p><h2><code>createVoiceOperationsRecordRoutes(...)</code> gives every call one debuggable object</h2><p class="muted">Use this as the support/debug payload across traces, provider routing, tools, handoffs, guardrails, audit, latency, replay, reviews, tasks, and webhook delivery.</p><pre><code>${snippet}</code></pre></section><section><h2>Provider Summary</h2><div class="grid">${providers}</div></section><section><h2>Handoffs</h2><ul>${handoffs}</ul></section><section><h2>Tools</h2><ul>${tools}</ul></section><section><h2>Reviews</h2><ul>${reviews}</ul></section><section><h2>Tasks</h2><ul>${tasks}</ul></section><section><h2>Integration Events</h2><ul>${integrationEvents}</ul></section></main></body></html>`;
25969
+ const incidentMarkdown = escapeHtml40(renderVoiceOperationsRecordIncidentMarkdown(record));
25970
+ const incidentLink = options.incidentHref ? `<a href="${escapeHtml40(options.incidentHref)}">Download incident.md</a>` : "";
25971
+ return `<!doctype html><html lang="en"><head><meta charset="utf-8" /><meta name="viewport" content="width=device-width, initial-scale=1" /><title>${escapeHtml40(options.title ?? "Voice Operations Record")}</title><style>body{background:#101417;color:#f9f4e8;font-family:ui-sans-serif,system-ui,sans-serif;margin:0}main{margin:auto;max-width:1120px;padding:32px}.eyebrow{color:#fbbf24;font-size:.8rem;font-weight:900;letter-spacing:.14em;text-transform:uppercase}h1{font-size:clamp(2.4rem,6vw,4.8rem);line-height:.9;margin:.2rem 0 1rem}.status{border:1px solid #475569;border-radius:999px;display:inline-flex;padding:8px 12px}.healthy{color:#86efac}.warning{color:#fbbf24}.failed,.error{color:#fca5a5}.grid{display:grid;gap:14px;grid-template-columns:repeat(auto-fit,minmax(180px,1fr));margin:20px 0}.card,.primitive{background:#182025;border:1px solid #2d3a43;border-radius:20px;padding:16px}.card span,.muted,.label{color:#a9b4bd}.label{display:block;font-size:.72rem;font-weight:900;letter-spacing:.12em;text-transform:uppercase}.card strong{display:block;font-size:2rem}section{margin-top:28px}article{display:grid;gap:8px}ul{display:grid;gap:10px;list-style:none;padding:0}li{background:#182025;border:1px solid #2d3a43;border-radius:16px;padding:14px}pre{background:#080d10;border:1px solid #2d3a43;border-radius:16px;color:#dbeafe;overflow:auto;padding:14px}.hero-actions{display:flex;flex-wrap:wrap;gap:10px;margin-top:16px}.hero-actions a{background:#fbbf24;border-radius:999px;color:#111827;font-weight:900;padding:10px 14px;text-decoration:none}.two-column{display:grid;gap:18px;grid-template-columns:minmax(0,1.15fr) minmax(280px,.85fr)}@media(max-width:860px){main{padding:20px}.two-column{grid-template-columns:1fr}}</style></head><body><main><p class="eyebrow">Call log replacement</p><h1>${escapeHtml40(options.title ?? "Voice Operations Record")}</h1><p class="status ${escapeHtml40(record.status)}">${escapeHtml40(record.status)}</p><div class="hero-actions"><a href="#transcript">Transcript</a><a href="#provider-decisions">Provider decisions</a><a href="#guardrails">Guardrails</a><a href="#incident-handoff">Incident handoff</a>${incidentLink}</div><section class="grid"><div class="card"><span>Events</span><strong>${String(record.summary.eventCount)}</strong></div><div class="card"><span>Turns</span><strong>${String(record.summary.turnCount)}</strong></div><div class="card"><span>Errors</span><strong>${String(record.summary.errorCount)}</strong></div><div class="card"><span>Duration</span><strong>${formatMs5(record.summary.callDurationMs)}</strong></div><div class="card"><span>Guardrails</span><strong>${String(record.guardrails.blocked)}</strong></div><div class="card"><span>Audit</span><strong>${String(record.audit?.total ?? 0)}</strong></div><div class="card"><span>Reviews</span><strong>${String(record.reviews?.total ?? 0)}</strong></div><div class="card"><span>Tasks</span><strong>${String(record.tasks?.total ?? 0)}</strong></div><div class="card"><span>Integrations</span><strong>${String(record.integrationEvents?.total ?? 0)}</strong></div></section><section class="two-column"><div><h2 id="transcript">Transcript</h2><ul>${transcript}</ul></div><div><h2 id="provider-decisions">Provider Decisions</h2><ul>${providerDecisions}</ul></div></section><section id="guardrails"><h2>Guardrail Evidence</h2><p class="muted">Live <code>assistant.guardrail</code> decisions attached to this session.</p><ul>${guardrails}</ul></section><section id="incident-handoff"><h2>Copyable Incident Handoff</h2><p class="muted">Paste this into Slack, Linear, Zendesk, or an incident review. ${incidentLink}</p><pre><code>${incidentMarkdown}</code></pre></section><section class="primitive"><p class="eyebrow">Copy into your app</p><h2><code>createVoiceOperationsRecordRoutes(...)</code> gives every call one debuggable object</h2><p class="muted">Use this as the support/debug payload across traces, provider routing, tools, handoffs, guardrails, audit, latency, replay, reviews, tasks, and webhook delivery.</p><pre><code>${snippet}</code></pre></section><section><h2>Provider Summary</h2><div class="grid">${providers}</div></section><section><h2>Handoffs</h2><ul>${handoffs}</ul></section><section><h2>Tools</h2><ul>${tools}</ul></section><section><h2>Reviews</h2><ul>${reviews}</ul></section><section><h2>Tasks</h2><ul>${tasks}</ul></section><section><h2>Integration Events</h2><ul>${integrationEvents}</ul></section></main></body></html>`;
25835
25972
  };
25836
25973
  var createVoiceOperationsRecordRoutes = (options) => {
25837
25974
  const path = options.path ?? "/api/voice-operations/:sessionId";
@@ -27375,7 +27512,7 @@ var createVoiceObservabilityExportRoutes = (options = {}) => {
27375
27512
  };
27376
27513
 
27377
27514
  // src/productionReadiness.ts
27378
- var escapeHtml40 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
27515
+ var escapeHtml41 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
27379
27516
  var rollupStatus3 = (checks) => checks.some((check) => check.status === "fail") ? "fail" : checks.some((check) => check.status === "warn") ? "warn" : "pass";
27380
27517
  var readinessGateCodes = {
27381
27518
  "Agent squad contracts": "voice.readiness.agent_squad_contracts",
@@ -28718,22 +28855,22 @@ var buildVoiceProductionReadinessReport = async (options, input = {}) => {
28718
28855
  var buildVoiceProductionReadinessGate = async (options, input = {}) => summarizeVoiceProductionReadinessGate(await buildVoiceProductionReadinessReport(options, input), options.gate || undefined);
28719
28856
  var renderVoiceProductionReadinessHTML = (report, options = {}) => {
28720
28857
  const title = options.title ?? "AbsoluteJS Voice Production Readiness";
28721
- const profile = report.profile ? `<section class="profile"><p class="eyebrow">Readiness profile</p><h2>${escapeHtml40(report.profile.name)}</h2><p>${escapeHtml40(report.profile.description)}</p><p>${escapeHtml40(report.profile.purpose)}</p><div class="profile-surfaces">${report.profile.surfaces.map((surface) => `<article class="${surface.configured ? "pass" : "warn"}"><span>${surface.configured ? "CONFIGURED" : "EXPECTED"}</span><strong>${surface.href ? `<a href="${escapeHtml40(surface.href)}">${escapeHtml40(surface.label)}</a>` : escapeHtml40(surface.label)}</strong></article>`).join("")}</div></section>` : "";
28858
+ const profile = report.profile ? `<section class="profile"><p class="eyebrow">Readiness profile</p><h2>${escapeHtml41(report.profile.name)}</h2><p>${escapeHtml41(report.profile.description)}</p><p>${escapeHtml41(report.profile.purpose)}</p><div class="profile-surfaces">${report.profile.surfaces.map((surface) => `<article class="${surface.configured ? "pass" : "warn"}"><span>${surface.configured ? "CONFIGURED" : "EXPECTED"}</span><strong>${surface.href ? `<a href="${escapeHtml41(surface.href)}">${escapeHtml41(surface.label)}</a>` : escapeHtml41(surface.label)}</strong></article>`).join("")}</div></section>` : "";
28722
28859
  const checks = report.checks.map((check, index) => {
28723
- const actions = (check.actions ?? []).map((action) => action.method === "POST" ? `<button type="button" data-readiness-action="${index}" data-action-url="${escapeHtml40(action.href)}">${escapeHtml40(action.label)}</button>` : `<a href="${escapeHtml40(action.href)}">${escapeHtml40(action.label)}</a>`).join("");
28724
- return `<article class="check ${escapeHtml40(check.status)}">
28860
+ const actions = (check.actions ?? []).map((action) => action.method === "POST" ? `<button type="button" data-readiness-action="${index}" data-action-url="${escapeHtml41(action.href)}">${escapeHtml41(action.label)}</button>` : `<a href="${escapeHtml41(action.href)}">${escapeHtml41(action.label)}</a>`).join("");
28861
+ return `<article class="check ${escapeHtml41(check.status)}">
28725
28862
  <div>
28726
- <span>${escapeHtml40(check.status.toUpperCase())}</span>
28727
- <h2>${escapeHtml40(check.label)}</h2>
28728
- ${check.detail ? `<p>${escapeHtml40(check.detail)}</p>` : ""}
28729
- ${check.proofSource ? `<p class="proof-source">Proof source: ${check.proofSource.href ? `<a href="${escapeHtml40(check.proofSource.href)}">${escapeHtml40(check.proofSource.sourceLabel)}</a>` : escapeHtml40(check.proofSource.sourceLabel)}${check.proofSource.detail ? ` \xB7 ${escapeHtml40(check.proofSource.detail)}` : ""}</p>` : ""}
28863
+ <span>${escapeHtml41(check.status.toUpperCase())}</span>
28864
+ <h2>${escapeHtml41(check.label)}</h2>
28865
+ ${check.detail ? `<p>${escapeHtml41(check.detail)}</p>` : ""}
28866
+ ${check.proofSource ? `<p class="proof-source">Proof source: ${check.proofSource.href ? `<a href="${escapeHtml41(check.proofSource.href)}">${escapeHtml41(check.proofSource.sourceLabel)}</a>` : escapeHtml41(check.proofSource.sourceLabel)}${check.proofSource.detail ? ` \xB7 ${escapeHtml41(check.proofSource.detail)}` : ""}</p>` : ""}
28730
28867
  ${actions ? `<p class="actions">${actions}</p>` : ""}
28731
28868
  </div>
28732
- <strong>${escapeHtml40(String(check.value ?? check.status))}</strong>
28733
- ${check.href ? `<a href="${escapeHtml40(check.href)}">Open surface</a>` : ""}
28869
+ <strong>${escapeHtml41(String(check.value ?? check.status))}</strong>
28870
+ ${check.href ? `<a href="${escapeHtml41(check.href)}">Open surface</a>` : ""}
28734
28871
  </article>`;
28735
28872
  }).join("");
28736
- const snippet = escapeHtml40(`createVoiceProductionReadinessRoutes({
28873
+ const snippet = escapeHtml41(`createVoiceProductionReadinessRoutes({
28737
28874
  htmlPath: '/production-readiness',
28738
28875
  path: '/api/production-readiness',
28739
28876
  gatePath: '/api/production-readiness/gate',
@@ -28749,7 +28886,7 @@ var renderVoiceProductionReadinessHTML = (report, options = {}) => {
28749
28886
  providerRoutingContracts: loadProviderRoutingContracts,
28750
28887
  store: traceStore
28751
28888
  });`);
28752
- return `<!doctype html><html lang="en"><head><meta charset="utf-8" /><meta name="viewport" content="width=device-width, initial-scale=1" /><title>${escapeHtml40(title)}</title><style>body{background:#0c0f14;color:#f6f2e8;font-family:ui-sans-serif,system-ui,sans-serif;margin:0}main{margin:auto;max-width:1060px;padding:32px}.hero,.primitive,.profile{background:linear-gradient(135deg,rgba(20,184,166,.18),rgba(245,158,11,.12));border:1px solid #26313d;border-radius:28px;margin-bottom:18px;padding:28px}.primitive,.profile{background:#111722}.primitive{border-color:#3a3f2d}.eyebrow{color:#fbbf24;font-weight:900;letter-spacing:.12em;text-transform:uppercase}h1{font-size:clamp(2.4rem,6vw,5rem);line-height:.9;margin:.2rem 0 1rem}.status{display:inline-flex;border:1px solid #3f3f46;border-radius:999px;padding:8px 12px}.primitive code{color:#fde68a}.primitive p{color:#c8ccd3;line-height:1.55;margin:.45rem 0 0}.primitive pre{background:#0b0f16;border:1px solid #2c3440;border-radius:18px;color:#fef3c7;margin:16px 0 0;overflow:auto;padding:16px}.status.pass,.check.pass,.profile-surfaces .pass{border-color:rgba(34,197,94,.55)}.status.warn,.check.warn,.profile-surfaces .warn{border-color:rgba(245,158,11,.65)}.status.fail,.check.fail{border-color:rgba(239,68,68,.75)}.checks{display:grid;gap:14px}.check{align-items:center;background:#141922;border:1px solid #26313d;border-radius:22px;display:grid;gap:16px;grid-template-columns:1fr auto auto;padding:18px}.check span,.profile-surfaces span{color:#a8b0b8;font-size:.78rem;font-weight:900;letter-spacing:.08em}.check h2{margin:.2rem 0}.check p,.profile p{color:#b9c0c8;margin:.2rem 0 0}.check .proof-source{color:#f9d77e;font-weight:800}.check strong{font-size:1.5rem}.profile-surfaces{display:grid;gap:10px;grid-template-columns:repeat(auto-fit,minmax(190px,1fr));margin-top:16px}.profile-surfaces article{background:#141922;border:1px solid #26313d;border-radius:16px;padding:14px}.profile-surfaces strong{display:block;margin-top:6px}.actions{display:flex;flex-wrap:wrap;gap:10px}.check a,a{color:#fbbf24}button{background:#fbbf24;border:0;border-radius:999px;color:#111827;cursor:pointer;font-weight:800;padding:9px 12px}button:disabled{cursor:wait;opacity:.65}@media(max-width:760px){main{padding:20px}.check{grid-template-columns:1fr}}</style></head><body><main><section class="hero"><p class="eyebrow">Self-hosted readiness</p><h1>${escapeHtml40(title)}</h1><p>One deployable pass/fail report for quality gates, provider failover, session health, handoffs, routing evidence, and optional carrier readiness.</p><p class="status ${escapeHtml40(report.status)}">Overall: ${escapeHtml40(report.status.toUpperCase())}</p><p>Checked ${escapeHtml40(new Date(report.checkedAt).toLocaleString())}</p></section>${profile}<section class="primitive"><p class="eyebrow">Copy into your app</p><h2><code>createVoiceProductionReadinessRoutes(...)</code> builds this deploy gate</h2><p>Mount one package primitive to expose JSON readiness, HTML readiness, and a machine-readable gate route. Feed it the proof stores and contract reports your app already owns.</p><pre><code>${snippet}</code></pre></section><section class="checks">${checks}</section></main><script>document.querySelectorAll("[data-readiness-action]").forEach((button)=>{button.addEventListener("click",async()=>{const url=button.getAttribute("data-action-url");if(!url)return;button.disabled=true;const original=button.textContent;button.textContent="Running...";try{const response=await fetch(url,{method:"POST"});button.textContent=response.ok?"Done. Reloading...":"Failed";if(response.ok)setTimeout(()=>location.reload(),500)}catch{button.textContent="Failed"}finally{setTimeout(()=>{button.disabled=false;button.textContent=original},1500)}})});</script></body></html>`;
28889
+ return `<!doctype html><html lang="en"><head><meta charset="utf-8" /><meta name="viewport" content="width=device-width, initial-scale=1" /><title>${escapeHtml41(title)}</title><style>body{background:#0c0f14;color:#f6f2e8;font-family:ui-sans-serif,system-ui,sans-serif;margin:0}main{margin:auto;max-width:1060px;padding:32px}.hero,.primitive,.profile{background:linear-gradient(135deg,rgba(20,184,166,.18),rgba(245,158,11,.12));border:1px solid #26313d;border-radius:28px;margin-bottom:18px;padding:28px}.primitive,.profile{background:#111722}.primitive{border-color:#3a3f2d}.eyebrow{color:#fbbf24;font-weight:900;letter-spacing:.12em;text-transform:uppercase}h1{font-size:clamp(2.4rem,6vw,5rem);line-height:.9;margin:.2rem 0 1rem}.status{display:inline-flex;border:1px solid #3f3f46;border-radius:999px;padding:8px 12px}.primitive code{color:#fde68a}.primitive p{color:#c8ccd3;line-height:1.55;margin:.45rem 0 0}.primitive pre{background:#0b0f16;border:1px solid #2c3440;border-radius:18px;color:#fef3c7;margin:16px 0 0;overflow:auto;padding:16px}.status.pass,.check.pass,.profile-surfaces .pass{border-color:rgba(34,197,94,.55)}.status.warn,.check.warn,.profile-surfaces .warn{border-color:rgba(245,158,11,.65)}.status.fail,.check.fail{border-color:rgba(239,68,68,.75)}.checks{display:grid;gap:14px}.check{align-items:center;background:#141922;border:1px solid #26313d;border-radius:22px;display:grid;gap:16px;grid-template-columns:1fr auto auto;padding:18px}.check span,.profile-surfaces span{color:#a8b0b8;font-size:.78rem;font-weight:900;letter-spacing:.08em}.check h2{margin:.2rem 0}.check p,.profile p{color:#b9c0c8;margin:.2rem 0 0}.check .proof-source{color:#f9d77e;font-weight:800}.check strong{font-size:1.5rem}.profile-surfaces{display:grid;gap:10px;grid-template-columns:repeat(auto-fit,minmax(190px,1fr));margin-top:16px}.profile-surfaces article{background:#141922;border:1px solid #26313d;border-radius:16px;padding:14px}.profile-surfaces strong{display:block;margin-top:6px}.actions{display:flex;flex-wrap:wrap;gap:10px}.check a,a{color:#fbbf24}button{background:#fbbf24;border:0;border-radius:999px;color:#111827;cursor:pointer;font-weight:800;padding:9px 12px}button:disabled{cursor:wait;opacity:.65}@media(max-width:760px){main{padding:20px}.check{grid-template-columns:1fr}}</style></head><body><main><section class="hero"><p class="eyebrow">Self-hosted readiness</p><h1>${escapeHtml41(title)}</h1><p>One deployable pass/fail report for quality gates, provider failover, session health, handoffs, routing evidence, and optional carrier readiness.</p><p class="status ${escapeHtml41(report.status)}">Overall: ${escapeHtml41(report.status.toUpperCase())}</p><p>Checked ${escapeHtml41(new Date(report.checkedAt).toLocaleString())}</p></section>${profile}<section class="primitive"><p class="eyebrow">Copy into your app</p><h2><code>createVoiceProductionReadinessRoutes(...)</code> builds this deploy gate</h2><p>Mount one package primitive to expose JSON readiness, HTML readiness, and a machine-readable gate route. Feed it the proof stores and contract reports your app already owns.</p><pre><code>${snippet}</code></pre></section><section class="checks">${checks}</section></main><script>document.querySelectorAll("[data-readiness-action]").forEach((button)=>{button.addEventListener("click",async()=>{const url=button.getAttribute("data-action-url");if(!url)return;button.disabled=true;const original=button.textContent;button.textContent="Running...";try{const response=await fetch(url,{method:"POST"});button.textContent=response.ok?"Done. Reloading...":"Failed";if(response.ok)setTimeout(()=>location.reload(),500)}catch{button.textContent="Failed"}finally{setTimeout(()=>{button.disabled=false;button.textContent=original},1500)}})});</script></body></html>`;
28753
28890
  };
28754
28891
  var createVoiceProductionReadinessRoutes = (options) => {
28755
28892
  const path = options.path ?? "/api/production-readiness";
@@ -28804,7 +28941,7 @@ var createVoiceProductionReadinessRoutes = (options) => {
28804
28941
  };
28805
28942
  // src/voiceMonitoring.ts
28806
28943
  import { Elysia as Elysia45 } from "elysia";
28807
- var escapeHtml41 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
28944
+ var escapeHtml42 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
28808
28945
  var issueIdForRun = (run) => `voice-monitor:${run.id}:${run.impactedSessions?.[0] ?? "global"}`;
28809
28946
  var rollupStatus4 = (runs) => runs.some((run) => run.status === "fail") ? "fail" : runs.some((run) => run.status === "warn") ? "warn" : "pass";
28810
28947
  var createVoiceMemoryMonitorIssueStore = (initial = []) => {
@@ -29057,14 +29194,14 @@ ${rows || "| none | pass | info | | | No monitors configured. |"}
29057
29194
  };
29058
29195
  var renderVoiceMonitorHTML = (report, options = {}) => {
29059
29196
  const title = options.title ?? "Voice Monitors";
29060
- const runs = report.runs.map((run) => `<tr><td>${escapeHtml41(run.label)}</td><td class="${escapeHtml41(run.status)}">${escapeHtml41(run.status)}</td><td>${escapeHtml41(run.severity)}</td><td>${escapeHtml41(String(run.value ?? ""))}</td><td>${escapeHtml41(String(run.threshold ?? ""))}</td><td>${escapeHtml41(run.detail ?? "")}</td></tr>`).join("");
29061
- const issues = report.issues.map((issue) => `<li><strong>${escapeHtml41(issue.label)}</strong> <span class="${escapeHtml41(issue.status)}">${escapeHtml41(issue.status)}</span> ${escapeHtml41(issue.detail ?? "")}</li>`).join("");
29062
- const snippet = escapeHtml41(`app.use(createVoiceMonitorRoutes({
29197
+ const runs = report.runs.map((run) => `<tr><td>${escapeHtml42(run.label)}</td><td class="${escapeHtml42(run.status)}">${escapeHtml42(run.status)}</td><td>${escapeHtml42(run.severity)}</td><td>${escapeHtml42(String(run.value ?? ""))}</td><td>${escapeHtml42(String(run.threshold ?? ""))}</td><td>${escapeHtml42(run.detail ?? "")}</td></tr>`).join("");
29198
+ const issues = report.issues.map((issue) => `<li><strong>${escapeHtml42(issue.label)}</strong> <span class="${escapeHtml42(issue.status)}">${escapeHtml42(issue.status)}</span> ${escapeHtml42(issue.detail ?? "")}</li>`).join("");
29199
+ const snippet = escapeHtml42(`app.use(createVoiceMonitorRoutes({
29063
29200
  evidence,
29064
29201
  issueStore,
29065
29202
  monitors: [defineVoiceMonitor(...)]
29066
29203
  }));`);
29067
- return `<!doctype html><html lang="en"><head><meta charset="utf-8" /><meta name="viewport" content="width=device-width, initial-scale=1" /><title>${escapeHtml41(title)}</title><style>body{background:#10141b;color:#f8f2df;font-family:ui-sans-serif,system-ui,sans-serif;margin:0}main{margin:auto;max-width:1100px;padding:32px}.hero,.card{background:#171f2b;border:1px solid #2e3a4b;border-radius:24px;margin-bottom:16px;padding:22px}.eyebrow{color:#93c5fd;font-weight:900;letter-spacing:.12em;text-transform:uppercase}h1{font-size:clamp(2.2rem,6vw,4.7rem);line-height:.92;margin:.2rem 0 1rem}.pill{border:1px solid #64748b;border-radius:999px;display:inline-flex;font-weight:900;margin-right:8px;padding:8px 12px}.pass{color:#86efac}.warn,.acknowledged{color:#fde68a}.fail,.open{color:#fca5a5}.resolved,.muted{color:#cbd5e1}table{border-collapse:collapse;width:100%}td,th{border-bottom:1px solid #2e3a4b;padding:12px;text-align:left;vertical-align:top}pre{background:#0c1118;border:1px solid #2e3a4b;border-radius:16px;color:#dbeafe;overflow:auto;padding:16px}</style></head><body><main><section class="hero"><p class="eyebrow">Code-owned monitoring</p><h1>${escapeHtml41(title)}</h1><p class="pill ${escapeHtml41(report.status)}">Status: ${escapeHtml41(report.status)}</p><p class="pill">Open issues: ${String(report.summary.open)}</p><p class="pill">Critical: ${String(report.summary.criticalOpen)}</p></section><section class="card"><h2>Monitor Runs</h2><table><thead><tr><th>Monitor</th><th>Status</th><th>Severity</th><th>Value</th><th>Threshold</th><th>Detail</th></tr></thead><tbody>${runs}</tbody></table></section><section class="card"><h2>Issues</h2>${issues ? `<ul>${issues}</ul>` : '<p class="pass">No monitor issues.</p>'}</section><section class="card"><p class="eyebrow">Copy into your app</p><h2><code>createVoiceMonitorRoutes(...)</code></h2><pre><code>${snippet}</code></pre></section></main></body></html>`;
29204
+ return `<!doctype html><html lang="en"><head><meta charset="utf-8" /><meta name="viewport" content="width=device-width, initial-scale=1" /><title>${escapeHtml42(title)}</title><style>body{background:#10141b;color:#f8f2df;font-family:ui-sans-serif,system-ui,sans-serif;margin:0}main{margin:auto;max-width:1100px;padding:32px}.hero,.card{background:#171f2b;border:1px solid #2e3a4b;border-radius:24px;margin-bottom:16px;padding:22px}.eyebrow{color:#93c5fd;font-weight:900;letter-spacing:.12em;text-transform:uppercase}h1{font-size:clamp(2.2rem,6vw,4.7rem);line-height:.92;margin:.2rem 0 1rem}.pill{border:1px solid #64748b;border-radius:999px;display:inline-flex;font-weight:900;margin-right:8px;padding:8px 12px}.pass{color:#86efac}.warn,.acknowledged{color:#fde68a}.fail,.open{color:#fca5a5}.resolved,.muted{color:#cbd5e1}table{border-collapse:collapse;width:100%}td,th{border-bottom:1px solid #2e3a4b;padding:12px;text-align:left;vertical-align:top}pre{background:#0c1118;border:1px solid #2e3a4b;border-radius:16px;color:#dbeafe;overflow:auto;padding:16px}</style></head><body><main><section class="hero"><p class="eyebrow">Code-owned monitoring</p><h1>${escapeHtml42(title)}</h1><p class="pill ${escapeHtml42(report.status)}">Status: ${escapeHtml42(report.status)}</p><p class="pill">Open issues: ${String(report.summary.open)}</p><p class="pill">Critical: ${String(report.summary.criticalOpen)}</p></section><section class="card"><h2>Monitor Runs</h2><table><thead><tr><th>Monitor</th><th>Status</th><th>Severity</th><th>Value</th><th>Threshold</th><th>Detail</th></tr></thead><tbody>${runs}</tbody></table></section><section class="card"><h2>Issues</h2>${issues ? `<ul>${issues}</ul>` : '<p class="pass">No monitor issues.</p>'}</section><section class="card"><p class="eyebrow">Copy into your app</p><h2><code>createVoiceMonitorRoutes(...)</code></h2><pre><code>${snippet}</code></pre></section></main></body></html>`;
29068
29205
  };
29069
29206
  var actorFromRequest = async (request) => {
29070
29207
  if (!request.headers.get("content-type")?.includes("application/json")) {
@@ -29512,7 +29649,7 @@ var recommendVoiceReadinessProfile = (options) => {
29512
29649
  };
29513
29650
  // src/providerStackRecommendations.ts
29514
29651
  import { Elysia as Elysia46 } from "elysia";
29515
- var escapeHtml42 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
29652
+ var escapeHtml43 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
29516
29653
  var profileProviderPriorities = {
29517
29654
  "meeting-recorder": {
29518
29655
  llm: ["openai", "anthropic", "gemini"],
@@ -29831,17 +29968,17 @@ var resolveProviderContractMatrixInput = async (matrix) => typeof matrix === "fu
29831
29968
  var renderVoiceProviderContractMatrixHTML = (report, options = {}) => {
29832
29969
  const title = options.title ?? "Voice Provider Contract Matrix";
29833
29970
  const rows = report.rows.map((row) => {
29834
- const checks = row.checks.map((check) => `<li class="${escapeHtml42(check.status)}"><strong>${escapeHtml42(check.label)}</strong><span>${escapeHtml42(check.detail ?? check.status)}</span>${check.remediation ? `<em>${check.remediation.href ? `<a href="${escapeHtml42(check.remediation.href)}">${escapeHtml42(check.remediation.label)}</a>` : escapeHtml42(check.remediation.label)}: ${escapeHtml42(check.remediation.detail)}</em>` : ""}</li>`).join("");
29835
- return `<article class="row ${escapeHtml42(row.status)}">
29971
+ const checks = row.checks.map((check) => `<li class="${escapeHtml43(check.status)}"><strong>${escapeHtml43(check.label)}</strong><span>${escapeHtml43(check.detail ?? check.status)}</span>${check.remediation ? `<em>${check.remediation.href ? `<a href="${escapeHtml43(check.remediation.href)}">${escapeHtml43(check.remediation.label)}</a>` : escapeHtml43(check.remediation.label)}: ${escapeHtml43(check.remediation.detail)}</em>` : ""}</li>`).join("");
29972
+ return `<article class="row ${escapeHtml43(row.status)}">
29836
29973
  <div>
29837
- <p class="eyebrow">${escapeHtml42(row.kind)}${row.selected ? " \xB7 selected" : ""}</p>
29838
- <h2>${escapeHtml42(row.provider)}</h2>
29839
- <p class="status ${escapeHtml42(row.status)}">${escapeHtml42(row.status.toUpperCase())}</p>
29974
+ <p class="eyebrow">${escapeHtml43(row.kind)}${row.selected ? " \xB7 selected" : ""}</p>
29975
+ <h2>${escapeHtml43(row.provider)}</h2>
29976
+ <p class="status ${escapeHtml43(row.status)}">${escapeHtml43(row.status.toUpperCase())}</p>
29840
29977
  </div>
29841
29978
  <ul>${checks}</ul>
29842
29979
  </article>`;
29843
29980
  }).join("");
29844
- const snippet = escapeHtml42(`const providerContracts = () =>
29981
+ const snippet = escapeHtml43(`const providerContracts = () =>
29845
29982
  createVoiceProviderContractMatrixPreset('phone-agent', {
29846
29983
  env: process.env,
29847
29984
  providers: {
@@ -29862,7 +29999,7 @@ createVoiceProductionReadinessRoutes({
29862
29999
  providerContractMatrix: () =>
29863
30000
  buildVoiceProviderContractMatrix(providerContracts())
29864
30001
  });`);
29865
- return `<!doctype html><html lang="en"><head><meta charset="utf-8" /><meta name="viewport" content="width=device-width, initial-scale=1" /><title>${escapeHtml42(title)}</title><style>body{background:#0f1412;color:#f7f3e8;font-family:ui-sans-serif,system-ui,sans-serif;margin:0}main{margin:auto;max-width:1180px;padding:32px}.hero,.primitive,.row{background:#17201b;border:1px solid #2d3b32;border-radius:24px;margin-bottom:16px;padding:22px}.hero{background:linear-gradient(135deg,rgba(34,197,94,.16),rgba(125,211,252,.12))}.primitive{background:#111814;border-color:#41604a}.eyebrow{color:#86efac;font-size:.78rem;font-weight:900;letter-spacing:.1em;text-transform:uppercase}h1{font-size:clamp(2.4rem,6vw,5rem);letter-spacing:-.06em;line-height:.9;margin:.2rem 0 1rem}h2{margin:.2rem 0}.summary{display:flex;flex-wrap:wrap;gap:10px}.pill,.status{border:1px solid #3f4f45;border-radius:999px;display:inline-flex;padding:8px 12px}.primitive code{color:#bbf7d0}.primitive p{color:#c8d8ca;line-height:1.55;margin:.45rem 0 0}.primitive pre{background:#08110d;border:1px solid #294132;border-radius:18px;color:#d9f99d;margin:16px 0 0;overflow:auto;padding:16px}.status.pass,.row.pass,.pass{border-color:rgba(34,197,94,.65)}.status.warn,.row.warn,.warn{border-color:rgba(245,158,11,.7)}.status.fail,.row.fail,.fail{border-color:rgba(239,68,68,.75)}.row{display:grid;gap:20px;grid-template-columns:minmax(180px,.45fr) 1fr}.row ul{display:grid;gap:10px;list-style:none;margin:0;padding:0}.row li{background:#111814;border:1px solid #2d3b32;border-radius:16px;display:grid;gap:4px;padding:12px}.row li span{color:#b8c2ba}.row li em{color:#f9d77e;font-style:normal}.row li a{color:#86efac}@media(max-width:760px){main{padding:18px}.row{grid-template-columns:1fr}}</style></head><body><main><section class="hero"><p class="eyebrow">Provider contracts</p><h1>${escapeHtml42(title)}</h1><p>Self-hosted provider proof for configured state, required env, latency budgets, fallback, streaming, and declared capabilities.</p><div class="summary"><span class="pill">${String(report.passed)} passing</span><span class="pill">${String(report.warned)} warning</span><span class="pill">${String(report.failed)} failing</span><span class="pill">${String(report.total)} total</span></div></section><section class="primitive"><p class="eyebrow">Copy into your app</p><h2><code>createVoiceProviderContractMatrixPreset(...)</code> builds this matrix</h2><p>Give AbsoluteJS your configured LLM, STT, and TTS providers once. It turns them into deploy-checkable proof for env, fallback, streaming, latency budgets, selected providers, and profile-required capabilities without a hosted dashboard.</p><pre><code>${snippet}</code></pre></section>${rows || '<article class="row"><p>No provider contracts configured.</p></article>'}</main></body></html>`;
30002
+ return `<!doctype html><html lang="en"><head><meta charset="utf-8" /><meta name="viewport" content="width=device-width, initial-scale=1" /><title>${escapeHtml43(title)}</title><style>body{background:#0f1412;color:#f7f3e8;font-family:ui-sans-serif,system-ui,sans-serif;margin:0}main{margin:auto;max-width:1180px;padding:32px}.hero,.primitive,.row{background:#17201b;border:1px solid #2d3b32;border-radius:24px;margin-bottom:16px;padding:22px}.hero{background:linear-gradient(135deg,rgba(34,197,94,.16),rgba(125,211,252,.12))}.primitive{background:#111814;border-color:#41604a}.eyebrow{color:#86efac;font-size:.78rem;font-weight:900;letter-spacing:.1em;text-transform:uppercase}h1{font-size:clamp(2.4rem,6vw,5rem);letter-spacing:-.06em;line-height:.9;margin:.2rem 0 1rem}h2{margin:.2rem 0}.summary{display:flex;flex-wrap:wrap;gap:10px}.pill,.status{border:1px solid #3f4f45;border-radius:999px;display:inline-flex;padding:8px 12px}.primitive code{color:#bbf7d0}.primitive p{color:#c8d8ca;line-height:1.55;margin:.45rem 0 0}.primitive pre{background:#08110d;border:1px solid #294132;border-radius:18px;color:#d9f99d;margin:16px 0 0;overflow:auto;padding:16px}.status.pass,.row.pass,.pass{border-color:rgba(34,197,94,.65)}.status.warn,.row.warn,.warn{border-color:rgba(245,158,11,.7)}.status.fail,.row.fail,.fail{border-color:rgba(239,68,68,.75)}.row{display:grid;gap:20px;grid-template-columns:minmax(180px,.45fr) 1fr}.row ul{display:grid;gap:10px;list-style:none;margin:0;padding:0}.row li{background:#111814;border:1px solid #2d3b32;border-radius:16px;display:grid;gap:4px;padding:12px}.row li span{color:#b8c2ba}.row li em{color:#f9d77e;font-style:normal}.row li a{color:#86efac}@media(max-width:760px){main{padding:18px}.row{grid-template-columns:1fr}}</style></head><body><main><section class="hero"><p class="eyebrow">Provider contracts</p><h1>${escapeHtml43(title)}</h1><p>Self-hosted provider proof for configured state, required env, latency budgets, fallback, streaming, and declared capabilities.</p><div class="summary"><span class="pill">${String(report.passed)} passing</span><span class="pill">${String(report.warned)} warning</span><span class="pill">${String(report.failed)} failing</span><span class="pill">${String(report.total)} total</span></div></section><section class="primitive"><p class="eyebrow">Copy into your app</p><h2><code>createVoiceProviderContractMatrixPreset(...)</code> builds this matrix</h2><p>Give AbsoluteJS your configured LLM, STT, and TTS providers once. It turns them into deploy-checkable proof for env, fallback, streaming, latency budgets, selected providers, and profile-required capabilities without a hosted dashboard.</p><pre><code>${snippet}</code></pre></section>${rows || '<article class="row"><p>No provider contracts configured.</p></article>'}</main></body></html>`;
29866
30003
  };
29867
30004
  var createVoiceProviderContractMatrixJSONHandler = (matrix) => async () => buildVoiceProviderContractMatrix(await resolveProviderContractMatrixInput(matrix));
29868
30005
  var createVoiceProviderContractMatrixHTMLHandler = (options) => async () => {
@@ -30030,7 +30167,7 @@ var DEFAULT_LINKS = [
30030
30167
  label: "Handoffs"
30031
30168
  }
30032
30169
  ];
30033
- var escapeHtml43 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
30170
+ var escapeHtml44 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
30034
30171
  var countProviderStatuses = (providers) => {
30035
30172
  const degradedStatuses = new Set(["degraded", "rate-limited", "suppressed"]);
30036
30173
  const healthy = providers.filter((provider) => provider.status === "healthy").length;
@@ -30099,16 +30236,16 @@ var buildVoiceOpsConsoleReport = async (options) => {
30099
30236
  trace
30100
30237
  };
30101
30238
  };
30102
- var renderMetricCard = (input) => `<article class="metric"><span>${escapeHtml43(input.label)}</span><strong>${escapeHtml43(String(input.value))}</strong>${input.status ? `<p class="${escapeHtml43(input.status)}">${escapeHtml43(input.status)}</p>` : ""}${input.href ? `<a href="${escapeHtml43(input.href)}">Open</a>` : ""}</article>`;
30239
+ var renderMetricCard = (input) => `<article class="metric"><span>${escapeHtml44(input.label)}</span><strong>${escapeHtml44(String(input.value))}</strong>${input.status ? `<p class="${escapeHtml44(input.status)}">${escapeHtml44(input.status)}</p>` : ""}${input.href ? `<a href="${escapeHtml44(input.href)}">Open</a>` : ""}</article>`;
30103
30240
  var renderVoiceOpsConsoleHTML = (report, options = {}) => {
30104
30241
  const links = report.links.map((link) => `<article class="surface">
30105
- <div><h2>${escapeHtml43(link.label)}</h2>${link.description ? `<p>${escapeHtml43(link.description)}</p>` : ""}</div>
30106
- <p><a href="${escapeHtml43(link.href)}">Open ${escapeHtml43(link.label)}</a>${link.statusHref ? ` \xB7 <a href="${escapeHtml43(link.statusHref)}">Status</a>` : ""}</p>
30242
+ <div><h2>${escapeHtml44(link.label)}</h2>${link.description ? `<p>${escapeHtml44(link.description)}</p>` : ""}</div>
30243
+ <p><a href="${escapeHtml44(link.href)}">Open ${escapeHtml44(link.label)}</a>${link.statusHref ? ` \xB7 <a href="${escapeHtml44(link.statusHref)}">Status</a>` : ""}</p>
30107
30244
  </article>`).join("");
30108
- const sessions = report.recentSessions.length ? report.recentSessions.map((session) => `<tr><td>${escapeHtml43(session.sessionId)}</td><td>${escapeHtml43(session.status)}</td><td>${session.turnCount}</td><td>${session.errorCount}</td><td>${session.replayHref ? `<a href="${escapeHtml43(session.replayHref)}">Replay</a>` : ""}</td></tr>`).join("") : '<tr><td colspan="5">No sessions yet.</td></tr>';
30109
- const routing = report.recentRoutingEvents.length ? report.recentRoutingEvents.map((event) => `<tr><td>${escapeHtml43(event.kind)}</td><td>${escapeHtml43(event.provider ?? "unknown")}</td><td>${escapeHtml43(event.status ?? "unknown")}</td><td>${event.elapsedMs ?? 0}ms</td><td>${escapeHtml43(event.sessionId)}</td></tr>`).join("") : '<tr><td colspan="5">No provider routing events yet.</td></tr>';
30245
+ const sessions = report.recentSessions.length ? report.recentSessions.map((session) => `<tr><td>${escapeHtml44(session.sessionId)}</td><td>${escapeHtml44(session.status)}</td><td>${session.turnCount}</td><td>${session.errorCount}</td><td>${session.replayHref ? `<a href="${escapeHtml44(session.replayHref)}">Replay</a>` : ""}</td></tr>`).join("") : '<tr><td colspan="5">No sessions yet.</td></tr>';
30246
+ const routing = report.recentRoutingEvents.length ? report.recentRoutingEvents.map((event) => `<tr><td>${escapeHtml44(event.kind)}</td><td>${escapeHtml44(event.provider ?? "unknown")}</td><td>${escapeHtml44(event.status ?? "unknown")}</td><td>${event.elapsedMs ?? 0}ms</td><td>${escapeHtml44(event.sessionId)}</td></tr>`).join("") : '<tr><td colspan="5">No provider routing events yet.</td></tr>';
30110
30247
  const title = options.title ?? "AbsoluteJS Voice Ops Console";
30111
- return `<!doctype html><html lang="en"><head><meta charset="utf-8" /><meta name="viewport" content="width=device-width, initial-scale=1" /><title>${escapeHtml43(title)}</title><style>body{font-family:ui-sans-serif,system-ui,sans-serif;background:#101316;color:#f6f2e8;margin:0}main{max-width:1180px;margin:auto;padding:32px}a{color:#fbbf24}header{display:flex;justify-content:space-between;gap:24px;align-items:flex-start;margin-bottom:24px}.eyebrow{color:#fbbf24;font-weight:800;letter-spacing:.08em;text-transform:uppercase}h1{font-size:clamp(2.2rem,5vw,4.5rem);line-height:.95;margin:.2rem 0 1rem}.muted{color:#a8b0b8}.grid{display:grid;gap:14px;grid-template-columns:repeat(auto-fit,minmax(180px,1fr));margin:20px 0}.metric,.surface{background:#181d22;border:1px solid #2a323a;border-radius:20px;padding:18px}.metric strong{display:block;font-size:2.2rem;margin:.25rem 0}.pass,.healthy{color:#86efac}.fail,.failed,.degraded{color:#fca5a5}.surfaces{display:grid;gap:16px;grid-template-columns:repeat(auto-fit,minmax(240px,1fr));margin:24px 0}table{width:100%;border-collapse:collapse;background:#181d22;border-radius:16px;overflow:hidden;margin:12px 0 28px}td,th{border-bottom:1px solid #2a323a;padding:12px;text-align:left}section{margin-top:30px}@media(max-width:700px){main{padding:20px}header{display:block}}</style></head><body><main><header><div><p class="eyebrow">Self-hosted voice operations</p><h1>${escapeHtml43(title)}</h1><p class="muted">One deployable control plane for quality gates, failover, traces, sessions, handoffs, and provider health.</p></div><p class="muted">Checked ${escapeHtml43(new Date(report.checkedAt).toLocaleString())}</p></header><div class="grid">${renderMetricCard({ label: "Quality", value: report.quality.status, status: report.quality.status, href: "/quality" })}${renderMetricCard({ label: "Events", value: report.eventCount, href: "/diagnostics" })}${renderMetricCard({ label: "Sessions", value: report.sessions.total, status: report.sessions.failed > 0 ? "failed" : "healthy", href: "/sessions" })}${renderMetricCard({ label: "Handoffs failed", value: report.handoffs.failed, status: report.handoffs.failed > 0 ? "failed" : "healthy", href: "/handoffs" })}${renderMetricCard({ label: "Providers degraded", value: report.providers.degraded, status: report.providers.degraded > 0 ? "degraded" : "healthy", href: "/resilience" })}</div><section><h2>Operational Surfaces</h2><div class="surfaces">${links}</div></section><section><h2>Recent Sessions</h2><table><thead><tr><th>Session</th><th>Status</th><th>Turns</th><th>Errors</th><th>Replay</th></tr></thead><tbody>${sessions}</tbody></table></section><section><h2>Recent Provider Routing</h2><table><thead><tr><th>Kind</th><th>Provider</th><th>Status</th><th>Elapsed</th><th>Session</th></tr></thead><tbody>${routing}</tbody></table></section></main></body></html>`;
30248
+ return `<!doctype html><html lang="en"><head><meta charset="utf-8" /><meta name="viewport" content="width=device-width, initial-scale=1" /><title>${escapeHtml44(title)}</title><style>body{font-family:ui-sans-serif,system-ui,sans-serif;background:#101316;color:#f6f2e8;margin:0}main{max-width:1180px;margin:auto;padding:32px}a{color:#fbbf24}header{display:flex;justify-content:space-between;gap:24px;align-items:flex-start;margin-bottom:24px}.eyebrow{color:#fbbf24;font-weight:800;letter-spacing:.08em;text-transform:uppercase}h1{font-size:clamp(2.2rem,5vw,4.5rem);line-height:.95;margin:.2rem 0 1rem}.muted{color:#a8b0b8}.grid{display:grid;gap:14px;grid-template-columns:repeat(auto-fit,minmax(180px,1fr));margin:20px 0}.metric,.surface{background:#181d22;border:1px solid #2a323a;border-radius:20px;padding:18px}.metric strong{display:block;font-size:2.2rem;margin:.25rem 0}.pass,.healthy{color:#86efac}.fail,.failed,.degraded{color:#fca5a5}.surfaces{display:grid;gap:16px;grid-template-columns:repeat(auto-fit,minmax(240px,1fr));margin:24px 0}table{width:100%;border-collapse:collapse;background:#181d22;border-radius:16px;overflow:hidden;margin:12px 0 28px}td,th{border-bottom:1px solid #2a323a;padding:12px;text-align:left}section{margin-top:30px}@media(max-width:700px){main{padding:20px}header{display:block}}</style></head><body><main><header><div><p class="eyebrow">Self-hosted voice operations</p><h1>${escapeHtml44(title)}</h1><p class="muted">One deployable control plane for quality gates, failover, traces, sessions, handoffs, and provider health.</p></div><p class="muted">Checked ${escapeHtml44(new Date(report.checkedAt).toLocaleString())}</p></header><div class="grid">${renderMetricCard({ label: "Quality", value: report.quality.status, status: report.quality.status, href: "/quality" })}${renderMetricCard({ label: "Events", value: report.eventCount, href: "/diagnostics" })}${renderMetricCard({ label: "Sessions", value: report.sessions.total, status: report.sessions.failed > 0 ? "failed" : "healthy", href: "/sessions" })}${renderMetricCard({ label: "Handoffs failed", value: report.handoffs.failed, status: report.handoffs.failed > 0 ? "failed" : "healthy", href: "/handoffs" })}${renderMetricCard({ label: "Providers degraded", value: report.providers.degraded, status: report.providers.degraded > 0 ? "degraded" : "healthy", href: "/resilience" })}</div><section><h2>Operational Surfaces</h2><div class="surfaces">${links}</div></section><section><h2>Recent Sessions</h2><table><thead><tr><th>Session</th><th>Status</th><th>Turns</th><th>Errors</th><th>Replay</th></tr></thead><tbody>${sessions}</tbody></table></section><section><h2>Recent Provider Routing</h2><table><thead><tr><th>Kind</th><th>Provider</th><th>Status</th><th>Elapsed</th><th>Session</th></tr></thead><tbody>${routing}</tbody></table></section></main></body></html>`;
30112
30249
  };
30113
30250
  var createVoiceOpsConsoleRoutes = (options) => {
30114
30251
  const path = options.path ?? "/ops-console";
@@ -30532,14 +30669,14 @@ var summarizeVoiceOpsStatus = async (options) => {
30532
30669
  };
30533
30670
  // src/opsStatusRoutes.ts
30534
30671
  import { Elysia as Elysia49 } from "elysia";
30535
- var escapeHtml44 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
30672
+ var escapeHtml45 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
30536
30673
  var renderVoiceOpsStatusHTML = (report, options = {}) => {
30537
30674
  const title = options.title ?? "AbsoluteJS Voice Ops Status";
30538
30675
  const surfaces = Object.entries(report.surfaces).map(([key, surface]) => {
30539
30676
  const value = "recovered" in surface ? surface.total === 0 ? "0 events" : `${surface.recovered}/${surface.total}` : ("auditTotal" in surface) ? `${surface.auditTotal + surface.traceTotal} deliveries` : ("total" in surface) ? `${Math.max(surface.total - ("failed" in surface ? surface.failed : ("degraded" in surface) ? surface.degraded : 0), 0)}/${surface.total}` : surface.status;
30540
- return `<article class="surface ${escapeHtml44(surface.status)}"><span>${escapeHtml44(surface.status.toUpperCase())}</span><h2>${escapeHtml44(key)}</h2><strong>${escapeHtml44(value)}</strong></article>`;
30677
+ return `<article class="surface ${escapeHtml45(surface.status)}"><span>${escapeHtml45(surface.status.toUpperCase())}</span><h2>${escapeHtml45(key)}</h2><strong>${escapeHtml45(value)}</strong></article>`;
30541
30678
  }).join("");
30542
- return `<!doctype html><html lang="en"><head><meta charset="utf-8" /><meta name="viewport" content="width=device-width, initial-scale=1" /><title>${escapeHtml44(title)}</title><style>body{background:#0d141b;color:#f8f3e7;font-family:ui-sans-serif,system-ui,sans-serif;margin:0}main{margin:auto;max-width:980px;padding:32px}.hero{background:linear-gradient(135deg,rgba(20,184,166,.2),rgba(245,158,11,.12));border:1px solid #283544;border-radius:28px;margin-bottom:18px;padding:28px}.eyebrow{color:#5eead4;font-weight:900;letter-spacing:.12em;text-transform:uppercase}h1{font-size:clamp(2.4rem,6vw,5rem);line-height:.9;margin:.2rem 0 1rem}.status{border:1px solid #3f3f46;border-radius:999px;display:inline-flex;font-weight:900;padding:8px 12px}.surfaces{display:grid;gap:14px;grid-template-columns:repeat(auto-fit,minmax(180px,1fr))}.surface{background:#151d26;border:1px solid #283544;border-radius:20px;padding:18px}.surface span{color:#aab5c0;font-size:.78rem;font-weight:900;letter-spacing:.08em}.surface strong{font-size:1.5rem}.pass{border-color:rgba(34,197,94,.55)}.fail{border-color:rgba(239,68,68,.75)}a{color:#5eead4}</style></head><body><main><section class="hero"><p class="eyebrow">Ops status</p><h1>${escapeHtml44(title)}</h1><p>Compact pass/fail status for framework widgets, demos, and small customer-facing health badges.</p><p class="status ${escapeHtml44(report.status)}">Overall: ${escapeHtml44(report.status.toUpperCase())}</p><p>${report.passed}/${report.total} checks passing</p></section><section class="surfaces">${surfaces || '<article class="surface pass"><span>PASS</span><h2>No checks configured</h2><strong>0/0</strong></article>'}</section></main></body></html>`;
30679
+ return `<!doctype html><html lang="en"><head><meta charset="utf-8" /><meta name="viewport" content="width=device-width, initial-scale=1" /><title>${escapeHtml45(title)}</title><style>body{background:#0d141b;color:#f8f3e7;font-family:ui-sans-serif,system-ui,sans-serif;margin:0}main{margin:auto;max-width:980px;padding:32px}.hero{background:linear-gradient(135deg,rgba(20,184,166,.2),rgba(245,158,11,.12));border:1px solid #283544;border-radius:28px;margin-bottom:18px;padding:28px}.eyebrow{color:#5eead4;font-weight:900;letter-spacing:.12em;text-transform:uppercase}h1{font-size:clamp(2.4rem,6vw,5rem);line-height:.9;margin:.2rem 0 1rem}.status{border:1px solid #3f3f46;border-radius:999px;display:inline-flex;font-weight:900;padding:8px 12px}.surfaces{display:grid;gap:14px;grid-template-columns:repeat(auto-fit,minmax(180px,1fr))}.surface{background:#151d26;border:1px solid #283544;border-radius:20px;padding:18px}.surface span{color:#aab5c0;font-size:.78rem;font-weight:900;letter-spacing:.08em}.surface strong{font-size:1.5rem}.pass{border-color:rgba(34,197,94,.55)}.fail{border-color:rgba(239,68,68,.75)}a{color:#5eead4}</style></head><body><main><section class="hero"><p class="eyebrow">Ops status</p><h1>${escapeHtml45(title)}</h1><p>Compact pass/fail status for framework widgets, demos, and small customer-facing health badges.</p><p class="status ${escapeHtml45(report.status)}">Overall: ${escapeHtml45(report.status.toUpperCase())}</p><p>${report.passed}/${report.total} checks passing</p></section><section class="surfaces">${surfaces || '<article class="surface pass"><span>PASS</span><h2>No checks configured</h2><strong>0/0</strong></article>'}</section></main></body></html>`;
30543
30680
  };
30544
30681
  var createVoiceOpsStatusRoutes = (options) => {
30545
30682
  const path = options.path ?? "/api/voice/ops-status";
@@ -30977,7 +31114,7 @@ var createVoiceTTSProviderRouter = (options) => {
30977
31114
  };
30978
31115
  // src/traceDeliveryRoutes.ts
30979
31116
  import { Elysia as Elysia50 } from "elysia";
30980
- var escapeHtml45 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
31117
+ var escapeHtml46 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
30981
31118
  var getString19 = (value) => typeof value === "string" && value.trim() ? value.trim() : undefined;
30982
31119
  var getNumber11 = (value) => {
30983
31120
  if (typeof value === "number" && Number.isFinite(value)) {
@@ -31058,14 +31195,14 @@ var renderSinkResults2 = (delivery) => {
31058
31195
  if (entries.length === 0) {
31059
31196
  return "<p>No sink delivery attempts recorded yet.</p>";
31060
31197
  }
31061
- return `<ul>${entries.map(([sinkId, result]) => `<li><strong>${escapeHtml45(sinkId)}</strong>: ${escapeHtml45(result.status)}${result.deliveredTo ? ` to ${escapeHtml45(result.deliveredTo)}` : ""}${result.error ? ` (${escapeHtml45(result.error)})` : ""}</li>`).join("")}</ul>`;
31198
+ return `<ul>${entries.map(([sinkId, result]) => `<li><strong>${escapeHtml46(sinkId)}</strong>: ${escapeHtml46(result.status)}${result.deliveredTo ? ` to ${escapeHtml46(result.deliveredTo)}` : ""}${result.error ? ` (${escapeHtml46(result.error)})` : ""}</li>`).join("")}</ul>`;
31062
31199
  };
31063
- var renderEventList2 = (delivery) => delivery.events.length === 0 ? "<p>No trace events in this delivery.</p>" : `<ul>${delivery.events.map((event) => `<li>${escapeHtml45(event.type)} <small>${escapeHtml45(event.id)}</small>${event.sessionId ? ` session=${escapeHtml45(event.sessionId)}` : ""}</li>`).join("")}</ul>`;
31200
+ var renderEventList2 = (delivery) => delivery.events.length === 0 ? "<p>No trace events in this delivery.</p>" : `<ul>${delivery.events.map((event) => `<li>${escapeHtml46(event.type)} <small>${escapeHtml46(event.id)}</small>${event.sessionId ? ` session=${escapeHtml46(event.sessionId)}` : ""}</li>`).join("")}</ul>`;
31064
31201
  var renderVoiceTraceDeliveryHTML = (report, options = {}) => {
31065
31202
  const title = options.title ?? "AbsoluteJS Voice Trace Deliveries";
31066
- const drainAction = options.workerPath === false ? "" : `<form method="post" action="${escapeHtml45(options.workerPath ?? "/api/voice-trace-deliveries/drain")}"><button type="submit">Drain trace deliveries</button></form>`;
31067
- const rows = report.deliveries.map((delivery) => `<article class="delivery ${escapeHtml45(delivery.deliveryStatus)}"><div class="head"><div><span>${escapeHtml45(delivery.deliveryStatus)}</span><h2>${escapeHtml45(delivery.id)}</h2><p>${escapeHtml45(new Date(delivery.createdAt).toLocaleString())}${delivery.deliveredAt ? ` \xB7 delivered ${escapeHtml45(new Date(delivery.deliveredAt).toLocaleString())}` : ""}</p></div><strong>${String(delivery.deliveryAttempts ?? 0)} attempt(s)</strong></div>${delivery.deliveryError ? `<p class="error">${escapeHtml45(delivery.deliveryError)}</p>` : ""}<h3>Sinks</h3>${renderSinkResults2(delivery)}<h3>Events</h3>${renderEventList2(delivery)}</article>`).join("");
31068
- return `<!doctype html><html lang="en"><head><meta charset="utf-8" /><meta name="viewport" content="width=device-width, initial-scale=1" /><title>${escapeHtml45(title)}</title><style>body{background:#0f1318;color:#f4efe1;font-family:ui-sans-serif,system-ui,sans-serif;margin:0}main{margin:auto;max-width:1120px;padding:32px}.hero{background:linear-gradient(135deg,rgba(34,197,94,.16),rgba(14,165,233,.14));border:1px solid #26313d;border-radius:28px;margin-bottom:18px;padding:28px}.eyebrow{color:#86efac;font-weight:900;letter-spacing:.12em;text-transform:uppercase}h1{font-size:clamp(2.2rem,5vw,4.8rem);line-height:.92;margin:.2rem 0 1rem}.grid{display:grid;gap:12px;grid-template-columns:repeat(4,1fr);margin-bottom:16px}.grid article,.delivery{background:#151b22;border:1px solid #26313d;border-radius:22px;padding:18px}.grid span,.delivery span{color:#86efac;font-size:.78rem;font-weight:900;letter-spacing:.08em;text-transform:uppercase}.grid strong{display:block;font-size:2rem}.deliveries{display:grid;gap:14px}.delivery.failed{border-color:rgba(239,68,68,.75)}.delivery.pending{border-color:rgba(245,158,11,.7)}.delivery.delivered{border-color:rgba(34,197,94,.55)}.delivery.skipped{border-color:rgba(148,163,184,.6)}.head{align-items:start;display:flex;gap:14px;justify-content:space-between}.delivery h2{font-size:1.05rem;margin:.3rem 0;overflow-wrap:anywhere}.delivery h3{margin:1rem 0 .3rem}.delivery p,.delivery li{color:#c8d0d8}.error{color:#fecaca!important}button{background:#86efac;border:0;border-radius:999px;color:#07111f;cursor:pointer;font-weight:900;margin-top:12px;padding:10px 14px}@media(max-width:760px){main{padding:20px}.grid{grid-template-columns:1fr 1fr}.head{display:block}}</style></head><body><main><section class="hero"><p class="eyebrow">Trace export health</p><h1>${escapeHtml45(title)}</h1><p>Checked ${escapeHtml45(new Date(report.checkedAt).toLocaleString())}. Showing ${String(report.deliveries.length)} delivery item(s).</p>${drainAction}</section>${renderMetricGrid3(report)}<section class="deliveries">${rows || "<p>No trace deliveries match this filter.</p>"}</section></main></body></html>`;
31203
+ const drainAction = options.workerPath === false ? "" : `<form method="post" action="${escapeHtml46(options.workerPath ?? "/api/voice-trace-deliveries/drain")}"><button type="submit">Drain trace deliveries</button></form>`;
31204
+ const rows = report.deliveries.map((delivery) => `<article class="delivery ${escapeHtml46(delivery.deliveryStatus)}"><div class="head"><div><span>${escapeHtml46(delivery.deliveryStatus)}</span><h2>${escapeHtml46(delivery.id)}</h2><p>${escapeHtml46(new Date(delivery.createdAt).toLocaleString())}${delivery.deliveredAt ? ` \xB7 delivered ${escapeHtml46(new Date(delivery.deliveredAt).toLocaleString())}` : ""}</p></div><strong>${String(delivery.deliveryAttempts ?? 0)} attempt(s)</strong></div>${delivery.deliveryError ? `<p class="error">${escapeHtml46(delivery.deliveryError)}</p>` : ""}<h3>Sinks</h3>${renderSinkResults2(delivery)}<h3>Events</h3>${renderEventList2(delivery)}</article>`).join("");
31205
+ return `<!doctype html><html lang="en"><head><meta charset="utf-8" /><meta name="viewport" content="width=device-width, initial-scale=1" /><title>${escapeHtml46(title)}</title><style>body{background:#0f1318;color:#f4efe1;font-family:ui-sans-serif,system-ui,sans-serif;margin:0}main{margin:auto;max-width:1120px;padding:32px}.hero{background:linear-gradient(135deg,rgba(34,197,94,.16),rgba(14,165,233,.14));border:1px solid #26313d;border-radius:28px;margin-bottom:18px;padding:28px}.eyebrow{color:#86efac;font-weight:900;letter-spacing:.12em;text-transform:uppercase}h1{font-size:clamp(2.2rem,5vw,4.8rem);line-height:.92;margin:.2rem 0 1rem}.grid{display:grid;gap:12px;grid-template-columns:repeat(4,1fr);margin-bottom:16px}.grid article,.delivery{background:#151b22;border:1px solid #26313d;border-radius:22px;padding:18px}.grid span,.delivery span{color:#86efac;font-size:.78rem;font-weight:900;letter-spacing:.08em;text-transform:uppercase}.grid strong{display:block;font-size:2rem}.deliveries{display:grid;gap:14px}.delivery.failed{border-color:rgba(239,68,68,.75)}.delivery.pending{border-color:rgba(245,158,11,.7)}.delivery.delivered{border-color:rgba(34,197,94,.55)}.delivery.skipped{border-color:rgba(148,163,184,.6)}.head{align-items:start;display:flex;gap:14px;justify-content:space-between}.delivery h2{font-size:1.05rem;margin:.3rem 0;overflow-wrap:anywhere}.delivery h3{margin:1rem 0 .3rem}.delivery p,.delivery li{color:#c8d0d8}.error{color:#fecaca!important}button{background:#86efac;border:0;border-radius:999px;color:#07111f;cursor:pointer;font-weight:900;margin-top:12px;padding:10px 14px}@media(max-width:760px){main{padding:20px}.grid{grid-template-columns:1fr 1fr}.head{display:block}}</style></head><body><main><section class="hero"><p class="eyebrow">Trace export health</p><h1>${escapeHtml46(title)}</h1><p>Checked ${escapeHtml46(new Date(report.checkedAt).toLocaleString())}. Showing ${String(report.deliveries.length)} delivery item(s).</p>${drainAction}</section>${renderMetricGrid3(report)}<section class="deliveries">${rows || "<p>No trace deliveries match this filter.</p>"}</section></main></body></html>`;
31069
31206
  };
31070
31207
  var createVoiceTraceDeliveryJSONHandler = (options) => async ({ query }) => buildVoiceTraceDeliveryReport(options, resolveVoiceTraceDeliveryFilter(query, options.filter));
31071
31208
  var createVoiceTraceDeliveryHTMLHandler = (options) => async ({ query }) => {
@@ -32788,6 +32925,8 @@ export {
32788
32925
  renderVoiceTraceDeliveryHTML,
32789
32926
  renderVoiceToolContractHTML,
32790
32927
  renderVoiceTelephonyCarrierMatrixHTML,
32928
+ renderVoiceSloReadinessThresholdMarkdown,
32929
+ renderVoiceSloReadinessThresholdHTML,
32791
32930
  renderVoiceSloCalibrationMarkdown,
32792
32931
  renderVoiceSimulationSuiteHTML,
32793
32932
  renderVoiceSessionsHTML,
@@ -32970,6 +33109,8 @@ export {
32970
33109
  createVoiceTaskCreatedEvent,
32971
33110
  createVoiceTTSProviderRouter,
32972
33111
  createVoiceSloThresholdProfile,
33112
+ createVoiceSloReadinessThresholdRoutes,
33113
+ createVoiceSloReadinessThresholdOptions,
32973
33114
  createVoiceSloCalibrationRoutes,
32974
33115
  createVoiceSimulationSuiteRoutes,
32975
33116
  createVoiceSessionsJSONHandler,
@@ -33204,6 +33345,7 @@ export {
33204
33345
  buildVoiceTraceReplay,
33205
33346
  buildVoiceTraceDeliveryReport,
33206
33347
  buildVoiceTelephonyWebhookSecurityReport,
33348
+ buildVoiceSloReadinessThresholdReport,
33207
33349
  buildVoiceSloCalibrationReport,
33208
33350
  buildVoiceProviderSloReport,
33209
33351
  buildVoiceProviderContractMatrix,