@absolutejs/voice 0.0.22-beta.501 → 0.0.22-beta.503

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
@@ -36781,6 +36781,51 @@ var createVoiceRouteAuth = (options) => {
36781
36781
  }
36782
36782
  });
36783
36783
  };
36784
+ // src/client/htmxAttributes.ts
36785
+ var escapeAttr = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
36786
+ var normalizeHxKey = (key) => key.startsWith("hx-") ? key : `hx-${key}`;
36787
+ var buildVoiceHTMXAttributes = (attrs) => {
36788
+ if (!attrs)
36789
+ return "";
36790
+ const out = [];
36791
+ if (attrs.poll && attrs.refreshUrl) {
36792
+ const intervalSec = Math.max(1, Math.round((attrs.pollIntervalMs ?? 5000) / 1000));
36793
+ out.push(`hx-get="${escapeAttr(attrs.refreshUrl)}"`);
36794
+ out.push(`hx-trigger="every ${intervalSec}s"`);
36795
+ out.push(`hx-swap="${escapeAttr(attrs.swap ?? "outerHTML")}"`);
36796
+ if (attrs.target) {
36797
+ out.push(`hx-target="${escapeAttr(attrs.target)}"`);
36798
+ }
36799
+ } else if (attrs.swap || attrs.target) {
36800
+ if (attrs.swap)
36801
+ out.push(`hx-swap="${escapeAttr(attrs.swap)}"`);
36802
+ if (attrs.target)
36803
+ out.push(`hx-target="${escapeAttr(attrs.target)}"`);
36804
+ }
36805
+ for (const [rawKey, value] of Object.entries(attrs.pushAttributes ?? {})) {
36806
+ const key = normalizeHxKey(rawKey);
36807
+ out.push(`${key}="${escapeAttr(value)}"`);
36808
+ }
36809
+ return out.length === 0 ? "" : ` ${out.join(" ")}`;
36810
+ };
36811
+ var FIRST_TAG_RE = /^(\s*)<([a-zA-Z][\w-]*)((?:\s|>|\/))/;
36812
+ var wrapVoiceHTMLWithHTMXPolling = (html, attrs) => {
36813
+ const attrString = buildVoiceHTMXAttributes(attrs);
36814
+ if (!attrString)
36815
+ return html;
36816
+ const match = FIRST_TAG_RE.exec(html);
36817
+ if (!match)
36818
+ return html;
36819
+ const [matched, leading, tag, terminator] = match;
36820
+ const replaced = `${leading}<${tag}${attrString}${terminator}`;
36821
+ return html.replace(matched, replaced);
36822
+ };
36823
+ var wrapVoiceHTMLInHTMXContainer = (html, attrs) => {
36824
+ const tag = attrs.elementTag ?? "div";
36825
+ const classAttr = attrs.className ? ` class="${escapeAttr(attrs.className)}"` : "";
36826
+ const hx = buildVoiceHTMXAttributes(attrs);
36827
+ return `<${tag}${classAttr}${hx}>${html}</${tag}>`;
36828
+ };
36784
36829
  // src/client/costDashboard.ts
36785
36830
  var padTwo = (value) => String(value).padStart(2, "0");
36786
36831
  var formatBucketKey = (epochMs, bucketBy) => {
@@ -36860,6 +36905,7 @@ var buildVoiceCostDashboardReport = (options) => {
36860
36905
  windowStartMs: Number.isFinite(minMs) ? minMs : 0
36861
36906
  };
36862
36907
  };
36908
+
36863
36909
  // src/client/liveCallViewer.ts
36864
36910
  var EVENT_BUFFER_LIMIT = 200;
36865
36911
  var createLiveCallViewer = (options) => {
@@ -36967,6 +37013,7 @@ var createLiveCallViewer = (options) => {
36967
37013
  }
36968
37014
  };
36969
37015
  };
37016
+
36970
37017
  // src/client/replayTimeline.ts
36971
37018
  var categorize = (entry) => {
36972
37019
  const event = entry.event.toLowerCase();
@@ -37017,6 +37064,276 @@ var buildReplayTimelineReport = (input) => {
37017
37064
  }
37018
37065
  };
37019
37066
  };
37067
+
37068
+ // src/client/htmxDashboardRenderers.ts
37069
+ var escapeHtml50 = (text) => text.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
37070
+ var formatUsd = (value, currency = "USD") => new Intl.NumberFormat("en-US", {
37071
+ currency,
37072
+ maximumFractionDigits: 4,
37073
+ minimumFractionDigits: 2,
37074
+ style: "currency"
37075
+ }).format(value);
37076
+ var formatInteger = (value) => new Intl.NumberFormat("en-US").format(value);
37077
+ var formatRelative = (ms) => {
37078
+ const seconds = Math.max(0, Math.floor(ms / 1000));
37079
+ const minutes = Math.floor(seconds / 60);
37080
+ const remaining = seconds % 60;
37081
+ return `${String(minutes).padStart(2, "0")}:${String(remaining).padStart(2, "0")}`;
37082
+ };
37083
+ var polledWrapperAttributes = (attrs) => buildVoiceHTMXAttributes(attrs);
37084
+ var renderCostRow = (bucket, currency, isTotal) => `<tr data-bucket-key="${escapeHtml50(bucket.bucketKey)}" style="${isTotal ? "border-top:2px solid rgba(255,255,255,0.15);font-weight:600;" : ""}">
37085
+ <td style="padding:8px 12px;">${escapeHtml50(bucket.bucketKey)}</td>
37086
+ <td style="padding:8px 12px;text-align:right;">${formatInteger(bucket.callCount)}</td>
37087
+ <td style="padding:8px 12px;text-align:right;">${formatUsd(bucket.llmUsd, currency)}</td>
37088
+ <td style="padding:8px 12px;text-align:right;">${formatUsd(bucket.ttsUsd, currency)}</td>
37089
+ <td style="padding:8px 12px;text-align:right;">${formatUsd(bucket.sttUsd, currency)}</td>
37090
+ <td style="padding:8px 12px;text-align:right;">${formatUsd(bucket.telephonyUsd, currency)}</td>
37091
+ <td style="padding:8px 12px;text-align:right;">${formatUsd(bucket.totalUsd, currency)}</td>
37092
+ </tr>`;
37093
+ var defaultCostDashboard = ({
37094
+ attributes,
37095
+ currency = "USD",
37096
+ emptyMessage = "No cost events in window.",
37097
+ report,
37098
+ title = "Voice cost dashboard"
37099
+ }) => {
37100
+ const body = report.buckets.map((bucket) => renderCostRow(bucket, currency, false)).join("");
37101
+ const total = renderCostRow(report.grandTotal, currency, true);
37102
+ const inner = report.buckets.length === 0 ? `<p style="font-size:13px;opacity:0.7;">${escapeHtml50(emptyMessage)}</p>` : `<table style="border-collapse:collapse;font-size:13px;width:100%;">
37103
+ <thead><tr style="opacity:0.7;text-align:left;">
37104
+ <th style="padding:8px 12px;">Bucket</th>
37105
+ <th style="padding:8px 12px;text-align:right;">Calls</th>
37106
+ <th style="padding:8px 12px;text-align:right;">LLM</th>
37107
+ <th style="padding:8px 12px;text-align:right;">TTS</th>
37108
+ <th style="padding:8px 12px;text-align:right;">STT</th>
37109
+ <th style="padding:8px 12px;text-align:right;">Tel.</th>
37110
+ <th style="padding:8px 12px;text-align:right;">Total</th>
37111
+ </tr></thead><tbody>${body}${total}</tbody></table>`;
37112
+ return `<section aria-label="voice-cost-dashboard" class="absolute-voice-cost-dashboard"${polledWrapperAttributes(attributes)} style="background:#0f172a;border-radius:16px;color:#f8fafc;font-family:ui-sans-serif,system-ui,sans-serif;padding:20px;">
37113
+ <header style="align-items:baseline;display:flex;gap:12px;margin-bottom:12px;">
37114
+ <strong style="font-size:16px;">${escapeHtml50(title)}</strong>
37115
+ <span style="font-size:13px;opacity:0.7;">${report.buckets.length} buckets \xB7 grand total ${formatUsd(report.grandTotal.totalUsd, currency)}</span>
37116
+ </header>
37117
+ ${inner}
37118
+ </section>`;
37119
+ };
37120
+ var REPLAY_CATEGORY_COLOR = {
37121
+ agent: "#3b82f6",
37122
+ lifecycle: "#94a3b8",
37123
+ tool: "#f59e0b",
37124
+ user: "#10b981"
37125
+ };
37126
+ var renderReplayEntry = (event, startedAt) => `<li style="align-items:center;border-left:3px solid ${REPLAY_CATEGORY_COLOR[event.category]};display:flex;font-size:13px;gap:12px;padding-left:12px;">
37127
+ <span style="color:#cbd5e1;font-family:ui-monospace,SFMono-Regular,Menlo,monospace;font-size:12px;width:60px;">${formatRelative(event.at - startedAt)}</span>
37128
+ <strong style="font-size:13px;">${escapeHtml50(event.label)}</strong>
37129
+ ${event.detail ? `<span style="opacity:0.85;">${escapeHtml50(event.detail)}</span>` : ""}
37130
+ </li>`;
37131
+ var defaultReplayTimeline = ({
37132
+ attributes,
37133
+ emptyMessage = "No timeline events.",
37134
+ report,
37135
+ title
37136
+ }) => {
37137
+ const headline = escapeHtml50(title ?? report.metadata.title ?? "Replay");
37138
+ const items = report.events.map((event) => renderReplayEntry(event, report.startedAt)).join("");
37139
+ const inner = report.events.length === 0 ? `<p style="font-size:13px;opacity:0.7;">${escapeHtml50(emptyMessage)}</p>` : `<ol style="display:flex;flex-direction:column;gap:6px;list-style:none;margin:0;padding:0;">${items}</ol>`;
37140
+ return `<section aria-label="voice-replay-timeline" class="absolute-voice-replay-timeline"${polledWrapperAttributes(attributes)} style="background:#0f172a;border-radius:16px;color:#f8fafc;font-family:ui-sans-serif,system-ui,sans-serif;padding:20px;">
37141
+ <header style="align-items:baseline;display:flex;gap:12px;margin-bottom:12px;">
37142
+ <strong style="font-size:16px;">${headline}</strong>
37143
+ <span style="font-size:13px;opacity:0.7;">${report.events.length} events \xB7 ${report.summary.userTurns} user \xB7 ${report.summary.agentTurns} agent \xB7 ${report.summary.toolCalls} tool</span>
37144
+ </header>
37145
+ ${inner}
37146
+ </section>`;
37147
+ };
37148
+ var LIVE_CATEGORY_COLOR = {
37149
+ agent_audio: "#3b82f6",
37150
+ agent_text: "#3b82f6",
37151
+ lifecycle: "#94a3b8",
37152
+ tool: "#f59e0b",
37153
+ transcript: "#10b981"
37154
+ };
37155
+ var renderLiveEntry = (event, firstAt) => `<li style="align-items:center;border-left:3px solid ${LIVE_CATEGORY_COLOR[event.kind] ?? "#94a3b8"};display:flex;font-size:13px;gap:12px;padding-left:12px;">
37156
+ <span style="color:#cbd5e1;font-family:ui-monospace,SFMono-Regular,Menlo,monospace;font-size:12px;width:60px;">${formatRelative(event.at - firstAt)}</span>
37157
+ <strong style="font-size:13px;">${escapeHtml50(event.title)}</strong>
37158
+ ${event.detail ? `<span style="opacity:0.85;">${escapeHtml50(event.detail)}</span>` : ""}
37159
+ </li>`;
37160
+ var defaultLiveCallViewer = ({
37161
+ attributes,
37162
+ state,
37163
+ title = "Live call"
37164
+ }) => {
37165
+ const firstAt = state.events[0]?.at ?? Date.now();
37166
+ const items = state.events.map((event) => renderLiveEntry(event, firstAt)).join("");
37167
+ return `<section aria-label="voice-live-call-viewer" class="absolute-voice-live-call-viewer" data-agent-state="${escapeHtml50(state.agentState)}"${polledWrapperAttributes(attributes)} style="background:#0f172a;border-radius:16px;color:#f8fafc;font-family:ui-sans-serif,system-ui,sans-serif;padding:20px;">
37168
+ <header style="align-items:center;display:flex;gap:12px;margin-bottom:12px;">
37169
+ <strong style="font-size:16px;">${escapeHtml50(title)}</strong>
37170
+ <span style="background:rgba(59,130,246,0.18);border-radius:999px;font-size:11px;padding:3px 10px;text-transform:uppercase;">${escapeHtml50(state.agentState)}</span>
37171
+ <span style="font-size:13px;margin-left:auto;opacity:0.7;">${escapeHtml50(state.sessionId)} \xB7 ${formatRelative(state.callDurationMs)}</span>
37172
+ </header>
37173
+ ${state.partialTranscript ? `<p style="background:rgba(16,185,129,0.12);border-radius:12px;font-size:13px;margin:0 0 12px;opacity:0.95;padding:10px 12px;">"${escapeHtml50(state.partialTranscript)}"</p>` : ""}
37174
+ <ol style="display:flex;flex-direction:column;gap:6px;list-style:none;margin:0;max-height:320px;overflow-y:auto;padding:0;">${items}</ol>
37175
+ </section>`;
37176
+ };
37177
+ var resolveVoiceDashboardRenderers = (custom) => ({
37178
+ costDashboard: custom?.costDashboard ?? defaultCostDashboard,
37179
+ liveCallViewer: custom?.liveCallViewer ?? defaultLiveCallViewer,
37180
+ replayTimeline: custom?.replayTimeline ?? defaultReplayTimeline
37181
+ });
37182
+ var renderVoiceCostDashboardHTMX = (input) => (input.custom ?? defaultCostDashboard)(input);
37183
+ var renderVoiceReplayTimelineHTMX = (input) => (input.custom ?? defaultReplayTimeline)(input);
37184
+ var renderVoiceLiveCallViewerHTMX = (input) => (input.custom ?? defaultLiveCallViewer)(input);
37185
+ var renderVoiceCostDashboardFromEvents = (input) => {
37186
+ const report = buildVoiceCostDashboardReport({
37187
+ bucketBy: input.options?.bucketBy,
37188
+ events: input.events,
37189
+ fromMs: input.options?.fromMs,
37190
+ toMs: input.options?.toMs
37191
+ });
37192
+ return renderVoiceCostDashboardHTMX({
37193
+ attributes: input.attributes,
37194
+ currency: input.currency,
37195
+ custom: input.renderer,
37196
+ report,
37197
+ title: input.title
37198
+ });
37199
+ };
37200
+ var renderVoiceReplayTimelineFromArtifact = (input) => {
37201
+ const report = buildReplayTimelineReport({ artifact: input.artifact });
37202
+ return renderVoiceReplayTimelineHTMX({
37203
+ attributes: input.attributes,
37204
+ custom: input.renderer,
37205
+ report,
37206
+ title: input.title
37207
+ });
37208
+ };
37209
+ var renderVoiceLiveCallViewerFromViewer = (input) => renderVoiceLiveCallViewerHTMX({
37210
+ attributes: input.attributes,
37211
+ custom: input.renderer,
37212
+ state: input.viewer.getState(),
37213
+ title: input.title
37214
+ });
37215
+ var renderVoiceLiveCallViewerFromState = (input) => renderVoiceLiveCallViewerHTMX({
37216
+ attributes: input.attributes,
37217
+ custom: input.renderer,
37218
+ state: input.state,
37219
+ title: input.title
37220
+ });
37221
+ var createLiveCallViewerFromOptions = createLiveCallViewer;
37222
+ // src/htmxDashboardRoutes.ts
37223
+ import { Elysia as Elysia54 } from "elysia";
37224
+ var HTML_HEADERS = { "content-type": "text/html; charset=utf-8" };
37225
+ var createVoiceCostDashboardHTMXRoute = (options) => {
37226
+ const renderers = resolveVoiceDashboardRenderers(options.render);
37227
+ const path = options.path ?? "/voice/htmx/cost-dashboard";
37228
+ return new Elysia54({ name: options.name ?? "voice-cost-dashboard-htmx" }).get(path, async () => {
37229
+ const events = await Promise.resolve(options.resolveEvents());
37230
+ const attributes = {
37231
+ poll: typeof options.pollIntervalMs === "number",
37232
+ pollIntervalMs: options.pollIntervalMs,
37233
+ refreshUrl: path
37234
+ };
37235
+ const html = renderVoiceCostDashboardFromEvents({
37236
+ attributes,
37237
+ currency: options.currency,
37238
+ events,
37239
+ options: {
37240
+ bucketBy: options.bucketBy,
37241
+ fromMs: options.fromMs?.(),
37242
+ toMs: options.toMs?.()
37243
+ },
37244
+ renderer: renderers.costDashboard,
37245
+ title: options.title
37246
+ });
37247
+ return new Response(html, { headers: HTML_HEADERS });
37248
+ });
37249
+ };
37250
+ var createVoiceReplayTimelineHTMXRoute = (options) => {
37251
+ const renderers = resolveVoiceDashboardRenderers(options.render);
37252
+ const basePath = options.path ?? "/voice/htmx/replay";
37253
+ return new Elysia54({
37254
+ name: options.name ?? "voice-replay-timeline-htmx"
37255
+ }).get(`${basePath}/:artifactId`, async ({ params, set }) => {
37256
+ const { artifactId } = params;
37257
+ const artifact = await Promise.resolve(options.resolveArtifact(artifactId));
37258
+ if (!artifact) {
37259
+ set.status = 404;
37260
+ return new Response(`<div class="absolute-voice-replay-timeline" data-status="not-found" style="background:#0f172a;color:#f8fafc;padding:20px;border-radius:16px;">Replay artifact not found.</div>`, { headers: HTML_HEADERS, status: 404 });
37261
+ }
37262
+ const html = renderVoiceReplayTimelineFromArtifact({
37263
+ artifact,
37264
+ renderer: renderers.replayTimeline,
37265
+ title: options.title
37266
+ });
37267
+ return new Response(html, { headers: HTML_HEADERS });
37268
+ });
37269
+ };
37270
+ var createVoiceLiveCallViewerHTMXRoute = (options) => {
37271
+ const renderers = resolveVoiceDashboardRenderers(options.render);
37272
+ const basePath = options.path ?? "/voice/htmx/live";
37273
+ return new Elysia54({
37274
+ name: options.name ?? "voice-live-call-viewer-htmx"
37275
+ }).get(`${basePath}/:sessionId`, async ({ params, set }) => {
37276
+ const { sessionId } = params;
37277
+ const viewer = await Promise.resolve(options.resolveViewer(sessionId));
37278
+ if (!viewer) {
37279
+ set.status = 404;
37280
+ return new Response(`<div class="absolute-voice-live-call-viewer" data-status="not-found" style="background:#0f172a;color:#f8fafc;padding:20px;border-radius:16px;">No active call for ${sessionId}.</div>`, { headers: HTML_HEADERS, status: 404 });
37281
+ }
37282
+ const attributes = {
37283
+ poll: typeof options.pollIntervalMs === "number",
37284
+ pollIntervalMs: options.pollIntervalMs,
37285
+ refreshUrl: `${basePath}/${sessionId}`
37286
+ };
37287
+ const html = renderVoiceLiveCallViewerFromViewer({
37288
+ attributes,
37289
+ renderer: renderers.liveCallViewer,
37290
+ title: options.title,
37291
+ viewer
37292
+ });
37293
+ return new Response(html, { headers: HTML_HEADERS });
37294
+ });
37295
+ };
37296
+ var createVoiceHTMXDashboardRoutes = (options) => {
37297
+ let app = new Elysia54({ name: options.name ?? "voice-htmx-dashboards" });
37298
+ if (options.cost) {
37299
+ app = app.use(createVoiceCostDashboardHTMXRoute({
37300
+ ...options.cost,
37301
+ render: options.render
37302
+ }));
37303
+ }
37304
+ if (options.replay) {
37305
+ app = app.use(createVoiceReplayTimelineHTMXRoute({
37306
+ ...options.replay,
37307
+ render: options.render
37308
+ }));
37309
+ }
37310
+ if (options.liveCall) {
37311
+ app = app.use(createVoiceLiveCallViewerHTMXRoute({
37312
+ ...options.liveCall,
37313
+ render: options.render
37314
+ }));
37315
+ }
37316
+ return app;
37317
+ };
37318
+ var createVoiceHTMXDashboardRoutesFromStores = (options) => createVoiceHTMXDashboardRoutes({
37319
+ cost: options.traceStore ? {
37320
+ pollIntervalMs: options.pollIntervalMs,
37321
+ resolveEvents: async () => {
37322
+ const events = await options.traceStore.list({
37323
+ type: "cost.ready"
37324
+ });
37325
+ return events;
37326
+ }
37327
+ } : undefined,
37328
+ liveCall: options.liveViewerByCallId ? {
37329
+ pollIntervalMs: options.pollIntervalMs,
37330
+ resolveViewer: options.liveViewerByCallId
37331
+ } : undefined,
37332
+ render: options.render,
37333
+ replay: options.reviewStore ? {
37334
+ resolveArtifact: async (artifactId) => await options.reviewStore.get(artifactId) ?? undefined
37335
+ } : undefined
37336
+ });
37020
37337
  // src/retention.ts
