@absolutejs/voice 0.0.22-beta.146 → 0.0.22-beta.148

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
@@ -11564,6 +11564,120 @@ var createVoiceDeliverySinkRoutes = (options) => {
11564
11564
  }
11565
11565
  return routes;
11566
11566
  };
11567
+ // src/deliveryRuntime.ts
11568
+ import { Elysia as Elysia12 } from "elysia";
11569
+ var escapeHtml15 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
11570
+ var renderSummaryCard = (label, summary) => {
11571
+ if (!summary) {
11572
+ return `<article><span>${escapeHtml15(label)}</span><strong>Disabled</strong><p class="muted">No worker configured.</p></article>`;
11573
+ }
11574
+ return `<article><span>${escapeHtml15(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>`;
11575
+ };
11576
+ var createVoiceDeliveryRuntime = (config) => {
11577
+ const audit = config.audit ? createVoiceAuditSinkDeliveryWorker(config.audit) : undefined;
11578
+ const trace = config.trace ? createVoiceTraceSinkDeliveryWorker(config.trace) : undefined;
11579
+ let auditLoop;
11580
+ let traceLoop;
11581
+ if (audit && config.audit) {
11582
+ auditLoop = createVoiceAuditSinkDeliveryWorkerLoop({
11583
+ onError: config.audit.onError,
11584
+ pollIntervalMs: config.audit.pollIntervalMs,
11585
+ worker: audit
11586
+ });
11587
+ }
11588
+ if (trace && config.trace) {
11589
+ traceLoop = createVoiceTraceSinkDeliveryWorkerLoop({
11590
+ onError: config.trace.onError,
11591
+ pollIntervalMs: config.trace.pollIntervalMs,
11592
+ worker: trace
11593
+ });
11594
+ }
11595
+ return {
11596
+ audit,
11597
+ isRunning: () => Boolean(auditLoop?.isRunning() || traceLoop?.isRunning()),
11598
+ start: () => {
11599
+ if (config.audit?.autoStart) {
11600
+ auditLoop?.start();
11601
+ }
11602
+ if (config.trace?.autoStart) {
11603
+ traceLoop?.start();
11604
+ }
11605
+ },
11606
+ stop: () => {
11607
+ auditLoop?.stop();
11608
+ traceLoop?.stop();
11609
+ },
11610
+ summarize: async () => {
11611
+ const summary = {};
11612
+ if (config.audit) {
11613
+ summary.audit = await summarizeVoiceAuditSinkDeliveries(await config.audit.deliveries.list(), {
11614
+ deadLetters: config.audit.deadLetters
11615
+ });
11616
+ }
11617
+ if (config.trace) {
11618
+ summary.trace = await summarizeVoiceTraceSinkDeliveries(await config.trace.deliveries.list(), {
11619
+ deadLetters: config.trace.deadLetters
11620
+ });
11621
+ }
11622
+ return summary;
11623
+ },
11624
+ tick: async () => {
11625
+ const result = {};
11626
+ if (auditLoop) {
11627
+ result.audit = await auditLoop.tick();
11628
+ }
11629
+ if (traceLoop) {
11630
+ result.trace = await traceLoop.tick();
11631
+ }
11632
+ return result;
11633
+ },
11634
+ trace
11635
+ };
11636
+ };
11637
+ var buildVoiceDeliveryRuntimeReport = async (runtime) => ({
11638
+ checkedAt: Date.now(),
11639
+ isRunning: runtime.isRunning(),
11640
+ summary: await runtime.summarize()
11641
+ });
11642
+ var renderVoiceDeliveryRuntimeHTML = (report, options = {}) => {
11643
+ const title = options.title ?? "AbsoluteJS Voice Delivery Runtime";
11644
+ const tickForm = options.tickPath === false ? "" : `<form method="post" action="${escapeHtml15(options.tickPath ?? "/api/voice-delivery-runtime/tick")}"><button type="submit">Tick delivery workers</button></form>`;
11645
+ return `<!doctype html><html lang="en"><head><meta charset="utf-8" /><meta name="viewport" content="width=device-width, initial-scale=1" /><title>${escapeHtml15(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}article span{color:#b9c3b4;display:block;font-weight:800}article strong{display:block;font-size:2.3rem;margin-top:8px}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}</style></head><body><main><p><a href="/delivery-sinks">Delivery sinks</a></p><section class="hero"><p class="eyebrow">Worker control plane</p><h1>${escapeHtml15(title)}</h1><p class="muted">Inspect queue summaries and manually tick audit and trace delivery workers from one runtime primitive.</p><p class="status ${report.isRunning ? "running" : ""}">${report.isRunning ? "Running" : "Stopped"}</p><p class="muted">Checked ${escapeHtml15(new Date(report.checkedAt).toLocaleString())}</p>${tickForm}</section><section class="grid">${renderSummaryCard("Audit", report.summary.audit)}${renderSummaryCard("Trace", report.summary.trace)}</section><section class="card"><h2>Runtime shape</h2><pre>const runtime = createVoiceDeliveryRuntime({ audit, trace })
11646
+
11647
+ await runtime.tick()
11648
+ await runtime.summarize()</pre></section></main></body></html>`;
11649
+ };
11650
+ var createVoiceDeliveryRuntimeRoutes = (options) => {
11651
+ const path = options.path ?? "/api/voice-delivery-runtime";
11652
+ const htmlPath = options.htmlPath === undefined ? "/delivery-runtime" : options.htmlPath;
11653
+ const tickPath = options.tickPath === undefined ? "/api/voice-delivery-runtime/tick" : options.tickPath;
11654
+ const routes = new Elysia12({
11655
+ name: options.name ?? "absolutejs-voice-delivery-runtime"
11656
+ }).get(path, () => buildVoiceDeliveryRuntimeReport(options.runtime));
11657
+ if (tickPath !== false) {
11658
+ routes.post(tickPath, async () => ({
11659
+ drainedAt: Date.now(),
11660
+ result: await options.runtime.tick(),
11661
+ summary: await options.runtime.summarize()
11662
+ }));
11663
+ }
11664
+ if (htmlPath !== false) {
11665
+ routes.get(htmlPath, async () => {
11666
+ const report = await buildVoiceDeliveryRuntimeReport(options.runtime);
11667
+ const body = await (options.render ?? renderVoiceDeliveryRuntimeHTML)(report, {
11668
+ tickPath,
11669
+ title: options.title
11670
+ });
11671
+ return new Response(body, {
11672
+ headers: {
11673
+ "Content-Type": "text/html; charset=utf-8",
11674
+ ...options.headers
11675
+ }
11676
+ });
11677
+ });
11678
+ }
11679
+ return routes;
11680
+ };
11567
11681
  // src/dataControl.ts
