@absolutejs/voice 0.0.22-beta.528 → 0.0.22-beta.529

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.
@@ -7867,6 +7867,9 @@ var runVoiceResilienceBenchmark = async () => {
7867
7867
  }
7868
7868
  };
7869
7869
  };
7870
+ // src/internal/html.ts
7871
+ var escapeHtml = (value) => String(value).replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
7872
+
7870
7873
  // src/testing/review.ts
7871
7874
  var roundMetric4 = (value) => typeof value === "number" ? Math.round(value * 100) / 100 : undefined;
7872
7875
  var formatMetric = (label, value, unit = "ms") => typeof value === "number" ? `${label}: ${roundMetric4(value)}${unit}` : undefined;
@@ -8312,7 +8315,6 @@ var renderVoiceCallReviewMarkdown = (artifact) => {
8312
8315
  ].filter((value) => typeof value === "string").join(`
8313
8316
  `);
8314
8317
  };
8315
- var escapeHtml = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
8316
8318
  var renderVoiceCallReviewHTML = (artifact) => {
8317
8319
  const notes = artifact.notes.map((note) => `<li>${escapeHtml(note)}</li>`).join("");
8318
8320
  const latency = artifact.latencyBreakdown.map((entry) => `<li><strong>${escapeHtml(entry.label)}:</strong> ${roundMetric4(entry.valueMs)}ms</li>`).join("");
@@ -9516,7 +9518,6 @@ var exportVoiceTrace = async (input) => {
9516
9518
  };
9517
9519
  };
9518
9520
  var toNumber = (value) => typeof value === "number" && Number.isFinite(value) ? value : 0;