37021
37338
  var defaultResolveAt = (event) => {
37022
37339
  if (!event || typeof event !== "object")
@@ -37653,10 +37970,10 @@ var assertVoiceAgentSquadContractEvidence = (reports, input = {}) => {
37653
37970
  return report;
37654
37971
  };
37655
37972
  // src/turnLatency.ts
37656
- import { Elysia as Elysia54 } from "elysia";
37973
+ import { Elysia as Elysia55 } from "elysia";
37657
37974
  var DEFAULT_WARN_AFTER_MS2 = 1800;
37658
37975
  var DEFAULT_FAIL_AFTER_MS2 = 3200;
37659
- var escapeHtml50 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
37976
+ var escapeHtml51 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
37660
37977
  var firstNumber3 = (values) => values.filter((value) => typeof value === "number").sort((left, right) => left - right)[0];
37661
37978
  var getString19 = (value) => typeof value === "string" && value.trim() ? value : undefined;
37662
37979
  var createTraceStageIndex = (events) => {
@@ -37792,11 +38109,11 @@ await traceStore.append({
37792
38109
  turnId,
37793
38110
  type: 'turn_latency.stage'
37794
38111
  });`;
37795
- const turns = report.turns.map((turn) => `<article class="turn ${escapeHtml50(turn.status)}">
37796
- <header><div><p class="eyebrow">${escapeHtml50(turn.sessionId)} \xB7 ${escapeHtml50(turn.turnId)}</p><h2>${escapeHtml50(turn.text || "Empty turn")}</h2></div><strong>${escapeHtml50(turn.status)}</strong></header>
37797
- <dl>${turn.stages.map((stage) => `<div><dt>${escapeHtml50(stage.label)}</dt><dd>${escapeHtml50(formatMs5(stage.valueMs))}</dd></div>`).join("")}</dl>
38112
+ const turns = report.turns.map((turn) => `<article class="turn ${escapeHtml51(turn.status)}">
38113
+ <header><div><p class="eyebrow">${escapeHtml51(turn.sessionId)} \xB7 ${escapeHtml51(turn.turnId)}</p><h2>${escapeHtml51(turn.text || "Empty turn")}</h2></div><strong>${escapeHtml51(turn.status)}</strong></header>
38114
+ <dl>${turn.stages.map((stage) => `<div><dt>${escapeHtml51(stage.label)}</dt><dd>${escapeHtml51(formatMs5(stage.valueMs))}</dd></div>`).join("")}</dl>
37798
38115
  </article>`).join("");
37799
- return `<!doctype html><html lang="en"><head><meta charset="utf-8" /><meta name="viewport" content="width=device-width, initial-scale=1" /><title>${escapeHtml50(title)}</title><style>body{background:#101316;color:#f6f2e8;font-family:ui-sans-serif,system-ui,sans-serif;margin:0}main{margin:auto;max-width:1180px;padding:32px}.hero,.turn,.primitive{background:#181d22;border:1px solid #2a323a;border-radius:20px;margin-bottom:16px;padding:20px}.hero{background:linear-gradient(135deg,rgba(94,234,212,.16),rgba(251,191,36,.1))}.eyebrow{color:#5eead4;font-size:.78rem;font-weight:900;letter-spacing:.08em;text-transform:uppercase}h1{font-size:clamp(2.3rem,6vw,5rem);letter-spacing:-.06em;line-height:.9;margin:.2rem 0 1rem}h2{margin:.2rem 0 1rem}.summary{display:flex;flex-wrap:wrap;gap:10px}.pill{background:#0f1217;border:1px solid #3f3f46;border-radius:999px;padding:7px 10px}.primitive p{color:#cbd5e1}.primitive pre{background:#0a0d10;border:1px solid #2a323a;border-radius:16px;color:#d9fff7;overflow:auto;padding:16px}.turn header{align-items:flex-start;display:flex;gap:16px;justify-content:space-between}.pass{color:#86efac}.warn,.empty{color:#fde68a}.fail{color:#fca5a5}.turn.fail{border-color:rgba(248,113,113,.45)}dl{display:grid;gap:8px;grid-template-columns:repeat(auto-fit,minmax(160px,1fr))}dt{color:#a8b0b8;font-size:.8rem}dd{font-weight:900;margin:0}@media(max-width:800px){main{padding:18px}.turn header{display:block}}</style></head><body><main><section class="hero"><p class="eyebrow">End-to-end responsiveness</p><h1>${escapeHtml50(title)}</h1><div class="summary"><span class="pill ${escapeHtml50(report.status)}">${escapeHtml50(report.status)}</span><span class="pill">${String(report.total)} turns</span><span class="pill">avg ${escapeHtml50(formatMs5(report.averageTotalMs))}</span><span class="pill">${String(report.warnings)} warnings</span><span class="pill">${String(report.failed)} failed</span></div></section><section class="primitive"><p class="eyebrow">Copy into your app</p><h2><code>createVoiceTurnLatencyRoutes(...)</code> exposes the full turn waterfall</h2><p>Attach stage traces for speech detection, commit, model response, TTS send, and first audio so teams can prove where latency actually comes from.</p><pre><code>${escapeHtml50(snippet)}</code></pre></section>${turns || '<section class="turn"><p>No committed turns found.</p></section>'}</main></body></html>`;
38116
+ return `<!doctype html><html lang="en"><head><meta charset="utf-8" /><meta name="viewport" content="width=device-width, initial-scale=1" /><title>${escapeHtml51(title)}</title><style>body{background:#101316;color:#f6f2e8;font-family:ui-sans-serif,system-ui,sans-serif;margin:0}main{margin:auto;max-width:1180px;padding:32px}.hero,.turn,.primitive{background:#181d22;border:1px solid #2a323a;border-radius:20px;margin-bottom:16px;padding:20px}.hero{background:linear-gradient(135deg,rgba(94,234,212,.16),rgba(251,191,36,.1))}.eyebrow{color:#5eead4;font-size:.78rem;font-weight:900;letter-spacing:.08em;text-transform:uppercase}h1{font-size:clamp(2.3rem,6vw,5rem);letter-spacing:-.06em;line-height:.9;margin:.2rem 0 1rem}h2{margin:.2rem 0 1rem}.summary{display:flex;flex-wrap:wrap;gap:10px}.pill{background:#0f1217;border:1px solid #3f3f46;border-radius:999px;padding:7px 10px}.primitive p{color:#cbd5e1}.primitive pre{background:#0a0d10;border:1px solid #2a323a;border-radius:16px;color:#d9fff7;overflow:auto;padding:16px}.turn header{align-items:flex-start;display:flex;gap:16px;justify-content:space-between}.pass{color:#86efac}.warn,.empty{color:#fde68a}.fail{color:#fca5a5}.turn.fail{border-color:rgba(248,113,113,.45)}dl{display:grid;gap:8px;grid-template-columns:repeat(auto-fit,minmax(160px,1fr))}dt{color:#a8b0b8;font-size:.8rem}dd{font-weight:900;margin:0}@media(max-width:800px){main{padding:18px}.turn header{display:block}}</style></head><body><main><section class="hero"><p class="eyebrow">End-to-end responsiveness</p><h1>${escapeHtml51(title)}</h1><div class="summary"><span class="pill ${escapeHtml51(report.status)}">${escapeHtml51(report.status)}</span><span class="pill">${String(report.total)} turns</span><span class="pill">avg ${escapeHtml51(formatMs5(report.averageTotalMs))}</span><span class="pill">${String(report.warnings)} warnings</span><span class="pill">${String(report.failed)} failed</span></div></section><section class="primitive"><p class="eyebrow">Copy into your app</p><h2><code>createVoiceTurnLatencyRoutes(...)</code> exposes the full turn waterfall</h2><p>Attach stage traces for speech detection, commit, model response, TTS send, and first audio so teams can prove where latency actually comes from.</p><pre><code>${escapeHtml51(snippet)}</code></pre></section>${turns || '<section class="turn"><p>No committed turns found.</p></section>'}</main></body></html>`;
37800
38117
  };
37801
38118
  var createVoiceTurnLatencyJSONHandler = (options) => async () => summarizeVoiceTurnLatency(options);
37802
38119
  var createVoiceTurnLatencyHTMLHandler = (options) => async () => {
@@ -37813,7 +38130,7 @@ var createVoiceTurnLatencyHTMLHandler = (options) => async () => {
37813
38130
  var createVoiceTurnLatencyRoutes = (options) => {
37814
38131
  const path = options.path ?? "/api/turn-latency";
37815
38132
  const htmlPath = options.htmlPath === undefined ? `${path}/htmx` : options.htmlPath;
37816
- const routes = new Elysia54({
38133
+ const routes = new Elysia55({
37817
38134
  name: options.name ?? "absolutejs-voice-turn-latency"
37818
38135
  }).get(path, createVoiceTurnLatencyJSONHandler(options));
37819
38136
  if (htmlPath) {
@@ -37822,8 +38139,8 @@ var createVoiceTurnLatencyRoutes = (options) => {
37822
38139
  return routes;
37823
38140
  };
37824
38141
  // src/liveLatency.ts
37825
- import { Elysia as Elysia55 } from "elysia";
37826
- var escapeHtml51 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
38142
+ import { Elysia as Elysia56 } from "elysia";
38143
+ var escapeHtml52 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
37827
38144
  var percentile6 = (values, percentileValue) => {
37828
38145
  if (values.length === 0) {
37829
38146
  return;
@@ -37890,13 +38207,13 @@ await traceStore.append({
37890
38207
  sessionId,
37891
38208
  type: 'client.live_latency'
37892
38209
  });`;
37893
- const rows = report.recent.map((sample) => `<tr><td>${escapeHtml51(sample.sessionId)}</td><td>${escapeHtml51(formatMs6(sample.latencyMs))}</td><td>${escapeHtml51(sample.status ?? "unknown")}</td><td>${escapeHtml51(new Date(sample.at).toLocaleString())}</td></tr>`).join("");
37894
- return `<!doctype html><html lang="en"><head><meta charset="utf-8" /><meta name="viewport" content="width=device-width, initial-scale=1" /><title>${escapeHtml51(title)}</title><style>body{background:#0c0f14;color:#f6f2e8;font-family:ui-sans-serif,system-ui,sans-serif;margin:0}main{margin:auto;max-width:1060px;padding:32px}.hero{background:linear-gradient(135deg,rgba(94,234,212,.16),rgba(245,158,11,.1));border:1px solid #26313d;border-radius:28px;margin-bottom:18px;padding:28px}.eyebrow{color:#5eead4;font-weight:900;letter-spacing:.12em;text-transform:uppercase}h1{font-size:clamp(2.4rem,6vw,5rem);line-height:.9;margin:.2rem 0 1rem}.status{border:1px solid #3f3f46;border-radius:999px;display:inline-flex;padding:8px 12px}.pass{color:#86efac}.warn,.empty{color:#fbbf24}.fail{color:#fca5a5}.metrics{display:grid;gap:14px;grid-template-columns:repeat(auto-fit,minmax(160px,1fr));margin:18px 0}.metrics article,table,.primitive{background:#141922;border:1px solid #26313d;border-radius:18px}.metrics article,.primitive{padding:16px}.metrics span{color:#a8b0b8}.metrics strong{display:block;font-size:2rem;margin-top:.25rem}.primitive{margin:0 0 18px}.primitive h2{margin:.2rem 0 .5rem}.primitive p{color:#cbd5e1}.primitive pre{background:#080b10;border:1px solid #26313d;border-radius:16px;color:#d9fff7;overflow:auto;padding:16px}table{border-collapse:collapse;overflow:hidden;width:100%}td,th{border-bottom:1px solid #26313d;padding:12px;text-align:left}@media(max-width:760px){main{padding:20px}}</style></head><body><main><section class="hero"><p class="eyebrow">Browser proof</p><h1>${escapeHtml51(title)}</h1><p>Recent real browser speech-to-assistant response measurements from persisted <code>client.live_latency</code> traces.</p><p class="status ${escapeHtml51(report.status)}">Status: ${escapeHtml51(report.status)}</p><section class="metrics"><article><span>p50</span><strong>${escapeHtml51(formatMs6(report.p50LatencyMs))}</strong></article><article><span>p95</span><strong>${escapeHtml51(formatMs6(report.p95LatencyMs))}</strong></article><article><span>Average</span><strong>${escapeHtml51(formatMs6(report.averageLatencyMs))}</strong></article><article><span>Samples</span><strong>${String(report.total)}</strong></article></section></section><section class="primitive"><p class="eyebrow">Copy into your app</p><h2><code>createVoiceLiveLatencyRoutes(...)</code> turns real browser timing into a release gate</h2><p>Persist live timing samples into the trace store so readiness, simulations, and trace timelines all point at the same self-hosted proof.</p><pre><code>${escapeHtml51(snippet)}</code></pre></section><table><thead><tr><th>Session</th><th>Latency</th><th>Status</th><th>Measured</th></tr></thead><tbody>${rows || '<tr><td colspan="4">No live latency samples yet.</td></tr>'}</tbody></table></main></body></html>`;
38210
+ const rows = report.recent.map((sample) => `<tr><td>${escapeHtml52(sample.sessionId)}</td><td>${escapeHtml52(formatMs6(sample.latencyMs))}</td><td>${escapeHtml52(sample.status ?? "unknown")}</td><td>${escapeHtml52(new Date(sample.at).toLocaleString())}</td></tr>`).join("");
38211
+ return `<!doctype html><html lang="en"><head><meta charset="utf-8" /><meta name="viewport" content="width=device-width, initial-scale=1" /><title>${escapeHtml52(title)}</title><style>body{background:#0c0f14;color:#f6f2e8;font-family:ui-sans-serif,system-ui,sans-serif;margin:0}main{margin:auto;max-width:1060px;padding:32px}.hero{background:linear-gradient(135deg,rgba(94,234,212,.16),rgba(245,158,11,.1));border:1px solid #26313d;border-radius:28px;margin-bottom:18px;padding:28px}.eyebrow{color:#5eead4;font-weight:900;letter-spacing:.12em;text-transform:uppercase}h1{font-size:clamp(2.4rem,6vw,5rem);line-height:.9;margin:.2rem 0 1rem}.status{border:1px solid #3f3f46;border-radius:999px;display:inline-flex;padding:8px 12px}.pass{color:#86efac}.warn,.empty{color:#fbbf24}.fail{color:#fca5a5}.metrics{display:grid;gap:14px;grid-template-columns:repeat(auto-fit,minmax(160px,1fr));margin:18px 0}.metrics article,table,.primitive{background:#141922;border:1px solid #26313d;border-radius:18px}.metrics article,.primitive{padding:16px}.metrics span{color:#a8b0b8}.metrics strong{display:block;font-size:2rem;margin-top:.25rem}.primitive{margin:0 0 18px}.primitive h2{margin:.2rem 0 .5rem}.primitive p{color:#cbd5e1}.primitive pre{background:#080b10;border:1px solid #26313d;border-radius:16px;color:#d9fff7;overflow:auto;padding:16px}table{border-collapse:collapse;overflow:hidden;width:100%}td,th{border-bottom:1px solid #26313d;padding:12px;text-align:left}@media(max-width:760px){main{padding:20px}}</style></head><body><main><section class="hero"><p class="eyebrow">Browser proof</p><h1>${escapeHtml52(title)}</h1><p>Recent real browser speech-to-assistant response measurements from persisted <code>client.live_latency</code> traces.</p><p class="status ${escapeHtml52(report.status)}">Status: ${escapeHtml52(report.status)}</p><section class="metrics"><article><span>p50</span><strong>${escapeHtml52(formatMs6(report.p50LatencyMs))}</strong></article><article><span>p95</span><strong>${escapeHtml52(formatMs6(report.p95LatencyMs))}</strong></article><article><span>Average</span><strong>${escapeHtml52(formatMs6(report.averageLatencyMs))}</strong></article><article><span>Samples</span><strong>${String(report.total)}</strong></article></section></section><section class="primitive"><p class="eyebrow">Copy into your app</p><h2><code>createVoiceLiveLatencyRoutes(...)</code> turns real browser timing into a release gate</h2><p>Persist live timing samples into the trace store so readiness, simulations, and trace timelines all point at the same self-hosted proof.</p><pre><code>${escapeHtml52(snippet)}</code></pre></section><table><thead><tr><th>Session</th><th>Latency</th><th>Status</th><th>Measured</th></tr></thead><tbody>${rows || '<tr><td colspan="4">No live latency samples yet.</td></tr>'}</tbody></table></main></body></html>`;
37895
38212
  };
37896
38213
  var createVoiceLiveLatencyRoutes = (options) => {
37897
38214
  const path = options.path ?? "/api/live-latency";
37898
38215
  const htmlPath = options.htmlPath === undefined ? "/live-latency" : options.htmlPath;
37899
- const routes = new Elysia55({
38216
+ const routes = new Elysia56({
37900
38217
  name: options.name ?? "absolutejs-voice-live-latency"
37901
38218
  }).get(path, () => summarizeVoiceLiveLatency(options));
37902
38219
  if (htmlPath) {
@@ -37913,9 +38230,9 @@ var createVoiceLiveLatencyRoutes = (options) => {
37913
38230
  return routes;
37914
38231
  };
37915
38232
  // src/turnQuality.ts
37916
- import { Elysia as Elysia56 } from "elysia";
38233
+ import { Elysia as Elysia57 } from "elysia";
37917
38234
  var DEFAULT_CONFIDENCE_WARN_THRESHOLD = 0.72;
37918
- var escapeHtml52 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
38235
+ var escapeHtml53 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
37919
38236
  var getTurnLatencyMs = (turn) => {
37920
38237
  const firstTranscriptAt = turn.transcripts.map((transcript) => transcript.endedAtMs ?? transcript.startedAtMs).filter((value) => typeof value === "number").sort((left, right) => left - right)[0];
37921
38238
  if (firstTranscriptAt === undefined) {
@@ -37985,24 +38302,24 @@ var summarizeVoiceTurnQuality = async (options) => {
37985
38302
  };
37986
38303
  var renderVoiceTurnQualityHTML = (report, options = {}) => {
37987
38304
  const title = options.title ?? "Voice Turn Quality";
37988
- const turns = report.turns.map((turn) => `<article class="turn ${escapeHtml52(turn.status)}">
38305
+ const turns = report.turns.map((turn) => `<article class="turn ${escapeHtml53(turn.status)}">
37989
38306
  <div class="turn-header">
37990
38307
  <div>
37991
- <p class="eyebrow">${escapeHtml52(turn.sessionId)} \xB7 ${escapeHtml52(turn.turnId)}</p>
37992
- <h2>${escapeHtml52(turn.text || "Empty turn")}</h2>
38308
+ <p class="eyebrow">${escapeHtml53(turn.sessionId)} \xB7 ${escapeHtml53(turn.turnId)}</p>
38309
+ <h2>${escapeHtml53(turn.text || "Empty turn")}</h2>
37993
38310
  </div>
37994
- <strong>${escapeHtml52(turn.status)}</strong>
38311
+ <strong>${escapeHtml53(turn.status)}</strong>
37995
38312
  </div>
37996
38313
  <dl>
37997
- <div><dt>Source</dt><dd>${escapeHtml52(turn.source ?? "unknown")}</dd></div>
38314
+ <div><dt>Source</dt><dd>${escapeHtml53(turn.source ?? "unknown")}</dd></div>
37998
38315
  <div><dt>Confidence</dt><dd>${turn.averageConfidence === undefined ? "n/a" : `${Math.round(turn.averageConfidence * 100)}%`}</dd></div>
37999
- <div><dt>Fallback</dt><dd>${turn.fallbackUsed ? `yes (${escapeHtml52(turn.fallbackSelectionReason ?? "selected")})` : "no"}</dd></div>
38000
- <div><dt>Correction</dt><dd>${turn.correctionChanged ? `changed${turn.correctionProvider ? ` by ${escapeHtml52(turn.correctionProvider)}` : ""}` : "none"}</dd></div>
38316
+ <div><dt>Fallback</dt><dd>${turn.fallbackUsed ? `yes (${escapeHtml53(turn.fallbackSelectionReason ?? "selected")})` : "no"}</dd></div>
38317
+ <div><dt>Correction</dt><dd>${turn.correctionChanged ? `changed${turn.correctionProvider ? ` by ${escapeHtml53(turn.correctionProvider)}` : ""}` : "none"}</dd></div>
38001
38318
  <div><dt>Transcripts</dt><dd>${String(turn.selectedTranscriptCount)} selected \xB7 ${String(turn.finalTranscriptCount)} final \xB7 ${String(turn.partialTranscriptCount)} partial</dd></div>
38002
38319
  <div><dt>Cost</dt><dd>${turn.costUnits === undefined ? "n/a" : String(turn.costUnits)}</dd></div>
38003
38320
  </dl>
38004
38321
  </article>`).join("");
38005
- return `<!doctype html><html lang="en"><head><meta charset="utf-8" /><meta name="viewport" content="width=device-width, initial-scale=1" /><title>${escapeHtml52(title)}</title><style>body{background:#101316;color:#f6f2e8;font-family:ui-sans-serif,system-ui,sans-serif;margin:0}main{margin:auto;max-width:1180px;padding:32px}.hero,.turn{background:#181d22;border:1px solid #2a323a;border-radius:20px;margin-bottom:16px;padding:20px}.hero{background:linear-gradient(135deg,rgba(251,191,36,.16),rgba(34,197,94,.1))}.eyebrow{color:#fbbf24;font-size:.78rem;font-weight:900;letter-spacing:.08em;text-transform:uppercase}h1{font-size:clamp(2.3rem,6vw,5rem);letter-spacing:-.06em;line-height:.9;margin:.2rem 0 1rem}h2{margin:.2rem 0 1rem}.summary{display:flex;flex-wrap:wrap;gap:10px}.pill{background:#0f1217;border:1px solid #3f3f46;border-radius:999px;padding:7px 10px}.turn-header{align-items:flex-start;display:flex;gap:16px;justify-content:space-between}.pass{color:#86efac}.warn,.unknown{color:#fde68a}.fail{color:#fca5a5}.turn.fail{border-color:rgba(248,113,113,.45)}dl{display:grid;gap:8px;grid-template-columns:repeat(auto-fit,minmax(160px,1fr))}dt{color:#a8b0b8;font-size:.8rem}dd{margin:0}@media(max-width:800px){main{padding:18px}.turn-header{display:block}}</style></head><body><main><section class="hero"><p class="eyebrow">Realtime STT Debugging</p><h1>${escapeHtml52(title)}</h1><div class="summary"><span class="pill ${escapeHtml52(report.status)}">${escapeHtml52(report.status)}</span><span class="pill">${String(report.total)} turns</span><span class="pill">${String(report.warnings)} warnings</span><span class="pill">${String(report.failed)} failed</span><span class="pill">${String(report.sessions)} sessions</span></div></section>${turns || '<section class="turn"><p>No committed turns found.</p></section>'}</main></body></html>`;
38322
+ return `<!doctype html><html lang="en"><head><meta charset="utf-8" /><meta name="viewport" content="width=device-width, initial-scale=1" /><title>${escapeHtml53(title)}</title><style>body{background:#101316;color:#f6f2e8;font-family:ui-sans-serif,system-ui,sans-serif;margin:0}main{margin:auto;max-width:1180px;padding:32px}.hero,.turn{background:#181d22;border:1px solid #2a323a;border-radius:20px;margin-bottom:16px;padding:20px}.hero{background:linear-gradient(135deg,rgba(251,191,36,.16),rgba(34,197,94,.1))}.eyebrow{color:#fbbf24;font-size:.78rem;font-weight:900;letter-spacing:.08em;text-transform:uppercase}h1{font-size:clamp(2.3rem,6vw,5rem);letter-spacing:-.06em;line-height:.9;margin:.2rem 0 1rem}h2{margin:.2rem 0 1rem}.summary{display:flex;flex-wrap:wrap;gap:10px}.pill{background:#0f1217;border:1px solid #3f3f46;border-radius:999px;padding:7px 10px}.turn-header{align-items:flex-start;display:flex;gap:16px;justify-content:space-between}.pass{color:#86efac}.warn,.unknown{color:#fde68a}.fail{color:#fca5a5}.turn.fail{border-color:rgba(248,113,113,.45)}dl{display:grid;gap:8px;grid-template-columns:repeat(auto-fit,minmax(160px,1fr))}dt{color:#a8b0b8;font-size:.8rem}dd{margin:0}@media(max-width:800px){main{padding:18px}.turn-header{display:block}}</style></head><body><main><section class="hero"><p class="eyebrow">Realtime STT Debugging</p><h1>${escapeHtml53(title)}</h1><div class="summary"><span class="pill ${escapeHtml53(report.status)}">${escapeHtml53(report.status)}</span><span class="pill">${String(report.total)} turns</span><span class="pill">${String(report.warnings)} warnings</span><span class="pill">${String(report.failed)} failed</span><span class="pill">${String(report.sessions)} sessions</span></div></section>${turns || '<section class="turn"><p>No committed turns found.</p></section>'}</main></body></html>`;
38006
38323
  };
38007
38324
  var createVoiceTurnQualityJSONHandler = (options) => async () => summarizeVoiceTurnQuality(options);
38008
38325
  var createVoiceTurnQualityHTMLHandler = (options) => async () => {
@@ -38019,7 +38336,7 @@ var createVoiceTurnQualityHTMLHandler = (options) => async () => {
38019
38336
  var createVoiceTurnQualityRoutes = (options) => {
38020
38337
  const path = options.path ?? "/api/turn-quality";
38021
38338
  const htmlPath = options.htmlPath === undefined ? `${path}/htmx` : options.htmlPath;
38022
- const routes = new Elysia56({
38339
+ const routes = new Elysia57({
38023
38340
  name: options.name ?? "absolutejs-voice-turn-quality"
38024
38341
  }).get(path, createVoiceTurnQualityJSONHandler(options));
38025
38342
  if (htmlPath) {
@@ -38028,10 +38345,10 @@ var createVoiceTurnQualityRoutes = (options) => {
38028
38345
  return routes;
38029
38346
  };
38030
38347
  // src/phoneAgent.ts
38031
- import { Elysia as Elysia58 } from "elysia";
38348
+ import { Elysia as Elysia59 } from "elysia";
38032
38349
 
38033
38350
  // src/phoneAgentProductionSmoke.ts
38034
- import { Elysia as Elysia57 } from "elysia";
38351
+ import { Elysia as Elysia58 } from "elysia";
38035
38352
  var defaultRequirements = [
38036
38353
  "media-started",
38037
38354
  "transcript",
@@ -38039,7 +38356,7 @@ var defaultRequirements = [
38039
38356
  "lifecycle-outcome",
38040
38357
  "no-session-error"
38041
38358
  ];
38042
- var escapeHtml53 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
38359
+ var escapeHtml54 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
38043
38360
  var payloadType = (event) => typeof event.payload.type === "string" ? event.payload.type : undefined;
38044
38361
  var hasTextPayload = (event) => ["text", "assistantText", "transcript"].some((key) => {
38045
38362
  const value = event.payload[key];
@@ -38148,10 +38465,10 @@ var resolveHandlerOptions = async (options, input) => ({
38148
38465
  });
38149
38466
  var renderVoicePhoneAgentProductionSmokeHTML = (report, options = {}) => {
38150
38467
  const title = options.title ?? "AbsoluteJS Voice Phone Smoke Contract";
38151
- const issues = report.issues.map((issue) => `<li><strong>${escapeHtml53(issue.requirement)}</strong>: ${escapeHtml53(issue.message)}</li>`).join("");
38152
- const outcomes = report.observed.lifecycleOutcomes.map((outcome) => `<span class="pill">${escapeHtml53(outcome)}</span>`).join("");
38153
- const requirements = report.required.map((requirement) => `<span class="pill">${escapeHtml53(requirement)}</span>`).join("");
38154
- return `<!doctype html><html lang="en"><head><meta charset="utf-8" /><meta name="viewport" content="width=device-width, initial-scale=1" /><title>${escapeHtml53(title)}</title><style>body{background:#0e141b;color:#f8f3e7;font-family:ui-sans-serif,system-ui,sans-serif;margin:0}main{margin:auto;max-width:1050px;padding:32px}.hero,.panel{background:#151d26;border:1px solid #283544;border-radius:24px;margin-bottom:16px;padding:22px}.hero{background:linear-gradient(135deg,rgba(20,184,166,.18),rgba(245,158,11,.12))}.eyebrow{color:#5eead4;font-weight:900;letter-spacing:.12em;text-transform:uppercase}h1{font-size:clamp(2.2rem,6vw,4.8rem);line-height:.92;margin:.2rem 0 1rem}.status{border:1px solid #3f3f46;border-radius:999px;display:inline-flex;font-weight:900;padding:8px 12px}.pass{color:#86efac}.fail{color:#fca5a5}.grid{display:grid;gap:12px;grid-template-columns:repeat(auto-fit,minmax(180px,1fr))}.metric{background:#0f151d;border:1px solid #283544;border-radius:16px;padding:14px}.metric strong{display:block;font-size:1.8rem}.pill{background:#0f151d;border:1px solid #3f3f46;border-radius:999px;display:inline-flex;margin:4px;padding:7px 10px}.issues{color:#fca5a5}code{color:#fde68a}@media(max-width:720px){main{padding:18px}}</style></head><body><main><section class="hero"><p class="eyebrow">Phone agent production smoke</p><h1>${escapeHtml53(title)}</h1><p class="status ${report.pass ? "pass" : "fail"}">${report.pass ? "PASS" : "FAIL"}</p><p>Contract <code>${escapeHtml53(report.contractId)}</code>${report.provider ? ` for <code>${escapeHtml53(report.provider)}</code>` : ""}${report.sessionId ? ` on session <code>${escapeHtml53(report.sessionId)}</code>` : ""}.</p></section><section class="panel"><h2>Observed Trace Evidence</h2><div class="grid"><div class="metric"><span>Media starts</span><strong>${String(report.observed.mediaStarts)}</strong></div><div class="metric"><span>Transcripts</span><strong>${String(report.observed.transcripts)}</strong></div><div class="metric"><span>Assistant responses</span><strong>${String(report.observed.assistantResponses)}</strong></div><div class="metric"><span>Session errors</span><strong>${String(report.observed.sessionErrors)}</strong></div></div><p>${outcomes || '<span class="pill">No lifecycle outcome</span>'}</p></section><section class="panel"><h2>Requirements</h2><p>${requirements}</p>${issues ? `<ul class="issues">${issues}</ul>` : '<p class="pass">All required phone-agent smoke evidence is present.</p>'}</section></main></body></html>`;
38468
+ const issues = report.issues.map((issue) => `<li><strong>${escapeHtml54(issue.requirement)}</strong>: ${escapeHtml54(issue.message)}</li>`).join("");
38469
+ const outcomes = report.observed.lifecycleOutcomes.map((outcome) => `<span class="pill">${escapeHtml54(outcome)}</span>`).join("");
38470
+ const requirements = report.required.map((requirement) => `<span class="pill">${escapeHtml54(requirement)}</span>`).join("");
38471
+ return `<!doctype html><html lang="en"><head><meta charset="utf-8" /><meta name="viewport" content="width=device-width, initial-scale=1" /><title>${escapeHtml54(title)}</title><style>body{background:#0e141b;color:#f8f3e7;font-family:ui-sans-serif,system-ui,sans-serif;margin:0}main{margin:auto;max-width:1050px;padding:32px}.hero,.panel{background:#151d26;border:1px solid #283544;border-radius:24px;margin-bottom:16px;padding:22px}.hero{background:linear-gradient(135deg,rgba(20,184,166,.18),rgba(245,158,11,.12))}.eyebrow{color:#5eead4;font-weight:900;letter-spacing:.12em;text-transform:uppercase}h1{font-size:clamp(2.2rem,6vw,4.8rem);line-height:.92;margin:.2rem 0 1rem}.status{border:1px solid #3f3f46;border-radius:999px;display:inline-flex;font-weight:900;padding:8px 12px}.pass{color:#86efac}.fail{color:#fca5a5}.grid{display:grid;gap:12px;grid-template-columns:repeat(auto-fit,minmax(180px,1fr))}.metric{background:#0f151d;border:1px solid #283544;border-radius:16px;padding:14px}.metric strong{display:block;font-size:1.8rem}.pill{background:#0f151d;border:1px solid #3f3f46;border-radius:999px;display:inline-flex;margin:4px;padding:7px 10px}.issues{color:#fca5a5}code{color:#fde68a}@media(max-width:720px){main{padding:18px}}</style></head><body><main><section class="hero"><p class="eyebrow">Phone agent production smoke</p><h1>${escapeHtml54(title)}</h1><p class="status ${report.pass ? "pass" : "fail"}">${report.pass ? "PASS" : "FAIL"}</p><p>Contract <code>${escapeHtml54(report.contractId)}</code>${report.provider ? ` for <code>${escapeHtml54(report.provider)}</code>` : ""}${report.sessionId ? ` on session <code>${escapeHtml54(report.sessionId)}</code>` : ""}.</p></section><section class="panel"><h2>Observed Trace Evidence</h2><div class="grid"><div class="metric"><span>Media starts</span><strong>${String(report.observed.mediaStarts)}</strong></div><div class="metric"><span>Transcripts</span><strong>${String(report.observed.transcripts)}</strong></div><div class="metric"><span>Assistant responses</span><strong>${String(report.observed.assistantResponses)}</strong></div><div class="metric"><span>Session errors</span><strong>${String(report.observed.sessionErrors)}</strong></div></div><p>${outcomes || '<span class="pill">No lifecycle outcome</span>'}</p></section><section class="panel"><h2>Requirements</h2><p>${requirements}</p>${issues ? `<ul class="issues">${issues}</ul>` : '<p class="pass">All required phone-agent smoke evidence is present.</p>'}</section></main></body></html>`;
38155
38472
  };
38156
38473
  var createVoicePhoneAgentProductionSmokeJSONHandler = (options) => async ({
38157
38474
  query,
@@ -38174,7 +38491,7 @@ var createVoicePhoneAgentProductionSmokeHTMLHandler = (options) => async ({
38174
38491
  var createVoicePhoneAgentProductionSmokeRoutes = (options) => {
38175
38492
  const path = options.path ?? "/api/voice/phone/smoke-contract";
38176
38493
  const htmlPath = options.htmlPath === undefined ? "/voice/phone/smoke-contract" : options.htmlPath;
38177
- const routes = new Elysia57({
38494
+ const routes = new Elysia58({
38178
38495
  name: options.name ?? "absolutejs-voice-phone-smoke-contract"
38179
38496
  }).get(path, createVoicePhoneAgentProductionSmokeJSONHandler(options));
38180
38497
  if (htmlPath) {
@@ -38217,7 +38534,7 @@ var PHONE_AGENT_LIFECYCLE_STAGES = [
38217
38534
  "completed",
38218
38535
  "failed"
38219
38536
  ];
38220
- var escapeHtml54 = (value) => value.replaceAll("&", "&amp;").replaceAll('"', "&quot;").replaceAll("'", "&#39;").replaceAll("<", "&lt;").replaceAll(">", "&gt;");
38537
+ var escapeHtml55 = (value) => value.replaceAll("&", "&amp;").replaceAll('"', "&quot;").replaceAll("'", "&#39;").replaceAll("<", "&lt;").replaceAll(">", "&gt;");
38221
38538
  var loadRouteJson = async (input) => {
38222
38539
  const response = await input.app.handle(new Request(new URL(input.path, input.origin).toString(), {
38223
38540
  headers: {
@@ -38455,10 +38772,10 @@ var renderVoicePhoneAgentSetupHTML = (report) => {
38455
38772
  const entry = findCarrierMatrixEntry(report.matrix, carrier);
38456
38773
  const urls = entry?.setup.urls;
38457
38774
  const primaryUrl = carrier.provider === "plivo" ? urls?.twiml : urls?.twiml;
38458
- return `<tr><td>${escapeHtml54(carrier.name ?? carrier.provider)}</td><td>${escapeHtml54(carrier.provider)}</td><td><code>${escapeHtml54(carrier.setupPath || "disabled")}</code></td><td><code>${escapeHtml54(carrier.smokePath || "disabled")}</code></td><td>${entry ? `<span class="${escapeHtml54(entry.status)}">${escapeHtml54(entry.status.toUpperCase())}</span>` : "unknown"}</td><td>${primaryUrl ? `<code>${escapeHtml54(primaryUrl)}</code>` : '<span class="muted">missing</span>'}</td><td>${urls?.webhook ? `<code>${escapeHtml54(urls.webhook)}</code>` : '<span class="muted">missing</span>'}</td><td>${urls?.stream ? `<code>${escapeHtml54(urls.stream)}</code>` : '<span class="muted">missing</span>'}</td></tr>`;
38775
+ return `<tr><td>${escapeHtml55(carrier.name ?? carrier.provider)}</td><td>${escapeHtml55(carrier.provider)}</td><td><code>${escapeHtml55(carrier.setupPath || "disabled")}</code></td><td><code>${escapeHtml55(carrier.smokePath || "disabled")}</code></td><td>${entry ? `<span class="${escapeHtml55(entry.status)}">${escapeHtml55(entry.status.toUpperCase())}</span>` : "unknown"}</td><td>${primaryUrl ? `<code>${escapeHtml55(primaryUrl)}</code>` : '<span class="muted">missing</span>'}</td><td>${urls?.webhook ? `<code>${escapeHtml55(urls.webhook)}</code>` : '<span class="muted">missing</span>'}</td><td>${urls?.stream ? `<code>${escapeHtml55(urls.stream)}</code>` : '<span class="muted">missing</span>'}</td></tr>`;
38459
38776
  }).join("");
38460
- const stageList = report.lifecycleStages.map((stage) => `<li><code>${escapeHtml54(stage)}</code></li>`).join("");
38461
- const snippet = escapeHtml54(`const phoneAgent = createVoicePhoneAgent({
38777
+ const stageList = report.lifecycleStages.map((stage) => `<li><code>${escapeHtml55(stage)}</code></li>`).join("");
38778
+ const snippet = escapeHtml55(`const phoneAgent = createVoicePhoneAgent({
38462
38779
  carriers: [
38463
38780
  {
38464
38781
  provider: 'twilio',
@@ -38492,11 +38809,11 @@ app.use(
38492
38809
  );`);
38493
38810
  const checklist = report.carriers.map((carrier) => {
38494
38811
  const instruction = report.setupInstructions.find((candidate) => candidate.provider === carrier.provider && candidate.carrierName === (carrier.name ?? carrier.provider));
38495
- const issueList = instruction?.issues.map((issue) => `<li>${escapeHtml54(issue)}</li>`).join("") ?? "";
38496
- const steps = instruction?.steps.map((step) => `<li>${escapeHtml54(step)}</li>`).join("") ?? "";
38497
- return `<article><h3>${escapeHtml54(carrier.name ?? carrier.provider)}</h3><ol>${steps}</ol>${issueList ? `<ul class="issues">${issueList}</ul>` : '<p class="pass">No carrier contract issues.</p>'}</article>`;
38812
+ const issueList = instruction?.issues.map((issue) => `<li>${escapeHtml55(issue)}</li>`).join("") ?? "";
38813
+ const steps = instruction?.steps.map((step) => `<li>${escapeHtml55(step)}</li>`).join("") ?? "";
38814
+ return `<article><h3>${escapeHtml55(carrier.name ?? carrier.provider)}</h3><ol>${steps}</ol>${issueList ? `<ul class="issues">${issueList}</ul>` : '<p class="pass">No carrier contract issues.</p>'}</article>`;
38498
38815
  }).join("");
38499
- return `<!doctype html><html lang="en"><head><meta charset="utf-8" /><meta name="viewport" content="width=device-width, initial-scale=1" /><title>${escapeHtml54(report.title)}</title><style>body{background:#10151c;color:#f8f3e7;font-family:ui-sans-serif,system-ui,sans-serif;margin:0}main{margin:auto;max-width:1180px;padding:32px}.hero,.primitive{background:linear-gradient(135deg,rgba(20,184,166,.2),rgba(245,158,11,.12));border:1px solid #283544;border-radius:28px;margin-bottom:18px;padding:28px}.primitive{background:#151d27;border-color:#365a60}.eyebrow{color:#5eead4;font-weight:900;letter-spacing:.12em;text-transform:uppercase}h1{font-size:clamp(2.3rem,6vw,4.8rem);line-height:.92;margin:.2rem 0 1rem}.badge{border:1px solid #3f3f46;border-radius:999px;display:inline-flex;padding:8px 12px}.pass{color:#86efac}.fail{color:#fca5a5}.warn{color:#fde68a}.muted{color:#aab5c0}table{background:#151d27;border:1px solid #283544;border-collapse:collapse;border-radius:18px;display:block;overflow:auto;width:100%}td,th{border-bottom:1px solid #283544;padding:12px;text-align:left;vertical-align:top}code{color:#fde68a;overflow-wrap:anywhere}.primitive p{color:#cbd5de;line-height:1.55}.primitive pre{background:#0b1118;border:1px solid #283544;border-radius:18px;color:#fef3c7;overflow:auto;padding:16px}.checklist{display:grid;gap:14px;grid-template-columns:repeat(auto-fit,minmax(280px,1fr));margin:18px 0}.checklist article{background:#151d27;border:1px solid #283544;border-radius:18px;padding:18px}.checklist ol{padding-left:20px}.issues{color:#fca5a5}.stages{display:grid;gap:8px;grid-template-columns:repeat(auto-fit,minmax(180px,1fr));padding-left:18px}a{color:#5eead4}</style></head><body><main><section class="hero"><p class="eyebrow">Phone agent setup</p><h1>${escapeHtml54(report.title)}</h1><p>One self-hosted entrypoint for carrier routes, setup reports, smoke checks, and normalized call lifecycle stages.</p><p class="badge ${report.ready ? "pass" : "fail"}">Ready: ${String(report.ready)}</p>${report.matrixPath ? `<p><a href="${escapeHtml54(report.matrixPath)}?format=html">Open carrier matrix</a></p>` : ""}</section><section class="primitive"><p class="eyebrow">Copy into your app</p><h2><code>createVoicePhoneAgent(...)</code> builds this carrier control plane</h2><p>Mount carrier routes once, expose setup and smoke proof, then feed the same carrier matrix and phone-agent smoke reports into production readiness so carrier regressions block deploys.</p><pre><code>${snippet}</code></pre></section><h2>Carrier Setup Checklist</h2><section class="checklist">${checklist}</section><h2>Carrier URLs</h2><table><thead><tr><th>Name</th><th>Provider</th><th>Setup</th><th>Smoke</th><th>Status</th><th>Answer/TwiML/TeXML</th><th>Webhook</th><th>Stream</th></tr></thead><tbody>${carrierRows}</tbody></table><h2>Lifecycle Schema</h2><ul class="stages">${stageList}</ul></main></body></html>`;
38816
+ return `<!doctype html><html lang="en"><head><meta charset="utf-8" /><meta name="viewport" content="width=device-width, initial-scale=1" /><title>${escapeHtml55(report.title)}</title><style>body{background:#10151c;color:#f8f3e7;font-family:ui-sans-serif,system-ui,sans-serif;margin:0}main{margin:auto;max-width:1180px;padding:32px}.hero,.primitive{background:linear-gradient(135deg,rgba(20,184,166,.2),rgba(245,158,11,.12));border:1px solid #283544;border-radius:28px;margin-bottom:18px;padding:28px}.primitive{background:#151d27;border-color:#365a60}.eyebrow{color:#5eead4;font-weight:900;letter-spacing:.12em;text-transform:uppercase}h1{font-size:clamp(2.3rem,6vw,4.8rem);line-height:.92;margin:.2rem 0 1rem}.badge{border:1px solid #3f3f46;border-radius:999px;display:inline-flex;padding:8px 12px}.pass{color:#86efac}.fail{color:#fca5a5}.warn{color:#fde68a}.muted{color:#aab5c0}table{background:#151d27;border:1px solid #283544;border-collapse:collapse;border-radius:18px;display:block;overflow:auto;width:100%}td,th{border-bottom:1px solid #283544;padding:12px;text-align:left;vertical-align:top}code{color:#fde68a;overflow-wrap:anywhere}.primitive p{color:#cbd5de;line-height:1.55}.primitive pre{background:#0b1118;border:1px solid #283544;border-radius:18px;color:#fef3c7;overflow:auto;padding:16px}.checklist{display:grid;gap:14px;grid-template-columns:repeat(auto-fit,minmax(280px,1fr));margin:18px 0}.checklist article{background:#151d27;border:1px solid #283544;border-radius:18px;padding:18px}.checklist ol{padding-left:20px}.issues{color:#fca5a5}.stages{display:grid;gap:8px;grid-template-columns:repeat(auto-fit,minmax(180px,1fr));padding-left:18px}a{color:#5eead4}</style></head><body><main><section class="hero"><p class="eyebrow">Phone agent setup</p><h1>${escapeHtml55(report.title)}</h1><p>One self-hosted entrypoint for carrier routes, setup reports, smoke checks, and normalized call lifecycle stages.</p><p class="badge ${report.ready ? "pass" : "fail"}">Ready: ${String(report.ready)}</p>${report.matrixPath ? `<p><a href="${escapeHtml55(report.matrixPath)}?format=html">Open carrier matrix</a></p>` : ""}</section><section class="primitive"><p class="eyebrow">Copy into your app</p><h2><code>createVoicePhoneAgent(...)</code> builds this carrier control plane</h2><p>Mount carrier routes once, expose setup and smoke proof, then feed the same carrier matrix and phone-agent smoke reports into production readiness so carrier regressions block deploys.</p><pre><code>${snippet}</code></pre></section><h2>Carrier Setup Checklist</h2><section class="checklist">${checklist}</section><h2>Carrier URLs</h2><table><thead><tr><th>Name</th><th>Provider</th><th>Setup</th><th>Smoke</th><th>Status</th><th>Answer/TwiML/TeXML</th><th>Webhook</th><th>Stream</th></tr></thead><tbody>${carrierRows}</tbody></table><h2>Lifecycle Schema</h2><ul class="stages">${stageList}</ul></main></body></html>`;
38500
38817
  };
38501
38818
  var createVoicePhoneAgent = (options) => {
38502
38819
  const carrierSummaries = options.carriers.map((carrier) => ({
@@ -38505,7 +38822,7 @@ var createVoicePhoneAgent = (options) => {
38505
38822
  setupPath: resolveSetupPath(carrier),
38506
38823
  smokePath: resolveSmokePath(carrier)
38507
38824
  }));
38508
- const app = new Elysia58({
38825
+ const app = new Elysia59({
38509
38826
  name: options.name ?? "absolutejs-voice-phone-agent"
38510
38827
  });
38511
38828
  for (const carrier of options.carriers) {
@@ -40314,8 +40631,8 @@ var createOpenAIVoiceTTS = (options) => {
40314
40631
  };
40315
40632
  };
40316
40633
  // src/providerCapabilities.ts
40317
- import { Elysia as Elysia59 } from "elysia";
40318
- var escapeHtml55 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
40634
+ import { Elysia as Elysia60 } from "elysia";
40635
+ var escapeHtml56 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
40319
40636
  var fromProviderList = (kind, providers, options) => (providers ?? []).map((provider) => ({
40320
40637
  configured: true,
40321
40638
  features: options.features?.[provider],
@@ -40380,27 +40697,27 @@ var summarizeVoiceProviderCapabilities = async (options) => {
40380
40697
  var renderVoiceProviderCapabilityHTML = (report, options = {}) => {
40381
40698
  const title = options.title ?? "Voice Provider Capabilities";
40382
40699
  const cards = report.capabilities.map((capability) => {
40383
- const features = (capability.features ?? []).map((feature) => `<span class="pill">${escapeHtml55(feature)}</span>`).join("");
40384
- return `<article class="card ${escapeHtml55(capability.status)}">
40700
+ const features = (capability.features ?? []).map((feature) => `<span class="pill">${escapeHtml56(feature)}</span>`).join("");
40701
+ return `<article class="card ${escapeHtml56(capability.status)}">
40385
40702
  <div class="card-header">
40386
40703
  <div>
40387
- <p class="eyebrow">${escapeHtml55(capability.kind)}</p>
40388
- <h2>${escapeHtml55(capability.label ?? capability.provider)}</h2>
40704
+ <p class="eyebrow">${escapeHtml56(capability.kind)}</p>
40705
+ <h2>${escapeHtml56(capability.label ?? capability.provider)}</h2>
40389
40706
  </div>
40390
- <strong>${escapeHtml55(capability.status)}</strong>
40707
+ <strong>${escapeHtml56(capability.status)}</strong>
40391
40708
  </div>
40392
- ${capability.description ? `<p>${escapeHtml55(capability.description)}</p>` : ""}
40709
+ ${capability.description ? `<p>${escapeHtml56(capability.description)}</p>` : ""}
40393
40710
  <dl>
40394
40711
  <div><dt>Configured</dt><dd>${capability.configured ? "yes" : "no"}</dd></div>
40395
40712
  <div><dt>Selected</dt><dd>${capability.selected ? "yes" : "no"}</dd></div>
40396
- <div><dt>Model</dt><dd>${escapeHtml55(capability.model ?? "default")}</dd></div>
40713
+ <div><dt>Model</dt><dd>${escapeHtml56(capability.model ?? "default")}</dd></div>
40397
40714
  <div><dt>Runs</dt><dd>${String(capability.health?.runCount ?? 0)}</dd></div>
40398
40715
  <div><dt>Errors</dt><dd>${String(capability.health?.errorCount ?? 0)}</dd></div>
40399
40716
  </dl>
40400
40717
  ${features ? `<div class="features">${features}</div>` : ""}
40401
40718
  </article>`;
40402
40719
  }).join("");
40403
- return `<!doctype html><html lang="en"><head><meta charset="utf-8" /><meta name="viewport" content="width=device-width, initial-scale=1" /><title>${escapeHtml55(title)}</title><style>body{background:#101316;color:#f6f2e8;font-family:ui-sans-serif,system-ui,sans-serif;margin:0}main{margin:auto;max-width:1180px;padding:32px}.hero,.card{background:#181d22;border:1px solid #2a323a;border-radius:20px;margin-bottom:16px;padding:20px}.hero{background:linear-gradient(135deg,rgba(14,165,233,.16),rgba(34,197,94,.12))}.eyebrow{color:#7dd3fc;font-size:.78rem;font-weight:900;letter-spacing:.08em;text-transform:uppercase}h1{font-size:clamp(2.3rem,6vw,5rem);letter-spacing:-.06em;line-height:.9;margin:.2rem 0 1rem}h2{margin:.2rem 0 1rem}.summary,.features{display:flex;flex-wrap:wrap;gap:10px}.pill{background:#0f1217;border:1px solid #3f3f46;border-radius:999px;padding:7px 10px}.grid{display:grid;gap:16px;grid-template-columns:repeat(auto-fit,minmax(260px,1fr))}.card-header{align-items:flex-start;display:flex;gap:16px;justify-content:space-between}.selected,.healthy{color:#86efac}.unconfigured,.degraded,.rate-limited,.suppressed{color:#fca5a5}.idle,.recoverable{color:#fde68a}dl{display:grid;gap:8px;grid-template-columns:repeat(2,minmax(0,1fr))}dt{color:#a8b0b8;font-size:.8rem}dd{margin:0}@media(max-width:800px){main{padding:18px}.card-header{display:block}}</style></head><body><main><section class="hero"><p class="eyebrow">Provider Discovery</p><h1>${escapeHtml55(title)}</h1><div class="summary"><span class="pill">${String(report.configured)} configured</span><span class="pill">${String(report.selected)} selected</span><span class="pill">${String(report.unconfigured)} missing</span><span class="pill">${String(report.total)} total</span></div></section><section class="grid">${cards || '<article class="card"><p>No provider capabilities configured.</p></article>'}</section></main></body></html>`;
40720
+ return `<!doctype html><html lang="en"><head><meta charset="utf-8" /><meta name="viewport" content="width=device-width, initial-scale=1" /><title>${escapeHtml56(title)}</title><style>body{background:#101316;color:#f6f2e8;font-family:ui-sans-serif,system-ui,sans-serif;margin:0}main{margin:auto;max-width:1180px;padding:32px}.hero,.card{background:#181d22;border:1px solid #2a323a;border-radius:20px;margin-bottom:16px;padding:20px}.hero{background:linear-gradient(135deg,rgba(14,165,233,.16),rgba(34,197,94,.12))}.eyebrow{color:#7dd3fc;font-size:.78rem;font-weight:900;letter-spacing:.08em;text-transform:uppercase}h1{font-size:clamp(2.3rem,6vw,5rem);letter-spacing:-.06em;line-height:.9;margin:.2rem 0 1rem}h2{margin:.2rem 0 1rem}.summary,.features{display:flex;flex-wrap:wrap;gap:10px}.pill{background:#0f1217;border:1px solid #3f3f46;border-radius:999px;padding:7px 10px}.grid{display:grid;gap:16px;grid-template-columns:repeat(auto-fit,minmax(260px,1fr))}.card-header{align-items:flex-start;display:flex;gap:16px;justify-content:space-between}.selected,.healthy{color:#86efac}.unconfigured,.degraded,.rate-limited,.suppressed{color:#fca5a5}.idle,.recoverable{color:#fde68a}dl{display:grid;gap:8px;grid-template-columns:repeat(2,minmax(0,1fr))}dt{color:#a8b0b8;font-size:.8rem}dd{margin:0}@media(max-width:800px){main{padding:18px}.card-header{display:block}}</style></head><body><main><section class="hero"><p class="eyebrow">Provider Discovery</p><h1>${escapeHtml56(title)}</h1><div class="summary"><span class="pill">${String(report.configured)} configured</span><span class="pill">${String(report.selected)} selected</span><span class="pill">${String(report.unconfigured)} missing</span><span class="pill">${String(report.total)} total</span></div></section><section class="grid">${cards || '<article class="card"><p>No provider capabilities configured.</p></article>'}</section></main></body></html>`;
40404
40721
  };
40405
40722
  var createVoiceProviderCapabilityJSONHandler = (options) => async () => summarizeVoiceProviderCapabilities(options);
40406
40723
  var createVoiceProviderCapabilityHTMLHandler = (options) => async () => {
@@ -40417,7 +40734,7 @@ var createVoiceProviderCapabilityHTMLHandler = (options) => async () => {
40417
40734
  var createVoiceProviderCapabilityRoutes = (options) => {
40418
40735
  const path = options.path ?? "/api/provider-capabilities";
40419
40736
  const htmlPath = options.htmlPath === undefined ? `${path}/htmx` : options.htmlPath;
40420
- const routes = new Elysia59({
40737
+ const routes = new Elysia60({
40421
40738
  name: options.name ?? "absolutejs-voice-provider-capabilities"
40422
40739
  }).get(path, createVoiceProviderCapabilityJSONHandler(options));
40423
40740
  if (htmlPath) {
@@ -40426,7 +40743,7 @@ var createVoiceProviderCapabilityRoutes = (options) => {
40426
40743
  return routes;
40427
40744
  };
40428
40745
  // src/providerOrchestration.ts
40429
- import { Elysia as Elysia60 } from "elysia";
40746
+ import { Elysia as Elysia61 } from "elysia";
40430
40747
  var defaultRequirement = {
40431
40748
  minProviders: 1,
40432
40749
  requireBudgetPolicy: false,
@@ -40439,7 +40756,7 @@ var statusRank7 = {
40439
40756
  warn: 1,
40440
40757
  fail: 2
40441
40758
  };
40442
- var escapeHtml56 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
40759
+ var escapeHtml57 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
40443
40760
  var isProviderList = (value) => Array.isArray(value) && value.every((entry) => typeof entry === "string");
40444
40761
  var uniqueSorted8 = (values) => [
40445
40762
  ...new Set(values.filter((value) => typeof value === "string"))
@@ -40582,27 +40899,27 @@ var renderVoiceProviderOrchestrationMarkdown = (report) => {
40582
40899
  };
40583
40900
  var renderVoiceProviderOrchestrationHTML = (report, options = {}) => {
40584
40901
  const title = options.title ?? "Voice Provider Orchestration";
40585
- const cards = report.surfaces.map((surface) => `<article class="card ${escapeHtml56(surface.status)}">
40586
- <div class="card-header"><div><p class="eyebrow">${escapeHtml56(surface.surface)}</p><h2>${escapeHtml56(surface.strategy ?? "default policy")}</h2></div><strong>${escapeHtml56(surface.status)}</strong></div>
40902
+ const cards = report.surfaces.map((surface) => `<article class="card ${escapeHtml57(surface.status)}">
40903
+ <div class="card-header"><div><p class="eyebrow">${escapeHtml57(surface.surface)}</p><h2>${escapeHtml57(surface.strategy ?? "default policy")}</h2></div><strong>${escapeHtml57(surface.status)}</strong></div>
40587
40904
  <dl>
40588
- <div><dt>Providers</dt><dd>${escapeHtml56(surface.providers.join(", ") || "none")}</dd></div>
40589
- <div><dt>Fallback</dt><dd>${escapeHtml56(surface.fallbackProviders.join(" -> ") || "none")}</dd></div>
40905
+ <div><dt>Providers</dt><dd>${escapeHtml57(surface.providers.join(", ") || "none")}</dd></div>
40906
+ <div><dt>Fallback</dt><dd>${escapeHtml57(surface.fallbackProviders.join(" -> ") || "none")}</dd></div>
40590
40907
  <div><dt>Circuit breaker</dt><dd>${surface.circuitBreaker ? "yes" : "no"}</dd></div>
40591
40908
  <div><dt>Timeout</dt><dd>${surface.timeoutBudget ? `${String(surface.timeoutMs)}ms` : "none"}</dd></div>
40592
40909
  <div><dt>Max cost</dt><dd>${surface.budgetPolicy.maxCost ?? "none"}</dd></div>
40593
40910
  <div><dt>Max latency</dt><dd>${surface.budgetPolicy.maxLatencyMs ? `${String(surface.budgetPolicy.maxLatencyMs)}ms` : "none"}</dd></div>
40594
40911
  <div><dt>Min quality</dt><dd>${surface.budgetPolicy.minQuality ?? "none"}</dd></div>
40595
- <div><dt>Fallback mode</dt><dd>${escapeHtml56(surface.fallbackMode || "default")}</dd></div>
40912
+ <div><dt>Fallback mode</dt><dd>${escapeHtml57(surface.fallbackMode || "default")}</dd></div>
40596
40913
  </dl>
40597
- ${surface.issues.length ? `<ul>${surface.issues.map((issue) => `<li><strong>${escapeHtml56(issue.status)}</strong> ${escapeHtml56(issue.message)}</li>`).join("")}</ul>` : "<p>No orchestration issues.</p>"}
40914
+ ${surface.issues.length ? `<ul>${surface.issues.map((issue) => `<li><strong>${escapeHtml57(issue.status)}</strong> ${escapeHtml57(issue.message)}</li>`).join("")}</ul>` : "<p>No orchestration issues.</p>"}
40598
40915
  </article>`).join("");
40599
- return `<!doctype html><html lang="en"><head><meta charset="utf-8" /><meta name="viewport" content="width=device-width, initial-scale=1" /><title>${escapeHtml56(title)}</title><style>body{background:#111827;color:#f9fafb;font-family:ui-sans-serif,system-ui,sans-serif;margin:0}main{margin:auto;max-width:1180px;padding:32px}.hero,.card{background:#172033;border:1px solid #2d3b55;border-radius:22px;margin-bottom:16px;padding:20px}.hero{background:linear-gradient(135deg,rgba(59,130,246,.18),rgba(20,184,166,.12))}.eyebrow{color:#93c5fd;font-size:.78rem;font-weight:900;letter-spacing:.08em;text-transform:uppercase}h1{font-size:clamp(2.3rem,6vw,5rem);letter-spacing:-.06em;line-height:.9;margin:.2rem 0 1rem}h2{margin:.2rem 0}.summary{display:flex;flex-wrap:wrap;gap:10px}.pill{background:#0f172a;border:1px solid #334155;border-radius:999px;padding:7px 10px}.grid{display:grid;gap:16px;grid-template-columns:repeat(auto-fit,minmax(300px,1fr))}.card-header{align-items:flex-start;display:flex;gap:16px;justify-content:space-between}.pass strong{color:#86efac}.warn strong{color:#fde68a}.fail strong{color:#fca5a5}dl{display:grid;gap:8px;grid-template-columns:repeat(2,minmax(0,1fr))}dt{color:#a8b0b8;font-size:.8rem}dd{margin:0;overflow-wrap:anywhere}li{margin:.35rem 0}@media(max-width:800px){main{padding:18px}.card-header{display:block}}</style></head><body><main><section class="hero"><p class="eyebrow">Provider Policy Proof</p><h1>${escapeHtml56(title)}</h1><div class="summary"><span class="pill">${escapeHtml56(report.profileId)}</span><span class="pill">${escapeHtml56(report.status)}</span><span class="pill">${String(report.summary.surfaces)} surfaces</span><span class="pill">${String(report.summary.providers)} providers</span><span class="pill">${String(report.issues.length)} issues</span></div></section><section class="grid">${cards || '<article class="card"><p>No provider orchestration surfaces configured.</p></article>'}</section></main></body></html>`;
40916
+ return `<!doctype html><html lang="en"><head><meta charset="utf-8" /><meta name="viewport" content="width=device-width, initial-scale=1" /><title>${escapeHtml57(title)}</title><style>body{background:#111827;color:#f9fafb;font-family:ui-sans-serif,system-ui,sans-serif;margin:0}main{margin:auto;max-width:1180px;padding:32px}.hero,.card{background:#172033;border:1px solid #2d3b55;border-radius:22px;margin-bottom:16px;padding:20px}.hero{background:linear-gradient(135deg,rgba(59,130,246,.18),rgba(20,184,166,.12))}.eyebrow{color:#93c5fd;font-size:.78rem;font-weight:900;letter-spacing:.08em;text-transform:uppercase}h1{font-size:clamp(2.3rem,6vw,5rem);letter-spacing:-.06em;line-height:.9;margin:.2rem 0 1rem}h2{margin:.2rem 0}.summary{display:flex;flex-wrap:wrap;gap:10px}.pill{background:#0f172a;border:1px solid #334155;border-radius:999px;padding:7px 10px}.grid{display:grid;gap:16px;grid-template-columns:repeat(auto-fit,minmax(300px,1fr))}.card-header{align-items:flex-start;display:flex;gap:16px;justify-content:space-between}.pass strong{color:#86efac}.warn strong{color:#fde68a}.fail strong{color:#fca5a5}dl{display:grid;gap:8px;grid-template-columns:repeat(2,minmax(0,1fr))}dt{color:#a8b0b8;font-size:.8rem}dd{margin:0;overflow-wrap:anywhere}li{margin:.35rem 0}@media(max-width:800px){main{padding:18px}.card-header{display:block}}</style></head><body><main><section class="hero"><p class="eyebrow">Provider Policy Proof</p><h1>${escapeHtml57(title)}</h1><div class="summary"><span class="pill">${escapeHtml57(report.profileId)}</span><span class="pill">${escapeHtml57(report.status)}</span><span class="pill">${String(report.summary.surfaces)} surfaces</span><span class="pill">${String(report.summary.providers)} providers</span><span class="pill">${String(report.issues.length)} issues</span></div></section><section class="grid">${cards || '<article class="card"><p>No provider orchestration surfaces configured.</p></article>'}</section></main></body></html>`;
40600
40917
  };
40601
40918
  var createVoiceProviderOrchestrationRoutes = (options) => {
40602
40919
  const path = options.path ?? "/api/voice/provider-orchestration";
40603
40920
  const htmlPath = options.htmlPath === undefined ? "/voice/provider-orchestration" : options.htmlPath;
40604
40921
  const markdownPath = options.markdownPath === undefined ? "/voice/provider-orchestration.md" : options.markdownPath;
40605
- const routes = new Elysia60({
40922
+ const routes = new Elysia61({
40606
40923
  name: options.name ?? "absolutejs-voice-provider-orchestration"
40607
40924
  }).get(path, () => buildVoiceProviderOrchestrationReport(options));
40608
40925
  if (htmlPath) {
@@ -40775,8 +41092,8 @@ var assertVoiceProviderRoutingContractEvidence = (reports, input = {}) => {
40775
41092
  return report;
40776
41093
  };
40777
41094
  // src/voiceMonitoring.ts
40778
- import { Elysia as Elysia61 } from "elysia";
40779
- var escapeHtml57 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
41095
+ import { Elysia as Elysia62 } from "elysia";
41096
+ var escapeHtml58 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
40780
41097
  var issueIdForRun = (run) => `voice-monitor:${run.id}:${run.impactedSessions?.[0] ?? "global"}`;
40781
41098
  var rollupStatus5 = (runs) => runs.some((run) => run.status === "fail") ? "fail" : runs.some((run) => run.status === "warn") ? "warn" : "pass";
40782
41099
  var createVoiceMemoryMonitorIssueStore = (initial = []) => {
@@ -41029,14 +41346,14 @@ ${rows || "| none | pass | info | | | No monitors configured. |"}
41029
41346
  };
41030
41347
  var renderVoiceMonitorHTML = (report, options = {}) => {
41031
41348
  const title = options.title ?? "Voice Monitors";
41032
- const runs = report.runs.map((run) => `<tr><td>${escapeHtml57(run.label)}</td><td class="${escapeHtml57(run.status)}">${escapeHtml57(run.status)}</td><td>${escapeHtml57(run.severity)}</td><td>${escapeHtml57(String(run.value ?? ""))}</td><td>${escapeHtml57(String(run.threshold ?? ""))}</td><td>${escapeHtml57(run.detail ?? "")}</td></tr>`).join("");
41033
- const issues = report.issues.map((issue) => `<li><strong>${escapeHtml57(issue.label)}</strong> <span class="${escapeHtml57(issue.status)}">${escapeHtml57(issue.status)}</span> ${escapeHtml57(issue.detail ?? "")}</li>`).join("");
41034
- const snippet = escapeHtml57(`app.use(createVoiceMonitorRoutes({
41349
+ const runs = report.runs.map((run) => `<tr><td>${escapeHtml58(run.label)}</td><td class="${escapeHtml58(run.status)}">${escapeHtml58(run.status)}</td><td>${escapeHtml58(run.severity)}</td><td>${escapeHtml58(String(run.value ?? ""))}</td><td>${escapeHtml58(String(run.threshold ?? ""))}</td><td>${escapeHtml58(run.detail ?? "")}</td></tr>`).join("");
41350
+ const issues = report.issues.map((issue) => `<li><strong>${escapeHtml58(issue.label)}</strong> <span class="${escapeHtml58(issue.status)}">${escapeHtml58(issue.status)}</span> ${escapeHtml58(issue.detail ?? "")}</li>`).join("");
41351
+ const snippet = escapeHtml58(`app.use(createVoiceMonitorRoutes({
41035
41352
  evidence,
41036
41353
  issueStore,
41037
41354
  monitors: [defineVoiceMonitor(...)]
41038
41355
  }));`);
41039
- return `<!doctype html><html lang="en"><head><meta charset="utf-8" /><meta name="viewport" content="width=device-width, initial-scale=1" /><title>${escapeHtml57(title)}</title><style>body{background:#10141b;color:#f8f2df;font-family:ui-sans-serif,system-ui,sans-serif;margin:0}main{margin:auto;max-width:1100px;padding:32px}.hero,.card{background:#171f2b;border:1px solid #2e3a4b;border-radius:24px;margin-bottom:16px;padding:22px}.eyebrow{color:#93c5fd;font-weight:900;letter-spacing:.12em;text-transform:uppercase}h1{font-size:clamp(2.2rem,6vw,4.7rem);line-height:.92;margin:.2rem 0 1rem}.pill{border:1px solid #64748b;border-radius:999px;display:inline-flex;font-weight:900;margin-right:8px;padding:8px 12px}.pass{color:#86efac}.warn,.acknowledged{color:#fde68a}.fail,.open{color:#fca5a5}.resolved,.muted{color:#cbd5e1}table{border-collapse:collapse;width:100%}td,th{border-bottom:1px solid #2e3a4b;padding:12px;text-align:left;vertical-align:top}pre{background:#0c1118;border:1px solid #2e3a4b;border-radius:16px;color:#dbeafe;overflow:auto;padding:16px}</style></head><body><main><section class="hero"><p class="eyebrow">Code-owned monitoring</p><h1>${escapeHtml57(title)}</h1><p class="pill ${escapeHtml57(report.status)}">Status: ${escapeHtml57(report.status)}</p><p class="pill">Open issues: ${String(report.summary.open)}</p><p class="pill">Critical: ${String(report.summary.criticalOpen)}</p></section><section class="card"><h2>Monitor Runs</h2><table><thead><tr><th>Monitor</th><th>Status</th><th>Severity</th><th>Value</th><th>Threshold</th><th>Detail</th></tr></thead><tbody>${runs}</tbody></table></section><section class="card"><h2>Issues</h2>${issues ? `<ul>${issues}</ul>` : '<p class="pass">No monitor issues.</p>'}</section><section class="card"><p class="eyebrow">Copy into your app</p><h2><code>createVoiceMonitorRoutes(...)</code></h2><pre><code>${snippet}</code></pre></section></main></body></html>`;
41356
+ return `<!doctype html><html lang="en"><head><meta charset="utf-8" /><meta name="viewport" content="width=device-width, initial-scale=1" /><title>${escapeHtml58(title)}</title><style>body{background:#10141b;color:#f8f2df;font-family:ui-sans-serif,system-ui,sans-serif;margin:0}main{margin:auto;max-width:1100px;padding:32px}.hero,.card{background:#171f2b;border:1px solid #2e3a4b;border-radius:24px;margin-bottom:16px;padding:22px}.eyebrow{color:#93c5fd;font-weight:900;letter-spacing:.12em;text-transform:uppercase}h1{font-size:clamp(2.2rem,6vw,4.7rem);line-height:.92;margin:.2rem 0 1rem}.pill{border:1px solid #64748b;border-radius:999px;display:inline-flex;font-weight:900;margin-right:8px;padding:8px 12px}.pass{color:#86efac}.warn,.acknowledged{color:#fde68a}.fail,.open{color:#fca5a5}.resolved,.muted{color:#cbd5e1}table{border-collapse:collapse;width:100%}td,th{border-bottom:1px solid #2e3a4b;padding:12px;text-align:left;vertical-align:top}pre{background:#0c1118;border:1px solid #2e3a4b;border-radius:16px;color:#dbeafe;overflow:auto;padding:16px}</style></head><body><main><section class="hero"><p class="eyebrow">Code-owned monitoring</p><h1>${escapeHtml58(title)}</h1><p class="pill ${escapeHtml58(report.status)}">Status: ${escapeHtml58(report.status)}</p><p class="pill">Open issues: ${String(report.summary.open)}</p><p class="pill">Critical: ${String(report.summary.criticalOpen)}</p></section><section class="card"><h2>Monitor Runs</h2><table><thead><tr><th>Monitor</th><th>Status</th><th>Severity</th><th>Value</th><th>Threshold</th><th>Detail</th></tr></thead><tbody>${runs}</tbody></table></section><section class="card"><h2>Issues</h2>${issues ? `<ul>${issues}</ul>` : '<p class="pass">No monitor issues.</p>'}</section><section class="card"><p class="eyebrow">Copy into your app</p><h2><code>createVoiceMonitorRoutes(...)</code></h2><pre><code>${snippet}</code></pre></section></main></body></html>`;
41040
41357
  };
41041
41358
  var actorFromRequest = async (request) => {
41042
41359
  if (!request.headers.get("content-type")?.includes("application/json")) {
@@ -41060,7 +41377,7 @@ var createVoiceMonitorRoutes = (options) => {
41060
41377
  monitors: options.monitors,
41061
41378
  now: options.now
41062
41379
  });
41063
- const routes = new Elysia61({
41380
+ const routes = new Elysia62({
41064
41381
  name: options.name ?? "absolutejs-voice-monitoring"
41065
41382
  }).get(path, report).get(`${path}.md`, async () => {
41066
41383
  return new Response(renderVoiceMonitorMarkdown(await report()), {
@@ -41107,7 +41424,7 @@ var createVoiceMonitorRoutes = (options) => {
41107
41424
  };
41108
41425
  var createVoiceMonitorRunnerRoutes = (options) => {
41109
41426
  const path = options.path ?? "/api/voice/monitor-runner";
41110
- return new Elysia61({
41427
+ return new Elysia62({
41111
41428
  name: options.name ?? "absolutejs-voice-monitor-runner"
41112
41429
  }).get(path, () => ({
41113
41430
  isRunning: options.runner.isRunning()
@@ -41495,8 +41812,8 @@ var recommendVoiceReadinessProfile = (options) => {
41495
41812
  };
41496
41813
  };
41497
41814
  // src/providerStackRecommendations.ts
41498
- import { Elysia as Elysia62 } from "elysia";
41499
- var escapeHtml58 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
41815
+ import { Elysia as Elysia63 } from "elysia";
41816
+ var escapeHtml59 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
41500
41817
  var profileProviderPriorities = {
41501
41818
  "meeting-recorder": {
41502
41819
  llm: ["openai", "anthropic", "gemini"],
@@ -41811,17 +42128,17 @@ var resolveProviderContractMatrixInput = async (matrix) => typeof matrix === "fu
41811
42128
  var renderVoiceProviderContractMatrixHTML = (report, options = {}) => {
41812
42129
  const title = options.title ?? "Voice Provider Contract Matrix";
41813
42130
  const rows = report.rows.map((row) => {
41814
- const checks = row.checks.map((check) => `<li class="${escapeHtml58(check.status)}"><strong>${escapeHtml58(check.label)}</strong><span>${escapeHtml58(check.detail ?? check.status)}</span>${check.remediation ? `<em>${check.remediation.href ? `<a href="${escapeHtml58(check.remediation.href)}">${escapeHtml58(check.remediation.label)}</a>` : escapeHtml58(check.remediation.label)}: ${escapeHtml58(check.remediation.detail)}</em>` : ""}</li>`).join("");
41815
- return `<article class="row ${escapeHtml58(row.status)}">
42131
+ const checks = row.checks.map((check) => `<li class="${escapeHtml59(check.status)}"><strong>${escapeHtml59(check.label)}</strong><span>${escapeHtml59(check.detail ?? check.status)}</span>${check.remediation ? `<em>${check.remediation.href ? `<a href="${escapeHtml59(check.remediation.href)}">${escapeHtml59(check.remediation.label)}</a>` : escapeHtml59(check.remediation.label)}: ${escapeHtml59(check.remediation.detail)}</em>` : ""}</li>`).join("");
42132
+ return `<article class="row ${escapeHtml59(row.status)}">
41816
42133
  <div>
41817
- <p class="eyebrow">${escapeHtml58(row.kind)}${row.selected ? " \xB7 selected" : ""}</p>
41818
- <h2>${escapeHtml58(row.provider)}</h2>
41819
- <p class="status ${escapeHtml58(row.status)}">${escapeHtml58(row.status.toUpperCase())}</p>
42134
+ <p class="eyebrow">${escapeHtml59(row.kind)}${row.selected ? " \xB7 selected" : ""}</p>
42135
+ <h2>${escapeHtml59(row.provider)}</h2>
42136
+ <p class="status ${escapeHtml59(row.status)}">${escapeHtml59(row.status.toUpperCase())}</p>
41820
42137
  </div>
41821
42138
  <ul>${checks}</ul>
41822
42139
  </article>`;
41823
42140
  }).join("");
41824
- const snippet = escapeHtml58(`const providerContracts = () =>
42141
+ const snippet = escapeHtml59(`const providerContracts = () =>
41825
42142
  createVoiceProviderContractMatrixPreset('phone-agent', {
41826
42143
  env: process.env,
41827
42144
  providers: {
@@ -41842,7 +42159,7 @@ createVoiceProductionReadinessRoutes({
41842
42159
  providerContractMatrix: () =>
41843
42160
  buildVoiceProviderContractMatrix(providerContracts())
41844
42161
  });`);
41845
- return `<!doctype html><html lang="en"><head><meta charset="utf-8" /><meta name="viewport" content="width=device-width, initial-scale=1" /><title>${escapeHtml58(title)}</title><style>body{background:#0f1412;color:#f7f3e8;font-family:ui-sans-serif,system-ui,sans-serif;margin:0}main{margin:auto;max-width:1180px;padding:32px}.hero,.primitive,.row{background:#17201b;border:1px solid #2d3b32;border-radius:24px;margin-bottom:16px;padding:22px}.hero{background:linear-gradient(135deg,rgba(34,197,94,.16),rgba(125,211,252,.12))}.primitive{background:#111814;border-color:#41604a}.eyebrow{color:#86efac;font-size:.78rem;font-weight:900;letter-spacing:.1em;text-transform:uppercase}h1{font-size:clamp(2.4rem,6vw,5rem);letter-spacing:-.06em;line-height:.9;margin:.2rem 0 1rem}h2{margin:.2rem 0}.summary{display:flex;flex-wrap:wrap;gap:10px}.pill,.status{border:1px solid #3f4f45;border-radius:999px;display:inline-flex;padding:8px 12px}.primitive code{color:#bbf7d0}.primitive p{color:#c8d8ca;line-height:1.55;margin:.45rem 0 0}.primitive pre{background:#08110d;border:1px solid #294132;border-radius:18px;color:#d9f99d;margin:16px 0 0;overflow:auto;padding:16px}.status.pass,.row.pass,.pass{border-color:rgba(34,197,94,.65)}.status.warn,.row.warn,.warn{border-color:rgba(245,158,11,.7)}.status.fail,.row.fail,.fail{border-color:rgba(239,68,68,.75)}.row{display:grid;gap:20px;grid-template-columns:minmax(180px,.45fr) 1fr}.row ul{display:grid;gap:10px;list-style:none;margin:0;padding:0}.row li{background:#111814;border:1px solid #2d3b32;border-radius:16px;display:grid;gap:4px;padding:12px}.row li span{color:#b8c2ba}.row li em{color:#f9d77e;font-style:normal}.row li a{color:#86efac}@media(max-width:760px){main{padding:18px}.row{grid-template-columns:1fr}}</style></head><body><main><section class="hero"><p class="eyebrow">Provider contracts</p><h1>${escapeHtml58(title)}</h1><p>Self-hosted provider proof for configured state, required env, latency budgets, fallback, streaming, and declared capabilities.</p><div class="summary"><span class="pill">${String(report.passed)} passing</span><span class="pill">${String(report.warned)} warning</span><span class="pill">${String(report.failed)} failing</span><span class="pill">${String(report.total)} total</span></div></section><section class="primitive"><p class="eyebrow">Copy into your app</p><h2><code>createVoiceProviderContractMatrixPreset(...)</code> builds this matrix</h2><p>Give AbsoluteJS your configured LLM, STT, and TTS providers once. It turns them into deploy-checkable proof for env, fallback, streaming, latency budgets, selected providers, and profile-required capabilities without a hosted dashboard.</p><pre><code>${snippet}</code></pre></section>${rows || '<article class="row"><p>No provider contracts configured.</p></article>'}</main></body></html>`;
42162
+ return `<!doctype html><html lang="en"><head><meta charset="utf-8" /><meta name="viewport" content="width=device-width, initial-scale=1" /><title>${escapeHtml59(title)}</title><style>body{background:#0f1412;color:#f7f3e8;font-family:ui-sans-serif,system-ui,sans-serif;margin:0}main{margin:auto;max-width:1180px;padding:32px}.hero,.primitive,.row{background:#17201b;border:1px solid #2d3b32;border-radius:24px;margin-bottom:16px;padding:22px}.hero{background:linear-gradient(135deg,rgba(34,197,94,.16),rgba(125,211,252,.12))}.primitive{background:#111814;border-color:#41604a}.eyebrow{color:#86efac;font-size:.78rem;font-weight:900;letter-spacing:.1em;text-transform:uppercase}h1{font-size:clamp(2.4rem,6vw,5rem);letter-spacing:-.06em;line-height:.9;margin:.2rem 0 1rem}h2{margin:.2rem 0}.summary{display:flex;flex-wrap:wrap;gap:10px}.pill,.status{border:1px solid #3f4f45;border-radius:999px;display:inline-flex;padding:8px 12px}.primitive code{color:#bbf7d0}.primitive p{color:#c8d8ca;line-height:1.55;margin:.45rem 0 0}.primitive pre{background:#08110d;border:1px solid #294132;border-radius:18px;color:#d9f99d;margin:16px 0 0;overflow:auto;padding:16px}.status.pass,.row.pass,.pass{border-color:rgba(34,197,94,.65)}.status.warn,.row.warn,.warn{border-color:rgba(245,158,11,.7)}.status.fail,.row.fail,.fail{border-color:rgba(239,68,68,.75)}.row{display:grid;gap:20px;grid-template-columns:minmax(180px,.45fr) 1fr}.row ul{display:grid;gap:10px;list-style:none;margin:0;padding:0}.row li{background:#111814;border:1px solid #2d3b32;border-radius:16px;display:grid;gap:4px;padding:12px}.row li span{color:#b8c2ba}.row li em{color:#f9d77e;font-style:normal}.row li a{color:#86efac}@media(max-width:760px){main{padding:18px}.row{grid-template-columns:1fr}}</style></head><body><main><section class="hero"><p class="eyebrow">Provider contracts</p><h1>${escapeHtml59(title)}</h1><p>Self-hosted provider proof for configured state, required env, latency budgets, fallback, streaming, and declared capabilities.</p><div class="summary"><span class="pill">${String(report.passed)} passing</span><span class="pill">${String(report.warned)} warning</span><span class="pill">${String(report.failed)} failing</span><span class="pill">${String(report.total)} total</span></div></section><section class="primitive"><p class="eyebrow">Copy into your app</p><h2><code>createVoiceProviderContractMatrixPreset(...)</code> builds this matrix</h2><p>Give AbsoluteJS your configured LLM, STT, and TTS providers once. It turns them into deploy-checkable proof for env, fallback, streaming, latency budgets, selected providers, and profile-required capabilities without a hosted dashboard.</p><pre><code>${snippet}</code></pre></section>${rows || '<article class="row"><p>No provider contracts configured.</p></article>'}</main></body></html>`;
41846
42163
  };
41847
42164
  var createVoiceProviderContractMatrixJSONHandler = (matrix) => async () => buildVoiceProviderContractMatrix(await resolveProviderContractMatrixInput(matrix));
41848
42165
  var createVoiceProviderContractMatrixHTMLHandler = (options) => async () => {
@@ -41857,7 +42174,7 @@ var createVoiceProviderContractMatrixHTMLHandler = (options) => async () => {
41857
42174
  var createVoiceProviderContractMatrixRoutes = (options) => {
41858
42175
  const path = options.path ?? "/api/provider-contracts";
41859
42176
  const htmlPath = options.htmlPath ?? "/provider-contracts";
41860
- const routes = new Elysia62({
42177
+ const routes = new Elysia63({
41861
42178
  name: options.name ?? "absolutejs-voice-provider-contract-matrix"
41862
42179
  });
41863
42180
  const jsonHandler = createVoiceProviderContractMatrixJSONHandler(options.matrix);
@@ -41975,7 +42292,7 @@ var assertVoiceProviderStackEvidence = (report, input = {}) => {
41975
42292
  return assertion;
41976
42293
  };
41977
42294
  // src/opsConsoleRoutes.ts
41978
- import { Elysia as Elysia63 } from "elysia";
42295
+ import { Elysia as Elysia64 } from "elysia";
41979
42296
  var DEFAULT_LINKS = [
41980
42297
  {
41981
42298
  description: "Quality gates for CI, deploy checks, and production readiness.",
@@ -42010,7 +42327,7 @@ var DEFAULT_LINKS = [
42010
42327
  label: "Handoffs"
42011
42328
  }
42012
42329
  ];
42013
- var escapeHtml59 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
42330
+ var escapeHtml60 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
42014
42331
  var countProviderStatuses = (providers) => {
42015
42332
  const degradedStatuses = new Set(["degraded", "rate-limited", "suppressed"]);
42016
42333
  const healthy = providers.filter((provider) => provider.status === "healthy").length;
@@ -42079,20 +42396,20 @@ var buildVoiceOpsConsoleReport = async (options) => {
42079
42396
  trace
42080
42397
  };
42081
42398
  };
42082
- var renderMetricCard = (input) => `<article class="metric"><span>${escapeHtml59(input.label)}</span><strong>${escapeHtml59(String(input.value))}</strong>${input.status ? `<p class="${escapeHtml59(input.status)}">${escapeHtml59(input.status)}</p>` : ""}${input.href ? `<a href="${escapeHtml59(input.href)}">Open</a>` : ""}</article>`;
42399
+ var renderMetricCard = (input) => `<article class="metric"><span>${escapeHtml60(input.label)}</span><strong>${escapeHtml60(String(input.value))}</strong>${input.status ? `<p class="${escapeHtml60(input.status)}">${escapeHtml60(input.status)}</p>` : ""}${input.href ? `<a href="${escapeHtml60(input.href)}">Open</a>` : ""}</article>`;
42083
42400
  var renderVoiceOpsConsoleHTML = (report, options = {}) => {
42084
42401
  const links = report.links.map((link) => `<article class="surface">
42085
- <div><h2>${escapeHtml59(link.label)}</h2>${link.description ? `<p>${escapeHtml59(link.description)}</p>` : ""}</div>
42086
- <p><a href="${escapeHtml59(link.href)}">Open ${escapeHtml59(link.label)}</a>${link.statusHref ? ` \xB7 <a href="${escapeHtml59(link.statusHref)}">Status</a>` : ""}</p>
42402
+ <div><h2>${escapeHtml60(link.label)}</h2>${link.description ? `<p>${escapeHtml60(link.description)}</p>` : ""}</div>
42403
+ <p><a href="${escapeHtml60(link.href)}">Open ${escapeHtml60(link.label)}</a>${link.statusHref ? ` \xB7 <a href="${escapeHtml60(link.statusHref)}">Status</a>` : ""}</p>
42087
42404
  </article>`).join("");
42088
- const sessions = report.recentSessions.length ? report.recentSessions.map((session) => `<tr><td>${escapeHtml59(session.sessionId)}</td><td>${escapeHtml59(session.status)}</td><td>${session.turnCount}</td><td>${session.errorCount}</td><td>${session.replayHref ? `<a href="${escapeHtml59(session.replayHref)}">Replay</a>` : ""}</td></tr>`).join("") : '<tr><td colspan="5">No sessions yet.</td></tr>';
42089
- const routing = report.recentRoutingEvents.length ? report.recentRoutingEvents.map((event) => `<tr><td>${escapeHtml59(event.kind)}</td><td>${escapeHtml59(event.provider ?? "unknown")}</td><td>${escapeHtml59(event.status ?? "unknown")}</td><td>${event.elapsedMs ?? 0}ms</td><td>${escapeHtml59(event.sessionId)}</td></tr>`).join("") : '<tr><td colspan="5">No provider routing events yet.</td></tr>';
42405
+ const sessions = report.recentSessions.length ? report.recentSessions.map((session) => `<tr><td>${escapeHtml60(session.sessionId)}</td><td>${escapeHtml60(session.status)}</td><td>${session.turnCount}</td><td>${session.errorCount}</td><td>${session.replayHref ? `<a href="${escapeHtml60(session.replayHref)}">Replay</a>` : ""}</td></tr>`).join("") : '<tr><td colspan="5">No sessions yet.</td></tr>';
42406
+ const routing = report.recentRoutingEvents.length ? report.recentRoutingEvents.map((event) => `<tr><td>${escapeHtml60(event.kind)}</td><td>${escapeHtml60(event.provider ?? "unknown")}</td><td>${escapeHtml60(event.status ?? "unknown")}</td><td>${event.elapsedMs ?? 0}ms</td><td>${escapeHtml60(event.sessionId)}</td></tr>`).join("") : '<tr><td colspan="5">No provider routing events yet.</td></tr>';
42090
42407
  const title = options.title ?? "AbsoluteJS Voice Ops Console";
42091
- return `<!doctype html><html lang="en"><head><meta charset="utf-8" /><meta name="viewport" content="width=device-width, initial-scale=1" /><title>${escapeHtml59(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>${escapeHtml59(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 ${escapeHtml59(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>`;
42408
+ return `<!doctype html><html lang="en"><head><meta charset="utf-8" /><meta name="viewport" content="width=device-width, initial-scale=1" /><title>${escapeHtml60(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>${escapeHtml60(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 ${escapeHtml60(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>`;
42092
42409
  };
42093
42410
  var createVoiceOpsConsoleRoutes = (options) => {
42094
42411
  const path = options.path ?? "/ops-console";
42095
- const routes = new Elysia63({
42412
+ const routes = new Elysia64({
42096
42413
  name: options.name ?? "absolutejs-voice-ops-console"
42097
42414
  });
42098
42415
  const getReport = () => buildVoiceOpsConsoleReport(options);
@@ -42109,7 +42426,7 @@ var createVoiceOpsConsoleRoutes = (options) => {
42109
42426
  return routes;
42110
42427
  };
42111
42428
  // src/incidentBundle.ts
42112
- import { Elysia as Elysia64 } from "elysia";
42429
+ import { Elysia as Elysia65 } from "elysia";
42113
42430
  var filterIncidentBundleArtifacts = (artifacts, filter = {}) => artifacts.filter((artifact) => {
42114
42431
  if (filter.sessionId && artifact.sessionId !== filter.sessionId) {
42115
42432
  return false;
@@ -42326,7 +42643,7 @@ var buildVoiceIncidentBundle = async (options) => {
42326
42643
  var createVoiceIncidentBundleRoutes = (options) => {
42327
42644
  const path = options.path ?? "/api/voice-incidents/:sessionId";
42328
42645
  const markdownPath = options.markdownPath === undefined ? "/voice-incidents/:sessionId/markdown" : options.markdownPath;
42329
- const routes = new Elysia64({
42646
+ const routes = new Elysia65({
42330
42647
  name: options.name ?? "absolutejs-voice-incident-bundle"
42331
42648
  });
42332
42649
  const getSessionId = (params) => params.sessionId ?? "";
@@ -42527,19 +42844,19 @@ var summarizeVoiceOpsStatus = async (options) => {
42527
42844
  };
42528
42845
  };
42529
42846
  // src/opsStatusRoutes.ts
42530
- import { Elysia as Elysia65 } from "elysia";
42531
- var escapeHtml60 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
42847
+ import { Elysia as Elysia66 } from "elysia";
42848
+ var escapeHtml61 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
42532
42849
  var renderVoiceOpsStatusHTML = (report, options = {}) => {
42533
42850
  const title = options.title ?? "AbsoluteJS Voice Ops Status";
42534
42851
  const surfaces = Object.entries(report.surfaces).map(([key, surface]) => {
42535
42852
  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;
42536
- return `<article class="surface ${escapeHtml60(surface.status)}"><span>${escapeHtml60(surface.status.toUpperCase())}</span><h2>${escapeHtml60(key)}</h2><strong>${escapeHtml60(value)}</strong></article>`;
42853
+ return `<article class="surface ${escapeHtml61(surface.status)}"><span>${escapeHtml61(surface.status.toUpperCase())}</span><h2>${escapeHtml61(key)}</h2><strong>${escapeHtml61(value)}</strong></article>`;
42537
42854
  }).join("");
42538
- return `<!doctype html><html lang="en"><head><meta charset="utf-8" /><meta name="viewport" content="width=device-width, initial-scale=1" /><title>${escapeHtml60(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>${escapeHtml60(title)}</h1><p>Compact pass/fail status for framework widgets, demos, and small customer-facing health badges.</p><p class="status ${escapeHtml60(report.status)}">Overall: ${escapeHtml60(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>`;
42855
+ return `<!doctype html><html lang="en"><head><meta charset="utf-8" /><meta name="viewport" content="width=device-width, initial-scale=1" /><title>${escapeHtml61(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>${escapeHtml61(title)}</h1><p>Compact pass/fail status for framework widgets, demos, and small customer-facing health badges.</p><p class="status ${escapeHtml61(report.status)}">Overall: ${escapeHtml61(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>`;
42539
42856
  };
42540
42857
  var createVoiceOpsStatusRoutes = (options) => {
42541
42858
  const path = options.path ?? "/api/voice/ops-status";
42542
- const routes = new Elysia65({
42859
+ const routes = new Elysia66({
42543
42860
  name: options.name ?? "absolutejs-voice-ops-status"
42544
42861
  });
42545
42862
  routes.get(path, async () => summarizeVoiceOpsStatus(options));
@@ -42972,8 +43289,8 @@ var createVoiceTTSProviderRouter = (options) => {
42972
43289
  };
42973
43290
  };
42974
43291
  // src/traceDeliveryRoutes.ts
42975
- import { Elysia as Elysia66 } from "elysia";
42976
- var escapeHtml61 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
43292
+ import { Elysia as Elysia67 } from "elysia";
43293
+ var escapeHtml62 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
42977
43294
  var getString20 = (value) => typeof value === "string" && value.trim() ? value.trim() : undefined;
42978
43295
  var getNumber12 = (value) => {
42979
43296
  if (typeof value === "number" && Number.isFinite(value)) {
@@ -43054,14 +43371,14 @@ var renderSinkResults2 = (delivery) => {
43054
43371
  if (entries.length === 0) {
43055
43372
  return "<p>No sink delivery attempts recorded yet.</p>";
43056
43373
  }
43057
- return `<ul>${entries.map(([sinkId, result]) => `<li><strong>${escapeHtml61(sinkId)}</strong>: ${escapeHtml61(result.status)}${result.deliveredTo ? ` to ${escapeHtml61(result.deliveredTo)}` : ""}${result.error ? ` (${escapeHtml61(result.error)})` : ""}</li>`).join("")}</ul>`;
43374
+ return `<ul>${entries.map(([sinkId, result]) => `<li><strong>${escapeHtml62(sinkId)}</strong>: ${escapeHtml62(result.status)}${result.deliveredTo ? ` to ${escapeHtml62(result.deliveredTo)}` : ""}${result.error ? ` (${escapeHtml62(result.error)})` : ""}</li>`).join("")}</ul>`;
43058
43375
  };
43059
- var renderEventList2 = (delivery) => delivery.events.length === 0 ? "<p>No trace events in this delivery.</p>" : `<ul>${delivery.events.map((event) => `<li>${escapeHtml61(event.type)} <small>${escapeHtml61(event.id)}</small>${event.sessionId ? ` session=${escapeHtml61(event.sessionId)}` : ""}</li>`).join("")}</ul>`;
43376
+ var renderEventList2 = (delivery) => delivery.events.length === 0 ? "<p>No trace events in this delivery.</p>" : `<ul>${delivery.events.map((event) => `<li>${escapeHtml62(event.type)} <small>${escapeHtml62(event.id)}</small>${event.sessionId ? ` session=${escapeHtml62(event.sessionId)}` : ""}</li>`).join("")}</ul>`;
43060
43377
  var renderVoiceTraceDeliveryHTML = (report, options = {}) => {
43061
43378
  const title = options.title ?? "AbsoluteJS Voice Trace Deliveries";
43062
- const drainAction = options.workerPath === false ? "" : `<form method="post" action="${escapeHtml61(options.workerPath ?? "/api/voice-trace-deliveries/drain")}"><button type="submit">Drain trace deliveries</button></form>`;
43063
- const rows = report.deliveries.map((delivery) => `<article class="delivery ${escapeHtml61(delivery.deliveryStatus)}"><div class="head"><div><span>${escapeHtml61(delivery.deliveryStatus)}</span><h2>${escapeHtml61(delivery.id)}</h2><p>${escapeHtml61(new Date(delivery.createdAt).toLocaleString())}${delivery.deliveredAt ? ` \xB7 delivered ${escapeHtml61(new Date(delivery.deliveredAt).toLocaleString())}` : ""}</p></div><strong>${String(delivery.deliveryAttempts ?? 0)} attempt(s)</strong></div>${delivery.deliveryError ? `<p class="error">${escapeHtml61(delivery.deliveryError)}</p>` : ""}<h3>Sinks</h3>${renderSinkResults2(delivery)}<h3>Events</h3>${renderEventList2(delivery)}</article>`).join("");
43064
- return `<!doctype html><html lang="en"><head><meta charset="utf-8" /><meta name="viewport" content="width=device-width, initial-scale=1" /><title>${escapeHtml61(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>${escapeHtml61(title)}</h1><p>Checked ${escapeHtml61(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>`;
43379
+ const drainAction = options.workerPath === false ? "" : `<form method="post" action="${escapeHtml62(options.workerPath ?? "/api/voice-trace-deliveries/drain")}"><button type="submit">Drain trace deliveries</button></form>`;
43380
+ const rows = report.deliveries.map((delivery) => `<article class="delivery ${escapeHtml62(delivery.deliveryStatus)}"><div class="head"><div><span>${escapeHtml62(delivery.deliveryStatus)}</span><h2>${escapeHtml62(delivery.id)}</h2><p>${escapeHtml62(new Date(delivery.createdAt).toLocaleString())}${delivery.deliveredAt ? ` \xB7 delivered ${escapeHtml62(new Date(delivery.deliveredAt).toLocaleString())}` : ""}</p></div><strong>${String(delivery.deliveryAttempts ?? 0)} attempt(s)</strong></div>${delivery.deliveryError ? `<p class="error">${escapeHtml62(delivery.deliveryError)}</p>` : ""}<h3>Sinks</h3>${renderSinkResults2(delivery)}<h3>Events</h3>${renderEventList2(delivery)}</article>`).join("");
43381
+ return `<!doctype html><html lang="en"><head><meta charset="utf-8" /><meta name="viewport" content="width=device-width, initial-scale=1" /><title>${escapeHtml62(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>${escapeHtml62(title)}</h1><p>Checked ${escapeHtml62(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>`;
43065
43382
  };
43066
43383
  var createVoiceTraceDeliveryJSONHandler = (options) => async ({ query }) => buildVoiceTraceDeliveryReport(options, resolveVoiceTraceDeliveryFilter(query, options.filter));
43067
43384
  var createVoiceTraceDeliveryHTMLHandler = (options) => async ({ query }) => {
@@ -43081,7 +43398,7 @@ var createVoiceTraceDeliveryRoutes = (options) => {
43081
43398
  const path = options.path ?? "/api/voice-trace-deliveries";
43082
43399
  const htmlPath = options.htmlPath === undefined ? "/traces/deliveries" : options.htmlPath;
43083
43400
  const workerPath = options.workerPath === undefined ? `${path}/drain` : options.workerPath;
43084
- const routes = new Elysia66({
43401
+ const routes = new Elysia67({
43085
43402
  name: options.name ?? "absolutejs-voice-trace-deliveries"
43086
43403
  }).get(path, createVoiceTraceDeliveryJSONHandler(options));
43087
43404
  if (htmlPath !== false) {
@@ -43234,7 +43551,7 @@ var createVoiceMemoryStore = () => {
43234
43551
  return { get, getOrCreate, list, remove, set };
43235
43552
  };
43236
43553
  // src/opsWebhook.ts
43237
- import { Elysia as Elysia67 } from "elysia";
43554
+ import { Elysia as Elysia68 } from "elysia";
43238
43555
  var toHex7 = (bytes) => Array.from(bytes, (byte) => byte.toString(16).padStart(2, "0")).join("");
43239
43556
  var signVoiceOpsWebhookBody = async (input) => {
43240
43557
  const encoder2 = new TextEncoder;
@@ -43364,7 +43681,7 @@ var verifyVoiceOpsWebhookSignature = async (input) => {
43364
43681
  };
43365
43682
  var createVoiceOpsWebhookReceiverRoutes = (options = {}) => {
43366
43683
  const path = options.path ?? "/api/voice-ops/webhook";
43367
- return new Elysia67().post(path, async ({ body, request, set }) => {
43684
+ return new Elysia68().post(path, async ({ body, request, set }) => {
43368
43685
  const bodyText = typeof body === "string" ? body : JSON.stringify(body);
43369
43686
  if (options.signingSecret) {
43370
43687
  const verification = await verifyVoiceOpsWebhookSignature({
@@ -43819,7 +44136,7 @@ var resolveVoiceOpsPreset = (name, overrides = {}) => {
43819
44136
  };
43820
44137
  };
43821
44138
  // src/postCallAnalysis.ts
43822
- import { Elysia as Elysia68 } from "elysia";
44139
+ import { Elysia as Elysia69 } from "elysia";
43823
44140
  var isStore = (value) => Boolean(value) && typeof value === "object" && value !== null && ("list" in value);
43824
44141
  var asArray = async (value) => Array.isArray(value) ? value : isStore(value) ? await value.list() : [];
43825
44142
  var getPathValue3 = (source, path) => {
@@ -43998,7 +44315,7 @@ var resolvePostCallAnalysisReport = async (options, input) => {
43998
44315
  };
43999
44316
  var createVoicePostCallAnalysisRoutes = (options = {}) => {
44000
44317
  const path = options.path ?? "/api/voice/post-call-analysis";
44001
- const routes = new Elysia68({
44318
+ const routes = new Elysia69({
44002
44319
  name: options.name ?? "absolutejs-voice-post-call-analysis"
44003
44320
  });
44004
44321
  routes.get(path, async ({ query }) => {
@@ -44023,7 +44340,7 @@ var createVoicePostCallAnalysisRoutes = (options = {}) => {
44023
44340
  return routes;
44024
44341
  };
44025
44342
  // src/guardrails.ts
44026
- import { Elysia as Elysia69 } from "elysia";
44343
+ import { Elysia as Elysia70 } from "elysia";
44027
44344
  var stringifyContent = (value) => typeof value === "string" ? value : JSON.stringify(value) ?? "";
44028
44345
  var appliesToStage = (rule, stage) => !rule.stages || rule.stages.length === 0 || rule.stages.includes(stage);
44029
44346
  var matchesRule = async (rule, input) => {
@@ -44325,7 +44642,7 @@ var resolveGuardrailReport = async (options, input) => {
44325
44642
  };
44326
44643
  var createVoiceGuardrailRoutes = (options = {}) => {
44327
44644
  const path = options.path ?? "/api/voice/guardrails";
44328
- const routes = new Elysia69({
44645
+ const routes = new Elysia70({
44329
44646
  name: options.name ?? "absolutejs-voice-guardrails"
44330
44647
  });
44331
44648
  routes.all(path, async ({ request }) => {
@@ -45104,7 +45421,7 @@ var shapeTelephonyAssistantText = (text, options = {}) => {
45104
45421
  return ensureTerminalPunctuation(normalizeWhitespace(limitedChars));
45105
45422
  };
45106
45423
  // src/proofPack.ts
45107
- import { Elysia as Elysia70 } from "elysia";
45424
+ import { Elysia as Elysia71 } from "elysia";
45108
45425
  import { mkdir as mkdir5 } from "fs/promises";
45109
45426
  import { dirname as dirname3, join as join4 } from "path";
45110
45427
  var toGeneratedAt = (value) => value === undefined ? new Date().toISOString() : typeof value === "number" ? new Date(value).toISOString() : value;
@@ -45690,7 +46007,7 @@ var createVoiceProofPackArtifacts = (input) => [
45690
46007
  var createVoiceProofPackRoutes = (options) => {
45691
46008
  const jsonPath = options.jsonPath ?? "/api/voice/proof-pack";
45692
46009
  const markdownPath = options.markdownPath ?? "/voice/proof-pack.md";
45693
- const app = new Elysia70({ name: options.name ?? "voice-proof-pack" });
46010
+ const app = new Elysia71({ name: options.name ?? "voice-proof-pack" });
45694
46011
  if (jsonPath !== false) {
45695
46012
  app.get(jsonPath, async () => new Response(JSON.stringify(await resolveProofPack(options.source), null, 2), {
45696
46013
  headers: {
@@ -46791,7 +47108,7 @@ var buildVoiceMultilingualProofReadinessCheck = (report, options = {}) => {
46791
47108
  };
46792
47109
  };
46793
47110
  // src/monitor.ts
46794
- import { Elysia as Elysia71 } from "elysia";
47111
+ import { Elysia as Elysia72 } from "elysia";
46795
47112
  var buildAudioFanout = () => {
46796
47113
  const handlers = new Set;
46797
47114
  return {
@@ -47080,7 +47397,7 @@ var createVoiceLiveMonitorRoutes = (options) => {
47080
47397
  transfer: options.controlHandlers?.transfer ?? buildDefaultControlHandler("transfer"),
47081
47398
  voicemail: options.controlHandlers?.voicemail ?? buildDefaultControlHandler("voicemail")
47082
47399
  };
47083
- const app = new Elysia71({ name: "absolutejs-voice-monitor" });
47400
+ const app = new Elysia72({ name: "absolutejs-voice-monitor" });
47084
47401
  const unsubscribers = new WeakMap;
47085
47402
  if (listenPath !== false && listenPath.length > 0) {
47086
47403
  app.ws(`/${listenPath.replace(/^\/+/, "")}`, {
@@ -47253,6 +47570,8 @@ var createVoiceLiveMonitorRoutes = (options) => {
47253
47570
  export {
47254
47571
  writeVoiceProofPack,
47255
47572
  writeVoiceMediaPipelineArtifacts,
47573
+ wrapVoiceHTMLWithHTMXPolling,
47574
+ wrapVoiceHTMLInHTMXContainer,
47256
47575
  withVoiceOpsTaskId,
47257
47576
  withVoiceIntegrationEventId,
47258
47577
  voiceTelephonyOutcomeToRouteResult,
@@ -47352,6 +47671,7 @@ export {
47352
47671
  resolveVoiceOpsPreset,
47353
47672
  resolveVoiceMonitorIssue,
47354
47673
  resolveVoiceDiagnosticsTraceFilter,
47674
+ resolveVoiceDashboardRenderers,
47355
47675
  resolveVoiceAuditTrailFilter,
47356
47676
  resolveVoiceAuditDeliveryFilter,
47357
47677
  resolveVoiceAssistantMode,
@@ -47382,6 +47702,8 @@ export {
47382
47702
  renderVoiceScenarioFixtureEvalHTML,
47383
47703
  renderVoiceScenarioEvalHTML,
47384
47704
  renderVoiceResilienceHTML,
47705
+ renderVoiceReplayTimelineHTMX,
47706
+ renderVoiceReplayTimelineFromArtifact,
47385
47707
  renderVoiceReconnectContractHTML,
47386
47708
  renderVoiceRealtimeProviderContractHTML,
47387
47709
  renderVoiceRealtimeChannelMarkdown,
@@ -47427,6 +47749,9 @@ export {
47427
47749
  renderVoiceMediaPipelineMarkdown,
47428
47750
  renderVoiceMediaPipelineHTML,
47429
47751
  renderVoiceLiveLatencyHTML,
47752
+ renderVoiceLiveCallViewerHTMX,
47753
+ renderVoiceLiveCallViewerFromViewer,
47754
+ renderVoiceLiveCallViewerFromState,
47430
47755
  renderVoiceLatencySLOMarkdown,
47431
47756
  renderVoiceIncidentTimelineMarkdown,
47432
47757
  renderVoiceIncidentTimelineHTML,
@@ -47443,6 +47768,8 @@ export {
47443
47768
  renderVoiceDeliveryRuntimeHTML,
47444
47769
  renderVoiceDataControlMarkdown,
47445
47770
  renderVoiceDataControlHTML,
47771
+ renderVoiceCostDashboardHTMX,
47772
+ renderVoiceCostDashboardFromEvents,
47446
47773
  renderVoiceCompetitiveCoverageMarkdown,
47447
47774
  renderVoiceCompetitiveCoverageHTML,
47448
47775
  renderVoiceCampaignsHTML,
@@ -47676,6 +48003,7 @@ export {
47676
48003
  createVoiceReviewSavedEvent,
47677
48004
  createVoiceRetentionScheduler,
47678
48005
  createVoiceResilienceRoutes,
48006
+ createVoiceReplayTimelineHTMXRoute,
47679
48007
  createVoiceRedisTelnyxWebhookEventStore,
47680
48008
  createVoiceRedisTelephonyWebhookIdempotencyStore,
47681
48009
  createVoiceRedisTaskLeaseCoordinator,
@@ -47800,6 +48128,7 @@ export {
47800
48128
  createVoiceLiveOpsController,
47801
48129
  createVoiceLiveMonitorRoutes,
47802
48130
  createVoiceLiveLatencyRoutes,
48131
+ createVoiceLiveCallViewerHTMXRoute,
47803
48132
  createVoiceLinearIssueUpdateSink,
47804
48133
  createVoiceLinearIssueSyncSinks,
47805
48134
  createVoiceLinearIssueSink,
@@ -47823,6 +48152,8 @@ export {
47823
48152
  createVoiceHandoffDeliveryWorkerLoop,
47824
48153
  createVoiceHandoffDeliveryWorker,
47825
48154
  createVoiceHandoffDeliveryRecord,
48155
+ createVoiceHTMXDashboardRoutesFromStores,
48156
+ createVoiceHTMXDashboardRoutes,
47826
48157
  createVoiceHMACAuthVerifier,
47827
48158
  createVoiceGuardrailRuntime,
47828
48159
  createVoiceGuardrailRoutes,
@@ -47861,6 +48192,7 @@ export {
47861
48192
  createVoiceDeliveryRuntime,
47862
48193
  createVoiceDataControlRoutes,
47863
48194
  createVoiceDTMFTool,
48195
+ createVoiceCostDashboardHTMXRoute,
47864
48196
  createVoiceCostAccountant,
47865
48197
  createVoiceCompetitiveCoverageRoutes,
47866
48198
  createVoiceCampaignWorkerLoop,
@@ -47929,6 +48261,7 @@ export {
47929
48261
  createMemoryVoiceTelnyxWebhookEventStore,
47930
48262
  createMemoryVoiceTelephonyWebhookIdempotencyStore,
47931
48263
  createMemoryVoicePlivoWebhookNonceStore,
48264
+ createLiveCallViewerFromOptions,
47932
48265
  createLiveCallViewer,
47933
48266
  createJSONVoiceAssistantModel,
47934
48267
  createInMemoryVoiceCallQuota,
@@ -48017,6 +48350,7 @@ export {
48017
48350
  buildVoiceIncidentRecoveryOutcomeReadinessCheck,
48018
48351
  buildVoiceIncidentBundle,
48019
48352
  buildVoiceIOProviderRouterTraceEvent,
48353
+ buildVoiceHTMXAttributes,
48020
48354
  buildVoiceGuardrailReport,
48021
48355
  buildVoiceFailureReplay,
48022
48356
  buildVoiceDiagnosticsMarkdown,