@absolutejs/voice 0.0.22-beta.166 → 0.0.22-beta.168

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
@@ -21342,6 +21342,8 @@ var recommendVoiceReadinessProfile = (options) => {
21342
21342
  };
21343
21343
  };
21344
21344
  // src/providerStackRecommendations.ts
21345
+ import { Elysia as Elysia34 } from "elysia";
21346
+ var escapeHtml36 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
21345
21347
  var profileProviderPriorities = {
21346
21348
  "meeting-recorder": {
21347
21349
  llm: ["openai", "anthropic", "gemini"],
@@ -21489,6 +21491,61 @@ var buildVoiceProviderContractMatrix = (input) => {
21489
21491
  warned
21490
21492
  };
21491
21493
  };
21494
+ var resolveProviderContractMatrixInput = async (matrix) => typeof matrix === "function" ? await matrix() : matrix;
21495
+ var renderVoiceProviderContractMatrixHTML = (report, options = {}) => {
21496
+ const title = options.title ?? "Voice Provider Contract Matrix";
21497
+ const rows = report.rows.map((row) => {
21498
+ const checks = row.checks.map((check) => `<li class="${escapeHtml36(check.status)}"><strong>${escapeHtml36(check.label)}</strong><span>${escapeHtml36(check.detail ?? check.status)}</span></li>`).join("");
21499
+ return `<article class="row ${escapeHtml36(row.status)}">
21500
+ <div>
21501
+ <p class="eyebrow">${escapeHtml36(row.kind)}${row.selected ? " \xB7 selected" : ""}</p>
21502
+ <h2>${escapeHtml36(row.provider)}</h2>
21503
+ <p class="status ${escapeHtml36(row.status)}">${escapeHtml36(row.status.toUpperCase())}</p>
21504
+ </div>
21505
+ <ul>${checks}</ul>
21506
+ </article>`;
21507
+ }).join("");
21508
+ 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:#0f1412;color:#f7f3e8;font-family:ui-sans-serif,system-ui,sans-serif;margin:0}main{margin:auto;max-width:1180px;padding:32px}.hero,.row{background:#17201b;border:1px solid #2d3b32;border-radius:24px;margin-bottom:16px;padding:22px}.hero{background:linear-gradient(135deg,rgba(34,197,94,.16),rgba(125,211,252,.12))}.eyebrow{color:#86efac;font-size:.78rem;font-weight:900;letter-spacing:.1em;text-transform:uppercase}h1{font-size:clamp(2.4rem,6vw,5rem);letter-spacing:-.06em;line-height:.9;margin:.2rem 0 1rem}h2{margin:.2rem 0}.summary{display:flex;flex-wrap:wrap;gap:10px}.pill,.status{border:1px solid #3f4f45;border-radius:999px;display:inline-flex;padding:8px 12px}.status.pass,.row.pass,.pass{border-color:rgba(34,197,94,.65)}.status.warn,.row.warn,.warn{border-color:rgba(245,158,11,.7)}.status.fail,.row.fail,.fail{border-color:rgba(239,68,68,.75)}.row{display:grid;gap:20px;grid-template-columns:minmax(180px,.45fr) 1fr}.row ul{display:grid;gap:10px;list-style:none;margin:0;padding:0}.row li{background:#111814;border:1px solid #2d3b32;border-radius:16px;display:grid;gap:4px;padding:12px}.row li span{color:#b8c2ba}@media(max-width:760px){main{padding:18px}.row{grid-template-columns:1fr}}</style></head><body><main><section class="hero"><p class="eyebrow">Provider contracts</p><h1>${escapeHtml36(title)}</h1><p>Self-hosted provider proof for configured state, required env, latency budgets, fallback, streaming, and declared capabilities.</p><div class="summary"><span class="pill">${String(report.passed)} passing</span><span class="pill">${String(report.warned)} warning</span><span class="pill">${String(report.failed)} failing</span><span class="pill">${String(report.total)} total</span></div></section>${rows || '<article class="row"><p>No provider contracts configured.</p></article>'}</main></body></html>`;
21509
+ };
21510
+ var createVoiceProviderContractMatrixJSONHandler = (matrix) => async () => buildVoiceProviderContractMatrix(await resolveProviderContractMatrixInput(matrix));
21511
+ var createVoiceProviderContractMatrixHTMLHandler = (options) => async () => {
21512
+ const report = buildVoiceProviderContractMatrix(await resolveProviderContractMatrixInput(options.matrix));
21513
+ const body = await (options.render ?? renderVoiceProviderContractMatrixHTML)(report, { title: options.title });
21514
+ return new Response(body, {
21515
+ headers: {
21516
+ "Content-Type": "text/html; charset=utf-8"
21517
+ }
21518
+ });
21519
+ };
21520
+ var createVoiceProviderContractMatrixRoutes = (options) => {
21521
+ const path = options.path ?? "/api/provider-contracts";
21522
+ const htmlPath = options.htmlPath ?? "/provider-contracts";
21523
+ const routes = new Elysia34({
21524
+ name: options.name ?? "absolutejs-voice-provider-contract-matrix"
21525
+ });
21526
+ const jsonHandler = createVoiceProviderContractMatrixJSONHandler(options.matrix);
21527
+ routes.get(path, async () => {
21528
+ const report = await jsonHandler();
21529
+ return new Response(JSON.stringify(report), {
21530
+ headers: {
21531
+ "Content-Type": "application/json; charset=utf-8",
21532
+ ...options.headers
21533
+ }
21534
+ });
21535
+ });
21536
+ if (htmlPath !== false) {
21537
+ routes.get(htmlPath, async () => {
21538
+ const response = await createVoiceProviderContractMatrixHTMLHandler(options)();
21539
+ return new Response(response.body, {
21540
+ headers: {
21541
+ ...Object.fromEntries(response.headers.entries()),
21542
+ ...options.headers
21543
+ }
21544
+ });
21545
+ });
21546
+ }
21547
+ return routes;
21548
+ };
21492
21549
  var normalizeCapability = (value) => value.toLowerCase().replace(/[^a-z0-9]+/g, "");
21493
21550
  var includesCapability = (capabilities, required) => {
21494
21551
  const normalizedRequired = normalizeCapability(required);
@@ -21522,7 +21579,7 @@ var evaluateVoiceProviderStackGaps = (input) => {
21522
21579
  };
21523
21580
  };
21524
21581
  // src/opsConsoleRoutes.ts
21525
- import { Elysia as Elysia34 } from "elysia";
21582
+ import { Elysia as Elysia35 } from "elysia";
21526
21583
  var DEFAULT_LINKS = [
21527
21584
  {
21528
21585
  description: "Quality gates for CI, deploy checks, and production readiness.",
@@ -21557,7 +21614,7 @@ var DEFAULT_LINKS = [
21557
21614
  label: "Handoffs"
21558
21615
  }
21559
21616
  ];
21560
- var escapeHtml36 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
21617
+ var escapeHtml37 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
21561
21618
  var countProviderStatuses = (providers) => {
21562
21619
  const degradedStatuses = new Set(["degraded", "rate-limited", "suppressed"]);
21563
21620
  const healthy = providers.filter((provider) => provider.status === "healthy").length;
@@ -21626,20 +21683,20 @@ var buildVoiceOpsConsoleReport = async (options) => {
21626
21683
  trace
21627
21684
  };
21628
21685
  };
21629
- var renderMetricCard = (input) => `<article class="metric"><span>${escapeHtml36(input.label)}</span><strong>${escapeHtml36(String(input.value))}</strong>${input.status ? `<p class="${escapeHtml36(input.status)}">${escapeHtml36(input.status)}</p>` : ""}${input.href ? `<a href="${escapeHtml36(input.href)}">Open</a>` : ""}</article>`;
21686
+ var renderMetricCard = (input) => `<article class="metric"><span>${escapeHtml37(input.label)}</span><strong>${escapeHtml37(String(input.value))}</strong>${input.status ? `<p class="${escapeHtml37(input.status)}">${escapeHtml37(input.status)}</p>` : ""}${input.href ? `<a href="${escapeHtml37(input.href)}">Open</a>` : ""}</article>`;
21630
21687
  var renderVoiceOpsConsoleHTML = (report, options = {}) => {
21631
21688
  const links = report.links.map((link) => `<article class="surface">
21632
- <div><h2>${escapeHtml36(link.label)}</h2>${link.description ? `<p>${escapeHtml36(link.description)}</p>` : ""}</div>
21633
- <p><a href="${escapeHtml36(link.href)}">Open ${escapeHtml36(link.label)}</a>${link.statusHref ? ` \xB7 <a href="${escapeHtml36(link.statusHref)}">Status</a>` : ""}</p>
21689
+ <div><h2>${escapeHtml37(link.label)}</h2>${link.description ? `<p>${escapeHtml37(link.description)}</p>` : ""}</div>
21690
+ <p><a href="${escapeHtml37(link.href)}">Open ${escapeHtml37(link.label)}</a>${link.statusHref ? ` \xB7 <a href="${escapeHtml37(link.statusHref)}">Status</a>` : ""}</p>
21634
21691
  </article>`).join("");
21635
- const sessions = report.recentSessions.length ? report.recentSessions.map((session) => `<tr><td>${escapeHtml36(session.sessionId)}</td><td>${escapeHtml36(session.status)}</td><td>${session.turnCount}</td><td>${session.errorCount}</td><td>${session.replayHref ? `<a href="${escapeHtml36(session.replayHref)}">Replay</a>` : ""}</td></tr>`).join("") : '<tr><td colspan="5">No sessions yet.</td></tr>';
21636
- const routing = report.recentRoutingEvents.length ? report.recentRoutingEvents.map((event) => `<tr><td>${escapeHtml36(event.kind)}</td><td>${escapeHtml36(event.provider ?? "unknown")}</td><td>${escapeHtml36(event.status ?? "unknown")}</td><td>${event.elapsedMs ?? 0}ms</td><td>${escapeHtml36(event.sessionId)}</td></tr>`).join("") : '<tr><td colspan="5">No provider routing events yet.</td></tr>';
21692
+ const sessions = report.recentSessions.length ? report.recentSessions.map((session) => `<tr><td>${escapeHtml37(session.sessionId)}</td><td>${escapeHtml37(session.status)}</td><td>${session.turnCount}</td><td>${session.errorCount}</td><td>${session.replayHref ? `<a href="${escapeHtml37(session.replayHref)}">Replay</a>` : ""}</td></tr>`).join("") : '<tr><td colspan="5">No sessions yet.</td></tr>';
21693
+ const routing = report.recentRoutingEvents.length ? report.recentRoutingEvents.map((event) => `<tr><td>${escapeHtml37(event.kind)}</td><td>${escapeHtml37(event.provider ?? "unknown")}</td><td>${escapeHtml37(event.status ?? "unknown")}</td><td>${event.elapsedMs ?? 0}ms</td><td>${escapeHtml37(event.sessionId)}</td></tr>`).join("") : '<tr><td colspan="5">No provider routing events yet.</td></tr>';
21637
21694
  const title = options.title ?? "AbsoluteJS Voice Ops Console";
21638
- 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{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>${escapeHtml36(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 ${escapeHtml36(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>`;
21695
+ return `<!doctype html><html lang="en"><head><meta charset="utf-8" /><meta name="viewport" content="width=device-width, initial-scale=1" /><title>${escapeHtml37(title)}</title><style>body{font-family:ui-sans-serif,system-ui,sans-serif;background:#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>${escapeHtml37(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 ${escapeHtml37(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>`;
21639
21696
  };
21640
21697
  var createVoiceOpsConsoleRoutes = (options) => {
21641
21698
  const path = options.path ?? "/ops-console";
21642
- const routes = new Elysia34({
21699
+ const routes = new Elysia35({
21643
21700
  name: options.name ?? "absolutejs-voice-ops-console"
21644
21701
  });
21645
21702
  const getReport = () => buildVoiceOpsConsoleReport(options);
@@ -21827,19 +21884,19 @@ var summarizeVoiceOpsStatus = async (options) => {
21827
21884
  };
21828
21885
  };
21829
21886
  // src/opsStatusRoutes.ts
21830
- import { Elysia as Elysia35 } from "elysia";
21831
- var escapeHtml37 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
21887
+ import { Elysia as Elysia36 } from "elysia";
21888
+ var escapeHtml38 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
21832
21889
  var renderVoiceOpsStatusHTML = (report, options = {}) => {
21833
21890
  const title = options.title ?? "AbsoluteJS Voice Ops Status";
21834
21891
  const surfaces = Object.entries(report.surfaces).map(([key, surface]) => {
21835
21892
  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;
21836
- return `<article class="surface ${escapeHtml37(surface.status)}"><span>${escapeHtml37(surface.status.toUpperCase())}</span><h2>${escapeHtml37(key)}</h2><strong>${escapeHtml37(value)}</strong></article>`;
21893
+ return `<article class="surface ${escapeHtml38(surface.status)}"><span>${escapeHtml38(surface.status.toUpperCase())}</span><h2>${escapeHtml38(key)}</h2><strong>${escapeHtml38(value)}</strong></article>`;
21837
21894
  }).join("");
21838
- 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:#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>${escapeHtml37(title)}</h1><p>Compact pass/fail status for framework widgets, demos, and small customer-facing health badges.</p><p class="status ${escapeHtml37(report.status)}">Overall: ${escapeHtml37(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>`;
21895
+ return `<!doctype html><html lang="en"><head><meta charset="utf-8" /><meta name="viewport" content="width=device-width, initial-scale=1" /><title>${escapeHtml38(title)}</title><style>body{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>${escapeHtml38(title)}</h1><p>Compact pass/fail status for framework widgets, demos, and small customer-facing health badges.</p><p class="status ${escapeHtml38(report.status)}">Overall: ${escapeHtml38(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>`;
21839
21896
  };
21840
21897
  var createVoiceOpsStatusRoutes = (options) => {
21841
21898
  const path = options.path ?? "/api/voice/ops-status";
21842
- const routes = new Elysia35({
21899
+ const routes = new Elysia36({
21843
21900
  name: options.name ?? "absolutejs-voice-ops-status"
21844
21901
  });
21845
21902
  routes.get(path, async () => summarizeVoiceOpsStatus(options));
@@ -22272,8 +22329,8 @@ var createVoiceTTSProviderRouter = (options) => {
22272
22329
  };
22273
22330
  };
22274
22331
  // src/traceDeliveryRoutes.ts
22275
- import { Elysia as Elysia36 } from "elysia";
22276
- var escapeHtml38 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
22332
+ import { Elysia as Elysia37 } from "elysia";
22333
+ var escapeHtml39 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
22277
22334
  var getString12 = (value) => typeof value === "string" && value.trim() ? value.trim() : undefined;
22278
22335
  var getNumber7 = (value) => {
22279
22336
  if (typeof value === "number" && Number.isFinite(value)) {
@@ -22354,14 +22411,14 @@ var renderSinkResults2 = (delivery) => {
22354
22411
  if (entries.length === 0) {
22355
22412
  return "<p>No sink delivery attempts recorded yet.</p>";
22356
22413
  }
22357
- return `<ul>${entries.map(([sinkId, result]) => `<li><strong>${escapeHtml38(sinkId)}</strong>: ${escapeHtml38(result.status)}${result.deliveredTo ? ` to ${escapeHtml38(result.deliveredTo)}` : ""}${result.error ? ` (${escapeHtml38(result.error)})` : ""}</li>`).join("")}</ul>`;
22414
+ return `<ul>${entries.map(([sinkId, result]) => `<li><strong>${escapeHtml39(sinkId)}</strong>: ${escapeHtml39(result.status)}${result.deliveredTo ? ` to ${escapeHtml39(result.deliveredTo)}` : ""}${result.error ? ` (${escapeHtml39(result.error)})` : ""}</li>`).join("")}</ul>`;
22358
22415
  };
22359
- var renderEventList2 = (delivery) => delivery.events.length === 0 ? "<p>No trace events in this delivery.</p>" : `<ul>${delivery.events.map((event) => `<li>${escapeHtml38(event.type)} <small>${escapeHtml38(event.id)}</small>${event.sessionId ? ` session=${escapeHtml38(event.sessionId)}` : ""}</li>`).join("")}</ul>`;
22416
+ var renderEventList2 = (delivery) => delivery.events.length === 0 ? "<p>No trace events in this delivery.</p>" : `<ul>${delivery.events.map((event) => `<li>${escapeHtml39(event.type)} <small>${escapeHtml39(event.id)}</small>${event.sessionId ? ` session=${escapeHtml39(event.sessionId)}` : ""}</li>`).join("")}</ul>`;
22360
22417
  var renderVoiceTraceDeliveryHTML = (report, options = {}) => {
22361
22418
  const title = options.title ?? "AbsoluteJS Voice Trace Deliveries";
22362
- const drainAction = options.workerPath === false ? "" : `<form method="post" action="${escapeHtml38(options.workerPath ?? "/api/voice-trace-deliveries/drain")}"><button type="submit">Drain trace deliveries</button></form>`;
22363
- const rows = report.deliveries.map((delivery) => `<article class="delivery ${escapeHtml38(delivery.deliveryStatus)}"><div class="head"><div><span>${escapeHtml38(delivery.deliveryStatus)}</span><h2>${escapeHtml38(delivery.id)}</h2><p>${escapeHtml38(new Date(delivery.createdAt).toLocaleString())}${delivery.deliveredAt ? ` \xB7 delivered ${escapeHtml38(new Date(delivery.deliveredAt).toLocaleString())}` : ""}</p></div><strong>${String(delivery.deliveryAttempts ?? 0)} attempt(s)</strong></div>${delivery.deliveryError ? `<p class="error">${escapeHtml38(delivery.deliveryError)}</p>` : ""}<h3>Sinks</h3>${renderSinkResults2(delivery)}<h3>Events</h3>${renderEventList2(delivery)}</article>`).join("");
22364
- return `<!doctype html><html lang="en"><head><meta charset="utf-8" /><meta name="viewport" content="width=device-width, initial-scale=1" /><title>${escapeHtml38(title)}</title><style>body{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>${escapeHtml38(title)}</h1><p>Checked ${escapeHtml38(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>`;
22419
+ const drainAction = options.workerPath === false ? "" : `<form method="post" action="${escapeHtml39(options.workerPath ?? "/api/voice-trace-deliveries/drain")}"><button type="submit">Drain trace deliveries</button></form>`;
22420
+ const rows = report.deliveries.map((delivery) => `<article class="delivery ${escapeHtml39(delivery.deliveryStatus)}"><div class="head"><div><span>${escapeHtml39(delivery.deliveryStatus)}</span><h2>${escapeHtml39(delivery.id)}</h2><p>${escapeHtml39(new Date(delivery.createdAt).toLocaleString())}${delivery.deliveredAt ? ` \xB7 delivered ${escapeHtml39(new Date(delivery.deliveredAt).toLocaleString())}` : ""}</p></div><strong>${String(delivery.deliveryAttempts ?? 0)} attempt(s)</strong></div>${delivery.deliveryError ? `<p class="error">${escapeHtml39(delivery.deliveryError)}</p>` : ""}<h3>Sinks</h3>${renderSinkResults2(delivery)}<h3>Events</h3>${renderEventList2(delivery)}</article>`).join("");
22421
+ return `<!doctype html><html lang="en"><head><meta charset="utf-8" /><meta name="viewport" content="width=device-width, initial-scale=1" /><title>${escapeHtml39(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>${escapeHtml39(title)}</h1><p>Checked ${escapeHtml39(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>`;
22365
22422
  };
22366
22423
  var createVoiceTraceDeliveryJSONHandler = (options) => async ({ query }) => buildVoiceTraceDeliveryReport(options, resolveVoiceTraceDeliveryFilter(query, options.filter));
22367
22424
  var createVoiceTraceDeliveryHTMLHandler = (options) => async ({ query }) => {
@@ -22381,7 +22438,7 @@ var createVoiceTraceDeliveryRoutes = (options) => {
22381
22438
  const path = options.path ?? "/api/voice-trace-deliveries";
22382
22439
  const htmlPath = options.htmlPath === undefined ? "/traces/deliveries" : options.htmlPath;
22383
22440
  const workerPath = options.workerPath === undefined ? `${path}/drain` : options.workerPath;
22384
- const routes = new Elysia36({
22441
+ const routes = new Elysia37({
22385
22442
  name: options.name ?? "absolutejs-voice-trace-deliveries"
22386
22443
  }).get(path, createVoiceTraceDeliveryJSONHandler(options));
22387
22444
  if (htmlPath !== false) {
@@ -22399,8 +22456,8 @@ var createVoiceTraceDeliveryRoutes = (options) => {
22399
22456
  return routes;
22400
22457
  };
22401
22458
  // src/traceTimeline.ts
22402
- import { Elysia as Elysia37 } from "elysia";
22403
- var escapeHtml39 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
22459
+ import { Elysia as Elysia38 } from "elysia";
22460
+ var escapeHtml40 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
22404
22461
  var getString13 = (value) => typeof value === "string" && value.trim() ? value : undefined;
22405
22462
  var getNumber8 = (value) => typeof value === "number" && Number.isFinite(value) ? value : undefined;
22406
22463
  var firstString3 = (payload, keys) => {
@@ -22568,20 +22625,20 @@ var summarizeVoiceTraceTimeline = (events, options = {}) => {
22568
22625
  };
22569
22626
  };
22570
22627
  var formatMs3 = (value) => value === undefined ? "n/a" : `${String(value)}ms`;
22571
- var renderProviderCards2 = (session) => session.providers.length === 0 ? '<p class="muted">No provider events recorded for this session.</p>' : `<div class="providers">${session.providers.map((provider) => `<article><strong>${escapeHtml39(provider.provider)}</strong><dl><div><dt>Events</dt><dd>${String(provider.eventCount)}</dd></div><div><dt>Avg</dt><dd>${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>`;
22628
+ 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>${escapeHtml40(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>`;
22572
22629
  var renderVoiceTraceTimelineSessionHTML = (session, options = {}) => {
22573
- const events = session.events.map((event) => `<tr class="${escapeHtml39(event.status ?? "")}"><td>+${String(event.offsetMs)}ms</td><td>${escapeHtml39(event.type)}</td><td>${escapeHtml39(event.label)}</td><td>${escapeHtml39(event.provider ?? "")}</td><td>${escapeHtml39(event.status ?? "")}</td><td>${formatMs3(event.elapsedMs)}</td></tr>`).join("");
22574
- const issues = session.evaluation.issues.length ? session.evaluation.issues.map((issue) => `<li class="${escapeHtml39(issue.severity)}">${escapeHtml39(issue.code)}: ${escapeHtml39(issue.message)}</li>`).join("") : "<li>none</li>";
22575
- return `<!doctype html><html lang="en"><head><meta charset="utf-8" /><meta name="viewport" content="width=device-width, initial-scale=1" /><title>${escapeHtml39(options.title ?? "Voice Trace Timeline")}</title><style>${timelineCSS}</style></head><body><main><a href="/traces">Back to traces</a><header><p class="eyebrow">Call timeline</p><h1>${escapeHtml39(session.sessionId)}</h1><p class="status ${escapeHtml39(session.status)}">${escapeHtml39(session.status)}</p></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>`;
22630
+ const events = session.events.map((event) => `<tr class="${escapeHtml40(event.status ?? "")}"><td>+${String(event.offsetMs)}ms</td><td>${escapeHtml40(event.type)}</td><td>${escapeHtml40(event.label)}</td><td>${escapeHtml40(event.provider ?? "")}</td><td>${escapeHtml40(event.status ?? "")}</td><td>${formatMs3(event.elapsedMs)}</td></tr>`).join("");
22631
+ const issues = session.evaluation.issues.length ? session.evaluation.issues.map((issue) => `<li class="${escapeHtml40(issue.severity)}">${escapeHtml40(issue.code)}: ${escapeHtml40(issue.message)}</li>`).join("") : "<li>none</li>";
22632
+ return `<!doctype html><html lang="en"><head><meta charset="utf-8" /><meta name="viewport" content="width=device-width, initial-scale=1" /><title>${escapeHtml40(options.title ?? "Voice Trace Timeline")}</title><style>${timelineCSS}</style></head><body><main><a href="/traces">Back to traces</a><header><p class="eyebrow">Call timeline</p><h1>${escapeHtml40(session.sessionId)}</h1><p class="status ${escapeHtml40(session.status)}">${escapeHtml40(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>`;
22576
22633
  };
22577
- var renderSessionRows = (report) => report.sessions.length === 0 ? '<tr><td colspan="7">No trace events recorded yet.</td></tr>' : report.sessions.map((session) => `<tr class="${escapeHtml39(session.status)}"><td><a href="/traces/${encodeURIComponent(session.sessionId)}">${escapeHtml39(session.sessionId)}</a></td><td>${escapeHtml39(session.status)}</td><td>${String(session.summary.eventCount)}</td><td>${String(session.summary.turnCount)}</td><td>${String(session.summary.errorCount)}</td><td>${formatMs3(session.summary.callDurationMs)}</td><td>${session.providers.map((provider) => escapeHtml39(provider.provider)).join(", ")}</td></tr>`).join("");
22634
+ var renderSessionRows = (report) => report.sessions.length === 0 ? '<tr><td colspan="7">No trace events recorded yet.</td></tr>' : report.sessions.map((session) => `<tr class="${escapeHtml40(session.status)}"><td><a href="/traces/${encodeURIComponent(session.sessionId)}">${escapeHtml40(session.sessionId)}</a></td><td>${escapeHtml40(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) => escapeHtml40(provider.provider)).join(", ")}</td></tr>`).join("");
22578
22635
  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}}";
22579
- 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>${escapeHtml39(options.title ?? "Voice Trace Timelines")}</title><style>${timelineCSS}</style></head><body><main><header><p class="eyebrow">Self-hosted voice debugging</p><h1>${escapeHtml39(options.title ?? "Voice Trace Timelines")}</h1><p class="muted">Per-call event timelines with provider latency, fallback, timeout, handoff, and error context.</p></header><section class="metrics"><article><span>Sessions</span><strong>${String(report.total)}</strong></article><article><span>Failed</span><strong>${String(report.failed)}</strong></article><article><span>Warnings</span><strong>${String(report.warnings)}</strong></article></section><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>`;
22636
+ 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>${escapeHtml40(options.title ?? "Voice Trace Timelines")}</title><style>${timelineCSS}</style></head><body><main><header><p class="eyebrow">Self-hosted voice debugging</p><h1>${escapeHtml40(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>`;
22580
22637
  var createVoiceTraceTimelineRoutes = (options) => {
22581
22638
  const path = options.path ?? "/api/voice-traces";
22582
22639
  const htmlPath = options.htmlPath ?? "/traces";
22583
22640
  const title = options.title ?? "AbsoluteJS Voice Trace Timelines";
22584
- const routes = new Elysia37({
22641
+ const routes = new Elysia38({
22585
22642
  name: options.name ?? "absolutejs-voice-trace-timelines"
22586
22643
  });
22587
22644
  const buildReport = async () => summarizeVoiceTraceTimeline(await options.store.list(), {
@@ -23234,7 +23291,7 @@ var createVoiceMemoryStore = () => {
23234
23291
  return { get, getOrCreate, list, remove, set };
23235
23292
  };
23236
23293
  // src/opsWebhook.ts
23237
- import { Elysia as Elysia38 } from "elysia";
23294
+ import { Elysia as Elysia39 } from "elysia";
23238
23295
  var toHex6 = (bytes) => Array.from(bytes, (byte) => byte.toString(16).padStart(2, "0")).join("");
23239
23296
  var signVoiceOpsWebhookBody = async (input) => {
23240
23297
  const encoder = new TextEncoder;
@@ -23364,7 +23421,7 @@ var verifyVoiceOpsWebhookSignature = async (input) => {
23364
23421
  };
23365
23422
  var createVoiceOpsWebhookReceiverRoutes = (options = {}) => {
23366
23423
  const path = options.path ?? "/api/voice-ops/webhook";
23367
- return new Elysia38().post(path, async ({ body, request, set }) => {
23424
+ return new Elysia39().post(path, async ({ body, request, set }) => {
23368
23425
  const bodyText = typeof body === "string" ? body : JSON.stringify(body);
23369
23426
  if (options.signingSecret) {
23370
23427
  const verification = await verifyVoiceOpsWebhookSignature({
@@ -24298,6 +24355,7 @@ export {
24298
24355
  renderVoiceReconnectContractHTML,
24299
24356
  renderVoiceQualityHTML,
24300
24357
  renderVoiceProviderHealthHTML,
24358
+ renderVoiceProviderContractMatrixHTML,
24301
24359
  renderVoiceProviderCapabilityHTML,
24302
24360
  renderVoiceProductionReadinessHTML,
24303
24361
  renderVoicePhoneAgentProductionSmokeHTML,
@@ -24454,6 +24512,9 @@ export {
24454
24512
  createVoiceProviderHealthRoutes,
24455
24513
  createVoiceProviderHealthJSONHandler,
24456
24514
  createVoiceProviderHealthHTMLHandler,
24515
+ createVoiceProviderContractMatrixRoutes,
24516
+ createVoiceProviderContractMatrixJSONHandler,
24517
+ createVoiceProviderContractMatrixHTMLHandler,
24457
24518
  createVoiceProviderCapabilityRoutes,
24458
24519
  createVoiceProviderCapabilityJSONHandler,
24459
24520
  createVoiceProviderCapabilityHTMLHandler,
@@ -1,3 +1,4 @@
1
+ import { Elysia } from 'elysia';
1
2
  import type { VoiceReadinessProfileName } from './readinessProfiles';
2
3
  export type VoiceProviderStackKind = 'llm' | 'stt' | 'tts';
3
4
  export type VoiceProviderStackInput<TProvider extends string = string> = {
@@ -58,6 +59,18 @@ export type VoiceProviderContractDefinition<TProvider extends string = string> =
58
59
  export type VoiceProviderContractMatrixInput<TProvider extends string = string> = {
59
60
  contracts: readonly VoiceProviderContractDefinition<TProvider>[];
60
61
  };
62
+ export type VoiceProviderContractMatrixHandlerOptions<TProvider extends string = string> = VoiceProviderContractMatrixInput<TProvider> | (() => Promise<VoiceProviderContractMatrixInput<TProvider>> | VoiceProviderContractMatrixInput<TProvider>);
63
+ export type VoiceProviderContractMatrixHTMLHandlerOptions<TProvider extends string = string> = {
64
+ matrix: VoiceProviderContractMatrixHandlerOptions<TProvider>;
65
+ render?: (report: VoiceProviderContractMatrixReport<TProvider>) => string | Promise<string>;
66
+ title?: string;
67
+ };
68
+ export type VoiceProviderContractMatrixRoutesOptions<TProvider extends string = string> = VoiceProviderContractMatrixHTMLHandlerOptions<TProvider> & {
69
+ headers?: HeadersInit;
70
+ htmlPath?: false | string;
71
+ name?: string;
72
+ path?: string;
73
+ };
61
74
  export type VoiceProviderContractMatrixRow<TProvider extends string = string> = {
62
75
  checks: VoiceProviderContractCheck[];
63
76
  configured: boolean;
@@ -76,4 +89,37 @@ export type VoiceProviderContractMatrixReport<TProvider extends string = string>
76
89
  };
77
90
  export declare const recommendVoiceProviderStack: <TProvider extends string = string>(input: VoiceProviderStackInput<TProvider>) => VoiceProviderStackRecommendation<TProvider>;
78
91
  export declare const buildVoiceProviderContractMatrix: <TProvider extends string = string>(input: VoiceProviderContractMatrixInput<TProvider>) => VoiceProviderContractMatrixReport<TProvider>;
92
+ export declare const renderVoiceProviderContractMatrixHTML: <TProvider extends string = string>(report: VoiceProviderContractMatrixReport<TProvider>, options?: {
93
+ title?: string;
94
+ }) => string;
95
+ export declare const createVoiceProviderContractMatrixJSONHandler: <TProvider extends string = string>(matrix: VoiceProviderContractMatrixHandlerOptions<TProvider>) => () => Promise<VoiceProviderContractMatrixReport<TProvider>>;
96
+ export declare const createVoiceProviderContractMatrixHTMLHandler: <TProvider extends string = string>(options: VoiceProviderContractMatrixHTMLHandlerOptions<TProvider>) => () => Promise<Response>;
97
+ export declare const createVoiceProviderContractMatrixRoutes: <TProvider extends string = string>(options: VoiceProviderContractMatrixRoutesOptions<TProvider>) => Elysia<"", {
98
+ decorator: {};
99
+ store: {};
100
+ derive: {};
101
+ resolve: {};
102
+ }, {
103
+ typebox: {};
104
+ error: {};
105
+ }, {
106
+ schema: {};
107
+ standaloneSchema: {};
108
+ macro: {};
109
+ macroFn: {};
110
+ parser: {};
111
+ response: {};
112
+ }, {}, {
113
+ derive: {};
114
+ resolve: {};
115
+ schema: {};
116
+ standaloneSchema: {};
117
+ response: {};
118
+ }, {
119
+ derive: {};
120
+ resolve: {};
121
+ schema: {};
122
+ standaloneSchema: {};
123
+ response: {};
124
+ }>;
79
125
  export declare const evaluateVoiceProviderStackGaps: <TProvider extends string = string>(input: VoiceProviderStackCapabilityGapInput<TProvider>) => VoiceProviderStackCapabilityGapReport<TProvider>;
@@ -0,0 +1,6 @@
1
+ import { type VoiceProviderContractsWidgetOptions } from '../client/providerContractsWidget';
2
+ export type VoiceProviderContractsProps = VoiceProviderContractsWidgetOptions & {
3
+ className?: string;
4
+ path?: string;
5
+ };
6
+ export declare const VoiceProviderContracts: ({ className, path, ...options }: VoiceProviderContractsProps) => import("react/jsx-runtime").JSX.Element;
@@ -3,6 +3,7 @@ export { VoiceOpsActionCenter } from './VoiceOpsActionCenter';
3
3
  export { VoiceDeliveryRuntime } from './VoiceDeliveryRuntime';
4
4
  export { VoiceProviderSimulationControls } from './VoiceProviderSimulationControls';
5
5
  export { VoiceProviderCapabilities } from './VoiceProviderCapabilities';
6
+ export { VoiceProviderContracts } from './VoiceProviderContracts';
6
7
  export { VoiceProviderStatus } from './VoiceProviderStatus';
7
8
  export { VoiceRoutingStatus } from './VoiceRoutingStatus';
8
9
  export { VoiceTraceTimeline } from './VoiceTraceTimeline';
@@ -16,6 +17,7 @@ export { useVoiceStream } from './useVoiceStream';
16
17
  export { useVoiceController } from './useVoiceController';
17
18
  export { useVoiceProviderStatus } from './useVoiceProviderStatus';
18
19
  export { useVoiceProviderCapabilities } from './useVoiceProviderCapabilities';
20
+ export { useVoiceProviderContracts } from './useVoiceProviderContracts';
19
21
  export { useVoiceProviderSimulationControls } from './useVoiceProviderSimulationControls';
20
22
  export { useVoiceRoutingStatus } from './useVoiceRoutingStatus';
21
23
  export { useVoiceTraceTimeline } from './useVoiceTraceTimeline';