9519
- var escapeHtml2 = (value) => value.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;");
9520
9521
  var formatTraceValue = (value) => {
9521
9522
  if (value === undefined || value === null) {
9522
9523
  return "";
@@ -9800,10 +9801,10 @@ var renderVoiceTraceHTML = (events, options = {}) => {
9800
9801
  const offset = summary.startedAt === undefined ? event.at : Math.max(0, event.at - summary.startedAt);
9801
9802
  return [
9802
9803
  "<tr>",
9803
- `<td>${escapeHtml2(String(offset))}</td>`,
9804
- `<td>${escapeHtml2(event.type)}</td>`,
9805
- `<td>${escapeHtml2(event.turnId ?? "")}</td>`,
9806
- `<td><code>${escapeHtml2(JSON.stringify(event.payload))}</code></td>`,
9804
+ `<td>${escapeHtml(String(offset))}</td>`,
9805
+ `<td>${escapeHtml(event.type)}</td>`,
9806
+ `<td>${escapeHtml(event.turnId ?? "")}</td>`,
9807
+ `<td><code>${escapeHtml(JSON.stringify(event.payload))}</code></td>`,
9807
9808
  "</tr>"
9808
9809
  ].join("");
9809
9810
  }).join(`
@@ -9814,7 +9815,7 @@ var renderVoiceTraceHTML = (events, options = {}) => {
9814
9815
  "<head>",
9815
9816
  '<meta charset="utf-8" />',
9816
9817
  '<meta name="viewport" content="width=device-width, initial-scale=1" />',
9817
- `<title>${escapeHtml2(options.title ?? "Voice Trace")}</title>`,
9818
+ `<title>${escapeHtml(options.title ?? "Voice Trace")}</title>`,
9818
9819
  "<style>",
9819
9820
  "body{font-family:ui-sans-serif,system-ui,sans-serif;margin:2rem;line-height:1.45;background:#f8f7f2;color:#181713}",
9820
9821
  "main{max-width:1100px;margin:auto}",
@@ -9828,7 +9829,7 @@ var renderVoiceTraceHTML = (events, options = {}) => {
9828
9829
  "</style>",
9829
9830
  "</head>",
9830
9831
  "<body><main>",
9831
- `<h1>${escapeHtml2(options.title ?? `Voice Trace ${summary.sessionId ?? ""}`.trim())}</h1>`,
9832
+ `<h1>${escapeHtml(options.title ?? `Voice Trace ${summary.sessionId ?? ""}`.trim())}</h1>`,
9832
9833
  `<p class="${evaluation.pass ? "pass" : "fail"}">QA: ${evaluation.pass ? "pass" : "fail"}</p>`,
9833
9834
  '<section class="summary">',
9834
9835
  `<div class="card"><strong>Events</strong><br>${summary.eventCount}</div>`,
@@ -9842,7 +9843,7 @@ var renderVoiceTraceHTML = (events, options = {}) => {
9842
9843
  eventRows,
9843
9844
  "</tbody></table>",
9844
9845
  "<h2>Markdown Export</h2>",
9845
- `<pre>${escapeHtml2(markdown)}</pre>`,
9846
+ `<pre>${escapeHtml(markdown)}</pre>`,
9846
9847
  "</main></body></html>"
9847
9848
  ].join(`
9848
9849
  `);
@@ -9856,7 +9857,6 @@ var buildVoiceTraceReplay = (events, options = {}) => ({
9856
9857
 
9857
9858
  // src/auditRoutes.ts
9858
9859
  import { Elysia } from "elysia";
9859
- var escapeHtml3 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
9860
9860
  var getString = (value) => typeof value === "string" && value.trim() ? value.trim() : undefined;
9861
9861
  var getNumber = (value) => {
9862
9862
  if (typeof value === "number" && Number.isFinite(value)) {
@@ -9954,14 +9954,14 @@ var buildVoiceAuditTrailReport = async (options) => {
9954
9954
  };
9955
9955
  var renderVoiceAuditTrailHTML = (report, options = {}) => {
9956
9956
  const title = options.title ?? "AbsoluteJS Voice Audit Trail";
9957
- const chips = report.summary.byType.map(([type, count]) => `<span>${escapeHtml3(type)} <strong>${count}</strong></span>`).join("");
9957
+ const chips = report.summary.byType.map(([type, count]) => `<span>${escapeHtml(type)} <strong>${count}</strong></span>`).join("");
9958
9958
  const rows = report.events.map((event) => {
9959
9959
  const actor = event.actor ? `${event.actor.kind}:${event.actor.id}` : "unknown";
9960
9960
  const resource = event.resource ? `${event.resource.type}${event.resource.id ? `:${event.resource.id}` : ""}` : "";
9961
9961
  const payload = event.payload ? JSON.stringify(event.payload, null, 2) : "";
9962
- return `<article class="event ${escapeHtml3(event.outcome ?? "unknown")}"><div><span>${escapeHtml3(event.type)}</span><h2>${escapeHtml3(event.action)}</h2><p>${escapeHtml3(new Date(event.at).toLocaleString())}</p><p>Actor: ${escapeHtml3(actor)}${resource ? ` \xB7 Resource: ${escapeHtml3(resource)}` : ""}</p>${event.sessionId ? `<p>Session: ${escapeHtml3(event.sessionId)}</p>` : ""}</div><strong>${escapeHtml3(event.outcome ?? "recorded")}</strong>${payload ? `<pre>${escapeHtml3(payload)}</pre>` : ""}</article>`;
9962
+ return `<article class="event ${escapeHtml(event.outcome ?? "unknown")}"><div><span>${escapeHtml(event.type)}</span><h2>${escapeHtml(event.action)}</h2><p>${escapeHtml(new Date(event.at).toLocaleString())}</p><p>Actor: ${escapeHtml(actor)}${resource ? ` \xB7 Resource: ${escapeHtml(resource)}` : ""}</p>${event.sessionId ? `<p>Session: ${escapeHtml(event.sessionId)}</p>` : ""}</div><strong>${escapeHtml(event.outcome ?? "recorded")}</strong>${payload ? `<pre>${escapeHtml(payload)}</pre>` : ""}</article>`;
9963
9963
  }).join("");
9964
- return `<!doctype html><html lang="en"><head><meta charset="utf-8" /><meta name="viewport" content="width=device-width, initial-scale=1" /><title>${escapeHtml3(title)}</title><style>body{background:#11140f;color:#f7f1df;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,.18),rgba(245,158,11,.12));border:1px solid #2c3327;border-radius:28px;margin-bottom:18px;padding:28px}.eyebrow{color:#facc15;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}.chips{display:flex;flex-wrap:wrap;gap:10px}.chips span{border:1px solid #46513b;border-radius:999px;padding:8px 12px}.events{display:grid;gap:14px}.event{background:#181d15;border:1px solid #2c3327;border-radius:22px;display:grid;gap:16px;grid-template-columns:1fr auto;padding:18px}.event.error{border-color:rgba(239,68,68,.75)}.event.skipped{border-color:rgba(245,158,11,.7)}.event.success{border-color:rgba(34,197,94,.55)}.event span{color:#facc15;font-size:.78rem;font-weight:900;letter-spacing:.08em;text-transform:uppercase}.event h2{margin:.2rem 0}.event p{color:#c8ccb8;margin:.2rem 0}.event strong{text-transform:uppercase}pre{background:#0c0f0a;border-radius:14px;grid-column:1/-1;overflow:auto;padding:14px;white-space:pre-wrap}@media(max-width:760px){main{padding:20px}.event{grid-template-columns:1fr}}</style></head><body><main><section class="hero"><p class="eyebrow">Self-hosted evidence</p><h1>${escapeHtml3(title)}</h1><p>${report.summary.total} event(s), ${report.summary.errors} error(s). Latest ${report.summary.latestAt ? escapeHtml3(new Date(report.summary.latestAt).toLocaleString()) : "never"}.</p><div class="chips">${chips}</div></section><section class="events">${rows || "<p>No audit events match this filter.</p>"}</section></main></body></html>`;
9964
+ return `<!doctype html><html lang="en"><head><meta charset="utf-8" /><meta name="viewport" content="width=device-width, initial-scale=1" /><title>${escapeHtml(title)}</title><style>body{background:#11140f;color:#f7f1df;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,.18),rgba(245,158,11,.12));border:1px solid #2c3327;border-radius:28px;margin-bottom:18px;padding:28px}.eyebrow{color:#facc15;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}.chips{display:flex;flex-wrap:wrap;gap:10px}.chips span{border:1px solid #46513b;border-radius:999px;padding:8px 12px}.events{display:grid;gap:14px}.event{background:#181d15;border:1px solid #2c3327;border-radius:22px;display:grid;gap:16px;grid-template-columns:1fr auto;padding:18px}.event.error{border-color:rgba(239,68,68,.75)}.event.skipped{border-color:rgba(245,158,11,.7)}.event.success{border-color:rgba(34,197,94,.55)}.event span{color:#facc15;font-size:.78rem;font-weight:900;letter-spacing:.08em;text-transform:uppercase}.event h2{margin:.2rem 0}.event p{color:#c8ccb8;margin:.2rem 0}.event strong{text-transform:uppercase}pre{background:#0c0f0a;border-radius:14px;grid-column:1/-1;overflow:auto;padding:14px;white-space:pre-wrap}@media(max-width:760px){main{padding:20px}.event{grid-template-columns:1fr}}</style></head><body><main><section class="hero"><p class="eyebrow">Self-hosted evidence</p><h1>${escapeHtml(title)}</h1><p>${report.summary.total} event(s), ${report.summary.errors} error(s). Latest ${report.summary.latestAt ? escapeHtml(new Date(report.summary.latestAt).toLocaleString()) : "never"}.</p><div class="chips">${chips}</div></section><section class="events">${rows || "<p>No audit events match this filter.</p>"}</section></main></body></html>`;
9965
9965
  };
9966
9966
  var createVoiceAuditTrailRoutes = (options) => {
9967
9967
  const path = options.path ?? "/api/voice-audit";
@@ -10053,7 +10053,6 @@ var createVoiceAuditTrailRoutes = (options) => {
10053
10053
  };
10054
10054
 
10055
10055
  // src/auditExport.ts
10056
- var escapeHtml4 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
10057
10056
  var normalizeRedactionKey2 = (key) => key.trim().toLowerCase().replace(/[^a-z0-9]/g, "");
10058
10057
  var resolveReplacement2 = (input) => typeof input.options.replacement === "function" ? input.options.replacement({
10059
10058
  key: input.key,
@@ -10171,8 +10170,8 @@ var renderVoiceAuditHTML = (events, options = {}) => {
10171
10170
  const markdown = renderVoiceAuditMarkdown(events, options);
10172
10171
  const renderEvents = options.redact ? redactVoiceAuditEvents(events, options.redact) : events;
10173
10172
  const summary = summarizeVoiceAuditTrail(renderEvents);
10174
- const rows = renderEvents.map((event) => `<tr><td>${escapeHtml4(new Date(event.at).toISOString())}</td><td>${escapeHtml4(event.type)}</td><td>${escapeHtml4(event.action)}</td><td>${escapeHtml4(event.outcome ?? "")}</td><td><code>${escapeHtml4(JSON.stringify(event.payload ?? {}))}</code></td></tr>`).join("");
10175
- return `<!doctype html><html lang="en"><head><meta charset="utf-8" /><meta name="viewport" content="width=device-width, initial-scale=1" /><title>${escapeHtml4(title)}</title><style>body{font-family:ui-sans-serif,system-ui,sans-serif;margin:2rem;line-height:1.45;background:#f8f7f2;color:#181713}main{max-width:1100px;margin:auto}.summary{display:grid;grid-template-columns:repeat(auto-fit,minmax(160px,1fr));gap:.75rem;margin:1rem 0}.card{background:white;border:1px solid #ded9cc;border-radius:12px;padding:1rem}table{border-collapse:collapse;width:100%;background:white;border:1px solid #ded9cc}th,td{border-bottom:1px solid #eee8dc;padding:.65rem;text-align:left;vertical-align:top}code{white-space:pre-wrap;word-break:break-word}pre{background:#181713;color:#f8f7f2;padding:1rem;border-radius:12px;overflow:auto}</style></head><body><main><h1>${escapeHtml4(title)}</h1><section class="summary"><div class="card"><strong>Events</strong><br>${summary.total}</div><div class="card"><strong>Errors</strong><br>${summary.errors}</div><div class="card"><strong>Latest</strong><br>${summary.latestAt ? escapeHtml4(new Date(summary.latestAt).toLocaleString()) : "never"}</div></section><table><thead><tr><th>At</th><th>Type</th><th>Action</th><th>Outcome</th><th>Payload</th></tr></thead><tbody>${rows}</tbody></table><h2>Markdown Export</h2><pre>${escapeHtml4(markdown)}</pre></main></body></html>`;
10173
+ const rows = renderEvents.map((event) => `<tr><td>${escapeHtml(new Date(event.at).toISOString())}</td><td>${escapeHtml(event.type)}</td><td>${escapeHtml(event.action)}</td><td>${escapeHtml(event.outcome ?? "")}</td><td><code>${escapeHtml(JSON.stringify(event.payload ?? {}))}</code></td></tr>`).join("");
10174
+ return `<!doctype html><html lang="en"><head><meta charset="utf-8" /><meta name="viewport" content="width=device-width, initial-scale=1" /><title>${escapeHtml(title)}</title><style>body{font-family:ui-sans-serif,system-ui,sans-serif;margin:2rem;line-height:1.45;background:#f8f7f2;color:#181713}main{max-width:1100px;margin:auto}.summary{display:grid;grid-template-columns:repeat(auto-fit,minmax(160px,1fr));gap:.75rem;margin:1rem 0}.card{background:white;border:1px solid #ded9cc;border-radius:12px;padding:1rem}table{border-collapse:collapse;width:100%;background:white;border:1px solid #ded9cc}th,td{border-bottom:1px solid #eee8dc;padding:.65rem;text-align:left;vertical-align:top}code{white-space:pre-wrap;word-break:break-word}pre{background:#181713;color:#f8f7f2;padding:1rem;border-radius:12px;overflow:auto}</style></head><body><main><h1>${escapeHtml(title)}</h1><section class="summary"><div class="card"><strong>Events</strong><br>${summary.total}</div><div class="card"><strong>Errors</strong><br>${summary.errors}</div><div class="card"><strong>Latest</strong><br>${summary.latestAt ? escapeHtml(new Date(summary.latestAt).toLocaleString()) : "never"}</div></section><table><thead><tr><th>At</th><th>Type</th><th>Action</th><th>Outcome</th><th>Payload</th></tr></thead><tbody>${rows}</tbody></table><h2>Markdown Export</h2><pre>${escapeHtml(markdown)}</pre></main></body></html>`;
10176
10175
  };
10177
10176
  var buildVoiceAuditExport = (events, options = {}) => {
10178
10177
  const exportEvents = options.redact ? redactVoiceAuditEvents(events, options.redact) : events;
@@ -10187,7 +10186,6 @@ var buildVoiceAuditExport = (events, options = {}) => {
10187
10186
  // src/sessionReplay.ts
10188
10187
  import { Elysia as Elysia2 } from "elysia";
10189
10188
  var getString2 = (value) => typeof value === "string" ? value : undefined;
10190
- var escapeHtml5 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
10191
10189
  var increment2 = (record, key) => {
10192
10190
  record[key] = (record[key] ?? 0) + 1;
10193
10191
  };
@@ -10384,10 +10382,10 @@ var summarizeVoiceSessions = async (options = {}) => {
10384
10382
  var renderVoiceSessionsHTML = (sessions) => sessions.length === 0 ? '<p class="voice-sessions-empty">No voice sessions found.</p>' : [
10385
10383
  '<div class="voice-sessions-list">',
10386
10384
  ...sessions.map((session) => [
10387
- `<article class="voice-session-card ${escapeHtml5(session.status)}">`,
10385
+ `<article class="voice-session-card ${escapeHtml(session.status)}">`,
10388
10386
  '<div class="voice-session-card-header">',
10389
- `<strong>${escapeHtml5(session.sessionId)}</strong>`,
10390
- `<span>${escapeHtml5(session.status)}</span>`,
10387
+ `<strong>${escapeHtml(session.sessionId)}</strong>`,
10388
+ `<span>${escapeHtml(session.status)}</span>`,
10391
10389
  "</div>",
10392
10390
  "<dl>",
10393
10391
  `<div><dt>Events</dt><dd>${String(session.eventCount)}</dd></div>`,
@@ -10395,9 +10393,9 @@ var renderVoiceSessionsHTML = (sessions) => sessions.length === 0 ? '<p class="v
10395
10393
  `<div><dt>Transcripts</dt><dd>${String(session.transcriptCount)}</dd></div>`,
10396
10394
  `<div><dt>Errors</dt><dd>${String(session.errorCount)}</dd></div>`,
10397
10395
  "</dl>",
10398
- session.latestOutcome ? `<p>Outcome: ${escapeHtml5(session.latestOutcome)}</p>` : "",
10399
- session.providers.length ? `<p>Providers: ${session.providers.map(escapeHtml5).join(", ")}</p>` : "",
10400
- session.replayHref ? `<p>${session.operationsRecordHref ? `<a href="${escapeHtml5(session.operationsRecordHref)}">Open operations record</a> \xB7 ` : ""}<a href="${escapeHtml5(session.replayHref)}">Open replay</a></p>` : "",
10396
+ session.latestOutcome ? `<p>Outcome: ${escapeHtml(session.latestOutcome)}</p>` : "",
10397
+ session.providers.length ? `<p>Providers: ${session.providers.map(escapeHtml).join(", ")}</p>` : "",
10398
+ session.replayHref ? `<p>${session.operationsRecordHref ? `<a href="${escapeHtml(session.operationsRecordHref)}">Open operations record</a> \xB7 ` : ""}<a href="${escapeHtml(session.replayHref)}">Open replay</a></p>` : "",
10401
10399
  "</article>"
10402
10400
  ].join("")),
10403
10401
  "</div>"
@@ -10467,7 +10465,6 @@ var createVoiceSessionReplayRoutes = (options) => {
10467
10465
 
10468
10466
  // src/traceTimeline.ts
10469
10467
  import { Elysia as Elysia3 } from "elysia";
10470
- var escapeHtml6 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
10471
10468
  var getString3 = (value) => typeof value === "string" && value.trim() ? value : undefined;
10472
10469
  var getNumber2 = (value) => typeof value === "number" && Number.isFinite(value) ? value : undefined;
10473
10470
  var firstString = (payload, keys) => {
@@ -10653,17 +10650,17 @@ var summarizeVoiceTraceTimeline = (events, options = {}) => {
10653
10650
  };
10654
10651
  };
10655
10652
  var formatMs = (value) => value === undefined ? "n/a" : `${String(value)}ms`;
10656
- var renderProviderCards = (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>${escapeHtml6(provider.provider)}</strong><dl><div><dt>Events</dt><dd>${String(provider.eventCount)}</dd></div><div><dt>Avg</dt><dd>${formatMs(provider.averageElapsedMs)}</dd></div><div><dt>Max</dt><dd>${formatMs(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>`;
10653
+ var renderProviderCards = (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>${escapeHtml(provider.provider)}</strong><dl><div><dt>Events</dt><dd>${String(provider.eventCount)}</dd></div><div><dt>Avg</dt><dd>${formatMs(provider.averageElapsedMs)}</dd></div><div><dt>Max</dt><dd>${formatMs(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>`;
10657
10654
  var renderVoiceTraceTimelineSessionHTML = (session, options = {}) => {
10658
- const events = session.events.map((event) => `<tr class="${escapeHtml6(event.status ?? "")}"><td>+${String(event.offsetMs)}ms</td><td>${escapeHtml6(event.type)}</td><td>${escapeHtml6(event.label)}</td><td>${escapeHtml6(event.provider ?? "")}</td><td>${escapeHtml6(event.status ?? "")}</td><td>${formatMs(event.elapsedMs)}</td></tr>`).join("");
10659
- const issues = session.evaluation.issues.length ? session.evaluation.issues.map((issue) => `<li class="${escapeHtml6(issue.severity)}">${escapeHtml6(issue.code)}: ${escapeHtml6(issue.message)}</li>`).join("") : "<li>none</li>";
10660
- const supportLinks = session.operationsRecordHref ? `<p><a href="${escapeHtml6(session.operationsRecordHref)}">Open operations record</a></p>` : "";
10661
- return `<!doctype html><html lang="en"><head><meta charset="utf-8" /><meta name="viewport" content="width=device-width, initial-scale=1" /><title>${escapeHtml6(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>${escapeHtml6(session.sessionId)}</h1><p class="status ${escapeHtml6(session.status)}">${escapeHtml6(session.status)}</p>${supportLinks}</header><section class="metrics"><article><span>Events</span><strong>${String(session.summary.eventCount)}</strong></article><article><span>Turns</span><strong>${String(session.summary.turnCount)}</strong></article><article><span>Errors</span><strong>${String(session.summary.errorCount)}</strong></article><article><span>Duration</span><strong>${formatMs(session.summary.callDurationMs)}</strong></article></section><section><h2>Providers</h2>${renderProviderCards(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>`;
10655
+ const events = session.events.map((event) => `<tr class="${escapeHtml(event.status ?? "")}"><td>+${String(event.offsetMs)}ms</td><td>${escapeHtml(event.type)}</td><td>${escapeHtml(event.label)}</td><td>${escapeHtml(event.provider ?? "")}</td><td>${escapeHtml(event.status ?? "")}</td><td>${formatMs(event.elapsedMs)}</td></tr>`).join("");
10656
+ const issues = session.evaluation.issues.length ? session.evaluation.issues.map((issue) => `<li class="${escapeHtml(issue.severity)}">${escapeHtml(issue.code)}: ${escapeHtml(issue.message)}</li>`).join("") : "<li>none</li>";
10657
+ const supportLinks = session.operationsRecordHref ? `<p><a href="${escapeHtml(session.operationsRecordHref)}">Open operations record</a></p>` : "";
10658
+ return `<!doctype html><html lang="en"><head><meta charset="utf-8" /><meta name="viewport" content="width=device-width, initial-scale=1" /><title>${escapeHtml(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>${escapeHtml(session.sessionId)}</h1><p class="status ${escapeHtml(session.status)}">${escapeHtml(session.status)}</p>${supportLinks}</header><section class="metrics"><article><span>Events</span><strong>${String(session.summary.eventCount)}</strong></article><article><span>Turns</span><strong>${String(session.summary.turnCount)}</strong></article><article><span>Errors</span><strong>${String(session.summary.errorCount)}</strong></article><article><span>Duration</span><strong>${formatMs(session.summary.callDurationMs)}</strong></article></section><section><h2>Providers</h2>${renderProviderCards(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>`;
10662
10659
  };
10663
- var renderSessionRows = (report) => report.sessions.length === 0 ? '<tr><td colspan="7">No trace events recorded yet.</td></tr>' : report.sessions.map((session) => `<tr class="${escapeHtml6(session.status)}"><td>${session.operationsRecordHref ? `<a href="${escapeHtml6(session.operationsRecordHref)}">${escapeHtml6(session.sessionId)}</a>` : `<a href="/traces/${encodeURIComponent(session.sessionId)}">${escapeHtml6(session.sessionId)}</a>`}</td><td>${escapeHtml6(session.status)}</td><td>${String(session.summary.eventCount)}</td><td>${String(session.summary.turnCount)}</td><td>${String(session.summary.errorCount)}</td><td>${formatMs(session.summary.callDurationMs)}</td><td>${session.providers.map((provider) => escapeHtml6(provider.provider)).join(", ")}</td></tr>`).join("");
10660
+ var renderSessionRows = (report) => report.sessions.length === 0 ? '<tr><td colspan="7">No trace events recorded yet.</td></tr>' : report.sessions.map((session) => `<tr class="${escapeHtml(session.status)}"><td>${session.operationsRecordHref ? `<a href="${escapeHtml(session.operationsRecordHref)}">${escapeHtml(session.sessionId)}</a>` : `<a href="/traces/${encodeURIComponent(session.sessionId)}">${escapeHtml(session.sessionId)}</a>`}</td><td>${escapeHtml(session.status)}</td><td>${String(session.summary.eventCount)}</td><td>${String(session.summary.turnCount)}</td><td>${String(session.summary.errorCount)}</td><td>${formatMs(session.summary.callDurationMs)}</td><td>${session.providers.map((provider) => escapeHtml(provider.provider)).join(", ")}</td></tr>`).join("");
10664
10661
  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}}";
10665
10662
  var renderVoiceTraceTimelineHTML = (report, options = {}) => {
10666
- const snippet = escapeHtml6(`const traceStore = createVoiceTraceSinkStore({
10663
+ const snippet = escapeHtml(`const traceStore = createVoiceTraceSinkStore({
10667
10664
  store: runtimeStorage.traces,
10668
10665
  sinks: [
10669
10666
  createVoiceTraceHTTPSink({
@@ -10689,7 +10686,7 @@ app.use(
10689
10686
  traceDeliveries: runtimeStorage.traceDeliveries
10690
10687
  })
10691
10688
  );`);
10692
- return `<!doctype html><html lang="en"><head><meta charset="utf-8" /><meta name="viewport" content="width=device-width, initial-scale=1" /><title>${escapeHtml6(options.title ?? "Voice Trace Timelines")}</title><style>${timelineCSS}.primitive{background:#181f27;border:1px solid #334155;border-radius:20px;margin:20px 0;padding:18px}.primitive p{line-height:1.55}.primitive pre{background:#0b1118;border:1px solid #2b3642;border-radius:16px;color:#dbeafe;overflow:auto;padding:14px}.primitive code{color:#bfdbfe}</style></head><body><main><header><p class="eyebrow">Self-hosted voice debugging</p><h1>${escapeHtml6(options.title ?? "Voice Trace Timelines")}</h1><p class="muted">Per-call event timelines with provider latency, fallback, timeout, handoff, and error context.</p></header><section class="metrics"><article><span>Sessions</span><strong>${String(report.total)}</strong></article><article><span>Failed</span><strong>${String(report.failed)}</strong></article><article><span>Warnings</span><strong>${String(report.warnings)}</strong></article></section><section class="primitive"><p class="eyebrow">Copy into your app</p><h2><code>createVoiceTraceTimelineRoutes(...)</code> makes traces the proof backbone</h2><p class="muted">Mount trace timelines from the same trace store used by readiness, simulations, provider recovery, delivery sinks, and phone-agent smoke proof.</p><pre><code>${snippet}</code></pre></section><table><thead><tr><th>Session</th><th>Status</th><th>Events</th><th>Turns</th><th>Errors</th><th>Duration</th><th>Providers</th></tr></thead><tbody>${renderSessionRows(report)}</tbody></table></main></body></html>`;
10689
+ return `<!doctype html><html lang="en"><head><meta charset="utf-8" /><meta name="viewport" content="width=device-width, initial-scale=1" /><title>${escapeHtml(options.title ?? "Voice Trace Timelines")}</title><style>${timelineCSS}.primitive{background:#181f27;border:1px solid #334155;border-radius:20px;margin:20px 0;padding:18px}.primitive p{line-height:1.55}.primitive pre{background:#0b1118;border:1px solid #2b3642;border-radius:16px;color:#dbeafe;overflow:auto;padding:14px}.primitive code{color:#bfdbfe}</style></head><body><main><header><p class="eyebrow">Self-hosted voice debugging</p><h1>${escapeHtml(options.title ?? "Voice Trace Timelines")}</h1><p class="muted">Per-call event timelines with provider latency, fallback, timeout, handoff, and error context.</p></header><section class="metrics"><article><span>Sessions</span><strong>${String(report.total)}</strong></article><article><span>Failed</span><strong>${String(report.failed)}</strong></article><article><span>Warnings</span><strong>${String(report.warnings)}</strong></article></section><section class="primitive"><p class="eyebrow">Copy into your app</p><h2><code>createVoiceTraceTimelineRoutes(...)</code> makes traces the proof backbone</h2><p class="muted">Mount trace timelines from the same trace store used by readiness, simulations, provider recovery, delivery sinks, and phone-agent smoke proof.</p><pre><code>${snippet}</code></pre></section><table><thead><tr><th>Session</th><th>Status</th><th>Events</th><th>Turns</th><th>Errors</th><th>Duration</th><th>Providers</th></tr></thead><tbody>${renderSessionRows(report)}</tbody></table></main></body></html>`;
10693
10690
  };
10694
10691
  var createVoiceTraceTimelineRoutes = (options) => {
10695
10692
  const path = options.path ?? "/api/voice-traces";
@@ -11359,7 +11356,6 @@ var renderVoiceFailureReplayMarkdown = (report) => {
11359
11356
  ].join(`
11360
11357
  `);
11361
11358
  };
11362
- var escapeHtml7 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
11363
11359
  var formatMs2 = (value) => value === undefined ? "n/a" : `${String(value)}ms`;
11364
11360
  var outcomeLabels = (outcome) => [
11365
11361
  outcome.complete ? "complete" : undefined,
@@ -11485,18 +11481,18 @@ var renderVoiceOperationsRecordGuardrailMarkdown = (record) => {
11485
11481
  `);
11486
11482
  };
11487
11483
  var renderVoiceOperationsRecordHTML = (record, options = {}) => {
11488
- const providers = record.providers.length ? record.providers.map((provider) => `<article><strong>${escapeHtml7(provider.provider)}</strong><span>${String(provider.eventCount)} events</span><span>${formatMs2(provider.averageElapsedMs)} avg</span><span>${String(provider.errorCount)} errors</span></article>`).join("") : '<p class="muted">No provider events recorded.</p>';
11489
- const transcript = record.transcript.length ? record.transcript.map((turn) => `<li><strong>${escapeHtml7(turn.id)}</strong>${turn.committedText ? `<p><span class="label">Caller</span>${escapeHtml7(turn.committedText)}</p>` : ""}${turn.assistantReplies.map((reply) => `<p><span class="label">Assistant</span>${escapeHtml7(reply)}</p>`).join("")}${turn.errors.map((error) => `<p class="error"><span class="label">Error</span>${escapeHtml7(error)}</p>`).join("")}</li>`).join("") : "<li>No transcript turns recorded.</li>";
11490
- const providerDecisions = record.providerDecisions.length ? record.providerDecisions.map((decision) => `<li><strong>${escapeHtml7(decision.provider ?? decision.selectedProvider ?? decision.fallbackProvider ?? "provider")}</strong> <span>${escapeHtml7(decision.status ?? decision.type)}</span> ${formatMs2(decision.elapsedMs)}${decision.surface ? `<p><span class="label">Surface</span>${escapeHtml7(decision.surface)}</p>` : ""}${decision.kind ? `<p><span class="label">Kind</span>${escapeHtml7(decision.kind)}</p>` : ""}${decision.selectedProvider ? `<p>Selected: ${escapeHtml7(decision.selectedProvider)}</p>` : ""}${decision.fallbackProvider ? `<p>Fallback: ${escapeHtml7(decision.fallbackProvider)}</p>` : ""}${decision.error ? `<p class="error">${escapeHtml7(decision.error)}</p>` : ""}${decision.reason ? `<p>${escapeHtml7(decision.reason)}</p>` : ""}</li>`).join("") : "<li>No provider decisions recorded.</li>";
11484
+ const providers = record.providers.length ? record.providers.map((provider) => `<article><strong>${escapeHtml(provider.provider)}</strong><span>${String(provider.eventCount)} events</span><span>${formatMs2(provider.averageElapsedMs)} avg</span><span>${String(provider.errorCount)} errors</span></article>`).join("") : '<p class="muted">No provider events recorded.</p>';
11485
+ const transcript = record.transcript.length ? record.transcript.map((turn) => `<li><strong>${escapeHtml(turn.id)}</strong>${turn.committedText ? `<p><span class="label">Caller</span>${escapeHtml(turn.committedText)}</p>` : ""}${turn.assistantReplies.map((reply) => `<p><span class="label">Assistant</span>${escapeHtml(reply)}</p>`).join("")}${turn.errors.map((error) => `<p class="error"><span class="label">Error</span>${escapeHtml(error)}</p>`).join("")}</li>`).join("") : "<li>No transcript turns recorded.</li>";
11486
+ const providerDecisions = record.providerDecisions.length ? record.providerDecisions.map((decision) => `<li><strong>${escapeHtml(decision.provider ?? decision.selectedProvider ?? decision.fallbackProvider ?? "provider")}</strong> <span>${escapeHtml(decision.status ?? decision.type)}</span> ${formatMs2(decision.elapsedMs)}${decision.surface ? `<p><span class="label">Surface</span>${escapeHtml(decision.surface)}</p>` : ""}${decision.kind ? `<p><span class="label">Kind</span>${escapeHtml(decision.kind)}</p>` : ""}${decision.selectedProvider ? `<p>Selected: ${escapeHtml(decision.selectedProvider)}</p>` : ""}${decision.fallbackProvider ? `<p>Fallback: ${escapeHtml(decision.fallbackProvider)}</p>` : ""}${decision.error ? `<p class="error">${escapeHtml(decision.error)}</p>` : ""}${decision.reason ? `<p>${escapeHtml(decision.reason)}</p>` : ""}</li>`).join("") : "<li>No provider decisions recorded.</li>";
11491
11487
  const providerDecisionSummary = record.providerDecisionSummary;
11492
- const handoffs = record.handoffs.length ? record.handoffs.map((handoff) => `<li><strong>${escapeHtml7(handoff.fromAgentId ?? "unknown")}</strong> to <strong>${escapeHtml7(handoff.targetAgentId ?? "unknown")}</strong> <span>${escapeHtml7(handoff.status ?? "")}</span><p>${escapeHtml7(handoff.summary ?? handoff.reason ?? "")}</p></li>`).join("") : "<li>No agent handoffs recorded.</li>";
11493
- const tools = record.tools.length ? record.tools.map((tool) => `<li><strong>${escapeHtml7(tool.toolName ?? "tool")}</strong> <span>${escapeHtml7(tool.status ?? "")}</span> ${formatMs2(tool.elapsedMs)} ${tool.error ? `<p>${escapeHtml7(tool.error)}</p>` : ""}</li>`).join("") : "<li>No tool calls recorded.</li>";
11494
- const reviews = record.reviews?.reviews.length ? record.reviews.reviews.map((review) => `<li><strong>${escapeHtml7(review.title)}</strong> <span>${escapeHtml7(review.summary.outcome ?? "")}</span><p>${escapeHtml7(review.postCall?.summary ?? review.transcript.actual)}</p></li>`).join("") : "<li>No call reviews recorded.</li>";
11495
- const tasks = record.tasks?.tasks.length ? record.tasks.tasks.map((task) => `<li><strong>${escapeHtml7(task.title)}</strong> <span>${escapeHtml7(task.status)}</span><p>${escapeHtml7(task.recommendedAction)}</p></li>`).join("") : "<li>No ops tasks recorded.</li>";
11496
- const integrationEvents = record.integrationEvents?.events.length ? record.integrationEvents.events.map((event) => `<li><strong>${escapeHtml7(event.type)}</strong> <span>${escapeHtml7(event.deliveryStatus ?? "local")}</span><p>${escapeHtml7(event.deliveryError ?? event.deliveredTo ?? "")}</p></li>`).join("") : "<li>No integration events recorded.</li>";
11488
+ const handoffs = record.handoffs.length ? record.handoffs.map((handoff) => `<li><strong>${escapeHtml(handoff.fromAgentId ?? "unknown")}</strong> to <strong>${escapeHtml(handoff.targetAgentId ?? "unknown")}</strong> <span>${escapeHtml(handoff.status ?? "")}</span><p>${escapeHtml(handoff.summary ?? handoff.reason ?? "")}</p></li>`).join("") : "<li>No agent handoffs recorded.</li>";
11489
+ const tools = record.tools.length ? record.tools.map((tool) => `<li><strong>${escapeHtml(tool.toolName ?? "tool")}</strong> <span>${escapeHtml(tool.status ?? "")}</span> ${formatMs2(tool.elapsedMs)} ${tool.error ? `<p>${escapeHtml(tool.error)}</p>` : ""}</li>`).join("") : "<li>No tool calls recorded.</li>";
11490
+ const reviews = record.reviews?.reviews.length ? record.reviews.reviews.map((review) => `<li><strong>${escapeHtml(review.title)}</strong> <span>${escapeHtml(review.summary.outcome ?? "")}</span><p>${escapeHtml(review.postCall?.summary ?? review.transcript.actual)}</p></li>`).join("") : "<li>No call reviews recorded.</li>";
11491
+ const tasks = record.tasks?.tasks.length ? record.tasks.tasks.map((task) => `<li><strong>${escapeHtml(task.title)}</strong> <span>${escapeHtml(task.status)}</span><p>${escapeHtml(task.recommendedAction)}</p></li>`).join("") : "<li>No ops tasks recorded.</li>";
11492
+ const integrationEvents = record.integrationEvents?.events.length ? record.integrationEvents.events.map((event) => `<li><strong>${escapeHtml(event.type)}</strong> <span>${escapeHtml(event.deliveryStatus ?? "local")}</span><p>${escapeHtml(event.deliveryError ?? event.deliveredTo ?? "")}</p></li>`).join("") : "<li>No integration events recorded.</li>";
11497
11493
  const guardrails = record.guardrails.total ? record.guardrails.decisions.map((decision) => {
11498
11494
  const findings = decision.findings.map((finding) => finding.label ?? finding.ruleId ?? finding.action).filter((value) => typeof value === "string").join(", ") || "none";
11499
- return `<li><strong>assistant.guardrail ${escapeHtml7(decision.stage ?? "unknown")}</strong> <span>${escapeHtml7(decision.status ?? "")}</span><p>Allowed: ${escapeHtml7(String(decision.allowed ?? "unknown"))} \xB7 Proof: ${escapeHtml7(decision.proof ?? "runtime")}${decision.turnId ? ` \xB7 Turn: ${escapeHtml7(decision.turnId)}` : ""}</p><p>${escapeHtml7(findings)}</p></li>`;
11495
+ return `<li><strong>assistant.guardrail ${escapeHtml(decision.stage ?? "unknown")}</strong> <span>${escapeHtml(decision.status ?? "")}</span><p>Allowed: ${escapeHtml(String(decision.allowed ?? "unknown"))} \xB7 Proof: ${escapeHtml(decision.proof ?? "runtime")}${decision.turnId ? ` \xB7 Turn: ${escapeHtml(decision.turnId)}` : ""}</p><p>${escapeHtml(findings)}</p></li>`;
11500
11496
  }).join("") : "<li>No assistant.guardrail events recorded.</li>";
11501
11497
  const telephonyMedia = record.telephonyMedia.events.length ? record.telephonyMedia.events.slice(0, 50).map((event) => {
11502
11498
  const details = [
@@ -11507,12 +11503,12 @@ var renderVoiceOperationsRecordHTML = (record, options = {}) => {
11507
11503
  event.sequenceNumber ? `Seq: ${event.sequenceNumber}` : undefined,
11508
11504
  `Audio bytes: ${String(event.audioBytes)}`
11509
11505
  ].filter((detail) => typeof detail === "string");
11510
- return `<li><strong>${escapeHtml7(event.event)}</strong> <span>${escapeHtml7(new Date(event.at).toLocaleString())}</span><p>${escapeHtml7(details.join(" \xB7 "))}</p></li>`;
11506
+ return `<li><strong>${escapeHtml(event.event)}</strong> <span>${escapeHtml(new Date(event.at).toLocaleString())}</span><p>${escapeHtml(details.join(" \xB7 "))}</p></li>`;
11511
11507
  }).join("") : "<li>No telephony media trace events recorded.</li>";
11512
- const mediaPipelineSection = record.mediaPipeline ? `<section id="media-pipeline"><h2>Media Pipeline</h2><p class="muted">Surface: ${escapeHtml7(record.mediaPipeline.surface)} \xB7 Status: ${escapeHtml7(record.mediaPipeline.status)} \xB7 Quality: ${escapeHtml7(record.mediaPipeline.qualityStatus)} \xB7 Transport: ${escapeHtml7(record.mediaPipeline.transportStatus ?? "n/a")} \xB7 Graph: ${escapeHtml7(record.mediaPipeline.processorGraphStatus ?? "n/a")} \xB7 Frames: ${String(record.mediaPipeline.frames)} \xB7 Jitter: ${record.mediaPipeline.jitterMs === undefined ? "n/a" : `${String(record.mediaPipeline.jitterMs)}ms`}</p><ul>${record.mediaPipeline.issueCodes.length ? record.mediaPipeline.issueCodes.map((code) => `<li><strong>${escapeHtml7(code)}</strong></li>`).join("") : "<li>No media pipeline issue codes.</li>"}</ul></section>` : "";
11513
- const mediaPipelineCard = record.mediaPipeline ? `<div class="card"><span>Media pipeline</span><strong>${escapeHtml7(record.mediaPipeline.status)}</strong><span>${String(record.mediaPipeline.issueCodes.length)} issue code(s)</span></div>` : "";
11508
+ const mediaPipelineSection = record.mediaPipeline ? `<section id="media-pipeline"><h2>Media Pipeline</h2><p class="muted">Surface: ${escapeHtml(record.mediaPipeline.surface)} \xB7 Status: ${escapeHtml(record.mediaPipeline.status)} \xB7 Quality: ${escapeHtml(record.mediaPipeline.qualityStatus)} \xB7 Transport: ${escapeHtml(record.mediaPipeline.transportStatus ?? "n/a")} \xB7 Graph: ${escapeHtml(record.mediaPipeline.processorGraphStatus ?? "n/a")} \xB7 Frames: ${String(record.mediaPipeline.frames)} \xB7 Jitter: ${record.mediaPipeline.jitterMs === undefined ? "n/a" : `${String(record.mediaPipeline.jitterMs)}ms`}</p><ul>${record.mediaPipeline.issueCodes.length ? record.mediaPipeline.issueCodes.map((code) => `<li><strong>${escapeHtml(code)}</strong></li>`).join("") : "<li>No media pipeline issue codes.</li>"}</ul></section>` : "";
11509
+ const mediaPipelineCard = record.mediaPipeline ? `<div class="card"><span>Media pipeline</span><strong>${escapeHtml(record.mediaPipeline.status)}</strong><span>${String(record.mediaPipeline.issueCodes.length)} issue code(s)</span></div>` : "";
11514
11510
  const mediaPipelineNavLink = record.mediaPipeline ? '<a href="#media-pipeline">Media pipeline</a>' : "";
11515
- const snippet = escapeHtml7(`app.use(
11511
+ const snippet = escapeHtml(`app.use(
11516
11512
  createVoiceOperationsRecordRoutes({
11517
11513
  audit: auditStore,
11518
11514
  integrationEvents: opsEvents,
@@ -11526,9 +11522,9 @@ var renderVoiceOperationsRecordHTML = (record, options = {}) => {
11526
11522
  tasks: opsTasks
11527
11523
  })
11528
11524
  );`);
11529
- const incidentMarkdown = escapeHtml7(renderVoiceOperationsRecordIncidentMarkdown(record));
11530
- const incidentLink = options.incidentHref ? `<a href="${escapeHtml7(options.incidentHref)}">Download incident.md</a>` : "";
11531
- return `<!doctype html><html lang="en"><head><meta charset="utf-8" /><meta name="viewport" content="width=device-width, initial-scale=1" /><title>${escapeHtml7(options.title ?? "Voice Operations Record")}</title><style>body{background:#101417;color:#f9f4e8;font-family:ui-sans-serif,system-ui,sans-serif;margin:0}main{margin:auto;max-width:1120px;padding:32px}.eyebrow{color:#fbbf24;font-size:.8rem;font-weight:900;letter-spacing:.14em;text-transform:uppercase}h1{font-size:clamp(2.4rem,6vw,4.8rem);line-height:.9;margin:.2rem 0 1rem}.status{border:1px solid #475569;border-radius:999px;display:inline-flex;padding:8px 12px}.healthy{color:#86efac}.warning{color:#fbbf24}.failed,.error{color:#fca5a5}.grid{display:grid;gap:14px;grid-template-columns:repeat(auto-fit,minmax(180px,1fr));margin:20px 0}.card,.primitive{background:#182025;border:1px solid #2d3a43;border-radius:20px;padding:16px}.card span,.muted,.label{color:#a9b4bd}.label{display:block;font-size:.72rem;font-weight:900;letter-spacing:.12em;text-transform:uppercase}.card strong{display:block;font-size:2rem}section{margin-top:28px}article{display:grid;gap:8px}ul{display:grid;gap:10px;list-style:none;padding:0}li{background:#182025;border:1px solid #2d3a43;border-radius:16px;padding:14px}pre{background:#080d10;border:1px solid #2d3a43;border-radius:16px;color:#dbeafe;overflow:auto;padding:14px}.hero-actions{display:flex;flex-wrap:wrap;gap:10px;margin-top:16px}.hero-actions a{background:#fbbf24;border-radius:999px;color:#111827;font-weight:900;padding:10px 14px;text-decoration:none}.two-column{display:grid;gap:18px;grid-template-columns:minmax(0,1.15fr) minmax(280px,.85fr)}@media(max-width:860px){main{padding:20px}.two-column{grid-template-columns:1fr}}</style></head><body><main><p class="eyebrow">Call log replacement</p><h1>${escapeHtml7(options.title ?? "Voice Operations Record")}</h1><p class="status ${escapeHtml7(record.status)}">${escapeHtml7(record.status)}</p><div class="hero-actions"><a href="#transcript">Transcript</a><a href="#provider-decisions">Provider decisions</a><a href="#telephony-media">Telephony media</a>${mediaPipelineNavLink}<a href="#guardrails">Guardrails</a><a href="#incident-handoff">Incident handoff</a>${incidentLink}</div><section class="grid"><div class="card"><span>Events</span><strong>${String(record.summary.eventCount)}</strong></div><div class="card"><span>Turns</span><strong>${String(record.summary.turnCount)}</strong></div><div class="card"><span>Errors</span><strong>${String(record.summary.errorCount)}</strong></div><div class="card"><span>Duration</span><strong>${formatMs2(record.summary.callDurationMs)}</strong></div><div class="card"><span>Provider recovery</span><strong>${escapeHtml7(providerDecisionSummary.recoveryStatus)}</strong><span>${String(providerDecisionSummary.fallbacks)} fallback / ${String(providerDecisionSummary.degraded)} degraded / ${String(providerDecisionSummary.errors)} errors</span></div><div class="card"><span>Telephony media</span><strong>${String(record.telephonyMedia.media)}</strong><span>${String(record.telephonyMedia.inbound)} inbound / ${String(record.telephonyMedia.outbound)} outbound / ${String(record.telephonyMedia.clears)} clears</span></div><div class="card"><span>Guardrails</span><strong>${String(record.guardrails.blocked)}</strong></div><div class="card"><span>Audit</span><strong>${String(record.audit?.total ?? 0)}</strong></div><div class="card"><span>Reviews</span><strong>${String(record.reviews?.total ?? 0)}</strong></div><div class="card"><span>Tasks</span><strong>${String(record.tasks?.total ?? 0)}</strong></div><div class="card"><span>Integrations</span><strong>${String(record.integrationEvents?.total ?? 0)}</strong></div>${mediaPipelineCard}</section><section class="two-column"><div><h2 id="transcript">Transcript</h2><ul>${transcript}</ul></div><div><h2 id="provider-decisions">Provider Decisions</h2><ul>${providerDecisions}</ul></div></section><section id="telephony-media"><h2>Telephony Media</h2><p class="muted">Live <code>client.telephony_media</code> stream lifecycle evidence attached to this session. Carriers: ${escapeHtml7(record.telephonyMedia.carriers.join(", ") || "none")}. Streams: ${escapeHtml7(record.telephonyMedia.streamIds.join(", ") || "none")}. Inbound: ${String(record.telephonyMedia.inbound)}. Outbound: ${String(record.telephonyMedia.outbound)}. Marks: ${String(record.telephonyMedia.marks)}. Clears: ${String(record.telephonyMedia.clears)}.</p><ul>${telephonyMedia}</ul></section>${mediaPipelineSection}<section id="guardrails"><h2>Guardrail Evidence</h2><p class="muted">Live <code>assistant.guardrail</code> decisions attached to this session.</p><ul>${guardrails}</ul></section><section id="incident-handoff"><h2>Copyable Incident Handoff</h2><p class="muted">Paste this into Slack, Linear, Zendesk, or an incident review. ${incidentLink}</p><pre><code>${incidentMarkdown}</code></pre></section><section class="primitive"><p class="eyebrow">Copy into your app</p><h2><code>createVoiceOperationsRecordRoutes(...)</code> gives every call one debuggable object</h2><p class="muted">Use this as the support/debug payload across traces, provider routing, tools, handoffs, guardrails, audit, latency, replay, reviews, tasks, media streams, and webhook delivery.</p><pre><code>${snippet}</code></pre></section><section><h2>Provider Summary</h2><div class="grid">${providers}</div></section><section><h2>Handoffs</h2><ul>${handoffs}</ul></section><section><h2>Tools</h2><ul>${tools}</ul></section><section><h2>Reviews</h2><ul>${reviews}</ul></section><section><h2>Tasks</h2><ul>${tasks}</ul></section><section><h2>Integration Events</h2><ul>${integrationEvents}</ul></section></main></body></html>`;
11525
+ const incidentMarkdown = escapeHtml(renderVoiceOperationsRecordIncidentMarkdown(record));
11526
+ const incidentLink = options.incidentHref ? `<a href="${escapeHtml(options.incidentHref)}">Download incident.md</a>` : "";
11527
+ return `<!doctype html><html lang="en"><head><meta charset="utf-8" /><meta name="viewport" content="width=device-width, initial-scale=1" /><title>${escapeHtml(options.title ?? "Voice Operations Record")}</title><style>body{background:#101417;color:#f9f4e8;font-family:ui-sans-serif,system-ui,sans-serif;margin:0}main{margin:auto;max-width:1120px;padding:32px}.eyebrow{color:#fbbf24;font-size:.8rem;font-weight:900;letter-spacing:.14em;text-transform:uppercase}h1{font-size:clamp(2.4rem,6vw,4.8rem);line-height:.9;margin:.2rem 0 1rem}.status{border:1px solid #475569;border-radius:999px;display:inline-flex;padding:8px 12px}.healthy{color:#86efac}.warning{color:#fbbf24}.failed,.error{color:#fca5a5}.grid{display:grid;gap:14px;grid-template-columns:repeat(auto-fit,minmax(180px,1fr));margin:20px 0}.card,.primitive{background:#182025;border:1px solid #2d3a43;border-radius:20px;padding:16px}.card span,.muted,.label{color:#a9b4bd}.label{display:block;font-size:.72rem;font-weight:900;letter-spacing:.12em;text-transform:uppercase}.card strong{display:block;font-size:2rem}section{margin-top:28px}article{display:grid;gap:8px}ul{display:grid;gap:10px;list-style:none;padding:0}li{background:#182025;border:1px solid #2d3a43;border-radius:16px;padding:14px}pre{background:#080d10;border:1px solid #2d3a43;border-radius:16px;color:#dbeafe;overflow:auto;padding:14px}.hero-actions{display:flex;flex-wrap:wrap;gap:10px;margin-top:16px}.hero-actions a{background:#fbbf24;border-radius:999px;color:#111827;font-weight:900;padding:10px 14px;text-decoration:none}.two-column{display:grid;gap:18px;grid-template-columns:minmax(0,1.15fr) minmax(280px,.85fr)}@media(max-width:860px){main{padding:20px}.two-column{grid-template-columns:1fr}}</style></head><body><main><p class="eyebrow">Call log replacement</p><h1>${escapeHtml(options.title ?? "Voice Operations Record")}</h1><p class="status ${escapeHtml(record.status)}">${escapeHtml(record.status)}</p><div class="hero-actions"><a href="#transcript">Transcript</a><a href="#provider-decisions">Provider decisions</a><a href="#telephony-media">Telephony media</a>${mediaPipelineNavLink}<a href="#guardrails">Guardrails</a><a href="#incident-handoff">Incident handoff</a>${incidentLink}</div><section class="grid"><div class="card"><span>Events</span><strong>${String(record.summary.eventCount)}</strong></div><div class="card"><span>Turns</span><strong>${String(record.summary.turnCount)}</strong></div><div class="card"><span>Errors</span><strong>${String(record.summary.errorCount)}</strong></div><div class="card"><span>Duration</span><strong>${formatMs2(record.summary.callDurationMs)}</strong></div><div class="card"><span>Provider recovery</span><strong>${escapeHtml(providerDecisionSummary.recoveryStatus)}</strong><span>${String(providerDecisionSummary.fallbacks)} fallback / ${String(providerDecisionSummary.degraded)} degraded / ${String(providerDecisionSummary.errors)} errors</span></div><div class="card"><span>Telephony media</span><strong>${String(record.telephonyMedia.media)}</strong><span>${String(record.telephonyMedia.inbound)} inbound / ${String(record.telephonyMedia.outbound)} outbound / ${String(record.telephonyMedia.clears)} clears</span></div><div class="card"><span>Guardrails</span><strong>${String(record.guardrails.blocked)}</strong></div><div class="card"><span>Audit</span><strong>${String(record.audit?.total ?? 0)}</strong></div><div class="card"><span>Reviews</span><strong>${String(record.reviews?.total ?? 0)}</strong></div><div class="card"><span>Tasks</span><strong>${String(record.tasks?.total ?? 0)}</strong></div><div class="card"><span>Integrations</span><strong>${String(record.integrationEvents?.total ?? 0)}</strong></div>${mediaPipelineCard}</section><section class="two-column"><div><h2 id="transcript">Transcript</h2><ul>${transcript}</ul></div><div><h2 id="provider-decisions">Provider Decisions</h2><ul>${providerDecisions}</ul></div></section><section id="telephony-media"><h2>Telephony Media</h2><p class="muted">Live <code>client.telephony_media</code> stream lifecycle evidence attached to this session. Carriers: ${escapeHtml(record.telephonyMedia.carriers.join(", ") || "none")}. Streams: ${escapeHtml(record.telephonyMedia.streamIds.join(", ") || "none")}. Inbound: ${String(record.telephonyMedia.inbound)}. Outbound: ${String(record.telephonyMedia.outbound)}. Marks: ${String(record.telephonyMedia.marks)}. Clears: ${String(record.telephonyMedia.clears)}.</p><ul>${telephonyMedia}</ul></section>${mediaPipelineSection}<section id="guardrails"><h2>Guardrail Evidence</h2><p class="muted">Live <code>assistant.guardrail</code> decisions attached to this session.</p><ul>${guardrails}</ul></section><section id="incident-handoff"><h2>Copyable Incident Handoff</h2><p class="muted">Paste this into Slack, Linear, Zendesk, or an incident review. ${incidentLink}</p><pre><code>${incidentMarkdown}</code></pre></section><section class="primitive"><p class="eyebrow">Copy into your app</p><h2><code>createVoiceOperationsRecordRoutes(...)</code> gives every call one debuggable object</h2><p class="muted">Use this as the support/debug payload across traces, provider routing, tools, handoffs, guardrails, audit, latency, replay, reviews, tasks, media streams, and webhook delivery.</p><pre><code>${snippet}</code></pre></section><section><h2>Provider Summary</h2><div class="grid">${providers}</div></section><section><h2>Handoffs</h2><ul>${handoffs}</ul></section><section><h2>Tools</h2><ul>${tools}</ul></section><section><h2>Reviews</h2><ul>${reviews}</ul></section><section><h2>Tasks</h2><ul>${tasks}</ul></section><section><h2>Integration Events</h2><ul>${integrationEvents}</ul></section></main></body></html>`;
11532
11528
  };
11533
11529
  var createVoiceOperationsRecordRoutes = (options) => {
11534
11530
  const path = options.path ?? "/api/voice-operations/:sessionId";
@@ -12419,7 +12415,6 @@ var resolveTwilioStreamParameters = async (parameters, input) => {
12419
12415
  return parameters;
12420
12416
  };
12421
12417
  var joinUrlPath = (origin, path) => `${origin.replace(/\/$/, "")}${path.startsWith("/") ? path : `/${path}`}`;
12422
- var escapeHtml8 = (value) => value.replaceAll("&", "&amp;").replaceAll('"', "&quot;").replaceAll("'", "&#39;").replaceAll("<", "&lt;").replaceAll(">", "&gt;");
12423
12418
  var getWebhookVerificationUrl = (webhook, input) => {
12424
12419
  if (!webhook?.verificationUrl) {
12425
12420
  return;
@@ -12464,23 +12459,23 @@ var buildTwilioVoiceSetupStatus = async (options, input) => {
12464
12459
  };
12465
12460
  var renderTwilioVoiceSetupHTML = (status, title) => `<main style="font-family: ui-sans-serif, system-ui; max-width: 860px; margin: 40px auto; padding: 0 20px;">
12466
12461
  <p style="letter-spacing: .12em; text-transform: uppercase; color: #52606d;">Twilio setup</p>
12467
- <h1>${escapeHtml8(title)}</h1>
12462
+ <h1>${escapeHtml(title)}</h1>
12468
12463
  <p><strong>Status:</strong> ${status.ready ? "Ready" : "Needs attention"}</p>
12469
12464
  <section>
12470
12465
  <h2>URLs</h2>
12471
12466
  <ul>
12472
- <li><strong>TwiML:</strong> <code>${escapeHtml8(status.urls.twiml)}</code></li>
12473
- <li><strong>Media stream:</strong> <code>${escapeHtml8(status.urls.stream)}</code></li>
12474
- <li><strong>Status webhook:</strong> <code>${escapeHtml8(status.urls.webhook)}</code></li>
12467
+ <li><strong>TwiML:</strong> <code>${escapeHtml(status.urls.twiml)}</code></li>
12468
+ <li><strong>Media stream:</strong> <code>${escapeHtml(status.urls.stream)}</code></li>
12469
+ <li><strong>Status webhook:</strong> <code>${escapeHtml(status.urls.webhook)}</code></li>
12475
12470
  </ul>
12476
12471
  </section>
12477
12472
  <section>
12478
12473
  <h2>Signing</h2>
12479
12474
  <p>Mode: <code>${status.signing.mode}</code></p>
12480
- ${status.signing.verificationUrl ? `<p>Verification URL: <code>${escapeHtml8(status.signing.verificationUrl)}</code></p>` : ""}
12475
+ ${status.signing.verificationUrl ? `<p>Verification URL: <code>${escapeHtml(status.signing.verificationUrl)}</code></p>` : ""}
12481
12476
  </section>
12482
- ${status.missing.length ? `<section><h2>Missing env</h2><ul>${status.missing.map((name) => `<li><code>${escapeHtml8(name)}</code></li>`).join("")}</ul></section>` : ""}
12483
- ${status.warnings.length ? `<section><h2>Warnings</h2><ul>${status.warnings.map((warning) => `<li>${escapeHtml8(warning)}</li>`).join("")}</ul></section>` : ""}
12477
+ ${status.missing.length ? `<section><h2>Missing env</h2><ul>${status.missing.map((name) => `<li><code>${escapeHtml(name)}</code></li>`).join("")}</ul></section>` : ""}
12478
+ ${status.warnings.length ? `<section><h2>Warnings</h2><ul>${status.warnings.map((warning) => `<li>${escapeHtml(warning)}</li>`).join("")}</ul></section>` : ""}
12484
12479
  </main>`;
12485
12480
  var extractTwilioStreamUrl = (twiml) => twiml.match(/<Stream\b[^>]*\surl="([^"]+)"/i)?.[1]?.replaceAll("&amp;", "&");
12486
12481
  var createSmokeCheck = (name, status, message, details) => ({
@@ -12491,20 +12486,20 @@ var createSmokeCheck = (name, status, message, details) => ({
12491
12486
  });
12492
12487
  var renderTwilioVoiceSmokeHTML = (report, title) => `<main style="font-family: ui-sans-serif, system-ui; max-width: 860px; margin: 40px auto; padding: 0 20px;">
12493
12488
  <p style="letter-spacing: .12em; text-transform: uppercase; color: #52606d;">Twilio smoke test</p>
12494
- <h1>${escapeHtml8(title)}</h1>
12489
+ <h1>${escapeHtml(title)}</h1>
12495
12490
  <p><strong>Status:</strong> ${report.pass ? "Pass" : "Fail"}</p>
12496
12491
  <section>
12497
12492
  <h2>Checks</h2>
12498
12493
  <ul>
12499
- ${report.checks.map((check) => `<li><strong>${escapeHtml8(check.name)}</strong>: ${escapeHtml8(check.status)}${check.message ? ` - ${escapeHtml8(check.message)}` : ""}</li>`).join("")}
12494
+ ${report.checks.map((check) => `<li><strong>${escapeHtml(check.name)}</strong>: ${escapeHtml(check.status)}${check.message ? ` - ${escapeHtml(check.message)}` : ""}</li>`).join("")}
12500
12495
  </ul>
12501
12496
  </section>
12502
12497
  <section>
12503
12498
  <h2>Observed URLs</h2>
12504
12499
  <ul>
12505
- <li><strong>TwiML:</strong> <code>${escapeHtml8(report.setup.urls.twiml)}</code></li>
12506
- <li><strong>Stream:</strong> <code>${escapeHtml8(report.twiml?.streamUrl ?? report.setup.urls.stream)}</code></li>
12507
- <li><strong>Webhook:</strong> <code>${escapeHtml8(report.setup.urls.webhook)}</code></li>
12500
+ <li><strong>TwiML:</strong> <code>${escapeHtml(report.setup.urls.twiml)}</code></li>
12501
+ <li><strong>Stream:</strong> <code>${escapeHtml(report.twiml?.streamUrl ?? report.setup.urls.stream)}</code></li>
12502
+ <li><strong>Webhook:</strong> <code>${escapeHtml(report.setup.urls.webhook)}</code></li>
12508
12503
  </ul>
12509
12504
  </section>
12510
12505
  </main>`;
@@ -37,7 +37,7 @@ export { VoiceCostDashboard } from "./VoiceCostDashboard";
37
37
  export { VoiceLiveAgentConsole } from "./VoiceLiveAgentConsole";
38
38
  export { VoiceLiveCallViewer } from "./VoiceLiveCallViewer";
39
39
  export { VoiceReplayTimeline } from "./VoiceReplayTimeline";
40
- export type { VoiceWidgetLabels, VoiceWidgetTheme, } from "./VoiceWidget";
40
+ export type { VoiceWidgetLabels, VoiceWidgetTheme } from "./VoiceWidget";
41
41
  export { useVoiceProviderStatus } from "./useVoiceProviderStatus";
42
42
  export { useVoiceProviderCapabilities } from "./useVoiceProviderCapabilities";
43
43
  export { useVoiceProviderContracts } from "./useVoiceProviderContracts";