11568
11682
  var allRetentionScopes = [
11569
11683
  "auditDeliveries",
@@ -11767,16 +11881,16 @@ var applyVoiceDataRetentionPolicy = async (options) => {
11767
11881
  };
11768
11882
  var buildVoiceDataRetentionPlan = (options) => applyVoiceDataRetentionPolicy({ ...options, dryRun: true });
11769
11883
  // src/evalRoutes.ts
11770
- import { Elysia as Elysia14 } from "elysia";
11884
+ import { Elysia as Elysia15 } from "elysia";
11771
11885
  import { mkdir } from "fs/promises";
11772
11886
  import { dirname } from "path";
11773
11887
 
11774
11888
  // src/qualityRoutes.ts
11775
- import { Elysia as Elysia13 } from "elysia";
11889
+ import { Elysia as Elysia14 } from "elysia";
11776
11890
 
11777
11891
  // src/handoffHealth.ts
11778
- import { Elysia as Elysia12 } from "elysia";
11779
- var escapeHtml15 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
11892
+ import { Elysia as Elysia13 } from "elysia";
11893
+ var escapeHtml16 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
11780
11894
  var getString6 = (value) => typeof value === "string" && value.length > 0 ? value : undefined;
11781
11895
  var isStatus = (value) => value === "delivered" || value === "failed" || value === "skipped";
11782
11896
  var increment3 = (record, key) => {
@@ -11894,10 +12008,10 @@ var renderActionSummary = (summary) => {
11894
12008
  return [
11895
12009
  '<section class="voice-handoff-health-columns">',
11896
12010
  "<article><h3>Actions</h3>",
11897
- actions.length === 0 ? "<p>No handoff actions yet.</p>" : `<ul>${actions.map(([action, count]) => `<li>${escapeHtml15(action)}: ${String(count)}</li>`).join("")}</ul>`,
12011
+ actions.length === 0 ? "<p>No handoff actions yet.</p>" : `<ul>${actions.map(([action, count]) => `<li>${escapeHtml16(action)}: ${String(count)}</li>`).join("")}</ul>`,
11898
12012
  "</article>",
11899
12013
  "<article><h3>Adapters</h3>",
11900
- adapters.length === 0 ? "<p>No adapter deliveries yet.</p>" : `<ul>${adapters.map(([adapterId, counts]) => `<li>${escapeHtml15(adapterId)}: ${String(counts.delivered)} delivered / ${String(counts.failed)} failed / ${String(counts.skipped)} skipped</li>`).join("")}</ul>`,
12014
+ adapters.length === 0 ? "<p>No adapter deliveries yet.</p>" : `<ul>${adapters.map(([adapterId, counts]) => `<li>${escapeHtml16(adapterId)}: ${String(counts.delivered)} delivered / ${String(counts.failed)} failed / ${String(counts.skipped)} skipped</li>`).join("")}</ul>`,
11901
12015
  "</article>",
11902
12016
  "</section>"
11903
12017
  ].join("");
@@ -11911,22 +12025,22 @@ var renderVoiceHandoffHealthHTML = (summary) => [
11911
12025
  summary.events.length === 0 ? '<p class="voice-handoff-health-empty">No handoffs found.</p>' : [
11912
12026
  '<div class="voice-handoff-health-events">',
11913
12027
  ...summary.events.map((event) => [
11914
- `<article class="${escapeHtml15(event.status)}">`,
12028
+ `<article class="${escapeHtml16(event.status)}">`,
11915
12029
  '<div class="voice-handoff-health-event-header">',
11916
- `<strong>${escapeHtml15(event.action ?? "handoff")}</strong>`,
11917
- `<span>${escapeHtml15(event.status)}</span>`,
12030
+ `<strong>${escapeHtml16(event.action ?? "handoff")}</strong>`,
12031
+ `<span>${escapeHtml16(event.status)}</span>`,
11918
12032
  "</div>",
11919
- `<p><small>${escapeHtml15(event.sessionId)}</small></p>`,
11920
- event.target ? `<p>Target: ${escapeHtml15(event.target)}</p>` : "",
11921
- event.reason ? `<p>Reason: ${escapeHtml15(event.reason)}</p>` : "",
12033
+ `<p><small>${escapeHtml16(event.sessionId)}</small></p>`,
12034
+ event.target ? `<p>Target: ${escapeHtml16(event.target)}</p>` : "",
12035
+ event.reason ? `<p>Reason: ${escapeHtml16(event.reason)}</p>` : "",
11922
12036
  event.deliveries.length ? `<ul>${event.deliveries.map((delivery) => [
11923
12037
  "<li>",
11924
- `${escapeHtml15(delivery.adapterId)}: ${escapeHtml15(delivery.status)}`,
11925
- delivery.deliveredTo ? ` to ${escapeHtml15(delivery.deliveredTo)}` : "",
11926
- delivery.error ? ` (${escapeHtml15(delivery.error)})` : "",
12038
+ `${escapeHtml16(delivery.adapterId)}: ${escapeHtml16(delivery.status)}`,
12039
+ delivery.deliveredTo ? ` to ${escapeHtml16(delivery.deliveredTo)}` : "",
12040
+ delivery.error ? ` (${escapeHtml16(delivery.error)})` : "",
11927
12041
  "</li>"
11928
12042
  ].join("")).join("")}</ul>` : "",
11929
- event.replayHref ? `<p><a href="${escapeHtml15(event.replayHref)}">Open replay</a></p>` : "",
12043
+ event.replayHref ? `<p><a href="${escapeHtml16(event.replayHref)}">Open replay</a></p>` : "",
11930
12044
  "</article>"
11931
12045
  ].join("")),
11932
12046
  "</div>"
@@ -11958,7 +12072,7 @@ var createVoiceHandoffHealthHTMLHandler = (options = {}) => async ({ query }) =>
11958
12072
  var createVoiceHandoffHealthRoutes = (options = {}) => {
11959
12073
  const path = options.path ?? "/api/voice-handoffs";
11960
12074
  const htmlPath = options.htmlPath === undefined ? `${path}/htmx` : options.htmlPath;
11961
- const routes = new Elysia12({
12075
+ const routes = new Elysia13({
11962
12076
  name: options.name ?? "absolutejs-voice-handoff-health"
11963
12077
  }).get(path, createVoiceHandoffHealthJSONHandler(options));
11964
12078
  if (htmlPath) {
@@ -12079,17 +12193,17 @@ var evaluateVoiceQuality = async (input) => {
12079
12193
  thresholds
12080
12194
  };
12081
12195
  };
12082
- var escapeHtml16 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
12196
+ var escapeHtml17 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
12083
12197
  var formatMetricValue = (metric) => metric.unit === "rate" ? `${(metric.actual * 100).toFixed(2)}%` : metric.unit === "ms" ? `${Math.round(metric.actual)}ms` : String(metric.actual);
12084
12198
  var formatThreshold = (metric) => metric.unit === "rate" ? `${(metric.threshold * 100).toFixed(2)}%` : metric.unit === "ms" ? `${Math.round(metric.threshold)}ms` : String(metric.threshold);
12085
12199
  var renderVoiceQualityHTML = (report, options = {}) => {
12086
- const rows = Object.entries(report.metrics).map(([key, metric]) => `<tr class="${metric.pass ? "pass" : "fail"}"><td>${escapeHtml16(metric.label)}</td><td>${escapeHtml16(formatMetricValue(metric))}</td><td>${escapeHtml16(formatThreshold(metric))}</td><td>${metric.pass ? "pass" : "fail"}</td><td><code>${escapeHtml16(key)}</code></td></tr>`).join("");
12087
- const links = options.links?.length ? `<nav>${options.links.map((link) => `<a href="${escapeHtml16(link.href)}">${escapeHtml16(link.label)}</a>`).join("")}</nav>` : "";
12200
+ const rows = Object.entries(report.metrics).map(([key, metric]) => `<tr class="${metric.pass ? "pass" : "fail"}"><td>${escapeHtml17(metric.label)}</td><td>${escapeHtml17(formatMetricValue(metric))}</td><td>${escapeHtml17(formatThreshold(metric))}</td><td>${metric.pass ? "pass" : "fail"}</td><td><code>${escapeHtml17(key)}</code></td></tr>`).join("");
12201
+ const links = options.links?.length ? `<nav>${options.links.map((link) => `<a href="${escapeHtml17(link.href)}">${escapeHtml17(link.label)}</a>`).join("")}</nav>` : "";
12088
12202
  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>`;
12089
12203
  };
12090
12204
  var createVoiceQualityRoutes = (options) => {
12091
12205
  const path = options.path ?? "/quality";
12092
- const routes = new Elysia13({
12206
+ const routes = new Elysia14({
12093
12207
  name: options.name ?? "absolutejs-voice-quality"
12094
12208
  });
12095
12209
  const getReport = () => evaluateVoiceQuality({
@@ -12118,7 +12232,7 @@ var createVoiceQualityRoutes = (options) => {
12118
12232
  };
12119
12233
 
12120
12234
  // src/evalRoutes.ts
12121
- var escapeHtml17 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
12235
+ var escapeHtml18 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
12122
12236
  var rate2 = (count, total) => count / Math.max(1, total);
12123
12237
  var normalizeSearchText = (value) => value.trim().toLowerCase();
12124
12238
  var getString8 = (value) => typeof value === "string" ? value : undefined;
@@ -12427,44 +12541,44 @@ var formatTime = (value) => value === undefined ? "unknown" : new Date(value).to
12427
12541
  var formatPercent = (value) => `${(value * 100).toFixed(2)}%`;
12428
12542
  var renderVoiceEvalHTML = (report, options = {}) => {
12429
12543
  const title = options.title ?? "AbsoluteJS Voice Evals";
12430
- const links = options.links?.length ? `<nav>${options.links.map((link) => `<a href="${escapeHtml17(link.href)}">${escapeHtml17(link.label)}</a>`).join("")}</nav>` : "";
12431
- const trend = report.trend.length ? report.trend.map((bucket) => `<tr><td>${escapeHtml17(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>';
12544
+ const links = options.links?.length ? `<nav>${options.links.map((link) => `<a href="${escapeHtml18(link.href)}">${escapeHtml18(link.label)}</a>`).join("")}</nav>` : "";
12545
+ const trend = report.trend.length ? report.trend.map((bucket) => `<tr><td>${escapeHtml18(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>';
12432
12546
  const sessions = report.sessions.length ? report.sessions.map((session) => {
12433
12547
  const failedMetrics = Object.entries(session.quality.metrics).filter(([, metric]) => !metric.pass).map(([, metric]) => metric.label).join(", ");
12434
- return `<tr class="${session.status}"><td>${escapeHtml17(session.sessionId)}</td><td>${escapeHtml17(session.status)}</td><td>${session.eventCount}</td><td>${session.summary.turnCount}</td><td>${session.summary.errorCount}</td><td>${escapeHtml17(formatTime(session.endedAt))}</td><td>${escapeHtml17(failedMetrics || "none")}</td></tr>`;
12548
+ return `<tr class="${session.status}"><td>${escapeHtml18(session.sessionId)}</td><td>${escapeHtml18(session.status)}</td><td>${session.eventCount}</td><td>${session.summary.turnCount}</td><td>${session.summary.errorCount}</td><td>${escapeHtml18(formatTime(session.endedAt))}</td><td>${escapeHtml18(failedMetrics || "none")}</td></tr>`;
12435
12549
  }).join("") : '<tr><td colspan="7">No sessions found.</td></tr>';
12436
- 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{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}.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{background:white;border:1px solid #e7e5e4;border-radius:1rem;padding:1rem}.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>${escapeHtml17(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><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>`;
12550
+ 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{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}.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{background:white;border:1px solid #e7e5e4;border-radius:1rem;padding:1rem}.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>${escapeHtml18(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><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>`;
12437
12551
  };
12438
12552
  var renderVoiceEvalBaselineHTML = (comparison, options = {}) => {
12439
12553
  const title = options.title ?? "AbsoluteJS Voice Eval Baseline";
12440
- const links = options.links?.length ? `<nav>${options.links.map((link) => `<a href="${escapeHtml17(link.href)}">${escapeHtml17(link.label)}</a>`).join("")}</nav>` : "";
12441
- const reasons = comparison.reasons.length ? comparison.reasons.map((reason) => `<li>${escapeHtml17(reason)}</li>`).join("") : "<li>No baseline regressions detected.</li>";
12442
- const newFailures = comparison.newFailedSessionIds.length ? comparison.newFailedSessionIds.map((id) => `<li>${escapeHtml17(id)}</li>`).join("") : "<li>none</li>";
12443
- const recovered = comparison.recoveredSessionIds.length ? comparison.recoveredSessionIds.map((id) => `<li>${escapeHtml17(id)}</li>`).join("") : "<li>none</li>";
12444
- 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{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>${escapeHtml17(title)}</h1><p class="status ${comparison.status}">${comparison.status}</p><div class="grid"><article class="card"><span>Baseline pass rate</span><strong>${escapeHtml17(formatPercent(comparison.baseline.passRate))}</strong></article><article class="card"><span>Current pass rate</span><strong>${escapeHtml17(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>${escapeHtml17(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>`;
12554
+ const links = options.links?.length ? `<nav>${options.links.map((link) => `<a href="${escapeHtml18(link.href)}">${escapeHtml18(link.label)}</a>`).join("")}</nav>` : "";
12555
+ const reasons = comparison.reasons.length ? comparison.reasons.map((reason) => `<li>${escapeHtml18(reason)}</li>`).join("") : "<li>No baseline regressions detected.</li>";
12556
+ const newFailures = comparison.newFailedSessionIds.length ? comparison.newFailedSessionIds.map((id) => `<li>${escapeHtml18(id)}</li>`).join("") : "<li>none</li>";
12557
+ const recovered = comparison.recoveredSessionIds.length ? comparison.recoveredSessionIds.map((id) => `<li>${escapeHtml18(id)}</li>`).join("") : "<li>none</li>";
12558
+ 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{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>${escapeHtml18(title)}</h1><p class="status ${comparison.status}">${comparison.status}</p><div class="grid"><article class="card"><span>Baseline pass rate</span><strong>${escapeHtml18(formatPercent(comparison.baseline.passRate))}</strong></article><article class="card"><span>Current pass rate</span><strong>${escapeHtml18(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>${escapeHtml18(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>`;
12445
12559
  };
12446
12560
  var renderVoiceScenarioEvalHTML = (report, options = {}) => {
12447
12561
  const title = options.title ?? "AbsoluteJS Voice Scenario Evals";
12448
- const links = options.links?.length ? `<nav>${options.links.map((link) => `<a href="${escapeHtml17(link.href)}">${escapeHtml17(link.label)}</a>`).join("")}</nav>` : "";
12562
+ const links = options.links?.length ? `<nav>${options.links.map((link) => `<a href="${escapeHtml18(link.href)}">${escapeHtml18(link.label)}</a>`).join("")}</nav>` : "";
12449
12563
  const scenarios = report.scenarios.length ? report.scenarios.map((scenario) => {
12450
- const scenarioIssues = scenario.issues.length ? `<ul>${scenario.issues.map((issue) => `<li>${escapeHtml17(issue)}</li>`).join("")}</ul>` : "";
12451
- const sessions = scenario.sessions.length ? scenario.sessions.map((session) => `<tr class="${session.status}"><td>${escapeHtml17(session.sessionId)}</td><td>${escapeHtml17(session.status)}</td><td>${session.eventCount}</td><td>${escapeHtml17(session.issues.join(", ") || "none")}</td></tr>`).join("") : '<tr><td colspan="4">No matching sessions.</td></tr>';
12452
- return `<section class="scenario ${scenario.status}"><h2>${escapeHtml17(scenario.label)}</h2>${scenario.description ? `<p>${escapeHtml17(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>`;
12564
+ const scenarioIssues = scenario.issues.length ? `<ul>${scenario.issues.map((issue) => `<li>${escapeHtml18(issue)}</li>`).join("")}</ul>` : "";
12565
+ const sessions = scenario.sessions.length ? scenario.sessions.map((session) => `<tr class="${session.status}"><td>${escapeHtml18(session.sessionId)}</td><td>${escapeHtml18(session.status)}</td><td>${session.eventCount}</td><td>${escapeHtml18(session.issues.join(", ") || "none")}</td></tr>`).join("") : '<tr><td colspan="4">No matching sessions.</td></tr>';
12566
+ return `<section class="scenario ${scenario.status}"><h2>${escapeHtml18(scenario.label)}</h2>${scenario.description ? `<p>${escapeHtml18(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>`;
12453
12567
  }).join("") : "<section><p>No scenarios configured.</p></section>";
12454
- 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{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}.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}.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>${escapeHtml17(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>${scenarios}</main></body></html>`;
12568
+ 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{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}.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}.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>${escapeHtml18(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>${scenarios}</main></body></html>`;
12455
12569
  };
12456
12570
  var renderVoiceScenarioFixtureEvalHTML = (report, options = {}) => {
12457
12571
  const title = options.title ?? "AbsoluteJS Voice Fixture Evals";
12458
- const links = options.links?.length ? `<nav>${options.links.map((link) => `<a href="${escapeHtml17(link.href)}">${escapeHtml17(link.label)}</a>`).join("")}</nav>` : "";
12572
+ const links = options.links?.length ? `<nav>${options.links.map((link) => `<a href="${escapeHtml18(link.href)}">${escapeHtml18(link.label)}</a>`).join("")}</nav>` : "";
12459
12573
  const fixtures = report.fixtures.length ? report.fixtures.map((fixture) => {
12460
- const scenarios = fixture.report.scenarios.map((scenario) => `<tr class="${scenario.status}"><td>${escapeHtml17(scenario.label)}</td><td>${escapeHtml17(scenario.status)}</td><td>${scenario.matchedSessions}</td><td>${escapeHtml17([...scenario.issues, ...scenario.sessions.flatMap((session) => session.issues)].join(", ") || "none")}</td></tr>`).join("");
12461
- return `<section class="${fixture.status}"><h2>${escapeHtml17(fixture.label)}</h2>${fixture.description ? `<p>${escapeHtml17(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>`;
12574
+ const scenarios = fixture.report.scenarios.map((scenario) => `<tr class="${scenario.status}"><td>${escapeHtml18(scenario.label)}</td><td>${escapeHtml18(scenario.status)}</td><td>${scenario.matchedSessions}</td><td>${escapeHtml18([...scenario.issues, ...scenario.sessions.flatMap((session) => session.issues)].join(", ") || "none")}</td></tr>`).join("");
12575
+ return `<section class="${fixture.status}"><h2>${escapeHtml18(fixture.label)}</h2>${fixture.description ? `<p>${escapeHtml18(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>`;
12462
12576
  }).join("") : "<section><p>No scenario fixtures configured.</p></section>";
12463
- 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{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}.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}.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>${escapeHtml17(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>${fixtures}</main></body></html>`;
12577
+ 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{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}.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}.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>${escapeHtml18(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>${fixtures}</main></body></html>`;
12464
12578
  };
12465
12579
  var createVoiceEvalRoutes = (options) => {
12466
12580
  const path = options.path ?? "/evals";
12467
- const routes = new Elysia14({
12581
+ const routes = new Elysia15({
12468
12582
  name: options.name ?? "absolutejs-voice-evals"
12469
12583
  });
12470
12584
  const getReport = () => runVoiceSessionEvals({
@@ -12598,11 +12712,11 @@ var createVoiceEvalRoutes = (options) => {
12598
12712
  return routes;
12599
12713
  };
12600
12714
  // src/simulationSuite.ts
12601
- import { Elysia as Elysia17 } from "elysia";
12715
+ import { Elysia as Elysia18 } from "elysia";
12602
12716
 
12603
12717
  // src/outcomeContract.ts
12604
- import { Elysia as Elysia15 } from "elysia";
12605
- var escapeHtml18 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
12718
+ import { Elysia as Elysia16 } from "elysia";
12719
+ var escapeHtml19 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
12606
12720
  var getPayloadString = (event, key) => typeof event.payload[key] === "string" ? event.payload[key] : undefined;
12607
12721
  var toList = async (input) => Array.isArray(input) ? input : await input?.list() ?? [];
12608
12722
  var hydrateSessions = async (input) => {
@@ -12710,9 +12824,9 @@ var renderVoiceOutcomeContractHTML = (report, options = {}) => {
12710
12824
  const contracts = report.contracts.map((contract) => `<section class="contract ${contract.pass ? "pass" : "fail"}">
12711
12825
  <div class="contract-header">
12712
12826
  <div>
12713
- <p class="eyebrow">${escapeHtml18(contract.contractId)}</p>
12714
- <h2>${escapeHtml18(contract.label ?? contract.contractId)}</h2>
12715
- ${contract.description ? `<p>${escapeHtml18(contract.description)}</p>` : ""}
12827
+ <p class="eyebrow">${escapeHtml19(contract.contractId)}</p>
12828
+ <h2>${escapeHtml19(contract.label ?? contract.contractId)}</h2>
12829
+ ${contract.description ? `<p>${escapeHtml19(contract.description)}</p>` : ""}
12716
12830
  </div>
12717
12831
  <strong>${contract.pass ? "pass" : "fail"}</strong>
12718
12832
  </div>
@@ -12723,9 +12837,9 @@ var renderVoiceOutcomeContractHTML = (report, options = {}) => {
12723
12837
  <span>handoffs ${String(contract.matched.handoffs)}</span>
12724
12838
  <span>events ${String(contract.matched.integrationEvents)}</span>
12725
12839
  </div>
12726
- ${contract.issues.length ? `<ul>${contract.issues.map((issue) => `<li>${escapeHtml18(issue.message)}</li>`).join("")}</ul>` : ""}
12840
+ ${contract.issues.length ? `<ul>${contract.issues.map((issue) => `<li>${escapeHtml19(issue.message)}</li>`).join("")}</ul>` : ""}
12727
12841
  </section>`).join("");
12728
- 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:#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>${escapeHtml18(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>`;
12842
+ return `<!doctype html><html lang="en"><head><meta charset="utf-8" /><meta name="viewport" content="width=device-width, initial-scale=1" /><title>${escapeHtml19(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>${escapeHtml19(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>`;
12729
12843
  };
12730
12844
  var createVoiceOutcomeContractJSONHandler = (options) => async () => runVoiceOutcomeContractSuite(options);
12731
12845
  var createVoiceOutcomeContractHTMLHandler = (options) => async () => {
@@ -12741,7 +12855,7 @@ var createVoiceOutcomeContractHTMLHandler = (options) => async () => {
12741
12855
  var createVoiceOutcomeContractRoutes = (options) => {
12742
12856
  const path = options.path ?? "/api/outcome-contracts";
12743
12857
  const htmlPath = options.htmlPath === undefined ? `${path}/htmx` : options.htmlPath;
12744
- const routes = new Elysia15({
12858
+ const routes = new Elysia16({
12745
12859
  name: options.name ?? "absolutejs-voice-outcome-contracts"
12746
12860
  }).get(path, createVoiceOutcomeContractJSONHandler(options));
12747
12861
  if (htmlPath) {
@@ -12751,7 +12865,7 @@ var createVoiceOutcomeContractRoutes = (options) => {
12751
12865
  };
12752
12866
 
12753
12867
  // src/toolContract.ts
12754
- import { Elysia as Elysia16 } from "elysia";
12868
+ import { Elysia as Elysia17 } from "elysia";
12755
12869
 
12756
12870
  // src/toolRuntime.ts
12757
12871
  var toErrorMessage4 = (error) => error instanceof Error ? error.message : String(error);
@@ -12960,7 +13074,7 @@ var createDefaultTurn = (caseId) => ({
12960
13074
  });
12961
13075
  var defaultApi = {};
12962
13076
  var sameJSON = (left, right) => JSON.stringify(left) === JSON.stringify(right);
12963
- var escapeHtml19 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
13077
+ var escapeHtml20 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
12964
13078
  var evaluateExpectation = (input) => {
12965
13079
  const issues = [];
12966
13080
  const expect = input.expect;
@@ -13126,19 +13240,19 @@ var renderVoiceToolContractHTML = (report, options = {}) => {
13126
13240
  const title = options.title ?? "Voice Tool Contracts";
13127
13241
  const contracts = report.contracts.map((contract) => {
13128
13242
  const cases = contract.cases.map((testCase) => `<tr>
13129
- <td>${escapeHtml19(testCase.label ?? testCase.caseId)}</td>
13243
+ <td>${escapeHtml20(testCase.label ?? testCase.caseId)}</td>
13130
13244
  <td class="${testCase.pass ? "pass" : "fail"}">${testCase.pass ? "pass" : "fail"}</td>
13131
- <td>${escapeHtml19(testCase.status)}</td>
13245
+ <td>${escapeHtml20(testCase.status)}</td>
13132
13246
  <td>${String(testCase.attempts)}</td>
13133
13247
  <td>${String(testCase.elapsedMs)}ms</td>
13134
13248
  <td>${testCase.timedOut ? "yes" : "no"}</td>
13135
- <td>${escapeHtml19(testCase.issues.map((issue) => issue.message).join(" ") || testCase.error || "")}</td>
13249
+ <td>${escapeHtml20(testCase.issues.map((issue) => issue.message).join(" ") || testCase.error || "")}</td>
13136
13250
  </tr>`).join("");
13137
13251
  return `<section class="contract ${contract.pass ? "pass" : "fail"}">
13138
13252
  <div class="contract-header">
13139
13253
  <div>
13140
- <p class="eyebrow">${escapeHtml19(contract.toolName)}</p>
13141
- <h2>${escapeHtml19(contract.label ?? contract.contractId)}</h2>
13254
+ <p class="eyebrow">${escapeHtml20(contract.toolName)}</p>
13255
+ <h2>${escapeHtml20(contract.label ?? contract.contractId)}</h2>
13142
13256
  </div>
13143
13257
  <strong class="${contract.pass ? "pass" : "fail"}">${contract.pass ? "Passing" : "Failing"}</strong>
13144
13258
  </div>
@@ -13148,7 +13262,7 @@ var renderVoiceToolContractHTML = (report, options = {}) => {
13148
13262
  </table>
13149
13263
  </section>`;
13150
13264
  }).join("");
13151
- return `<!doctype html><html lang="en"><head><meta charset="utf-8" /><meta name="viewport" content="width=device-width, initial-scale=1" /><title>${escapeHtml19(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(245,158,11,.12))}.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)}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>${escapeHtml19(title)}</h1><div class="summary"><span class="pill ${report.status === "pass" ? "pass" : "fail"}">${escapeHtml19(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 tool contracts configured.</p></section>'}</main></body></html>`;
13265
+ 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{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(245,158,11,.12))}.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)}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>${escapeHtml20(title)}</h1><div class="summary"><span class="pill ${report.status === "pass" ? "pass" : "fail"}">${escapeHtml20(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 tool contracts configured.</p></section>'}</main></body></html>`;
13152
13266
  };
13153
13267
  var createVoiceToolContractJSONHandler = (options) => () => runVoiceToolContractSuite(options);
13154
13268
  var createVoiceToolContractHTMLHandler = (options) => async () => {
@@ -13165,7 +13279,7 @@ var createVoiceToolContractHTMLHandler = (options) => async () => {
13165
13279
  var createVoiceToolContractRoutes = (options) => {
13166
13280
  const path = options.path ?? "/api/tool-contracts";
13167
13281
  const htmlPath = options.htmlPath === undefined ? `${path}/htmx` : options.htmlPath;
13168
- const routes = new Elysia16({
13282
+ const routes = new Elysia17({
13169
13283
  name: options.name ?? "absolutejs-voice-tool-contracts"
13170
13284
  }).get(path, createVoiceToolContractJSONHandler(options));
13171
13285
  if (htmlPath) {
@@ -13175,7 +13289,7 @@ var createVoiceToolContractRoutes = (options) => {
13175
13289
  };
13176
13290
 
13177
13291
  // src/simulationSuite.ts
13178
- var escapeHtml20 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
13292
+ var escapeHtml21 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
13179
13293
  var summarizeSection = (report) => ({
13180
13294
  failed: report.failed,
13181
13295
  passed: report.passed,
@@ -13311,20 +13425,20 @@ var renderSection = (label, summary) => {
13311
13425
  if (!summary) {
13312
13426
  return "";
13313
13427
  }
13314
- return `<article class="${escapeHtml20(summary.status)}"><span>${escapeHtml20(label)}</span><strong>${escapeHtml20(summary.status)}</strong><p>${summary.passed}/${summary.total} passed, ${summary.failed} failed.</p></article>`;
13428
+ return `<article class="${escapeHtml21(summary.status)}"><span>${escapeHtml21(label)}</span><strong>${escapeHtml21(summary.status)}</strong><p>${summary.passed}/${summary.total} passed, ${summary.failed} failed.</p></article>`;
13315
13429
  };
13316
13430
  var renderAction = (action) => {
13317
- const content = `<strong>${escapeHtml20(action.label)}</strong><p>${escapeHtml20(action.description)}</p><span>${escapeHtml20(action.section)} / ${escapeHtml20(action.severity)}</span>`;
13318
- return action.href ? `<a class="action" href="${escapeHtml20(action.href)}">${content}</a>` : `<article class="action">${content}</article>`;
13431
+ const content = `<strong>${escapeHtml21(action.label)}</strong><p>${escapeHtml21(action.description)}</p><span>${escapeHtml21(action.section)} / ${escapeHtml21(action.severity)}</span>`;
13432
+ return action.href ? `<a class="action" href="${escapeHtml21(action.href)}">${content}</a>` : `<article class="action">${content}</article>`;
13319
13433
  };
13320
13434
  var renderVoiceSimulationSuiteHTML = (report, options = {}) => {
13321
13435
  const title = options.title ?? "Voice Simulation Suite";
13322
- 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{background:#10151c;color:#f8f3e7;font-family:ui-sans-serif,system-ui,sans-serif;margin:0}main{margin:auto;max-width:1080px;padding:32px}.hero{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}.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{color:#d8dee6;margin:.3rem 0 .6rem}pre{background:#151d27;border:1px solid #283544;border-radius:18px;overflow:auto;padding:16px}</style></head><body><main><section class="hero"><p class="eyebrow">Pre-production proof</p><h1>${escapeHtml20(title)}</h1><p>One report for session quality, scenario evals, fixture simulations, tool contracts, and outcome contracts.</p><p class="badge ${escapeHtml20(report.status)}">Status: ${escapeHtml20(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><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>${escapeHtml20(JSON.stringify({ summary: report.summary, actions: report.actions }, null, 2))}</pre></main></body></html>`;
13436
+ 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:#10151c;color:#f8f3e7;font-family:ui-sans-serif,system-ui,sans-serif;margin:0}main{margin:auto;max-width:1080px;padding:32px}.hero{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}.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{color:#d8dee6;margin:.3rem 0 .6rem}pre{background:#151d27;border:1px solid #283544;border-radius:18px;overflow:auto;padding:16px}</style></head><body><main><section class="hero"><p class="eyebrow">Pre-production proof</p><h1>${escapeHtml21(title)}</h1><p>One report for session quality, scenario evals, fixture simulations, tool contracts, and outcome contracts.</p><p class="badge ${escapeHtml21(report.status)}">Status: ${escapeHtml21(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><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>${escapeHtml21(JSON.stringify({ summary: report.summary, actions: report.actions }, null, 2))}</pre></main></body></html>`;
13323
13437
  };
13324
13438
  var createVoiceSimulationSuiteRoutes = (options) => {
13325
13439
  const path = options.path ?? "/api/voice/simulations";
13326
13440
  const htmlPath = options.htmlPath === undefined ? "/voice/simulations" : options.htmlPath;
13327
- const app = new Elysia17({
13441
+ const app = new Elysia18({
13328
13442
  name: options.name ?? "absolutejs-voice-simulation-suite"
13329
13443
  }).get(path, () => runVoiceSimulationSuite(options));
13330
13444
  if (htmlPath) {
@@ -13636,9 +13750,9 @@ var createVoiceWorkflowContractHandler = (input) => {
13636
13750
  };
13637
13751
  };
13638
13752
  // src/sessionReplay.ts
13639
- import { Elysia as Elysia18 } from "elysia";
13753
+ import { Elysia as Elysia19 } from "elysia";
13640
13754
  var getString9 = (value) => typeof value === "string" ? value : undefined;
13641
- var escapeHtml21 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
13755
+ var escapeHtml22 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
13642
13756
  var increment4 = (record, key) => {
13643
13757
  record[key] = (record[key] ?? 0) + 1;
13644
13758
  };
@@ -13818,10 +13932,10 @@ var summarizeVoiceSessions = async (options = {}) => {
13818
13932
  var renderVoiceSessionsHTML = (sessions) => sessions.length === 0 ? '<p class="voice-sessions-empty">No voice sessions found.</p>' : [
13819
13933
  '<div class="voice-sessions-list">',
13820
13934
  ...sessions.map((session) => [
13821
- `<article class="voice-session-card ${escapeHtml21(session.status)}">`,
13935
+ `<article class="voice-session-card ${escapeHtml22(session.status)}">`,
13822
13936
  '<div class="voice-session-card-header">',
13823
- `<strong>${escapeHtml21(session.sessionId)}</strong>`,
13824
- `<span>${escapeHtml21(session.status)}</span>`,
13937
+ `<strong>${escapeHtml22(session.sessionId)}</strong>`,
13938
+ `<span>${escapeHtml22(session.status)}</span>`,
13825
13939
  "</div>",
13826
13940
  "<dl>",
13827
13941
  `<div><dt>Events</dt><dd>${String(session.eventCount)}</dd></div>`,
@@ -13829,9 +13943,9 @@ var renderVoiceSessionsHTML = (sessions) => sessions.length === 0 ? '<p class="v
13829
13943
  `<div><dt>Transcripts</dt><dd>${String(session.transcriptCount)}</dd></div>`,
13830
13944
  `<div><dt>Errors</dt><dd>${String(session.errorCount)}</dd></div>`,
13831
13945
  "</dl>",
13832
- session.latestOutcome ? `<p>Outcome: ${escapeHtml21(session.latestOutcome)}</p>` : "",
13833
- session.providers.length ? `<p>Providers: ${session.providers.map(escapeHtml21).join(", ")}</p>` : "",
13834
- session.replayHref ? `<p><a href="${escapeHtml21(session.replayHref)}">Open replay</a></p>` : "",
13946
+ session.latestOutcome ? `<p>Outcome: ${escapeHtml22(session.latestOutcome)}</p>` : "",
13947
+ session.providers.length ? `<p>Providers: ${session.providers.map(escapeHtml22).join(", ")}</p>` : "",
13948
+ session.replayHref ? `<p><a href="${escapeHtml22(session.replayHref)}">Open replay</a></p>` : "",
13835
13949
  "</article>"
13836
13950
  ].join("")),
13837
13951
  "</div>"
@@ -13862,7 +13976,7 @@ var createVoiceSessionsHTMLHandler = (options = {}) => async ({ query }) => {
13862
13976
  var createVoiceSessionListRoutes = (options = {}) => {
13863
13977
  const path = options.path ?? "/api/voice-sessions";
13864
13978
  const htmlPath = options.htmlPath === undefined ? `${path}/htmx` : options.htmlPath;
13865
- const routes = new Elysia18({
13979
+ const routes = new Elysia19({
13866
13980
  name: options.name ?? "absolutejs-voice-session-list"
13867
13981
  }).get(path, createVoiceSessionsJSONHandler(options));
13868
13982
  if (htmlPath) {
@@ -13890,7 +14004,7 @@ var createVoiceSessionReplayHTMLHandler = (options) => async ({ params }) => {
13890
14004
  var createVoiceSessionReplayRoutes = (options) => {
13891
14005
  const path = options.path ?? "/api/voice-sessions/:sessionId/replay";
13892
14006
  const htmlPath = options.htmlPath === undefined ? `${path}/htmx` : options.htmlPath;
13893
- const routes = new Elysia18({
14007
+ const routes = new Elysia19({
13894
14008
  name: options.name ?? "absolutejs-voice-session-replay"
13895
14009
  }).get(path, createVoiceSessionReplayJSONHandler(options));
13896
14010
  if (htmlPath) {
@@ -14057,10 +14171,10 @@ var assertVoiceAgentSquadContract = async (options) => {
14057
14171
  return report;
14058
14172
  };
14059
14173
  // src/turnLatency.ts
14060
- import { Elysia as Elysia19 } from "elysia";
14174
+ import { Elysia as Elysia20 } from "elysia";
14061
14175
  var DEFAULT_WARN_AFTER_MS = 1800;
14062
14176
  var DEFAULT_FAIL_AFTER_MS = 3200;
14063
- var escapeHtml22 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
14177
+ var escapeHtml23 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
14064
14178
  var firstNumber = (values) => values.filter((value) => typeof value === "number").sort((left, right) => left - right)[0];
14065
14179
  var getString10 = (value) => typeof value === "string" && value.trim() ? value : undefined;
14066
14180
  var createTraceStageIndex = (events) => {
@@ -14174,11 +14288,11 @@ var summarizeVoiceTurnLatency = async (options) => {
14174
14288
  var formatMs = (value) => typeof value === "number" ? `${Math.round(value)}ms` : "n/a";
14175
14289
  var renderVoiceTurnLatencyHTML = (report, options = {}) => {
14176
14290
  const title = options.title ?? "Voice Turn Latency";
14177
- const turns = report.turns.map((turn) => `<article class="turn ${escapeHtml22(turn.status)}">
14178
- <header><div><p class="eyebrow">${escapeHtml22(turn.sessionId)} \xB7 ${escapeHtml22(turn.turnId)}</p><h2>${escapeHtml22(turn.text || "Empty turn")}</h2></div><strong>${escapeHtml22(turn.status)}</strong></header>
14179
- <dl>${turn.stages.map((stage) => `<div><dt>${escapeHtml22(stage.label)}</dt><dd>${escapeHtml22(formatMs(stage.valueMs))}</dd></div>`).join("")}</dl>
14291
+ const turns = report.turns.map((turn) => `<article class="turn ${escapeHtml23(turn.status)}">
14292
+ <header><div><p class="eyebrow">${escapeHtml23(turn.sessionId)} \xB7 ${escapeHtml23(turn.turnId)}</p><h2>${escapeHtml23(turn.text || "Empty turn")}</h2></div><strong>${escapeHtml23(turn.status)}</strong></header>
14293
+ <dl>${turn.stages.map((stage) => `<div><dt>${escapeHtml23(stage.label)}</dt><dd>${escapeHtml23(formatMs(stage.valueMs))}</dd></div>`).join("")}</dl>
14180
14294
  </article>`).join("");
14181
- 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,.turn{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}.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>${escapeHtml22(title)}</h1><div class="summary"><span class="pill ${escapeHtml22(report.status)}">${escapeHtml22(report.status)}</span><span class="pill">${String(report.total)} turns</span><span class="pill">avg ${escapeHtml22(formatMs(report.averageTotalMs))}</span><span class="pill">${String(report.warnings)} warnings</span><span class="pill">${String(report.failed)} failed</span></div></section>${turns || '<section class="turn"><p>No committed turns found.</p></section>'}</main></body></html>`;
14295
+ 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,.turn{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}.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>${escapeHtml23(title)}</h1><div class="summary"><span class="pill ${escapeHtml23(report.status)}">${escapeHtml23(report.status)}</span><span class="pill">${String(report.total)} turns</span><span class="pill">avg ${escapeHtml23(formatMs(report.averageTotalMs))}</span><span class="pill">${String(report.warnings)} warnings</span><span class="pill">${String(report.failed)} failed</span></div></section>${turns || '<section class="turn"><p>No committed turns found.</p></section>'}</main></body></html>`;
14182
14296
  };
14183
14297
  var createVoiceTurnLatencyJSONHandler = (options) => async () => summarizeVoiceTurnLatency(options);
14184
14298
  var createVoiceTurnLatencyHTMLHandler = (options) => async () => {
@@ -14195,7 +14309,7 @@ var createVoiceTurnLatencyHTMLHandler = (options) => async () => {
14195
14309
  var createVoiceTurnLatencyRoutes = (options) => {
14196
14310
  const path = options.path ?? "/api/turn-latency";
14197
14311
  const htmlPath = options.htmlPath === undefined ? `${path}/htmx` : options.htmlPath;
14198
- const routes = new Elysia19({
14312
+ const routes = new Elysia20({
14199
14313
  name: options.name ?? "absolutejs-voice-turn-latency"
14200
14314
  }).get(path, createVoiceTurnLatencyJSONHandler(options));
14201
14315
  if (htmlPath) {
@@ -14204,8 +14318,8 @@ var createVoiceTurnLatencyRoutes = (options) => {
14204
14318
  return routes;
14205
14319
  };
14206
14320
  // src/liveLatency.ts
14207
- import { Elysia as Elysia20 } from "elysia";
14208
- var escapeHtml23 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
14321
+ import { Elysia as Elysia21 } from "elysia";
14322
+ var escapeHtml24 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
14209
14323
  var percentile = (values, percentileValue) => {
14210
14324
  if (values.length === 0) {
14211
14325
  return;
@@ -14253,13 +14367,13 @@ var summarizeVoiceLiveLatency = async (options) => {
14253
14367
  var formatMs2 = (value) => typeof value === "number" ? `${Math.round(value)}ms` : "n/a";
14254
14368
  var renderVoiceLiveLatencyHTML = (report, options = {}) => {
14255
14369
  const title = options.title ?? "Voice Live Latency";
14256
- const rows = report.recent.map((sample) => `<tr><td>${escapeHtml23(sample.sessionId)}</td><td>${escapeHtml23(formatMs2(sample.latencyMs))}</td><td>${escapeHtml23(sample.status ?? "unknown")}</td><td>${escapeHtml23(new Date(sample.at).toLocaleString())}</td></tr>`).join("");
14257
- 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:#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{background:#141922;border:1px solid #26313d;border-radius:18px}.metrics article{padding:16px}.metrics span{color:#a8b0b8}.metrics strong{display:block;font-size:2rem;margin-top:.25rem}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>${escapeHtml23(title)}</h1><p>Recent real browser speech-to-assistant response measurements from persisted <code>client.live_latency</code> traces.</p><p class="status ${escapeHtml23(report.status)}">Status: ${escapeHtml23(report.status)}</p><section class="metrics"><article><span>p50</span><strong>${escapeHtml23(formatMs2(report.p50LatencyMs))}</strong></article><article><span>p95</span><strong>${escapeHtml23(formatMs2(report.p95LatencyMs))}</strong></article><article><span>Average</span><strong>${escapeHtml23(formatMs2(report.averageLatencyMs))}</strong></article><article><span>Samples</span><strong>${String(report.total)}</strong></article></section></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>`;
14370
+ const rows = report.recent.map((sample) => `<tr><td>${escapeHtml24(sample.sessionId)}</td><td>${escapeHtml24(formatMs2(sample.latencyMs))}</td><td>${escapeHtml24(sample.status ?? "unknown")}</td><td>${escapeHtml24(new Date(sample.at).toLocaleString())}</td></tr>`).join("");
14371
+ 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:#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{background:#141922;border:1px solid #26313d;border-radius:18px}.metrics article{padding:16px}.metrics span{color:#a8b0b8}.metrics strong{display:block;font-size:2rem;margin-top:.25rem}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>${escapeHtml24(title)}</h1><p>Recent real browser speech-to-assistant response measurements from persisted <code>client.live_latency</code> traces.</p><p class="status ${escapeHtml24(report.status)}">Status: ${escapeHtml24(report.status)}</p><section class="metrics"><article><span>p50</span><strong>${escapeHtml24(formatMs2(report.p50LatencyMs))}</strong></article><article><span>p95</span><strong>${escapeHtml24(formatMs2(report.p95LatencyMs))}</strong></article><article><span>Average</span><strong>${escapeHtml24(formatMs2(report.averageLatencyMs))}</strong></article><article><span>Samples</span><strong>${String(report.total)}</strong></article></section></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>`;
14258
14372
  };
14259
14373
  var createVoiceLiveLatencyRoutes = (options) => {
14260
14374
  const path = options.path ?? "/api/live-latency";
14261
14375
  const htmlPath = options.htmlPath === undefined ? "/live-latency" : options.htmlPath;
14262
- const routes = new Elysia20({
14376
+ const routes = new Elysia21({
14263
14377
  name: options.name ?? "absolutejs-voice-live-latency"
14264
14378
  }).get(path, () => summarizeVoiceLiveLatency(options));
14265
14379
  if (htmlPath) {
@@ -14276,9 +14390,9 @@ var createVoiceLiveLatencyRoutes = (options) => {
14276
14390
  return routes;
14277
14391
  };
14278
14392
  // src/turnQuality.ts
14279
- import { Elysia as Elysia21 } from "elysia";
14393
+ import { Elysia as Elysia22 } from "elysia";
14280
14394
  var DEFAULT_CONFIDENCE_WARN_THRESHOLD = 0.72;
14281
- var escapeHtml24 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
14395
+ var escapeHtml25 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
14282
14396
  var getTurnLatencyMs = (turn) => {
14283
14397
  const firstTranscriptAt = turn.transcripts.map((transcript) => transcript.endedAtMs ?? transcript.startedAtMs).filter((value) => typeof value === "number").sort((left, right) => left - right)[0];
14284
14398
  if (firstTranscriptAt === undefined) {
@@ -14349,24 +14463,24 @@ var summarizeVoiceTurnQuality = async (options) => {
14349
14463
  };
14350
14464
  var renderVoiceTurnQualityHTML = (report, options = {}) => {
14351
14465
  const title = options.title ?? "Voice Turn Quality";
14352
- const turns = report.turns.map((turn) => `<article class="turn ${escapeHtml24(turn.status)}">
14466
+ const turns = report.turns.map((turn) => `<article class="turn ${escapeHtml25(turn.status)}">
14353
14467
  <div class="turn-header">
14354
14468
  <div>
14355
- <p class="eyebrow">${escapeHtml24(turn.sessionId)} \xB7 ${escapeHtml24(turn.turnId)}</p>
14356
- <h2>${escapeHtml24(turn.text || "Empty turn")}</h2>
14469
+ <p class="eyebrow">${escapeHtml25(turn.sessionId)} \xB7 ${escapeHtml25(turn.turnId)}</p>
14470
+ <h2>${escapeHtml25(turn.text || "Empty turn")}</h2>
14357
14471
  </div>
14358
- <strong>${escapeHtml24(turn.status)}</strong>
14472
+ <strong>${escapeHtml25(turn.status)}</strong>
14359
14473
  </div>
14360
14474
  <dl>
14361
- <div><dt>Source</dt><dd>${escapeHtml24(turn.source ?? "unknown")}</dd></div>
14475
+ <div><dt>Source</dt><dd>${escapeHtml25(turn.source ?? "unknown")}</dd></div>
14362
14476
  <div><dt>Confidence</dt><dd>${turn.averageConfidence === undefined ? "n/a" : `${Math.round(turn.averageConfidence * 100)}%`}</dd></div>
14363
- <div><dt>Fallback</dt><dd>${turn.fallbackUsed ? `yes (${escapeHtml24(turn.fallbackSelectionReason ?? "selected")})` : "no"}</dd></div>
14364
- <div><dt>Correction</dt><dd>${turn.correctionChanged ? `changed${turn.correctionProvider ? ` by ${escapeHtml24(turn.correctionProvider)}` : ""}` : "none"}</dd></div>
14477
+ <div><dt>Fallback</dt><dd>${turn.fallbackUsed ? `yes (${escapeHtml25(turn.fallbackSelectionReason ?? "selected")})` : "no"}</dd></div>
14478
+ <div><dt>Correction</dt><dd>${turn.correctionChanged ? `changed${turn.correctionProvider ? ` by ${escapeHtml25(turn.correctionProvider)}` : ""}` : "none"}</dd></div>
14365
14479
  <div><dt>Transcripts</dt><dd>${String(turn.selectedTranscriptCount)} selected \xB7 ${String(turn.finalTranscriptCount)} final \xB7 ${String(turn.partialTranscriptCount)} partial</dd></div>
14366
14480
  <div><dt>Cost</dt><dd>${turn.costUnits === undefined ? "n/a" : String(turn.costUnits)}</dd></div>
14367
14481
  </dl>
14368
14482
  </article>`).join("");
14369
- 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:#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>${escapeHtml24(title)}</h1><div class="summary"><span class="pill ${escapeHtml24(report.status)}">${escapeHtml24(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>`;
14483
+ 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{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>${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">${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>`;
14370
14484
  };
14371
14485
  var createVoiceTurnQualityJSONHandler = (options) => async () => summarizeVoiceTurnQuality(options);
14372
14486
  var createVoiceTurnQualityHTMLHandler = (options) => async () => {
@@ -14383,7 +14497,7 @@ var createVoiceTurnQualityHTMLHandler = (options) => async () => {
14383
14497
  var createVoiceTurnQualityRoutes = (options) => {
14384
14498
  const path = options.path ?? "/api/turn-quality";
14385
14499
  const htmlPath = options.htmlPath === undefined ? `${path}/htmx` : options.htmlPath;
14386
- const routes = new Elysia21({
14500
+ const routes = new Elysia22({
14387
14501
  name: options.name ?? "absolutejs-voice-turn-quality"
14388
14502
  }).get(path, createVoiceTurnQualityJSONHandler(options));
14389
14503
  if (htmlPath) {
@@ -14392,7 +14506,7 @@ var createVoiceTurnQualityRoutes = (options) => {
14392
14506
  return routes;
14393
14507
  };
14394
14508
  // src/telephonyOutcome.ts
14395
- import { Elysia as Elysia22 } from "elysia";
14509
+ import { Elysia as Elysia23 } from "elysia";
14396
14510
  var DEFAULT_COMPLETED_STATUSES = [
14397
14511
  "answered",
14398
14512
  "completed",
@@ -15042,7 +15156,7 @@ var createVoiceTelephonyWebhookHandler = (options = {}) => async (input) => {
15042
15156
  var createVoiceTelephonyWebhookRoutes = (options = {}) => {
15043
15157
  const path = options.path ?? "/api/voice/telephony/webhook";
15044
15158
  const handler = createVoiceTelephonyWebhookHandler(options);
15045
- return new Elysia22({
15159
+ return new Elysia23({
15046
15160
  name: options.name ?? "absolutejs-voice-telephony-webhooks"
15047
15161
  }).post(path, async ({ query, request }) => {
15048
15162
  try {
@@ -15063,11 +15177,11 @@ var createVoiceTelephonyWebhookRoutes = (options = {}) => {
15063
15177
  });
15064
15178
  };
15065
15179
  // src/phoneAgent.ts
15066
- import { Elysia as Elysia28 } from "elysia";
15180
+ import { Elysia as Elysia29 } from "elysia";
15067
15181
 
15068
15182
  // src/telephony/plivo.ts
15069
15183
  import { Buffer as Buffer5 } from "buffer";
15070
- import { Elysia as Elysia24 } from "elysia";
15184
+ import { Elysia as Elysia25 } from "elysia";
15071
15185
 
15072
15186
  // src/telephony/contract.ts
15073
15187
  var DEFAULT_REQUIREMENTS = [
@@ -15151,7 +15265,7 @@ var evaluateVoiceTelephonyContract = (input) => {
15151
15265
 
15152
15266
  // src/telephony/twilio.ts
15153
15267
  import { Buffer as Buffer4 } from "buffer";
15154
- import { Elysia as Elysia23 } from "elysia";
15268
+ import { Elysia as Elysia24 } from "elysia";
15155
15269
  var TWILIO_MULAW_SAMPLE_RATE = 8000;
15156
15270
  var VOICE_PCM_SAMPLE_RATE = 16000;
15157
15271
  var escapeXml2 = (value) => value.replaceAll("&", "&amp;").replaceAll('"', "&quot;").replaceAll("'", "&apos;").replaceAll("<", "&lt;").replaceAll(">", "&gt;");
@@ -15181,7 +15295,7 @@ var resolveTwilioStreamParameters = async (parameters, input) => {
15181
15295
  return parameters;
15182
15296
  };
15183
15297
  var joinUrlPath2 = (origin, path) => `${origin.replace(/\/$/, "")}${path.startsWith("/") ? path : `/${path}`}`;
15184
- var escapeHtml25 = (value) => value.replaceAll("&", "&amp;").replaceAll('"', "&quot;").replaceAll("'", "&#39;").replaceAll("<", "&lt;").replaceAll(">", "&gt;");
15298
+ var escapeHtml26 = (value) => value.replaceAll("&", "&amp;").replaceAll('"', "&quot;").replaceAll("'", "&#39;").replaceAll("<", "&lt;").replaceAll(">", "&gt;");
15185
15299
  var getWebhookVerificationUrl = (webhook, input) => {
15186
15300
  if (!webhook?.verificationUrl) {
15187
15301
  return;
@@ -15224,23 +15338,23 @@ var buildTwilioVoiceSetupStatus = async (options, input) => {
15224
15338
  };
15225
15339
  var renderTwilioVoiceSetupHTML = (status, title) => `<main style="font-family: ui-sans-serif, system-ui; max-width: 860px; margin: 40px auto; padding: 0 20px;">
15226
15340
  <p style="letter-spacing: .12em; text-transform: uppercase; color: #52606d;">Twilio setup</p>
15227
- <h1>${escapeHtml25(title)}</h1>
15341
+ <h1>${escapeHtml26(title)}</h1>
15228
15342
  <p><strong>Status:</strong> ${status.ready ? "Ready" : "Needs attention"}</p>
15229
15343
  <section>
15230
15344
  <h2>URLs</h2>
15231
15345
  <ul>
15232
- <li><strong>TwiML:</strong> <code>${escapeHtml25(status.urls.twiml)}</code></li>
15233
- <li><strong>Media stream:</strong> <code>${escapeHtml25(status.urls.stream)}</code></li>
15234
- <li><strong>Status webhook:</strong> <code>${escapeHtml25(status.urls.webhook)}</code></li>
15346
+ <li><strong>TwiML:</strong> <code>${escapeHtml26(status.urls.twiml)}</code></li>
15347
+ <li><strong>Media stream:</strong> <code>${escapeHtml26(status.urls.stream)}</code></li>
15348
+ <li><strong>Status webhook:</strong> <code>${escapeHtml26(status.urls.webhook)}</code></li>
15235
15349
  </ul>
15236
15350
  </section>
15237
15351
  <section>
15238
15352
  <h2>Signing</h2>
15239
15353
  <p>Mode: <code>${status.signing.mode}</code></p>
15240
- ${status.signing.verificationUrl ? `<p>Verification URL: <code>${escapeHtml25(status.signing.verificationUrl)}</code></p>` : ""}
15354
+ ${status.signing.verificationUrl ? `<p>Verification URL: <code>${escapeHtml26(status.signing.verificationUrl)}</code></p>` : ""}
15241
15355
  </section>
15242
- ${status.missing.length ? `<section><h2>Missing env</h2><ul>${status.missing.map((name) => `<li><code>${escapeHtml25(name)}</code></li>`).join("")}</ul></section>` : ""}
15243
- ${status.warnings.length ? `<section><h2>Warnings</h2><ul>${status.warnings.map((warning) => `<li>${escapeHtml25(warning)}</li>`).join("")}</ul></section>` : ""}
15356
+ ${status.missing.length ? `<section><h2>Missing env</h2><ul>${status.missing.map((name) => `<li><code>${escapeHtml26(name)}</code></li>`).join("")}</ul></section>` : ""}
15357
+ ${status.warnings.length ? `<section><h2>Warnings</h2><ul>${status.warnings.map((warning) => `<li>${escapeHtml26(warning)}</li>`).join("")}</ul></section>` : ""}
15244
15358
  </main>`;
15245
15359
  var extractTwilioStreamUrl = (twiml) => twiml.match(/<Stream\b[^>]*\surl="([^"]+)"/i)?.[1]?.replaceAll("&amp;", "&");
15246
15360
  var createSmokeCheck = (name, status, message, details) => ({
@@ -15251,20 +15365,20 @@ var createSmokeCheck = (name, status, message, details) => ({
15251
15365
  });
15252
15366
  var renderTwilioVoiceSmokeHTML = (report, title) => `<main style="font-family: ui-sans-serif, system-ui; max-width: 860px; margin: 40px auto; padding: 0 20px;">
15253
15367
  <p style="letter-spacing: .12em; text-transform: uppercase; color: #52606d;">Twilio smoke test</p>
15254
- <h1>${escapeHtml25(title)}</h1>
15368
+ <h1>${escapeHtml26(title)}</h1>
15255
15369
  <p><strong>Status:</strong> ${report.pass ? "Pass" : "Fail"}</p>
15256
15370
  <section>
15257
15371
  <h2>Checks</h2>
15258
15372
  <ul>
15259
- ${report.checks.map((check) => `<li><strong>${escapeHtml25(check.name)}</strong>: ${escapeHtml25(check.status)}${check.message ? ` - ${escapeHtml25(check.message)}` : ""}</li>`).join("")}
15373
+ ${report.checks.map((check) => `<li><strong>${escapeHtml26(check.name)}</strong>: ${escapeHtml26(check.status)}${check.message ? ` - ${escapeHtml26(check.message)}` : ""}</li>`).join("")}
15260
15374
  </ul>
15261
15375
  </section>
15262
15376
  <section>
15263
15377
  <h2>Observed URLs</h2>
15264
15378
  <ul>
15265
- <li><strong>TwiML:</strong> <code>${escapeHtml25(report.setup.urls.twiml)}</code></li>
15266
- <li><strong>Stream:</strong> <code>${escapeHtml25(report.twiml?.streamUrl ?? report.setup.urls.stream)}</code></li>
15267
- <li><strong>Webhook:</strong> <code>${escapeHtml25(report.setup.urls.webhook)}</code></li>
15379
+ <li><strong>TwiML:</strong> <code>${escapeHtml26(report.setup.urls.twiml)}</code></li>
15380
+ <li><strong>Stream:</strong> <code>${escapeHtml26(report.twiml?.streamUrl ?? report.setup.urls.stream)}</code></li>
15381
+ <li><strong>Webhook:</strong> <code>${escapeHtml26(report.setup.urls.webhook)}</code></li>
15268
15382
  </ul>
15269
15383
  </section>
15270
15384
  </main>`;
@@ -15724,7 +15838,7 @@ var createTwilioVoiceRoutes = (options) => {
15724
15838
  const smokePath = options.smoke?.path === false ? false : options.smoke?.path ?? "/api/voice/twilio/smoke";
15725
15839
  const bridges = new WeakMap;
15726
15840
  const webhookPolicy = options.webhook?.policy ?? options.outcomePolicy ?? createVoiceTelephonyOutcomePolicy();
15727
- const app = new Elysia23({
15841
+ const app = new Elysia24({
15728
15842
  name: options.name ?? "absolutejs-voice-twilio"
15729
15843
  }).get(twimlPath, async ({ query, request }) => {
15730
15844
  const streamUrl = await resolveTwilioStreamUrl(options, {
@@ -15861,7 +15975,7 @@ var createTwilioVoiceRoutes = (options) => {
15861
15975
 
15862
15976
  // src/telephony/plivo.ts
15863
15977
  var escapeXml3 = (value) => value.replaceAll("&", "&amp;").replaceAll('"', "&quot;").replaceAll("'", "&apos;").replaceAll("<", "&lt;").replaceAll(">", "&gt;");
15864
- var escapeHtml26 = (value) => value.replaceAll("&", "&amp;").replaceAll('"', "&quot;").replaceAll("'", "&#39;").replaceAll("<", "&lt;").replaceAll(">", "&gt;");
15978
+ var escapeHtml27 = (value) => value.replaceAll("&", "&amp;").replaceAll('"', "&quot;").replaceAll("'", "&#39;").replaceAll("<", "&lt;").replaceAll(">", "&gt;");
15865
15979
  var joinUrlPath3 = (origin, path) => `${origin.replace(/\/$/, "")}${path.startsWith("/") ? path : `/${path}`}`;
15866
15980
  var resolveRequestOrigin2 = (request) => {
15867
15981
  const url = new URL(request.url);
@@ -16112,21 +16226,21 @@ var buildPlivoVoiceSetupStatus = async (options, input) => {
16112
16226
  };
16113
16227
  var renderPlivoSetupHTML = (status, title) => `<main style="font-family: ui-sans-serif, system-ui; max-width: 860px; margin: 40px auto; padding: 0 20px;">
16114
16228
  <p style="letter-spacing: .12em; text-transform: uppercase; color: #52606d;">Plivo setup</p>
16115
- <h1>${escapeHtml26(title)}</h1>
16229
+ <h1>${escapeHtml27(title)}</h1>
16116
16230
  <p><strong>Status:</strong> ${status.ready ? "Ready" : "Needs attention"}</p>
16117
16231
  <ul>
16118
- <li><strong>Answer XML:</strong> <code>${escapeHtml26(status.urls.answer)}</code></li>
16119
- <li><strong>Audio stream:</strong> <code>${escapeHtml26(status.urls.stream)}</code></li>
16120
- <li><strong>Status webhook:</strong> <code>${escapeHtml26(status.urls.webhook)}</code></li>
16232
+ <li><strong>Answer XML:</strong> <code>${escapeHtml27(status.urls.answer)}</code></li>
16233
+ <li><strong>Audio stream:</strong> <code>${escapeHtml27(status.urls.stream)}</code></li>
16234
+ <li><strong>Status webhook:</strong> <code>${escapeHtml27(status.urls.webhook)}</code></li>
16121
16235
  </ul>
16122
- ${status.missing.length ? `<h2>Missing env</h2><ul>${status.missing.map((name) => `<li><code>${escapeHtml26(name)}</code></li>`).join("")}</ul>` : ""}
16123
- ${status.warnings.length ? `<h2>Warnings</h2><ul>${status.warnings.map((warning) => `<li>${escapeHtml26(warning)}</li>`).join("")}</ul>` : ""}
16236
+ ${status.missing.length ? `<h2>Missing env</h2><ul>${status.missing.map((name) => `<li><code>${escapeHtml27(name)}</code></li>`).join("")}</ul>` : ""}
16237
+ ${status.warnings.length ? `<h2>Warnings</h2><ul>${status.warnings.map((warning) => `<li>${escapeHtml27(warning)}</li>`).join("")}</ul>` : ""}
16124
16238
  </main>`;
16125
16239
  var renderPlivoSmokeHTML = (report, title) => `<main style="font-family: ui-sans-serif, system-ui; max-width: 860px; margin: 40px auto; padding: 0 20px;">
16126
16240
  <p style="letter-spacing: .12em; text-transform: uppercase; color: #52606d;">Plivo smoke test</p>
16127
- <h1>${escapeHtml26(title)}</h1>
16241
+ <h1>${escapeHtml27(title)}</h1>
16128
16242
  <p><strong>Status:</strong> ${report.pass ? "Pass" : "Fail"}</p>
16129
- <ul>${report.checks.map((check) => `<li><strong>${escapeHtml26(check.name)}</strong>: ${escapeHtml26(check.status)}${check.message ? ` - ${escapeHtml26(check.message)}` : ""}</li>`).join("")}</ul>
16243
+ <ul>${report.checks.map((check) => `<li><strong>${escapeHtml27(check.name)}</strong>: ${escapeHtml27(check.status)}${check.message ? ` - ${escapeHtml27(check.message)}` : ""}</li>`).join("")}</ul>
16130
16244
  </main>`;
16131
16245
  var runPlivoSmokeTest = async (input) => {
16132
16246
  const setup = await buildPlivoVoiceSetupStatus(input.options, input);
@@ -16221,7 +16335,7 @@ var createPlivoVoiceRoutes = (options = {}) => {
16221
16335
  request: input.request
16222
16336
  }) : verificationUrl ?? input.request.url
16223
16337
  }) : undefined);
16224
- const app = new Elysia24({
16338
+ const app = new Elysia25({
16225
16339
  name: options.name ?? "absolutejs-voice-plivo"
16226
16340
  }).get(answerPath, async ({ query, request }) => {
16227
16341
  const streamUrl = await resolvePlivoStreamUrl(options, {
@@ -16332,9 +16446,9 @@ var createPlivoVoiceRoutes = (options = {}) => {
16332
16446
 
16333
16447
  // src/telephony/telnyx.ts
16334
16448
  import { Buffer as Buffer6 } from "buffer";
16335
- import { Elysia as Elysia25 } from "elysia";
16449
+ import { Elysia as Elysia26 } from "elysia";
16336
16450
  var escapeXml4 = (value) => value.replaceAll("&", "&amp;").replaceAll('"', "&quot;").replaceAll("'", "&apos;").replaceAll("<", "&lt;").replaceAll(">", "&gt;");
16337
- var escapeHtml27 = (value) => value.replaceAll("&", "&amp;").replaceAll('"', "&quot;").replaceAll("'", "&#39;").replaceAll("<", "&lt;").replaceAll(">", "&gt;");
16451
+ var escapeHtml28 = (value) => value.replaceAll("&", "&amp;").replaceAll('"', "&quot;").replaceAll("'", "&#39;").replaceAll("<", "&lt;").replaceAll(">", "&gt;");
16338
16452
  var joinUrlPath4 = (origin, path) => `${origin.replace(/\/$/, "")}${path.startsWith("/") ? path : `/${path}`}`;
16339
16453
  var resolveRequestOrigin3 = (request) => {
16340
16454
  const url = new URL(request.url);
@@ -16535,21 +16649,21 @@ var buildTelnyxVoiceSetupStatus = async (options, input) => {
16535
16649
  };
16536
16650
  var renderTelnyxSetupHTML = (status, title) => `<main style="font-family: ui-sans-serif, system-ui; max-width: 860px; margin: 40px auto; padding: 0 20px;">
16537
16651
  <p style="letter-spacing: .12em; text-transform: uppercase; color: #52606d;">Telnyx setup</p>
16538
- <h1>${escapeHtml27(title)}</h1>
16652
+ <h1>${escapeHtml28(title)}</h1>
16539
16653
  <p><strong>Status:</strong> ${status.ready ? "Ready" : "Needs attention"}</p>
16540
16654
  <ul>
16541
- <li><strong>TeXML:</strong> <code>${escapeHtml27(status.urls.texml)}</code></li>
16542
- <li><strong>Media stream:</strong> <code>${escapeHtml27(status.urls.stream)}</code></li>
16543
- <li><strong>Status webhook:</strong> <code>${escapeHtml27(status.urls.webhook)}</code></li>
16655
+ <li><strong>TeXML:</strong> <code>${escapeHtml28(status.urls.texml)}</code></li>
16656
+ <li><strong>Media stream:</strong> <code>${escapeHtml28(status.urls.stream)}</code></li>
16657
+ <li><strong>Status webhook:</strong> <code>${escapeHtml28(status.urls.webhook)}</code></li>
16544
16658
  </ul>
16545
- ${status.missing.length ? `<h2>Missing env</h2><ul>${status.missing.map((name) => `<li><code>${escapeHtml27(name)}</code></li>`).join("")}</ul>` : ""}
16546
- ${status.warnings.length ? `<h2>Warnings</h2><ul>${status.warnings.map((warning) => `<li>${escapeHtml27(warning)}</li>`).join("")}</ul>` : ""}
16659
+ ${status.missing.length ? `<h2>Missing env</h2><ul>${status.missing.map((name) => `<li><code>${escapeHtml28(name)}</code></li>`).join("")}</ul>` : ""}
16660
+ ${status.warnings.length ? `<h2>Warnings</h2><ul>${status.warnings.map((warning) => `<li>${escapeHtml28(warning)}</li>`).join("")}</ul>` : ""}
16547
16661
  </main>`;
16548
16662
  var renderTelnyxSmokeHTML = (report, title) => `<main style="font-family: ui-sans-serif, system-ui; max-width: 860px; margin: 40px auto; padding: 0 20px;">
16549
16663
  <p style="letter-spacing: .12em; text-transform: uppercase; color: #52606d;">Telnyx smoke test</p>
16550
- <h1>${escapeHtml27(title)}</h1>
16664
+ <h1>${escapeHtml28(title)}</h1>
16551
16665
  <p><strong>Status:</strong> ${report.pass ? "Pass" : "Fail"}</p>
16552
- <ul>${report.checks.map((check) => `<li><strong>${escapeHtml27(check.name)}</strong>: ${escapeHtml27(check.status)}${check.message ? ` - ${escapeHtml27(check.message)}` : ""}</li>`).join("")}</ul>
16666
+ <ul>${report.checks.map((check) => `<li><strong>${escapeHtml28(check.name)}</strong>: ${escapeHtml28(check.status)}${check.message ? ` - ${escapeHtml28(check.message)}` : ""}</li>`).join("")}</ul>
16553
16667
  </main>`;
16554
16668
  var runTelnyxSmokeTest = async (input) => {
16555
16669
  const setup = await buildTelnyxVoiceSetupStatus(input.options, input);
@@ -16643,7 +16757,7 @@ var createTelnyxVoiceRoutes = (options = {}) => {
16643
16757
  publicKey: options.webhook?.publicKey,
16644
16758
  toleranceSeconds: options.webhook?.toleranceSeconds
16645
16759
  }) : undefined);
16646
- const app = new Elysia25({
16760
+ const app = new Elysia26({
16647
16761
  name: options.name ?? "absolutejs-voice-telnyx"
16648
16762
  }).get(texmlPath, async ({ query, request }) => {
16649
16763
  const streamUrl = await resolveTelnyxStreamUrl(options, {
@@ -16753,8 +16867,8 @@ var createTelnyxVoiceRoutes = (options = {}) => {
16753
16867
  };
16754
16868
 
16755
16869
  // src/telephony/matrix.ts
16756
- import { Elysia as Elysia26 } from "elysia";
16757
- var escapeHtml28 = (value) => value.replaceAll("&", "&amp;").replaceAll('"', "&quot;").replaceAll("'", "&#39;").replaceAll("<", "&lt;").replaceAll(">", "&gt;");
16870
+ import { Elysia as Elysia27 } from "elysia";
16871
+ var escapeHtml29 = (value) => value.replaceAll("&", "&amp;").replaceAll('"', "&quot;").replaceAll("'", "&#39;").replaceAll("<", "&lt;").replaceAll(">", "&gt;");
16758
16872
  var labelForProvider = (provider) => provider.split("-").map((part) => `${part.slice(0, 1).toUpperCase()}${part.slice(1)}`).join(" ");
16759
16873
  var resolveEntryStatus = (contract, setup, smoke) => {
16760
16874
  if (!contract.pass || !setup.ready || smoke?.pass === false) {
@@ -16815,13 +16929,13 @@ var badgeStyles = {
16815
16929
  };
16816
16930
  var renderVoiceTelephonyCarrierMatrixHTML = (matrix, options = {}) => `<main style="font-family: ui-sans-serif, system-ui; max-width: 1040px; margin: 40px auto; padding: 0 20px; color: #172033;">
16817
16931
  <p style="letter-spacing: .12em; text-transform: uppercase; color: #52606d;">Carrier matrix</p>
16818
- <h1 style="font-size: 34px; margin: 0 0 8px;">${escapeHtml28(options.title ?? "AbsoluteJS Voice Carrier Matrix")}</h1>
16932
+ <h1 style="font-size: 34px; margin: 0 0 8px;">${escapeHtml29(options.title ?? "AbsoluteJS Voice Carrier Matrix")}</h1>
16819
16933
  <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>
16820
16934
  <section style="display:grid; grid-template-columns: repeat(auto-fit, minmax(260px, 1fr)); gap: 16px;">
16821
16935
  ${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);">
16822
16936
  <div style="display:flex; justify-content:space-between; gap:12px; align-items:center;">
16823
- <h2 style="margin:0; font-size:20px;">${escapeHtml28(entry.name)}</h2>
16824
- <span style="border:1px solid; border-radius:999px; padding:4px 10px; font-size:12px; font-weight:700; ${badgeStyles[entry.status]}">${escapeHtml28(entry.status.toUpperCase())}</span>
16937
+ <h2 style="margin:0; font-size:20px;">${escapeHtml29(entry.name)}</h2>
16938
+ <span style="border:1px solid; border-radius:999px; padding:4px 10px; font-size:12px; font-weight:700; ${badgeStyles[entry.status]}">${escapeHtml29(entry.status.toUpperCase())}</span>
16825
16939
  </div>
16826
16940
  <dl style="display:grid; grid-template-columns: 1fr 1fr; gap:8px 12px; margin:16px 0;">
16827
16941
  <dt style="color:#64748b;">Setup</dt><dd style="margin:0; font-weight:700;">${entry.ready ? "Ready" : "Needs attention"}</dd>
@@ -16829,15 +16943,15 @@ ${matrix.entries.map((entry) => `<article style="border:1px solid #d9e2ec; borde
16829
16943
  <dt style="color:#64748b;">Smoke</dt><dd style="margin:0; font-weight:700;">${entry.smoke ? entry.smoke.pass ? "Pass" : "Fail" : "Missing"}</dd>
16830
16944
  <dt style="color:#64748b;">Contract</dt><dd style="margin:0; font-weight:700;">${entry.contract.pass ? "Pass" : "Fail"}</dd>
16831
16945
  </dl>
16832
- <p style="margin:0 0 8px; color:#475569;"><strong>Stream:</strong> <code>${escapeHtml28(entry.setup.urls.stream || "missing")}</code></p>
16833
- <p style="margin:0 0 12px; color:#475569;"><strong>Webhook:</strong> <code>${escapeHtml28(entry.setup.urls.webhook || "missing")}</code></p>
16834
- ${entry.issues.length ? `<ul style="margin:12px 0 0; padding-left:18px;">${entry.issues.map((issue) => `<li>${escapeHtml28(issue.severity)}: ${escapeHtml28(issue.message)}</li>`).join("")}</ul>` : '<p style="margin:12px 0 0; color:#166534;">No contract issues.</p>'}
16946
+ <p style="margin:0 0 8px; color:#475569;"><strong>Stream:</strong> <code>${escapeHtml29(entry.setup.urls.stream || "missing")}</code></p>
16947
+ <p style="margin:0 0 12px; color:#475569;"><strong>Webhook:</strong> <code>${escapeHtml29(entry.setup.urls.webhook || "missing")}</code></p>
16948
+ ${entry.issues.length ? `<ul style="margin:12px 0 0; padding-left:18px;">${entry.issues.map((issue) => `<li>${escapeHtml29(issue.severity)}: ${escapeHtml29(issue.message)}</li>`).join("")}</ul>` : '<p style="margin:12px 0 0; color:#166534;">No contract issues.</p>'}
16835
16949
  </article>`).join("")}
16836
16950
  </section>
16837
16951
  </main>`;
16838
16952
  var createVoiceTelephonyCarrierMatrixRoutes = (options) => {
16839
16953
  const path = options.path ?? "/api/voice/telephony/carriers";
16840
- return new Elysia26({
16954
+ return new Elysia27({
16841
16955
  name: options.name ?? "absolutejs-voice-telephony-carrier-matrix"
16842
16956
  }).get(path, async ({ query, request }) => {
16843
16957
  const providers = await options.load({ query, request });
@@ -16859,7 +16973,7 @@ var createVoiceTelephonyCarrierMatrixRoutes = (options) => {
16859
16973
  };
16860
16974
 
16861
16975
  // src/phoneAgentProductionSmoke.ts
16862
- import { Elysia as Elysia27 } from "elysia";
16976
+ import { Elysia as Elysia28 } from "elysia";
16863
16977
  var defaultRequirements = [
16864
16978
  "media-started",
16865
16979
  "transcript",
@@ -16867,7 +16981,7 @@ var defaultRequirements = [
16867
16981
  "lifecycle-outcome",
16868
16982
  "no-session-error"
16869
16983
  ];
16870
- var escapeHtml29 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
16984
+ var escapeHtml30 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
16871
16985
  var payloadType = (event) => typeof event.payload.type === "string" ? event.payload.type : undefined;
16872
16986
  var hasTextPayload = (event) => ["text", "assistantText", "transcript"].some((key) => {
16873
16987
  const value = event.payload[key];
@@ -16976,10 +17090,10 @@ var resolveHandlerOptions = async (options, input) => ({
16976
17090
  });
16977
17091
  var renderVoicePhoneAgentProductionSmokeHTML = (report, options = {}) => {
16978
17092
  const title = options.title ?? "AbsoluteJS Voice Phone Smoke Contract";
16979
- const issues = report.issues.map((issue) => `<li><strong>${escapeHtml29(issue.requirement)}</strong>: ${escapeHtml29(issue.message)}</li>`).join("");
16980
- const outcomes = report.observed.lifecycleOutcomes.map((outcome) => `<span class="pill">${escapeHtml29(outcome)}</span>`).join("");
16981
- const requirements = report.required.map((requirement) => `<span class="pill">${escapeHtml29(requirement)}</span>`).join("");
16982
- return `<!doctype html><html lang="en"><head><meta charset="utf-8" /><meta name="viewport" content="width=device-width, initial-scale=1" /><title>${escapeHtml29(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>${escapeHtml29(title)}</h1><p class="status ${report.pass ? "pass" : "fail"}">${report.pass ? "PASS" : "FAIL"}</p><p>Contract <code>${escapeHtml29(report.contractId)}</code>${report.provider ? ` for <code>${escapeHtml29(report.provider)}</code>` : ""}${report.sessionId ? ` on session <code>${escapeHtml29(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>`;
17093
+ const issues = report.issues.map((issue) => `<li><strong>${escapeHtml30(issue.requirement)}</strong>: ${escapeHtml30(issue.message)}</li>`).join("");
17094
+ const outcomes = report.observed.lifecycleOutcomes.map((outcome) => `<span class="pill">${escapeHtml30(outcome)}</span>`).join("");
17095
+ const requirements = report.required.map((requirement) => `<span class="pill">${escapeHtml30(requirement)}</span>`).join("");
17096
+ return `<!doctype html><html lang="en"><head><meta charset="utf-8" /><meta name="viewport" content="width=device-width, initial-scale=1" /><title>${escapeHtml30(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>${escapeHtml30(title)}</h1><p class="status ${report.pass ? "pass" : "fail"}">${report.pass ? "PASS" : "FAIL"}</p><p>Contract <code>${escapeHtml30(report.contractId)}</code>${report.provider ? ` for <code>${escapeHtml30(report.provider)}</code>` : ""}${report.sessionId ? ` on session <code>${escapeHtml30(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>`;
16983
17097
  };
16984
17098
  var createVoicePhoneAgentProductionSmokeJSONHandler = (options) => async ({
16985
17099
  query,
@@ -17002,7 +17116,7 @@ var createVoicePhoneAgentProductionSmokeHTMLHandler = (options) => async ({
17002
17116
  var createVoicePhoneAgentProductionSmokeRoutes = (options) => {
17003
17117
  const path = options.path ?? "/api/voice/phone/smoke-contract";
17004
17118
  const htmlPath = options.htmlPath === undefined ? "/voice/phone/smoke-contract" : options.htmlPath;
17005
- const routes = new Elysia27({
17119
+ const routes = new Elysia28({
17006
17120
  name: options.name ?? "absolutejs-voice-phone-smoke-contract"
17007
17121
  }).get(path, createVoicePhoneAgentProductionSmokeJSONHandler(options));
17008
17122
  if (htmlPath) {
@@ -17045,7 +17159,7 @@ var PHONE_AGENT_LIFECYCLE_STAGES = [
17045
17159
  "completed",
17046
17160
  "failed"
17047
17161
  ];
17048
- var escapeHtml30 = (value) => value.replaceAll("&", "&amp;").replaceAll('"', "&quot;").replaceAll("'", "&#39;").replaceAll("<", "&lt;").replaceAll(">", "&gt;");
17162
+ var escapeHtml31 = (value) => value.replaceAll("&", "&amp;").replaceAll('"', "&quot;").replaceAll("'", "&#39;").replaceAll("<", "&lt;").replaceAll(">", "&gt;");
17049
17163
  var loadRouteJson = async (input) => {
17050
17164
  const response = await input.app.handle(new Request(new URL(input.path, input.origin).toString(), {
17051
17165
  headers: {
@@ -17105,18 +17219,18 @@ var renderVoicePhoneAgentSetupHTML = (report) => {
17105
17219
  const entry = report.matrix?.entries.find((candidate) => candidate.provider === carrier.provider && (candidate.name === carrier.name || candidate.name === (carrier.name ?? carrier.provider)));
17106
17220
  const urls = entry?.setup.urls;
17107
17221
  const primaryUrl = carrier.provider === "plivo" ? urls?.twiml : urls?.twiml;
17108
- return `<tr><td>${escapeHtml30(carrier.name ?? carrier.provider)}</td><td>${escapeHtml30(carrier.provider)}</td><td><code>${escapeHtml30(carrier.setupPath || "disabled")}</code></td><td><code>${escapeHtml30(carrier.smokePath || "disabled")}</code></td><td>${entry ? `<span class="${escapeHtml30(entry.status)}">${escapeHtml30(entry.status.toUpperCase())}</span>` : "unknown"}</td><td>${primaryUrl ? `<code>${escapeHtml30(primaryUrl)}</code>` : '<span class="muted">missing</span>'}</td><td>${urls?.webhook ? `<code>${escapeHtml30(urls.webhook)}</code>` : '<span class="muted">missing</span>'}</td><td>${urls?.stream ? `<code>${escapeHtml30(urls.stream)}</code>` : '<span class="muted">missing</span>'}</td></tr>`;
17222
+ return `<tr><td>${escapeHtml31(carrier.name ?? carrier.provider)}</td><td>${escapeHtml31(carrier.provider)}</td><td><code>${escapeHtml31(carrier.setupPath || "disabled")}</code></td><td><code>${escapeHtml31(carrier.smokePath || "disabled")}</code></td><td>${entry ? `<span class="${escapeHtml31(entry.status)}">${escapeHtml31(entry.status.toUpperCase())}</span>` : "unknown"}</td><td>${primaryUrl ? `<code>${escapeHtml31(primaryUrl)}</code>` : '<span class="muted">missing</span>'}</td><td>${urls?.webhook ? `<code>${escapeHtml31(urls.webhook)}</code>` : '<span class="muted">missing</span>'}</td><td>${urls?.stream ? `<code>${escapeHtml31(urls.stream)}</code>` : '<span class="muted">missing</span>'}</td></tr>`;
17109
17223
  }).join("");
17110
- const stageList = report.lifecycleStages.map((stage) => `<li><code>${escapeHtml30(stage)}</code></li>`).join("");
17224
+ const stageList = report.lifecycleStages.map((stage) => `<li><code>${escapeHtml31(stage)}</code></li>`).join("");
17111
17225
  const checklist = report.carriers.map((carrier) => {
17112
17226
  const entry = report.matrix?.entries.find((candidate) => candidate.provider === carrier.provider && (candidate.name === carrier.name || candidate.name === (carrier.name ?? carrier.provider)));
17113
17227
  const urls = entry?.setup.urls;
17114
17228
  const answerLabel = carrier.provider === "telnyx" ? "TeXML URL" : carrier.provider === "plivo" ? "Answer URL" : "TwiML URL";
17115
17229
  const answerUrl = urls?.twiml;
17116
- const issueList = entry?.issues.map((issue) => `<li>${escapeHtml30(issue.severity)}: ${escapeHtml30(issue.message)}</li>`).join("") ?? "";
17117
- return `<article><h3>${escapeHtml30(carrier.name ?? carrier.provider)}</h3><ol><li>Set ${escapeHtml30(answerLabel)} to <code>${escapeHtml30(answerUrl ?? "missing")}</code>.</li><li>Set status webhook to <code>${escapeHtml30(urls?.webhook ?? "missing")}</code>.</li><li>Allow media stream URL <code>${escapeHtml30(urls?.stream ?? "missing")}</code>.</li><li>Open setup: ${carrier.setupPath ? `<a href="${escapeHtml30(carrier.setupPath)}?format=html">${escapeHtml30(carrier.setupPath)}</a>` : '<span class="muted">disabled</span>'}.</li><li>Run smoke: ${carrier.smokePath ? `<a href="${escapeHtml30(carrier.smokePath)}?format=html">${escapeHtml30(carrier.smokePath)}</a>` : '<span class="muted">disabled</span>'}.</li>${report.productionSmokePath ? `<li>Certify production smoke traces: <a href="${escapeHtml30(report.productionSmokePath.replace("/api/", "/"))}?sessionId=">${escapeHtml30(report.productionSmokePath)}</a>.</li>` : ""}</ol>${issueList ? `<ul class="issues">${issueList}</ul>` : '<p class="pass">No carrier contract issues.</p>'}</article>`;
17230
+ const issueList = entry?.issues.map((issue) => `<li>${escapeHtml31(issue.severity)}: ${escapeHtml31(issue.message)}</li>`).join("") ?? "";
17231
+ return `<article><h3>${escapeHtml31(carrier.name ?? carrier.provider)}</h3><ol><li>Set ${escapeHtml31(answerLabel)} to <code>${escapeHtml31(answerUrl ?? "missing")}</code>.</li><li>Set status webhook to <code>${escapeHtml31(urls?.webhook ?? "missing")}</code>.</li><li>Allow media stream URL <code>${escapeHtml31(urls?.stream ?? "missing")}</code>.</li><li>Open setup: ${carrier.setupPath ? `<a href="${escapeHtml31(carrier.setupPath)}?format=html">${escapeHtml31(carrier.setupPath)}</a>` : '<span class="muted">disabled</span>'}.</li><li>Run smoke: ${carrier.smokePath ? `<a href="${escapeHtml31(carrier.smokePath)}?format=html">${escapeHtml31(carrier.smokePath)}</a>` : '<span class="muted">disabled</span>'}.</li>${report.productionSmokePath ? `<li>Certify production smoke traces: <a href="${escapeHtml31(report.productionSmokePath.replace("/api/", "/"))}?sessionId=">${escapeHtml31(report.productionSmokePath)}</a>.</li>` : ""}</ol>${issueList ? `<ul class="issues">${issueList}</ul>` : '<p class="pass">No carrier contract issues.</p>'}</article>`;
17118
17232
  }).join("");
17119
- return `<!doctype html><html lang="en"><head><meta charset="utf-8" /><meta name="viewport" content="width=device-width, initial-scale=1" /><title>${escapeHtml30(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{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.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}.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>${escapeHtml30(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="${escapeHtml30(report.matrixPath)}?format=html">Open carrier matrix</a></p>` : ""}</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>`;
17233
+ return `<!doctype html><html lang="en"><head><meta charset="utf-8" /><meta name="viewport" content="width=device-width, initial-scale=1" /><title>${escapeHtml31(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{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.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}.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>${escapeHtml31(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="${escapeHtml31(report.matrixPath)}?format=html">Open carrier matrix</a></p>` : ""}</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>`;
17120
17234
  };
17121
17235
  var createVoicePhoneAgent = (options) => {
17122
17236
  const carrierSummaries = options.carriers.map((carrier) => ({
@@ -17125,7 +17239,7 @@ var createVoicePhoneAgent = (options) => {
17125
17239
  setupPath: resolveSetupPath(carrier),
17126
17240
  smokePath: resolveSmokePath(carrier)
17127
17241
  }));
17128
- const app = new Elysia28({
17242
+ const app = new Elysia29({
17129
17243
  name: options.name ?? "absolutejs-voice-phone-agent"
17130
17244
  });
17131
17245
  for (const carrier of options.carriers) {
@@ -19137,8 +19251,8 @@ var createOpenAIVoiceTTS = (options) => {
19137
19251
  };
19138
19252
  };
19139
19253
  // src/providerCapabilities.ts
19140
- import { Elysia as Elysia29 } from "elysia";
19141
- var escapeHtml31 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
19254
+ import { Elysia as Elysia30 } from "elysia";
19255
+ var escapeHtml32 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
19142
19256
  var fromProviderList = (kind, providers, options) => (providers ?? []).map((provider) => ({
19143
19257
  configured: true,
19144
19258
  features: options.features?.[provider],
@@ -19201,27 +19315,27 @@ var summarizeVoiceProviderCapabilities = async (options) => {
19201
19315
  var renderVoiceProviderCapabilityHTML = (report, options = {}) => {
19202
19316
  const title = options.title ?? "Voice Provider Capabilities";
19203
19317
  const cards = report.capabilities.map((capability) => {
19204
- const features = (capability.features ?? []).map((feature) => `<span class="pill">${escapeHtml31(feature)}</span>`).join("");
19205
- return `<article class="card ${escapeHtml31(capability.status)}">
19318
+ const features = (capability.features ?? []).map((feature) => `<span class="pill">${escapeHtml32(feature)}</span>`).join("");
19319
+ return `<article class="card ${escapeHtml32(capability.status)}">
19206
19320
  <div class="card-header">
19207
19321
  <div>
19208
- <p class="eyebrow">${escapeHtml31(capability.kind)}</p>
19209
- <h2>${escapeHtml31(capability.label ?? capability.provider)}</h2>
19322
+ <p class="eyebrow">${escapeHtml32(capability.kind)}</p>
19323
+ <h2>${escapeHtml32(capability.label ?? capability.provider)}</h2>
19210
19324
  </div>
19211
- <strong>${escapeHtml31(capability.status)}</strong>
19325
+ <strong>${escapeHtml32(capability.status)}</strong>
19212
19326
  </div>
19213
- ${capability.description ? `<p>${escapeHtml31(capability.description)}</p>` : ""}
19327
+ ${capability.description ? `<p>${escapeHtml32(capability.description)}</p>` : ""}
19214
19328
  <dl>
19215
19329
  <div><dt>Configured</dt><dd>${capability.configured ? "yes" : "no"}</dd></div>
19216
19330
  <div><dt>Selected</dt><dd>${capability.selected ? "yes" : "no"}</dd></div>
19217
- <div><dt>Model</dt><dd>${escapeHtml31(capability.model ?? "default")}</dd></div>
19331
+ <div><dt>Model</dt><dd>${escapeHtml32(capability.model ?? "default")}</dd></div>
19218
19332
  <div><dt>Runs</dt><dd>${String(capability.health?.runCount ?? 0)}</dd></div>
19219
19333
  <div><dt>Errors</dt><dd>${String(capability.health?.errorCount ?? 0)}</dd></div>
19220
19334
  </dl>
19221
19335
  ${features ? `<div class="features">${features}</div>` : ""}
19222
19336
  </article>`;
19223
19337
  }).join("");
19224
- return `<!doctype html><html lang="en"><head><meta charset="utf-8" /><meta name="viewport" content="width=device-width, initial-scale=1" /><title>${escapeHtml31(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>${escapeHtml31(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>`;
19338
+ 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:#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>${escapeHtml32(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>`;
19225
19339
  };
19226
19340
  var createVoiceProviderCapabilityJSONHandler = (options) => async () => summarizeVoiceProviderCapabilities(options);
19227
19341
  var createVoiceProviderCapabilityHTMLHandler = (options) => async () => {
@@ -19238,7 +19352,7 @@ var createVoiceProviderCapabilityHTMLHandler = (options) => async () => {
19238
19352
  var createVoiceProviderCapabilityRoutes = (options) => {
19239
19353
  const path = options.path ?? "/api/provider-capabilities";
19240
19354
  const htmlPath = options.htmlPath === undefined ? `${path}/htmx` : options.htmlPath;
19241
- const routes = new Elysia29({
19355
+ const routes = new Elysia30({
19242
19356
  name: options.name ?? "absolutejs-voice-provider-capabilities"
19243
19357
  }).get(path, createVoiceProviderCapabilityJSONHandler(options));
19244
19358
  if (htmlPath) {
@@ -19247,8 +19361,8 @@ var createVoiceProviderCapabilityRoutes = (options) => {
19247
19361
  return routes;
19248
19362
  };
19249
19363
  // src/resilienceRoutes.ts
19250
- import { Elysia as Elysia30 } from "elysia";
19251
- var escapeHtml32 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
19364
+ import { Elysia as Elysia31 } from "elysia";
19365
+ var escapeHtml33 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
19252
19366
  var getString11 = (value) => typeof value === "string" ? value : undefined;
19253
19367
  var getNumber6 = (value) => typeof value === "number" && Number.isFinite(value) ? value : undefined;
19254
19368
  var getBoolean2 = (value) => value === true;
@@ -19395,13 +19509,13 @@ var summarizeRoutingEvents = (events) => {
19395
19509
  };
19396
19510
  var renderProviderCards = (title, providers) => {
19397
19511
  if (providers.length === 0) {
19398
- return `<p class="muted">No ${escapeHtml32(title)} provider health yet.</p>`;
19512
+ return `<p class="muted">No ${escapeHtml33(title)} provider health yet.</p>`;
19399
19513
  }
19400
19514
  return `<div class="provider-grid">${providers.map((provider) => `
19401
- <article class="card provider ${escapeHtml32(provider.status)}">
19515
+ <article class="card provider ${escapeHtml33(provider.status)}">
19402
19516
  <div class="card-header">
19403
- <strong>${escapeHtml32(provider.provider)}</strong>
19404
- <span>${escapeHtml32(provider.status)}${provider.recommended ? " \xB7 recommended" : ""}</span>
19517
+ <strong>${escapeHtml33(provider.provider)}</strong>
19518
+ <span>${escapeHtml33(provider.status)}${provider.recommended ? " \xB7 recommended" : ""}</span>
19405
19519
  </div>
19406
19520
  <dl>
19407
19521
  <div><dt>Runs</dt><dd>${provider.runCount}</dd></div>
@@ -19410,7 +19524,7 @@ var renderProviderCards = (title, providers) => {
19410
19524
  <div><dt>Timeouts</dt><dd>${provider.timeoutCount}</dd></div>
19411
19525
  <div><dt>Fallbacks</dt><dd>${provider.fallbackCount}</dd></div>
19412
19526
  </dl>
19413
- ${provider.lastError ? `<p class="muted">${escapeHtml32(provider.lastError)}</p>` : ""}
19527
+ ${provider.lastError ? `<p class="muted">${escapeHtml33(provider.lastError)}</p>` : ""}
19414
19528
  </article>
19415
19529
  `).join("")}</div>`;
19416
19530
  };
@@ -19419,24 +19533,24 @@ var renderTimeline2 = (events) => {
19419
19533
  return '<p class="muted">No provider routing events yet. Run the app or simulate provider failover.</p>';
19420
19534
  }
19421
19535
  return `<div class="timeline">${events.slice(0, 40).map((event) => `
19422
- <article class="card event ${escapeHtml32(event.status ?? "unknown")}">
19536
+ <article class="card event ${escapeHtml33(event.status ?? "unknown")}">
19423
19537
  <div class="card-header">
19424
- <strong>${escapeHtml32(event.kind.toUpperCase())} ${escapeHtml32(event.operation ?? "generate")}</strong>
19538
+ <strong>${escapeHtml33(event.kind.toUpperCase())} ${escapeHtml33(event.operation ?? "generate")}</strong>
19425
19539
  <span>${new Date(event.at).toLocaleString()}</span>
19426
19540
  </div>
19427
19541
  <p>
19428
- <span class="pill">${escapeHtml32(event.status ?? "unknown")}</span>
19429
- <span class="pill">provider: ${escapeHtml32(event.provider ?? "unknown")}</span>
19430
- ${event.fallbackProvider ? `<span class="pill">fallback: ${escapeHtml32(event.fallbackProvider)}</span>` : ""}
19542
+ <span class="pill">${escapeHtml33(event.status ?? "unknown")}</span>
19543
+ <span class="pill">provider: ${escapeHtml33(event.provider ?? "unknown")}</span>
19544
+ ${event.fallbackProvider ? `<span class="pill">fallback: ${escapeHtml33(event.fallbackProvider)}</span>` : ""}
19431
19545
  ${event.timedOut ? '<span class="pill danger">timed out</span>' : ""}
19432
19546
  </p>
19433
19547
  <dl>
19434
19548
  <div><dt>Attempt</dt><dd>${event.attempt ?? 0}</dd></div>
19435
19549
  <div><dt>Elapsed</dt><dd>${event.elapsedMs ?? 0}ms</dd></div>
19436
19550
  <div><dt>Budget</dt><dd>${event.latencyBudgetMs ?? 0}ms</dd></div>
19437
- <div><dt>Session</dt><dd>${escapeHtml32(event.sessionId)}</dd></div>
19551
+ <div><dt>Session</dt><dd>${escapeHtml33(event.sessionId)}</dd></div>
19438
19552
  </dl>
19439
- ${event.error ? `<p class="muted">${escapeHtml32(event.error)}</p>` : ""}
19553
+ ${event.error ? `<p class="muted">${escapeHtml33(event.error)}</p>` : ""}
19440
19554
  </article>
19441
19555
  `).join("")}</div>`;
19442
19556
  };
@@ -19446,9 +19560,9 @@ var renderSessionKind = (kind, summary) => {
19446
19560
  const status = latest?.status ?? "idle";
19447
19561
  const fallback = latest?.fallbackProvider && latest.fallbackProvider !== provider ? ` -> ${latest.fallbackProvider}` : "";
19448
19562
  return `<div>
19449
- <dt>${escapeHtml32(kind.toUpperCase())}</dt>
19450
- <dd>${escapeHtml32(provider)}${escapeHtml32(fallback)}</dd>
19451
- <small>${escapeHtml32(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>
19563
+ <dt>${escapeHtml33(kind.toUpperCase())}</dt>
19564
+ <dd>${escapeHtml33(provider)}${escapeHtml33(fallback)}</dd>
19565
+ <small>${escapeHtml33(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>
19452
19566
  </div>`;
19453
19567
  };
19454
19568
  var renderSessionSummaries = (sessions) => {
@@ -19456,10 +19570,10 @@ var renderSessionSummaries = (sessions) => {
19456
19570
  return '<p class="muted">No call-level routing summaries yet. Run a voice session or provider simulation.</p>';
19457
19571
  }
19458
19572
  return `<div class="session-grid">${sessions.slice(0, 12).map((session) => `
19459
- <article class="card session ${escapeHtml32(session.status)}">
19573
+ <article class="card session ${escapeHtml33(session.status)}">
19460
19574
  <div class="card-header">
19461
- <strong>${escapeHtml32(session.sessionId)}</strong>
19462
- <span>${escapeHtml32(session.status)}</span>
19575
+ <strong>${escapeHtml33(session.sessionId)}</strong>
19576
+ <span>${escapeHtml33(session.status)}</span>
19463
19577
  </div>
19464
19578
  <p>
19465
19579
  <span class="pill">${session.eventCount} routing events</span>
@@ -19486,26 +19600,26 @@ var renderSimulationControls = (kind, simulation) => {
19486
19600
  const pathPrefix = simulation.pathPrefix ?? `/api/${kind}-simulate`;
19487
19601
  const failureProviders = simulation.failureProviders ?? configuredProviders.map(({ provider }) => provider);
19488
19602
  const canFail = (provider) => configuredProviders.some((entry) => entry.provider === provider) && (!simulation.fallbackRequiredProvider || configuredProviders.some((entry) => entry.provider === simulation.fallbackRequiredProvider));
19489
- return `<div class="simulate-panel" data-sim-kind="${kind}" data-sim-prefix="${escapeHtml32(pathPrefix)}">
19490
- <p class="muted">${escapeHtml32(simulation.failureMessage ?? `Simulate ${kind.toUpperCase()} provider failure without changing provider credentials.`)}</p>
19603
+ return `<div class="simulate-panel" data-sim-kind="${kind}" data-sim-prefix="${escapeHtml33(pathPrefix)}">
19604
+ <p class="muted">${escapeHtml33(simulation.failureMessage ?? `Simulate ${kind.toUpperCase()} provider failure without changing provider credentials.`)}</p>
19491
19605
  <div class="simulate-actions">
19492
- ${failureProviders.map((provider) => `<button type="button" data-provider-fail="${escapeHtml32(provider)}"${canFail(provider) ? "" : " disabled"}>Simulate ${escapeHtml32(provider)} ${kind.toUpperCase()} failure</button>`).join("")}
19493
- ${configuredProviders.map((provider) => `<button type="button" data-provider-recover="${escapeHtml32(provider.provider)}">Mark ${escapeHtml32(provider.provider)} recovered</button>`).join("")}
19606
+ ${failureProviders.map((provider) => `<button type="button" data-provider-fail="${escapeHtml33(provider)}"${canFail(provider) ? "" : " disabled"}>Simulate ${escapeHtml33(provider)} ${kind.toUpperCase()} failure</button>`).join("")}
19607
+ ${configuredProviders.map((provider) => `<button type="button" data-provider-recover="${escapeHtml33(provider.provider)}">Mark ${escapeHtml33(provider.provider)} recovered</button>`).join("")}
19494
19608
  </div>
19495
- ${simulation.fallbackRequiredProvider && !configuredProviders.some((entry) => entry.provider === simulation.fallbackRequiredProvider) ? `<p class="muted">${escapeHtml32(simulation.fallbackRequiredMessage ?? `Configure ${simulation.fallbackRequiredProvider} to enable fallback simulation.`)}</p>` : ""}
19609
+ ${simulation.fallbackRequiredProvider && !configuredProviders.some((entry) => entry.provider === simulation.fallbackRequiredProvider) ? `<p class="muted">${escapeHtml33(simulation.fallbackRequiredMessage ?? `Configure ${simulation.fallbackRequiredProvider} to enable fallback simulation.`)}</p>` : ""}
19496
19610
  <pre class="simulate-output" hidden></pre>
19497
19611
  </div>`;
19498
19612
  };
19499
19613
  var renderVoiceResilienceHTML = (input) => {
19500
19614
  const summary = summarizeRoutingEvents(input.routingEvents);
19501
- const kindCounts = [...summary.byKind.entries()].map(([kind, count]) => `<span class="pill">${escapeHtml32(kind)}: ${String(count)}</span>`).join("");
19502
- const links = input.links?.length ? input.links.map((link) => `<a href="${escapeHtml32(link.href)}">${escapeHtml32(link.label)}</a>`).join(" \xB7 ") : "";
19615
+ const kindCounts = [...summary.byKind.entries()].map(([kind, count]) => `<span class="pill">${escapeHtml33(kind)}: ${String(count)}</span>`).join("");
19616
+ const links = input.links?.length ? input.links.map((link) => `<a href="${escapeHtml33(link.href)}">${escapeHtml33(link.label)}</a>`).join(" \xB7 ") : "";
19503
19617
  return `<!doctype html>
19504
19618
  <html lang="en">
19505
19619
  <head>
19506
19620
  <meta charset="utf-8" />
19507
19621
  <meta name="viewport" content="width=device-width, initial-scale=1" />
19508
- <title>${escapeHtml32(input.title ?? "AbsoluteJS Voice Resilience")}</title>
19622
+ <title>${escapeHtml33(input.title ?? "AbsoluteJS Voice Resilience")}</title>
19509
19623
  <style>
19510
19624
  :root { color-scheme: dark; }
19511
19625
  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; }
@@ -19648,7 +19762,7 @@ var registerSimulationRoutes = (routes, simulation, defaultPathPrefix) => {
19648
19762
  };
19649
19763
  var createVoiceResilienceRoutes = (options) => {
19650
19764
  const path = options.path ?? "/resilience";
19651
- const routes = new Elysia30({
19765
+ const routes = new Elysia31({
19652
19766
  name: options.name ?? "absolutejs-voice-resilience"
19653
19767
  }).get(path, async () => {
19654
19768
  const events = await options.store.list();
@@ -19726,8 +19840,8 @@ var assertVoiceProviderRoutingContract = async (options) => {
19726
19840
  return report;
19727
19841
  };
19728
19842
  // src/productionReadiness.ts
19729
- import { Elysia as Elysia31 } from "elysia";
19730
- var escapeHtml33 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
19843
+ import { Elysia as Elysia32 } from "elysia";
19844
+ var escapeHtml34 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
19731
19845
  var rollupStatus2 = (checks) => checks.some((check) => check.status === "fail") ? "fail" : checks.some((check) => check.status === "warn") ? "warn" : "pass";
19732
19846
  var carrierStatus = (matrix) => matrix.summary.failing > 0 ? "fail" : matrix.summary.warnings > 0 || matrix.summary.ready < matrix.summary.providers ? "warn" : "pass";
19733
19847
  var resolveCarriers = async (options, input) => {
@@ -20330,25 +20444,25 @@ var buildVoiceProductionReadinessReport = async (options, input = {}) => {
20330
20444
  var renderVoiceProductionReadinessHTML = (report, options = {}) => {
20331
20445
  const title = options.title ?? "AbsoluteJS Voice Production Readiness";
20332
20446
  const checks = report.checks.map((check, index) => {
20333
- const actions = (check.actions ?? []).map((action) => action.method === "POST" ? `<button type="button" data-readiness-action="${index}" data-action-url="${escapeHtml33(action.href)}">${escapeHtml33(action.label)}</button>` : `<a href="${escapeHtml33(action.href)}">${escapeHtml33(action.label)}</a>`).join("");
20334
- return `<article class="check ${escapeHtml33(check.status)}">
20447
+ const actions = (check.actions ?? []).map((action) => action.method === "POST" ? `<button type="button" data-readiness-action="${index}" data-action-url="${escapeHtml34(action.href)}">${escapeHtml34(action.label)}</button>` : `<a href="${escapeHtml34(action.href)}">${escapeHtml34(action.label)}</a>`).join("");
20448
+ return `<article class="check ${escapeHtml34(check.status)}">
20335
20449
  <div>
20336
- <span>${escapeHtml33(check.status.toUpperCase())}</span>
20337
- <h2>${escapeHtml33(check.label)}</h2>
20338
- ${check.detail ? `<p>${escapeHtml33(check.detail)}</p>` : ""}
20339
- ${check.proofSource ? `<p class="proof-source">Proof source: ${check.proofSource.href ? `<a href="${escapeHtml33(check.proofSource.href)}">${escapeHtml33(check.proofSource.sourceLabel)}</a>` : escapeHtml33(check.proofSource.sourceLabel)}${check.proofSource.detail ? ` \xB7 ${escapeHtml33(check.proofSource.detail)}` : ""}</p>` : ""}
20450
+ <span>${escapeHtml34(check.status.toUpperCase())}</span>
20451
+ <h2>${escapeHtml34(check.label)}</h2>
20452
+ ${check.detail ? `<p>${escapeHtml34(check.detail)}</p>` : ""}
20453
+ ${check.proofSource ? `<p class="proof-source">Proof source: ${check.proofSource.href ? `<a href="${escapeHtml34(check.proofSource.href)}">${escapeHtml34(check.proofSource.sourceLabel)}</a>` : escapeHtml34(check.proofSource.sourceLabel)}${check.proofSource.detail ? ` \xB7 ${escapeHtml34(check.proofSource.detail)}` : ""}</p>` : ""}
20340
20454
  ${actions ? `<p class="actions">${actions}</p>` : ""}
20341
20455
  </div>
20342
- <strong>${escapeHtml33(String(check.value ?? check.status))}</strong>
20343
- ${check.href ? `<a href="${escapeHtml33(check.href)}">Open surface</a>` : ""}
20456
+ <strong>${escapeHtml34(String(check.value ?? check.status))}</strong>
20457
+ ${check.href ? `<a href="${escapeHtml34(check.href)}">Open surface</a>` : ""}
20344
20458
  </article>`;
20345
20459
  }).join("");
20346
- 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:#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(20,184,166,.18),rgba(245,158,11,.12));border:1px solid #26313d;border-radius:28px;margin-bottom:18px;padding:28px}.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}.status.pass,.check.pass{border-color:rgba(34,197,94,.55)}.status.warn,.check.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{color:#a8b0b8;font-size:.78rem;font-weight:900;letter-spacing:.08em}.check h2{margin:.2rem 0}.check p{color:#b9c0c8;margin:.2rem 0 0}.check .proof-source{color:#f9d77e;font-weight:800}.check strong{font-size:1.5rem}.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>${escapeHtml33(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 ${escapeHtml33(report.status)}">Overall: ${escapeHtml33(report.status.toUpperCase())}</p><p>Checked ${escapeHtml33(new Date(report.checkedAt).toLocaleString())}</p></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>`;
20460
+ 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:#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(20,184,166,.18),rgba(245,158,11,.12));border:1px solid #26313d;border-radius:28px;margin-bottom:18px;padding:28px}.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}.status.pass,.check.pass{border-color:rgba(34,197,94,.55)}.status.warn,.check.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{color:#a8b0b8;font-size:.78rem;font-weight:900;letter-spacing:.08em}.check h2{margin:.2rem 0}.check p{color:#b9c0c8;margin:.2rem 0 0}.check .proof-source{color:#f9d77e;font-weight:800}.check strong{font-size:1.5rem}.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>${escapeHtml34(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 ${escapeHtml34(report.status)}">Overall: ${escapeHtml34(report.status.toUpperCase())}</p><p>Checked ${escapeHtml34(new Date(report.checkedAt).toLocaleString())}</p></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>`;
20347
20461
  };
20348
20462
  var createVoiceProductionReadinessRoutes = (options) => {
20349
20463
  const path = options.path ?? "/api/production-readiness";
20350
20464
  const htmlPath = options.htmlPath ?? "/production-readiness";
20351
- const routes = new Elysia31({
20465
+ const routes = new Elysia32({
20352
20466
  name: options.name ?? "absolutejs-voice-production-readiness"
20353
20467
  });
20354
20468
  routes.get(path, async ({ query, request }) => buildVoiceProductionReadinessReport(options, { query, request }));
@@ -20370,7 +20484,7 @@ var createVoiceProductionReadinessRoutes = (options) => {
20370
20484
  return routes;
20371
20485
  };
20372
20486
  // src/opsConsoleRoutes.ts
20373
- import { Elysia as Elysia32 } from "elysia";
20487
+ import { Elysia as Elysia33 } from "elysia";
20374
20488
  var DEFAULT_LINKS = [
20375
20489
  {
20376
20490
  description: "Quality gates for CI, deploy checks, and production readiness.",
@@ -20405,7 +20519,7 @@ var DEFAULT_LINKS = [
20405
20519
  label: "Handoffs"
20406
20520
  }
20407
20521
  ];
20408
- var escapeHtml34 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
20522
+ var escapeHtml35 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
20409
20523
  var countProviderStatuses = (providers) => {
20410
20524
  const degradedStatuses = new Set(["degraded", "rate-limited", "suppressed"]);
20411
20525
  const healthy = providers.filter((provider) => provider.status === "healthy").length;
@@ -20474,20 +20588,20 @@ var buildVoiceOpsConsoleReport = async (options) => {
20474
20588
  trace
20475
20589
  };
20476
20590
  };
20477
- var renderMetricCard = (input) => `<article class="metric"><span>${escapeHtml34(input.label)}</span><strong>${escapeHtml34(String(input.value))}</strong>${input.status ? `<p class="${escapeHtml34(input.status)}">${escapeHtml34(input.status)}</p>` : ""}${input.href ? `<a href="${escapeHtml34(input.href)}">Open</a>` : ""}</article>`;
20591
+ var renderMetricCard = (input) => `<article class="metric"><span>${escapeHtml35(input.label)}</span><strong>${escapeHtml35(String(input.value))}</strong>${input.status ? `<p class="${escapeHtml35(input.status)}">${escapeHtml35(input.status)}</p>` : ""}${input.href ? `<a href="${escapeHtml35(input.href)}">Open</a>` : ""}</article>`;
20478
20592
  var renderVoiceOpsConsoleHTML = (report, options = {}) => {
20479
20593
  const links = report.links.map((link) => `<article class="surface">
20480
- <div><h2>${escapeHtml34(link.label)}</h2>${link.description ? `<p>${escapeHtml34(link.description)}</p>` : ""}</div>
20481
- <p><a href="${escapeHtml34(link.href)}">Open ${escapeHtml34(link.label)}</a>${link.statusHref ? ` \xB7 <a href="${escapeHtml34(link.statusHref)}">Status</a>` : ""}</p>
20594
+ <div><h2>${escapeHtml35(link.label)}</h2>${link.description ? `<p>${escapeHtml35(link.description)}</p>` : ""}</div>
20595
+ <p><a href="${escapeHtml35(link.href)}">Open ${escapeHtml35(link.label)}</a>${link.statusHref ? ` \xB7 <a href="${escapeHtml35(link.statusHref)}">Status</a>` : ""}</p>
20482
20596
  </article>`).join("");
20483
- const sessions = report.recentSessions.length ? report.recentSessions.map((session) => `<tr><td>${escapeHtml34(session.sessionId)}</td><td>${escapeHtml34(session.status)}</td><td>${session.turnCount}</td><td>${session.errorCount}</td><td>${session.replayHref ? `<a href="${escapeHtml34(session.replayHref)}">Replay</a>` : ""}</td></tr>`).join("") : '<tr><td colspan="5">No sessions yet.</td></tr>';
20484
- const routing = report.recentRoutingEvents.length ? report.recentRoutingEvents.map((event) => `<tr><td>${escapeHtml34(event.kind)}</td><td>${escapeHtml34(event.provider ?? "unknown")}</td><td>${escapeHtml34(event.status ?? "unknown")}</td><td>${event.elapsedMs ?? 0}ms</td><td>${escapeHtml34(event.sessionId)}</td></tr>`).join("") : '<tr><td colspan="5">No provider routing events yet.</td></tr>';
20597
+ const sessions = report.recentSessions.length ? report.recentSessions.map((session) => `<tr><td>${escapeHtml35(session.sessionId)}</td><td>${escapeHtml35(session.status)}</td><td>${session.turnCount}</td><td>${session.errorCount}</td><td>${session.replayHref ? `<a href="${escapeHtml35(session.replayHref)}">Replay</a>` : ""}</td></tr>`).join("") : '<tr><td colspan="5">No sessions yet.</td></tr>';
20598
+ const routing = report.recentRoutingEvents.length ? report.recentRoutingEvents.map((event) => `<tr><td>${escapeHtml35(event.kind)}</td><td>${escapeHtml35(event.provider ?? "unknown")}</td><td>${escapeHtml35(event.status ?? "unknown")}</td><td>${event.elapsedMs ?? 0}ms</td><td>${escapeHtml35(event.sessionId)}</td></tr>`).join("") : '<tr><td colspan="5">No provider routing events yet.</td></tr>';
20485
20599
  const title = options.title ?? "AbsoluteJS Voice Ops Console";
20486
- 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{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>${escapeHtml34(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 ${escapeHtml34(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>`;
20600
+ 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{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>${escapeHtml35(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 ${escapeHtml35(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>`;
20487
20601
  };
20488
20602
  var createVoiceOpsConsoleRoutes = (options) => {
20489
20603
  const path = options.path ?? "/ops-console";
20490
- const routes = new Elysia32({
20604
+ const routes = new Elysia33({
20491
20605
  name: options.name ?? "absolutejs-voice-ops-console"
20492
20606
  });
20493
20607
  const getReport = () => buildVoiceOpsConsoleReport(options);
@@ -20675,19 +20789,19 @@ var summarizeVoiceOpsStatus = async (options) => {
20675
20789
  };
20676
20790
  };
20677
20791
  // src/opsStatusRoutes.ts
20678
- import { Elysia as Elysia33 } from "elysia";
20679
- var escapeHtml35 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
20792
+ import { Elysia as Elysia34 } from "elysia";
20793
+ var escapeHtml36 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
20680
20794
  var renderVoiceOpsStatusHTML = (report, options = {}) => {
20681
20795
  const title = options.title ?? "AbsoluteJS Voice Ops Status";
20682
20796
  const surfaces = Object.entries(report.surfaces).map(([key, surface]) => {
20683
20797
  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;
20684
- return `<article class="surface ${escapeHtml35(surface.status)}"><span>${escapeHtml35(surface.status.toUpperCase())}</span><h2>${escapeHtml35(key)}</h2><strong>${escapeHtml35(value)}</strong></article>`;
20798
+ return `<article class="surface ${escapeHtml36(surface.status)}"><span>${escapeHtml36(surface.status.toUpperCase())}</span><h2>${escapeHtml36(key)}</h2><strong>${escapeHtml36(value)}</strong></article>`;
20685
20799
  }).join("");
20686
- 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:#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>${escapeHtml35(title)}</h1><p>Compact pass/fail status for framework widgets, demos, and small customer-facing health badges.</p><p class="status ${escapeHtml35(report.status)}">Overall: ${escapeHtml35(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>`;
20800
+ 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:#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>${escapeHtml36(title)}</h1><p>Compact pass/fail status for framework widgets, demos, and small customer-facing health badges.</p><p class="status ${escapeHtml36(report.status)}">Overall: ${escapeHtml36(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>`;
20687
20801
  };
20688
20802
  var createVoiceOpsStatusRoutes = (options) => {
20689
20803
  const path = options.path ?? "/api/voice/ops-status";
20690
- const routes = new Elysia33({
20804
+ const routes = new Elysia34({
20691
20805
  name: options.name ?? "absolutejs-voice-ops-status"
20692
20806
  });
20693
20807
  routes.get(path, async () => summarizeVoiceOpsStatus(options));
@@ -21120,8 +21234,8 @@ var createVoiceTTSProviderRouter = (options) => {
21120
21234
  };
21121
21235
  };
21122
21236
  // src/traceDeliveryRoutes.ts
21123
- import { Elysia as Elysia34 } from "elysia";
21124
- var escapeHtml36 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
21237
+ import { Elysia as Elysia35 } from "elysia";
21238
+ var escapeHtml37 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
21125
21239
  var getString12 = (value) => typeof value === "string" && value.trim() ? value.trim() : undefined;
21126
21240
  var getNumber7 = (value) => {
21127
21241
  if (typeof value === "number" && Number.isFinite(value)) {
@@ -21202,14 +21316,14 @@ var renderSinkResults2 = (delivery) => {
21202
21316
  if (entries.length === 0) {
21203
21317
  return "<p>No sink delivery attempts recorded yet.</p>";
21204
21318
  }
21205
- return `<ul>${entries.map(([sinkId, result]) => `<li><strong>${escapeHtml36(sinkId)}</strong>: ${escapeHtml36(result.status)}${result.deliveredTo ? ` to ${escapeHtml36(result.deliveredTo)}` : ""}${result.error ? ` (${escapeHtml36(result.error)})` : ""}</li>`).join("")}</ul>`;
21319
+ return `<ul>${entries.map(([sinkId, result]) => `<li><strong>${escapeHtml37(sinkId)}</strong>: ${escapeHtml37(result.status)}${result.deliveredTo ? ` to ${escapeHtml37(result.deliveredTo)}` : ""}${result.error ? ` (${escapeHtml37(result.error)})` : ""}</li>`).join("")}</ul>`;
21206
21320
  };
21207
- var renderEventList2 = (delivery) => delivery.events.length === 0 ? "<p>No trace events in this delivery.</p>" : `<ul>${delivery.events.map((event) => `<li>${escapeHtml36(event.type)} <small>${escapeHtml36(event.id)}</small>${event.sessionId ? ` session=${escapeHtml36(event.sessionId)}` : ""}</li>`).join("")}</ul>`;
21321
+ var renderEventList2 = (delivery) => delivery.events.length === 0 ? "<p>No trace events in this delivery.</p>" : `<ul>${delivery.events.map((event) => `<li>${escapeHtml37(event.type)} <small>${escapeHtml37(event.id)}</small>${event.sessionId ? ` session=${escapeHtml37(event.sessionId)}` : ""}</li>`).join("")}</ul>`;
21208
21322
  var renderVoiceTraceDeliveryHTML = (report, options = {}) => {
21209
21323
  const title = options.title ?? "AbsoluteJS Voice Trace Deliveries";
21210
- const drainAction = options.workerPath === false ? "" : `<form method="post" action="${escapeHtml36(options.workerPath ?? "/api/voice-trace-deliveries/drain")}"><button type="submit">Drain trace deliveries</button></form>`;
21211
- const rows = report.deliveries.map((delivery) => `<article class="delivery ${escapeHtml36(delivery.deliveryStatus)}"><div class="head"><div><span>${escapeHtml36(delivery.deliveryStatus)}</span><h2>${escapeHtml36(delivery.id)}</h2><p>${escapeHtml36(new Date(delivery.createdAt).toLocaleString())}${delivery.deliveredAt ? ` \xB7 delivered ${escapeHtml36(new Date(delivery.deliveredAt).toLocaleString())}` : ""}</p></div><strong>${String(delivery.deliveryAttempts ?? 0)} attempt(s)</strong></div>${delivery.deliveryError ? `<p class="error">${escapeHtml36(delivery.deliveryError)}</p>` : ""}<h3>Sinks</h3>${renderSinkResults2(delivery)}<h3>Events</h3>${renderEventList2(delivery)}</article>`).join("");
21212
- 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:#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>${escapeHtml36(title)}</h1><p>Checked ${escapeHtml36(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>`;
21324
+ const drainAction = options.workerPath === false ? "" : `<form method="post" action="${escapeHtml37(options.workerPath ?? "/api/voice-trace-deliveries/drain")}"><button type="submit">Drain trace deliveries</button></form>`;
21325
+ const rows = report.deliveries.map((delivery) => `<article class="delivery ${escapeHtml37(delivery.deliveryStatus)}"><div class="head"><div><span>${escapeHtml37(delivery.deliveryStatus)}</span><h2>${escapeHtml37(delivery.id)}</h2><p>${escapeHtml37(new Date(delivery.createdAt).toLocaleString())}${delivery.deliveredAt ? ` \xB7 delivered ${escapeHtml37(new Date(delivery.deliveredAt).toLocaleString())}` : ""}</p></div><strong>${String(delivery.deliveryAttempts ?? 0)} attempt(s)</strong></div>${delivery.deliveryError ? `<p class="error">${escapeHtml37(delivery.deliveryError)}</p>` : ""}<h3>Sinks</h3>${renderSinkResults2(delivery)}<h3>Events</h3>${renderEventList2(delivery)}</article>`).join("");
21326
+ 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:#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>${escapeHtml37(title)}</h1><p>Checked ${escapeHtml37(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>`;
21213
21327
  };
21214
21328
  var createVoiceTraceDeliveryJSONHandler = (options) => async ({ query }) => buildVoiceTraceDeliveryReport(options, resolveVoiceTraceDeliveryFilter(query, options.filter));
21215
21329
  var createVoiceTraceDeliveryHTMLHandler = (options) => async ({ query }) => {
@@ -21229,7 +21343,7 @@ var createVoiceTraceDeliveryRoutes = (options) => {
21229
21343
  const path = options.path ?? "/api/voice-trace-deliveries";
21230
21344
  const htmlPath = options.htmlPath === undefined ? "/traces/deliveries" : options.htmlPath;
21231
21345
  const workerPath = options.workerPath === undefined ? `${path}/drain` : options.workerPath;
21232
- const routes = new Elysia34({
21346
+ const routes = new Elysia35({
21233
21347
  name: options.name ?? "absolutejs-voice-trace-deliveries"
21234
21348
  }).get(path, createVoiceTraceDeliveryJSONHandler(options));
21235
21349
  if (htmlPath !== false) {
@@ -21247,8 +21361,8 @@ var createVoiceTraceDeliveryRoutes = (options) => {
21247
21361
  return routes;
21248
21362
  };
21249
21363
  // src/traceTimeline.ts
21250
- import { Elysia as Elysia35 } from "elysia";
21251
- var escapeHtml37 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
21364
+ import { Elysia as Elysia36 } from "elysia";
21365
+ var escapeHtml38 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
21252
21366
  var getString13 = (value) => typeof value === "string" && value.trim() ? value : undefined;
21253
21367
  var getNumber8 = (value) => typeof value === "number" && Number.isFinite(value) ? value : undefined;
21254
21368
  var firstString3 = (payload, keys) => {
@@ -21416,20 +21530,20 @@ var summarizeVoiceTraceTimeline = (events, options = {}) => {
21416
21530
  };
21417
21531
  };
21418
21532
  var formatMs3 = (value) => value === undefined ? "n/a" : `${String(value)}ms`;
21419
- 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>${escapeHtml37(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>`;
21533
+ 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>`;
21420
21534
  var renderVoiceTraceTimelineSessionHTML = (session, options = {}) => {
21421
- const events = session.events.map((event) => `<tr class="${escapeHtml37(event.status ?? "")}"><td>+${String(event.offsetMs)}ms</td><td>${escapeHtml37(event.type)}</td><td>${escapeHtml37(event.label)}</td><td>${escapeHtml37(event.provider ?? "")}</td><td>${escapeHtml37(event.status ?? "")}</td><td>${formatMs3(event.elapsedMs)}</td></tr>`).join("");
21422
- const issues = session.evaluation.issues.length ? session.evaluation.issues.map((issue) => `<li class="${escapeHtml37(issue.severity)}">${escapeHtml37(issue.code)}: ${escapeHtml37(issue.message)}</li>`).join("") : "<li>none</li>";
21423
- return `<!doctype html><html lang="en"><head><meta charset="utf-8" /><meta name="viewport" content="width=device-width, initial-scale=1" /><title>${escapeHtml37(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>${escapeHtml37(session.sessionId)}</h1><p class="status ${escapeHtml37(session.status)}">${escapeHtml37(session.status)}</p></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>`;
21535
+ 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("");
21536
+ 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>";
21537
+ 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></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>`;
21424
21538
  };
21425
- var renderSessionRows = (report) => report.sessions.length === 0 ? '<tr><td colspan="7">No trace events recorded yet.</td></tr>' : report.sessions.map((session) => `<tr class="${escapeHtml37(session.status)}"><td><a href="/traces/${encodeURIComponent(session.sessionId)}">${escapeHtml37(session.sessionId)}</a></td><td>${escapeHtml37(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) => escapeHtml37(provider.provider)).join(", ")}</td></tr>`).join("");
21539
+ 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><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("");
21426
21540
  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}}";
21427
- var renderVoiceTraceTimelineHTML = (report, options = {}) => `<!doctype html><html lang="en"><head><meta charset="utf-8" /><meta name="viewport" content="width=device-width, initial-scale=1" /><title>${escapeHtml37(options.title ?? "Voice Trace Timelines")}</title><style>${timelineCSS}</style></head><body><main><header><p class="eyebrow">Self-hosted voice debugging</p><h1>${escapeHtml37(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><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>`;
21541
+ var renderVoiceTraceTimelineHTML = (report, options = {}) => `<!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}</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><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>`;
21428
21542
  var createVoiceTraceTimelineRoutes = (options) => {
21429
21543
  const path = options.path ?? "/api/voice-traces";
21430
21544
  const htmlPath = options.htmlPath ?? "/traces";
21431
21545
  const title = options.title ?? "AbsoluteJS Voice Trace Timelines";
21432
- const routes = new Elysia35({
21546
+ const routes = new Elysia36({
21433
21547
  name: options.name ?? "absolutejs-voice-trace-timelines"
21434
21548
  });
21435
21549
  const buildReport = async () => summarizeVoiceTraceTimeline(await options.store.list(), {
@@ -22082,7 +22196,7 @@ var createVoiceMemoryStore = () => {
22082
22196
  return { get, getOrCreate, list, remove, set };
22083
22197
  };
22084
22198
  // src/opsWebhook.ts
22085
- import { Elysia as Elysia36 } from "elysia";
22199
+ import { Elysia as Elysia37 } from "elysia";
22086
22200
  var toHex6 = (bytes) => Array.from(bytes, (byte) => byte.toString(16).padStart(2, "0")).join("");
22087
22201
  var signVoiceOpsWebhookBody = async (input) => {
22088
22202
  const encoder = new TextEncoder;
@@ -22212,7 +22326,7 @@ var verifyVoiceOpsWebhookSignature = async (input) => {
22212
22326
  };
22213
22327
  var createVoiceOpsWebhookReceiverRoutes = (options = {}) => {
22214
22328
  const path = options.path ?? "/api/voice-ops/webhook";
22215
- return new Elysia36().post(path, async ({ body, request, set }) => {
22329
+ return new Elysia37().post(path, async ({ body, request, set }) => {
22216
22330
  const bodyText = typeof body === "string" ? body : JSON.stringify(body);
22217
22331
  if (options.signingSecret) {
22218
22332
  const verification = await verifyVoiceOpsWebhookSignature({
@@ -23157,6 +23271,7 @@ export {
23157
23271
  renderVoiceEvalBaselineHTML,
23158
23272
  renderVoiceDemoReadyHTML,
23159
23273
  renderVoiceDeliverySinkHTML,
23274
+ renderVoiceDeliveryRuntimeHTML,
23160
23275
  renderVoiceCampaignsHTML,
23161
23276
  renderVoiceCampaignObservabilityHTML,
23162
23277
  renderVoiceCallReviewMarkdown,
@@ -23378,6 +23493,8 @@ export {
23378
23493
  createVoiceDeliverySinkRoutes,
23379
23494
  createVoiceDeliverySinkPair,
23380
23495
  createVoiceDeliverySinkDescriptor,
23496
+ createVoiceDeliveryRuntimeRoutes,
23497
+ createVoiceDeliveryRuntime,
23381
23498
  createVoiceCampaignWorkerLoop,
23382
23499
  createVoiceCampaignWorker,
23383
23500
  createVoiceCampaignTelephonyOutcomeHandler,
@@ -23449,6 +23566,7 @@ export {
23449
23566
  buildVoiceDiagnosticsMarkdown,
23450
23567
  buildVoiceDemoReadyReport,
23451
23568
  buildVoiceDeliverySinkReport,
23569
+ buildVoiceDeliveryRuntimeReport,
23452
23570
  buildVoiceDataRetentionPlan,
23453
23571
  buildVoiceCampaignObservabilityReport,
23454
23572
  buildVoiceAuditTrailReport,