@absolutejs/voice 0.0.22-beta.431 → 0.0.22-beta.432
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/incidentTimeline.d.ts +117 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +452 -170
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -30113,8 +30113,286 @@ var createVoiceOperationalStatusRoutes = (options) => {
|
|
|
30113
30113
|
}
|
|
30114
30114
|
return routes;
|
|
30115
30115
|
};
|
|
30116
|
-
// src/
|
|
30116
|
+
// src/incidentTimeline.ts
|
|
30117
30117
|
import { Elysia as Elysia46 } from "elysia";
|
|
30118
|
+
var escapeHtml43 = (value) => value.replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">").replaceAll('"', """).replaceAll("'", "'");
|
|
30119
|
+
var resolveValue2 = async (value) => typeof value === "function" ? await value() : value;
|
|
30120
|
+
var linkForSession = (link, sessionId) => {
|
|
30121
|
+
if (!link || !sessionId) {
|
|
30122
|
+
return;
|
|
30123
|
+
}
|
|
30124
|
+
return typeof link === "function" ? link(sessionId) : link;
|
|
30125
|
+
};
|
|
30126
|
+
var statusToSeverity = (status) => status === "fail" || status === "failed" ? "critical" : status === "warn" || status === "warning" || status === "recovered" ? "warn" : "info";
|
|
30127
|
+
var failureReplayStatusToSeverity = (status) => status === "failed" ? "critical" : status === "healthy" ? "info" : "warn";
|
|
30128
|
+
var withinWindow = (event, now, windowMs) => !windowMs || event.at >= now - windowMs;
|
|
30129
|
+
var eventStatus2 = (event) => event.severity === "critical" ? "fail" : event.severity === "warn" ? "warn" : "pass";
|
|
30130
|
+
var worstStatus3 = (statuses) => statuses.includes("fail") ? "fail" : statuses.includes("warn") ? "warn" : "pass";
|
|
30131
|
+
var pushOperationalStatusEvents = (events, report, links) => {
|
|
30132
|
+
if (!report) {
|
|
30133
|
+
return;
|
|
30134
|
+
}
|
|
30135
|
+
for (const check of report.checks) {
|
|
30136
|
+
if (check.status === "pass") {
|
|
30137
|
+
continue;
|
|
30138
|
+
}
|
|
30139
|
+
events.push({
|
|
30140
|
+
action: {
|
|
30141
|
+
href: check.href ?? links.operationalStatus,
|
|
30142
|
+
label: "Open source"
|
|
30143
|
+
},
|
|
30144
|
+
at: report.checkedAt,
|
|
30145
|
+
category: check.label.toLowerCase().includes("readiness") ? "readiness" : "operational-status",
|
|
30146
|
+
detail: check.detail,
|
|
30147
|
+
href: check.href ?? links.operationalStatus,
|
|
30148
|
+
id: `operational:${check.label}`,
|
|
30149
|
+
label: check.label,
|
|
30150
|
+
severity: statusToSeverity(check.status),
|
|
30151
|
+
source: "operational-status",
|
|
30152
|
+
value: check.value
|
|
30153
|
+
});
|
|
30154
|
+
}
|
|
30155
|
+
};
|
|
30156
|
+
var pushOpsRecoveryEvents = (events, report, links) => {
|
|
30157
|
+
if (!report) {
|
|
30158
|
+
return;
|
|
30159
|
+
}
|
|
30160
|
+
for (const issue of report.issues) {
|
|
30161
|
+
events.push({
|
|
30162
|
+
action: {
|
|
30163
|
+
href: issue.href ?? links.operationalStatus,
|
|
30164
|
+
label: "Inspect recovery issue"
|
|
30165
|
+
},
|
|
30166
|
+
at: report.checkedAt,
|
|
30167
|
+
category: "recovery",
|
|
30168
|
+
detail: issue.detail,
|
|
30169
|
+
href: issue.href,
|
|
30170
|
+
id: `ops-recovery:${issue.code}`,
|
|
30171
|
+
label: issue.label,
|
|
30172
|
+
severity: issue.severity === "fail" ? "critical" : "warn",
|
|
30173
|
+
source: "ops-recovery",
|
|
30174
|
+
value: issue.value
|
|
30175
|
+
});
|
|
30176
|
+
}
|
|
30177
|
+
for (const session of report.failedSessions) {
|
|
30178
|
+
events.push({
|
|
30179
|
+
action: {
|
|
30180
|
+
href: session.operationsRecordHref ?? linkForSession(links.operationsRecords, session.sessionId) ?? linkForSession(links.callDebugger, session.sessionId),
|
|
30181
|
+
label: "Open affected call"
|
|
30182
|
+
},
|
|
30183
|
+
at: session.at,
|
|
30184
|
+
category: "call",
|
|
30185
|
+
detail: session.error,
|
|
30186
|
+
href: session.operationsRecordHref ?? linkForSession(links.operationsRecords, session.sessionId),
|
|
30187
|
+
id: `failed-session:${session.sessionId}:${session.at}`,
|
|
30188
|
+
label: "Failed session",
|
|
30189
|
+
sessionId: session.sessionId,
|
|
30190
|
+
severity: "critical",
|
|
30191
|
+
source: "ops-recovery",
|
|
30192
|
+
value: session.provider
|
|
30193
|
+
});
|
|
30194
|
+
}
|
|
30195
|
+
};
|
|
30196
|
+
var pushMonitorEvents = (events, issues, links) => {
|
|
30197
|
+
if (!issues) {
|
|
30198
|
+
return;
|
|
30199
|
+
}
|
|
30200
|
+
for (const issue of issues) {
|
|
30201
|
+
if (issue.status === "resolved") {
|
|
30202
|
+
continue;
|
|
30203
|
+
}
|
|
30204
|
+
const sessionId = issue.impactedSessions[0];
|
|
30205
|
+
events.push({
|
|
30206
|
+
action: {
|
|
30207
|
+
href: issue.operationsRecordHrefs[0] ?? linkForSession(links.operationsRecords, sessionId) ?? links.monitorIssues,
|
|
30208
|
+
label: "Open monitor evidence"
|
|
30209
|
+
},
|
|
30210
|
+
at: issue.lastSeenAt,
|
|
30211
|
+
category: "monitor",
|
|
30212
|
+
detail: issue.detail,
|
|
30213
|
+
href: issue.operationsRecordHrefs[0] ?? linkForSession(links.operationsRecords, sessionId) ?? links.monitorIssues,
|
|
30214
|
+
id: `monitor:${issue.id}`,
|
|
30215
|
+
label: issue.label,
|
|
30216
|
+
sessionId,
|
|
30217
|
+
severity: issue.severity === "critical" ? "critical" : issue.severity === "warn" ? "warn" : "info",
|
|
30218
|
+
source: `monitor:${issue.monitorId}`,
|
|
30219
|
+
value: issue.value
|
|
30220
|
+
});
|
|
30221
|
+
}
|
|
30222
|
+
};
|
|
30223
|
+
var pushOperationsRecordEvents = (events, records, links) => {
|
|
30224
|
+
if (!records) {
|
|
30225
|
+
return;
|
|
30226
|
+
}
|
|
30227
|
+
for (const record of records) {
|
|
30228
|
+
if (record.status === "healthy") {
|
|
30229
|
+
continue;
|
|
30230
|
+
}
|
|
30231
|
+
const href = linkForSession(links.operationsRecords, record.sessionId);
|
|
30232
|
+
const debuggerHref = linkForSession(links.callDebugger, record.sessionId);
|
|
30233
|
+
events.push({
|
|
30234
|
+
action: {
|
|
30235
|
+
href: debuggerHref ?? href,
|
|
30236
|
+
label: debuggerHref ? "Open call debugger" : "Open operations record"
|
|
30237
|
+
},
|
|
30238
|
+
at: record.checkedAt,
|
|
30239
|
+
category: "call",
|
|
30240
|
+
detail: record.status === "failed" ? "Call operations record failed." : "Call operations record has warnings.",
|
|
30241
|
+
href,
|
|
30242
|
+
id: `operations-record:${record.sessionId}`,
|
|
30243
|
+
label: `Operations record ${record.status}`,
|
|
30244
|
+
sessionId: record.sessionId,
|
|
30245
|
+
severity: statusToSeverity(record.status),
|
|
30246
|
+
source: "operations-record",
|
|
30247
|
+
value: record.outcome.complete ? "complete" : "incomplete"
|
|
30248
|
+
});
|
|
30249
|
+
}
|
|
30250
|
+
};
|
|
30251
|
+
var pushFailureReplayEvents = (events, replays, links) => {
|
|
30252
|
+
if (!replays) {
|
|
30253
|
+
return;
|
|
30254
|
+
}
|
|
30255
|
+
for (const replay of replays) {
|
|
30256
|
+
if (replay.status === "healthy") {
|
|
30257
|
+
continue;
|
|
30258
|
+
}
|
|
30259
|
+
const href = replay.operationsRecordHref ?? linkForSession(links.failureReplay, replay.sessionId) ?? linkForSession(links.callDebugger, replay.sessionId);
|
|
30260
|
+
events.push({
|
|
30261
|
+
action: {
|
|
30262
|
+
href: linkForSession(links.callDebugger, replay.sessionId) ?? href ?? linkForSession(links.supportBundle, replay.sessionId),
|
|
30263
|
+
label: "Open replay/debug artifact"
|
|
30264
|
+
},
|
|
30265
|
+
at: replay.providers.steps[0]?.at ?? replay.media.steps[0]?.at ?? Date.now(),
|
|
30266
|
+
category: "failure-replay",
|
|
30267
|
+
detail: replay.summary.issues.join("; ") || replay.summary.userHeard.join(" ") || `Failure replay is ${replay.status}.`,
|
|
30268
|
+
href,
|
|
30269
|
+
id: `failure-replay:${replay.sessionId}`,
|
|
30270
|
+
label: `Failure replay ${replay.status}`,
|
|
30271
|
+
sessionId: replay.sessionId,
|
|
30272
|
+
severity: failureReplayStatusToSeverity(replay.status),
|
|
30273
|
+
source: "failure-replay",
|
|
30274
|
+
value: `${replay.providers.errors} provider errors / ${replay.media.errors} media errors`
|
|
30275
|
+
});
|
|
30276
|
+
}
|
|
30277
|
+
};
|
|
30278
|
+
var buildVoiceIncidentTimelineReport = async (options) => {
|
|
30279
|
+
const now = options.now ?? Date.now();
|
|
30280
|
+
const links = options.links ?? {};
|
|
30281
|
+
const [
|
|
30282
|
+
operationalStatus,
|
|
30283
|
+
opsRecovery,
|
|
30284
|
+
monitorIssues,
|
|
30285
|
+
operationsRecords,
|
|
30286
|
+
failureReplays
|
|
30287
|
+
] = await Promise.all([
|
|
30288
|
+
resolveValue2(options.operationalStatus),
|
|
30289
|
+
resolveValue2(options.opsRecovery),
|
|
30290
|
+
resolveValue2(options.monitorIssues),
|
|
30291
|
+
resolveValue2(options.operationsRecords),
|
|
30292
|
+
resolveValue2(options.failureReplays)
|
|
30293
|
+
]);
|
|
30294
|
+
const events = [];
|
|
30295
|
+
pushOperationalStatusEvents(events, operationalStatus, links);
|
|
30296
|
+
pushOpsRecoveryEvents(events, opsRecovery, links);
|
|
30297
|
+
pushMonitorEvents(events, monitorIssues, links);
|
|
30298
|
+
pushOperationsRecordEvents(events, operationsRecords, links);
|
|
30299
|
+
pushFailureReplayEvents(events, failureReplays, links);
|
|
30300
|
+
const filtered = events.filter((event) => withinWindow(event, now, options.windowMs)).sort((left, right) => right.at - left.at).slice(0, options.limit ?? 50);
|
|
30301
|
+
const summary = {
|
|
30302
|
+
critical: filtered.filter((event) => event.severity === "critical").length,
|
|
30303
|
+
info: filtered.filter((event) => event.severity === "info").length,
|
|
30304
|
+
total: filtered.length,
|
|
30305
|
+
warn: filtered.filter((event) => event.severity === "warn").length
|
|
30306
|
+
};
|
|
30307
|
+
return {
|
|
30308
|
+
events: filtered,
|
|
30309
|
+
generatedAt: now,
|
|
30310
|
+
links,
|
|
30311
|
+
status: worstStatus3(filtered.map(eventStatus2)),
|
|
30312
|
+
summary,
|
|
30313
|
+
windowMs: options.windowMs
|
|
30314
|
+
};
|
|
30315
|
+
};
|
|
30316
|
+
var renderVoiceIncidentTimelineMarkdown = (report, options = {}) => {
|
|
30317
|
+
const title = options.title ?? "AbsoluteJS Voice Incident Timeline";
|
|
30318
|
+
const rows = report.events.map((event) => {
|
|
30319
|
+
const when = new Date(event.at).toISOString();
|
|
30320
|
+
const target = event.href ? ` [open](${event.href})` : "";
|
|
30321
|
+
const session = event.sessionId ? ` session=${event.sessionId}` : "";
|
|
30322
|
+
const value = event.value === undefined ? "" : ` value=${event.value}`;
|
|
30323
|
+
return `- ${when} ${event.severity.toUpperCase()} ${event.label}${session}${value}${target}${event.detail ? ` - ${event.detail}` : ""}`;
|
|
30324
|
+
}).join(`
|
|
30325
|
+
`);
|
|
30326
|
+
return `# ${title}
|
|
30327
|
+
|
|
30328
|
+
Status: ${report.status}
|
|
30329
|
+
|
|
30330
|
+
Generated: ${new Date(report.generatedAt).toISOString()}
|
|
30331
|
+
|
|
30332
|
+
Summary: ${report.summary.critical} critical, ${report.summary.warn} warn, ${report.summary.info} info, ${report.summary.total} total.
|
|
30333
|
+
|
|
30334
|
+
## Events
|
|
30335
|
+
|
|
30336
|
+
${rows || "- No incident timeline events."}
|
|
30337
|
+
`;
|
|
30338
|
+
};
|
|
30339
|
+
var renderVoiceIncidentTimelineHTML = (report, options = {}) => {
|
|
30340
|
+
const title = options.title ?? "AbsoluteJS Voice Incident Timeline";
|
|
30341
|
+
const events = report.events.map((event) => `<article class="${escapeHtml43(event.severity)}">
|
|
30342
|
+
<span>${escapeHtml43(event.severity.toUpperCase())} / ${escapeHtml43(event.category)}</span>
|
|
30343
|
+
<h2>${escapeHtml43(event.label)}</h2>
|
|
30344
|
+
<p>${escapeHtml43(new Date(event.at).toLocaleString())}${event.sessionId ? ` \xB7 session ${escapeHtml43(event.sessionId)}` : ""}</p>
|
|
30345
|
+
${event.value === undefined ? "" : `<strong>${escapeHtml43(String(event.value))}</strong>`}
|
|
30346
|
+
${event.detail ? `<p>${escapeHtml43(event.detail)}</p>` : ""}
|
|
30347
|
+
<div>${event.href ? `<a href="${escapeHtml43(event.href)}">Open source</a>` : ""}${event.action?.href ? `<a href="${escapeHtml43(event.action.href)}">${escapeHtml43(event.action.label)}</a>` : ""}</div>
|
|
30348
|
+
</article>`).join("");
|
|
30349
|
+
return `<!doctype html><html lang="en"><head><meta charset="utf-8" /><meta name="viewport" content="width=device-width, initial-scale=1" /><title>${escapeHtml43(title)}</title><style>body{background:#11110d;color:#faf4df;font-family:ui-sans-serif,system-ui,sans-serif;margin:0}main{margin:auto;max-width:1100px;padding:32px}.hero{background:linear-gradient(135deg,rgba(248,113,113,.2),rgba(245,158,11,.13),rgba(34,197,94,.12));border:1px solid #39301d;border-radius:30px;margin-bottom:18px;padding:28px}.eyebrow{color:#fcd34d;font-weight:900;letter-spacing:.12em;text-transform:uppercase}h1{font-size:clamp(2.4rem,6vw,5rem);letter-spacing:-.06em;line-height:.9;margin:.2rem 0 1rem}.status{border:1px solid #575030;border-radius:999px;display:inline-flex;font-weight:900;padding:8px 12px}.status.pass{border-color:rgba(34,197,94,.65)}.status.warn{border-color:rgba(245,158,11,.75)}.status.fail{border-color:rgba(239,68,68,.85)}.grid{display:grid;gap:14px}.summary{display:flex;flex-wrap:wrap;gap:10px}.summary span{background:#181711;border:1px solid #39301d;border-radius:999px;padding:8px 12px}article{background:#181711;border:1px solid #39301d;border-radius:22px;padding:18px}article.critical{border-color:rgba(239,68,68,.85)}article.warn{border-color:rgba(245,158,11,.75)}article.info{border-color:rgba(34,197,94,.55)}article span{color:#fcd34d;font-size:.78rem;font-weight:900;letter-spacing:.08em}article h2{margin:.35rem 0}.muted,article p{color:#cfc5a8}article strong{display:block;font-size:1.3rem;margin:.5rem 0}a{color:#fde68a;margin-right:12px}</style></head><body><main><section class="hero"><p class="eyebrow">Operational triage</p><h1>${escapeHtml43(title)}</h1><p class="status ${escapeHtml43(report.status)}">Overall: ${escapeHtml43(report.status.toUpperCase())}</p><p class="muted">Generated ${escapeHtml43(new Date(report.generatedAt).toLocaleString())}</p><div class="summary"><span>${String(report.summary.critical)} critical</span><span>${String(report.summary.warn)} warn</span><span>${String(report.summary.info)} info</span><span>${String(report.summary.total)} total</span></div></section><section class="grid">${events || '<article class="info"><span>INFO</span><h2>No incident events</h2><p>No non-pass operational events were found in this window.</p></article>'}</section></main></body></html>`;
|
|
30350
|
+
};
|
|
30351
|
+
var createVoiceIncidentTimelineRoutes = (options) => {
|
|
30352
|
+
const path = options.path ?? "/api/voice/incident-timeline";
|
|
30353
|
+
const htmlPath = options.htmlPath === undefined ? "/voice/incident-timeline" : options.htmlPath;
|
|
30354
|
+
const markdownPath = options.markdownPath === undefined ? "/voice/incident-timeline.md" : options.markdownPath;
|
|
30355
|
+
const routes = new Elysia46({
|
|
30356
|
+
name: options.name ?? "absolutejs-voice-incident-timeline"
|
|
30357
|
+
}).get(path, async () => {
|
|
30358
|
+
const report = await buildVoiceIncidentTimelineReport(options);
|
|
30359
|
+
return new Response(JSON.stringify(report), {
|
|
30360
|
+
headers: {
|
|
30361
|
+
"Content-Type": "application/json; charset=utf-8",
|
|
30362
|
+
...options.headers
|
|
30363
|
+
},
|
|
30364
|
+
status: report.status === "fail" ? 503 : 200
|
|
30365
|
+
});
|
|
30366
|
+
});
|
|
30367
|
+
if (htmlPath !== false) {
|
|
30368
|
+
routes.get(htmlPath, async () => {
|
|
30369
|
+
const report = await buildVoiceIncidentTimelineReport(options);
|
|
30370
|
+
const body = await (options.render ?? ((input) => renderVoiceIncidentTimelineHTML(input, { title: options.title })))(report);
|
|
30371
|
+
return new Response(body, {
|
|
30372
|
+
headers: {
|
|
30373
|
+
"Content-Type": "text/html; charset=utf-8",
|
|
30374
|
+
...options.headers
|
|
30375
|
+
}
|
|
30376
|
+
});
|
|
30377
|
+
});
|
|
30378
|
+
}
|
|
30379
|
+
if (markdownPath !== false) {
|
|
30380
|
+
routes.get(markdownPath, async () => {
|
|
30381
|
+
const report = await buildVoiceIncidentTimelineReport(options);
|
|
30382
|
+
return new Response(renderVoiceIncidentTimelineMarkdown(report, {
|
|
30383
|
+
title: options.title
|
|
30384
|
+
}), {
|
|
30385
|
+
headers: {
|
|
30386
|
+
"Content-Type": "text/markdown; charset=utf-8",
|
|
30387
|
+
...options.headers
|
|
30388
|
+
}
|
|
30389
|
+
});
|
|
30390
|
+
});
|
|
30391
|
+
}
|
|
30392
|
+
return routes;
|
|
30393
|
+
};
|
|
30394
|
+
// src/dataControl.ts
|
|
30395
|
+
import { Elysia as Elysia47 } from "elysia";
|
|
30118
30396
|
var voiceComplianceRedactionDefaults = {
|
|
30119
30397
|
keys: [
|
|
30120
30398
|
"apiKey",
|
|
@@ -30353,7 +30631,7 @@ var parseRetentionScopes = (value) => {
|
|
|
30353
30631
|
const allowed = new Set(allRetentionScopes);
|
|
30354
30632
|
return value.split(",").map((entry) => entry.trim()).filter((entry) => allowed.has(entry));
|
|
30355
30633
|
};
|
|
30356
|
-
var
|
|
30634
|
+
var escapeHtml44 = (value) => value.replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">").replaceAll('"', """).replaceAll("'", "'");
|
|
30357
30635
|
var buildStorageSurfaces = (options) => [
|
|
30358
30636
|
{
|
|
30359
30637
|
configured: Boolean(options.session ?? options.sessions),
|
|
@@ -30590,12 +30868,12 @@ var buildVoiceDataControlReport = async (options) => {
|
|
|
30590
30868
|
zeroRetentionAvailable: true
|
|
30591
30869
|
};
|
|
30592
30870
|
};
|
|
30593
|
-
var renderDataRetentionReportRows = (report) => report.scopes.map((scope) => `<tr><td>${
|
|
30871
|
+
var renderDataRetentionReportRows = (report) => report.scopes.map((scope) => `<tr><td>${escapeHtml44(scope.scope)}</td><td>${scope.scannedCount}</td><td>${scope.deletedCount}</td><td>${escapeHtml44(scope.skippedReason ?? "")}</td><td><code>${escapeHtml44(scope.deletedIds.join(", "))}</code></td></tr>`).join("");
|
|
30594
30872
|
var renderVoiceDataControlHTML = (report, options = {}) => {
|
|
30595
30873
|
const title = options.title ?? "Voice Data Control";
|
|
30596
|
-
const storageRows = report.storage.map((surface) => `<tr><td>${
|
|
30597
|
-
const keyRows = report.providerKeys.map((key) => `<tr><td>${
|
|
30598
|
-
return `<!doctype html><html lang="en"><head><meta charset="utf-8" /><meta name="viewport" content="width=device-width,initial-scale=1" /><title>${
|
|
30874
|
+
const storageRows = report.storage.map((surface) => `<tr><td>${escapeHtml44(surface.name)}</td><td>${surface.configured ? "Configured" : "Missing"}</td><td>${escapeHtml44(surface.control)}</td><td>${surface.selfHosted ? "Yes" : "No"}</td></tr>`).join("");
|
|
30875
|
+
const keyRows = report.providerKeys.map((key) => `<tr><td>${escapeHtml44(key.name)}</td><td><code>${escapeHtml44(key.env ?? "n/a")}</code></td><td>${key.required ? "Required" : "Optional"}</td><td>${escapeHtml44(key.recommendation)}</td></tr>`).join("");
|
|
30876
|
+
return `<!doctype html><html lang="en"><head><meta charset="utf-8" /><meta name="viewport" content="width=device-width,initial-scale=1" /><title>${escapeHtml44(title)}</title><style>body{background:#f8f7f2;color:#181713;font-family:ui-sans-serif,system-ui,sans-serif;line-height:1.45;margin:2rem}main{max-width:1120px;margin:auto}.summary{display:grid;gap:1rem;grid-template-columns:repeat(auto-fit,minmax(180px,1fr));margin:1rem 0}.card,table{background:white;border:1px solid #ddd6c8;border-radius:14px}.card{padding:1rem}table{border-collapse:collapse;width:100%;overflow:hidden}td,th{border-bottom:1px solid #eee8dc;padding:.7rem;text-align:left;vertical-align:top}code{white-space:pre-wrap;word-break:break-word}a{color:#9a3412}</style></head><body><main><h1>${escapeHtml44(title)}</h1><p>Self-hosted data-control proof for retention, redaction, audit export, deletion planning, customer-owned storage, and provider key handling.</p><section class="summary"><div class="card"><strong>Redaction</strong><br>${report.redaction.enabled ? "enabled" : "disabled"}</div><div class="card"><strong>Retention dry-run deletes</strong><br>${report.retentionPlan.deletedCount}</div><div class="card"><strong>Audit export events</strong><br>${report.auditExport?.events.length ?? 0}</div><div class="card"><strong>Zero retention recipe</strong><br>${report.zeroRetentionAvailable ? "available" : "missing"}</div></section><h2>Customer-Owned Storage</h2><table><thead><tr><th>Surface</th><th>Status</th><th>Control</th><th>Self-hosted</th></tr></thead><tbody>${storageRows}</tbody></table><h2>Retention Plan</h2><table><thead><tr><th>Scope</th><th>Scanned</th><th>Would delete</th><th>Skipped</th><th>Ids</th></tr></thead><tbody>${renderDataRetentionReportRows(report.retentionPlan)}</tbody></table><h2>Provider Keys</h2><table><thead><tr><th>Provider</th><th>Env</th><th>Required</th><th>Recommendation</th></tr></thead><tbody>${keyRows}</tbody></table><p><a href="./data-control/audit.md">Redacted audit Markdown</a> \xB7 <a href="./data-control/audit.html">Redacted audit HTML</a></p></main></body></html>`;
|
|
30599
30877
|
};
|
|
30600
30878
|
var renderVoiceDataControlMarkdown = (report, options = {}) => [
|
|
30601
30879
|
`# ${options.title ?? "Voice Data Control"}`,
|
|
@@ -30653,7 +30931,7 @@ var parseRetentionPolicyBody = (body, options, dryRun) => {
|
|
|
30653
30931
|
var createVoiceDataControlRoutes = (options) => {
|
|
30654
30932
|
const path = options.path ?? "/data-control";
|
|
30655
30933
|
const title = options.title ?? "AbsoluteJS Voice Data Control";
|
|
30656
|
-
const routes = new
|
|
30934
|
+
const routes = new Elysia47({
|
|
30657
30935
|
name: options.name ?? "absolutejs-voice-data-control"
|
|
30658
30936
|
});
|
|
30659
30937
|
routes.get(path, async ({ query }) => {
|
|
@@ -30729,10 +31007,10 @@ var createVoiceDataControlRoutes = (options) => {
|
|
|
30729
31007
|
return routes;
|
|
30730
31008
|
};
|
|
30731
31009
|
// src/evalRoutes.ts
|
|
30732
|
-
import { Elysia as
|
|
31010
|
+
import { Elysia as Elysia48 } from "elysia";
|
|
30733
31011
|
import { mkdir as mkdir3 } from "fs/promises";
|
|
30734
31012
|
import { dirname as dirname2 } from "path";
|
|
30735
|
-
var
|
|
31013
|
+
var escapeHtml45 = (value) => value.replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">").replaceAll('"', """).replaceAll("'", "'");
|
|
30736
31014
|
var rate3 = (count, total) => count / Math.max(1, total);
|
|
30737
31015
|
var normalizeSearchText = (value) => value.trim().toLowerCase();
|
|
30738
31016
|
var getString18 = (value) => typeof value === "string" ? value : undefined;
|
|
@@ -31054,7 +31332,7 @@ var createVoiceFileScenarioFixtureStore = (filePath) => ({
|
|
|
31054
31332
|
var formatTime = (value) => value === undefined ? "unknown" : new Date(value).toLocaleString();
|
|
31055
31333
|
var formatPercent = (value) => `${(value * 100).toFixed(2)}%`;
|
|
31056
31334
|
var renderVoiceEvalPrimitiveCopy = () => {
|
|
31057
|
-
const snippet =
|
|
31335
|
+
const snippet = escapeHtml45(`app.use(
|
|
31058
31336
|
createVoiceEvalRoutes({
|
|
31059
31337
|
path: '/evals',
|
|
31060
31338
|
store: traceStore,
|
|
@@ -31075,48 +31353,48 @@ var renderVoiceEvalPrimitiveCopy = () => {
|
|
|
31075
31353
|
};
|
|
31076
31354
|
var renderVoiceEvalHTML = (report, options = {}) => {
|
|
31077
31355
|
const title = options.title ?? "AbsoluteJS Voice Evals";
|
|
31078
|
-
const links = options.links?.length ? `<nav>${options.links.map((link) => `<a href="${
|
|
31079
|
-
const trend = report.trend.length ? report.trend.map((bucket) => `<tr><td>${
|
|
31356
|
+
const links = options.links?.length ? `<nav>${options.links.map((link) => `<a href="${escapeHtml45(link.href)}">${escapeHtml45(link.label)}</a>`).join("")}</nav>` : "";
|
|
31357
|
+
const trend = report.trend.length ? report.trend.map((bucket) => `<tr><td>${escapeHtml45(bucket.key)}</td><td>${bucket.total}</td><td>${bucket.passed}</td><td>${bucket.failed}</td></tr>`).join("") : '<tr><td colspan="4">No eval buckets yet.</td></tr>';
|
|
31080
31358
|
const sessions = report.sessions.length ? report.sessions.map((session) => {
|
|
31081
31359
|
const failedMetrics = Object.entries(session.quality.metrics).filter(([, metric]) => !metric.pass).map(([, metric]) => metric.label).join(", ");
|
|
31082
|
-
const sessionLabel = session.operationsRecordHref ? `<a href="${
|
|
31083
|
-
return `<tr class="${session.status}"><td>${sessionLabel}</td><td>${
|
|
31360
|
+
const sessionLabel = session.operationsRecordHref ? `<a href="${escapeHtml45(session.operationsRecordHref)}">${escapeHtml45(session.sessionId)}</a>` : escapeHtml45(session.sessionId);
|
|
31361
|
+
return `<tr class="${session.status}"><td>${sessionLabel}</td><td>${escapeHtml45(session.status)}</td><td>${session.eventCount}</td><td>${session.summary.turnCount}</td><td>${session.summary.errorCount}</td><td>${escapeHtml45(formatTime(session.endedAt))}</td><td>${escapeHtml45(failedMetrics || "none")}</td></tr>`;
|
|
31084
31362
|
}).join("") : '<tr><td colspan="7">No sessions found.</td></tr>';
|
|
31085
|
-
return `<!doctype html><html lang="en"><head><meta charset="utf-8" /><meta name="viewport" content="width=device-width, initial-scale=1" /><title>${
|
|
31363
|
+
return `<!doctype html><html lang="en"><head><meta charset="utf-8" /><meta name="viewport" content="width=device-width, initial-scale=1" /><title>${escapeHtml45(title)}</title><style>body{font-family:ui-sans-serif,system-ui,sans-serif;margin:2rem;background:#f8f7f2;color:#181713}main{max-width:1180px;margin:auto}nav{display:flex;gap:.5rem;flex-wrap:wrap;margin-bottom:1rem}nav a{background:#181713;border-radius:999px;color:white;padding:.35rem .7rem;text-decoration:none}.eyebrow{font-size:.78rem;font-weight:900;letter-spacing:.08em;text-transform:uppercase}.status{border-radius:999px;display:inline-flex;font-weight:800;padding:.35rem .75rem}.pass{color:#166534}.fail{color:#991b1b}.status.pass{background:#dcfce7}.status.fail{background:#fee2e2}.grid{display:grid;gap:1rem;grid-template-columns:repeat(auto-fit,minmax(160px,1fr));margin:1rem 0}.card,.primitive{background:white;border:1px solid #e7e5e4;border-radius:1rem;padding:1rem}.primitive{background:#fffdf7;border-color:#d6c7a3;margin:1rem 0}.primitive p{line-height:1.55}.primitive pre{background:#181713;border-radius:.85rem;color:#fef3c7;overflow:auto;padding:1rem}.primitive code{color:#fef3c7}.card strong{display:block;font-size:2rem}table{border-collapse:collapse;background:white;width:100%;margin:1rem 0 2rem}td,th{border-bottom:1px solid #eee;padding:.75rem;text-align:left}tr.fail td{border-left:4px solid #dc2626}tr.pass td{border-left:4px solid #16a34a}</style></head><body><main>${links}<h1>${escapeHtml45(title)}</h1><p class="status ${report.status}">${report.status}</p><div class="grid"><article class="card"><span>Total</span><strong>${report.total}</strong></article><article class="card"><span>Passed</span><strong>${report.passed}</strong></article><article class="card"><span>Failed</span><strong>${report.failed}</strong></article></div>${renderVoiceEvalPrimitiveCopy()}<h2>Trend</h2><table><thead><tr><th>Day</th><th>Total</th><th>Passed</th><th>Failed</th></tr></thead><tbody>${trend}</tbody></table><h2>Session Eval Results</h2><table><thead><tr><th>Session</th><th>Status</th><th>Events</th><th>Turns</th><th>Errors</th><th>Last event</th><th>Failed metrics</th></tr></thead><tbody>${sessions}</tbody></table></main></body></html>`;
|
|
31086
31364
|
};
|
|
31087
31365
|
var renderVoiceEvalBaselineHTML = (comparison, options = {}) => {
|
|
31088
31366
|
const title = options.title ?? "AbsoluteJS Voice Eval Baseline";
|
|
31089
|
-
const links = options.links?.length ? `<nav>${options.links.map((link) => `<a href="${
|
|
31090
|
-
const reasons = comparison.reasons.length ? comparison.reasons.map((reason) => `<li>${
|
|
31091
|
-
const newFailures = comparison.newFailedSessionIds.length ? comparison.newFailedSessionIds.map((id) => `<li>${
|
|
31092
|
-
const recovered = comparison.recoveredSessionIds.length ? comparison.recoveredSessionIds.map((id) => `<li>${
|
|
31093
|
-
return `<!doctype html><html lang="en"><head><meta charset="utf-8" /><meta name="viewport" content="width=device-width, initial-scale=1" /><title>${
|
|
31367
|
+
const links = options.links?.length ? `<nav>${options.links.map((link) => `<a href="${escapeHtml45(link.href)}">${escapeHtml45(link.label)}</a>`).join("")}</nav>` : "";
|
|
31368
|
+
const reasons = comparison.reasons.length ? comparison.reasons.map((reason) => `<li>${escapeHtml45(reason)}</li>`).join("") : "<li>No baseline regressions detected.</li>";
|
|
31369
|
+
const newFailures = comparison.newFailedSessionIds.length ? comparison.newFailedSessionIds.map((id) => `<li>${escapeHtml45(id)}</li>`).join("") : "<li>none</li>";
|
|
31370
|
+
const recovered = comparison.recoveredSessionIds.length ? comparison.recoveredSessionIds.map((id) => `<li>${escapeHtml45(id)}</li>`).join("") : "<li>none</li>";
|
|
31371
|
+
return `<!doctype html><html lang="en"><head><meta charset="utf-8" /><meta name="viewport" content="width=device-width, initial-scale=1" /><title>${escapeHtml45(title)}</title><style>body{font-family:ui-sans-serif,system-ui,sans-serif;margin:2rem;background:#f8f7f2;color:#181713}main{max-width:1000px;margin:auto}nav{display:flex;gap:.5rem;flex-wrap:wrap;margin-bottom:1rem}nav a{background:#181713;border-radius:999px;color:white;padding:.35rem .7rem;text-decoration:none}.status{border-radius:999px;display:inline-flex;font-weight:800;padding:.35rem .75rem}.pass{background:#dcfce7;color:#166534}.fail{background:#fee2e2;color:#991b1b}.grid{display:grid;gap:1rem;grid-template-columns:repeat(auto-fit,minmax(180px,1fr));margin:1rem 0}.card{background:white;border:1px solid #e7e5e4;border-radius:1rem;padding:1rem}.card strong{display:block;font-size:2rem}section{background:white;border:1px solid #e7e5e4;border-radius:1rem;margin:1rem 0;padding:1rem}</style></head><body><main>${links}<h1>${escapeHtml45(title)}</h1><p class="status ${comparison.status}">${comparison.status}</p><div class="grid"><article class="card"><span>Baseline pass rate</span><strong>${escapeHtml45(formatPercent(comparison.baseline.passRate))}</strong></article><article class="card"><span>Current pass rate</span><strong>${escapeHtml45(formatPercent(comparison.current.passRate))}</strong></article><article class="card"><span>Failed delta</span><strong>${comparison.deltas.failed}</strong></article><article class="card"><span>Pass rate delta</span><strong>${escapeHtml45(formatPercent(comparison.deltas.passRate))}</strong></article></div><section><h2>Regression Reasons</h2><ul>${reasons}</ul></section><section><h2>New Failed Sessions</h2><ul>${newFailures}</ul></section><section><h2>Recovered Sessions</h2><ul>${recovered}</ul></section></main></body></html>`;
|
|
31094
31372
|
};
|
|
31095
31373
|
var renderVoiceScenarioEvalHTML = (report, options = {}) => {
|
|
31096
31374
|
const title = options.title ?? "AbsoluteJS Voice Scenario Evals";
|
|
31097
|
-
const links = options.links?.length ? `<nav>${options.links.map((link) => `<a href="${
|
|
31375
|
+
const links = options.links?.length ? `<nav>${options.links.map((link) => `<a href="${escapeHtml45(link.href)}">${escapeHtml45(link.label)}</a>`).join("")}</nav>` : "";
|
|
31098
31376
|
const scenarios = report.scenarios.length ? report.scenarios.map((scenario) => {
|
|
31099
|
-
const scenarioIssues = scenario.issues.length ? `<ul>${scenario.issues.map((issue) => `<li>${
|
|
31377
|
+
const scenarioIssues = scenario.issues.length ? `<ul>${scenario.issues.map((issue) => `<li>${escapeHtml45(issue)}</li>`).join("")}</ul>` : "";
|
|
31100
31378
|
const sessions = scenario.sessions.length ? scenario.sessions.map((session) => {
|
|
31101
|
-
const sessionLabel = session.operationsRecordHref ? `<a href="${
|
|
31102
|
-
return `<tr class="${session.status}"><td>${sessionLabel}</td><td>${
|
|
31379
|
+
const sessionLabel = session.operationsRecordHref ? `<a href="${escapeHtml45(session.operationsRecordHref)}">${escapeHtml45(session.sessionId)}</a>` : escapeHtml45(session.sessionId);
|
|
31380
|
+
return `<tr class="${session.status}"><td>${sessionLabel}</td><td>${escapeHtml45(session.status)}</td><td>${session.eventCount}</td><td>${escapeHtml45(session.issues.join(", ") || "none")}</td></tr>`;
|
|
31103
31381
|
}).join("") : '<tr><td colspan="4">No matching sessions.</td></tr>';
|
|
31104
|
-
return `<section class="scenario ${scenario.status}"><h2>${
|
|
31382
|
+
return `<section class="scenario ${scenario.status}"><h2>${escapeHtml45(scenario.label)}</h2>${scenario.description ? `<p>${escapeHtml45(scenario.description)}</p>` : ""}<p class="status ${scenario.status}">${scenario.status}</p><p>${scenario.passed} passed, ${scenario.failed} failed, ${scenario.matchedSessions} matched.</p>${scenarioIssues}<table><thead><tr><th>Session</th><th>Status</th><th>Events</th><th>Issues</th></tr></thead><tbody>${sessions}</tbody></table></section>`;
|
|
31105
31383
|
}).join("") : "<section><p>No scenarios configured.</p></section>";
|
|
31106
|
-
return `<!doctype html><html lang="en"><head><meta charset="utf-8" /><meta name="viewport" content="width=device-width, initial-scale=1" /><title>${
|
|
31384
|
+
return `<!doctype html><html lang="en"><head><meta charset="utf-8" /><meta name="viewport" content="width=device-width, initial-scale=1" /><title>${escapeHtml45(title)}</title><style>body{font-family:ui-sans-serif,system-ui,sans-serif;margin:2rem;background:#f8f7f2;color:#181713}main{max-width:1180px;margin:auto}nav{display:flex;gap:.5rem;flex-wrap:wrap;margin-bottom:1rem}nav a{background:#181713;border-radius:999px;color:white;padding:.35rem .7rem;text-decoration:none}.eyebrow{font-size:.78rem;font-weight:900;letter-spacing:.08em;text-transform:uppercase}.status{border-radius:999px;display:inline-flex;font-weight:800;padding:.35rem .75rem}.status.pass{background:#dcfce7;color:#166534}.status.fail{background:#fee2e2;color:#991b1b}.grid{display:grid;gap:1rem;grid-template-columns:repeat(auto-fit,minmax(160px,1fr));margin:1rem 0}.card,section{background:white;border:1px solid #e7e5e4;border-radius:1rem;padding:1rem}.primitive{background:#fffdf7;border-color:#d6c7a3}.primitive p{line-height:1.55}.primitive pre{background:#181713;border-radius:.85rem;color:#fef3c7;overflow:auto;padding:1rem}.primitive code{color:#fef3c7}.card strong{display:block;font-size:2rem}section{margin:1rem 0}table{border-collapse:collapse;width:100%;margin-top:1rem}td,th{border-bottom:1px solid #eee;padding:.75rem;text-align:left}tr.fail td{border-left:4px solid #dc2626}tr.pass td{border-left:4px solid #16a34a}</style></head><body><main>${links}<h1>${escapeHtml45(title)}</h1><p class="status ${report.status}">${report.status}</p><div class="grid"><article class="card"><span>Total</span><strong>${report.total}</strong></article><article class="card"><span>Passed</span><strong>${report.passed}</strong></article><article class="card"><span>Failed</span><strong>${report.failed}</strong></article></div>${renderVoiceEvalPrimitiveCopy()}${scenarios}</main></body></html>`;
|
|
31107
31385
|
};
|
|
31108
31386
|
var renderVoiceScenarioFixtureEvalHTML = (report, options = {}) => {
|
|
31109
31387
|
const title = options.title ?? "AbsoluteJS Voice Fixture Evals";
|
|
31110
|
-
const links = options.links?.length ? `<nav>${options.links.map((link) => `<a href="${
|
|
31388
|
+
const links = options.links?.length ? `<nav>${options.links.map((link) => `<a href="${escapeHtml45(link.href)}">${escapeHtml45(link.label)}</a>`).join("")}</nav>` : "";
|
|
31111
31389
|
const fixtures = report.fixtures.length ? report.fixtures.map((fixture) => {
|
|
31112
|
-
const scenarios = fixture.report.scenarios.map((scenario) => `<tr class="${scenario.status}"><td>${
|
|
31113
|
-
return `<section class="${fixture.status}"><h2>${
|
|
31390
|
+
const scenarios = fixture.report.scenarios.map((scenario) => `<tr class="${scenario.status}"><td>${escapeHtml45(scenario.label)}</td><td>${escapeHtml45(scenario.status)}</td><td>${scenario.matchedSessions}</td><td>${escapeHtml45([...scenario.issues, ...scenario.sessions.flatMap((session) => session.issues)].join(", ") || "none")}</td></tr>`).join("");
|
|
31391
|
+
return `<section class="${fixture.status}"><h2>${escapeHtml45(fixture.label)}</h2>${fixture.description ? `<p>${escapeHtml45(fixture.description)}</p>` : ""}<p class="status ${fixture.status}">${fixture.status}</p><table><thead><tr><th>Scenario</th><th>Status</th><th>Sessions</th><th>Issues</th></tr></thead><tbody>${scenarios}</tbody></table></section>`;
|
|
31114
31392
|
}).join("") : "<section><p>No scenario fixtures configured.</p></section>";
|
|
31115
|
-
return `<!doctype html><html lang="en"><head><meta charset="utf-8" /><meta name="viewport" content="width=device-width, initial-scale=1" /><title>${
|
|
31393
|
+
return `<!doctype html><html lang="en"><head><meta charset="utf-8" /><meta name="viewport" content="width=device-width, initial-scale=1" /><title>${escapeHtml45(title)}</title><style>body{font-family:ui-sans-serif,system-ui,sans-serif;margin:2rem;background:#f8f7f2;color:#181713}main{max-width:1180px;margin:auto}nav{display:flex;gap:.5rem;flex-wrap:wrap;margin-bottom:1rem}nav a{background:#181713;border-radius:999px;color:white;padding:.35rem .7rem;text-decoration:none}.eyebrow{font-size:.78rem;font-weight:900;letter-spacing:.08em;text-transform:uppercase}.status{border-radius:999px;display:inline-flex;font-weight:800;padding:.35rem .75rem}.status.pass{background:#dcfce7;color:#166534}.status.fail{background:#fee2e2;color:#991b1b}.grid{display:grid;gap:1rem;grid-template-columns:repeat(auto-fit,minmax(160px,1fr));margin:1rem 0}.card,section{background:white;border:1px solid #e7e5e4;border-radius:1rem;padding:1rem}.primitive{background:#fffdf7;border-color:#d6c7a3}.primitive p{line-height:1.55}.primitive pre{background:#181713;border-radius:.85rem;color:#fef3c7;overflow:auto;padding:1rem}.primitive code{color:#fef3c7}.card strong{display:block;font-size:2rem}section{margin:1rem 0}table{border-collapse:collapse;width:100%;margin-top:1rem}td,th{border-bottom:1px solid #eee;padding:.75rem;text-align:left}tr.fail td{border-left:4px solid #dc2626}tr.pass td{border-left:4px solid #16a34a}</style></head><body><main>${links}<h1>${escapeHtml45(title)}</h1><p class="status ${report.status}">${report.status}</p><div class="grid"><article class="card"><span>Total</span><strong>${report.total}</strong></article><article class="card"><span>Passed</span><strong>${report.passed}</strong></article><article class="card"><span>Failed</span><strong>${report.failed}</strong></article></div>${renderVoiceEvalPrimitiveCopy()}${fixtures}</main></body></html>`;
|
|
31116
31394
|
};
|
|
31117
31395
|
var createVoiceEvalRoutes = (options) => {
|
|
31118
31396
|
const path = options.path ?? "/evals";
|
|
31119
|
-
const routes = new
|
|
31397
|
+
const routes = new Elysia48({
|
|
31120
31398
|
name: options.name ?? "absolutejs-voice-evals"
|
|
31121
31399
|
});
|
|
31122
31400
|
const getReport = () => runVoiceSessionEvals({
|
|
@@ -31253,11 +31531,11 @@ var createVoiceEvalRoutes = (options) => {
|
|
|
31253
31531
|
return routes;
|
|
31254
31532
|
};
|
|
31255
31533
|
// src/simulationSuite.ts
|
|
31256
|
-
import { Elysia as
|
|
31534
|
+
import { Elysia as Elysia51 } from "elysia";
|
|
31257
31535
|
|
|
31258
31536
|
// src/outcomeContract.ts
|
|
31259
|
-
import { Elysia as
|
|
31260
|
-
var
|
|
31537
|
+
import { Elysia as Elysia49 } from "elysia";
|
|
31538
|
+
var escapeHtml46 = (value) => value.replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">").replaceAll('"', """).replaceAll("'", "'");
|
|
31261
31539
|
var resolveSessionHref4 = (value, sessionId) => {
|
|
31262
31540
|
if (value === false) {
|
|
31263
31541
|
return;
|
|
@@ -31468,13 +31746,13 @@ var assertVoiceOutcomeContractEvidence = (report, input = {}) => {
|
|
|
31468
31746
|
var renderVoiceOutcomeContractHTML = (report, options = {}) => {
|
|
31469
31747
|
const title = options.title ?? "Voice Outcome Contracts";
|
|
31470
31748
|
const contracts = report.contracts.map((contract) => {
|
|
31471
|
-
const sessionLinks = contract.operationsRecordHrefs.length ? `<p>${contract.operationsRecordHrefs.map((href, index) => `<a href="${
|
|
31749
|
+
const sessionLinks = contract.operationsRecordHrefs.length ? `<p>${contract.operationsRecordHrefs.map((href, index) => `<a href="${escapeHtml46(href)}">${escapeHtml46(contract.sessionIds[index] ?? href)}</a>`).join(" \xB7 ")}</p>` : "";
|
|
31472
31750
|
return `<section class="contract ${contract.pass ? "pass" : "fail"}">
|
|
31473
31751
|
<div class="contract-header">
|
|
31474
31752
|
<div>
|
|
31475
|
-
<p class="eyebrow">${
|
|
31476
|
-
<h2>${
|
|
31477
|
-
${contract.description ? `<p>${
|
|
31753
|
+
<p class="eyebrow">${escapeHtml46(contract.contractId)}</p>
|
|
31754
|
+
<h2>${escapeHtml46(contract.label ?? contract.contractId)}</h2>
|
|
31755
|
+
${contract.description ? `<p>${escapeHtml46(contract.description)}</p>` : ""}
|
|
31478
31756
|
${sessionLinks}
|
|
31479
31757
|
</div>
|
|
31480
31758
|
<strong>${contract.pass ? "pass" : "fail"}</strong>
|
|
@@ -31486,10 +31764,10 @@ var renderVoiceOutcomeContractHTML = (report, options = {}) => {
|
|
|
31486
31764
|
<span>handoffs ${String(contract.matched.handoffs)}</span>
|
|
31487
31765
|
<span>events ${String(contract.matched.integrationEvents)}</span>
|
|
31488
31766
|
</div>
|
|
31489
|
-
${contract.issues.length ? `<ul>${contract.issues.map((issue) => `<li>${
|
|
31767
|
+
${contract.issues.length ? `<ul>${contract.issues.map((issue) => `<li>${escapeHtml46(issue.message)}</li>`).join("")}</ul>` : ""}
|
|
31490
31768
|
</section>`;
|
|
31491
31769
|
}).join("");
|
|
31492
|
-
return `<!doctype html><html lang="en"><head><meta charset="utf-8" /><meta name="viewport" content="width=device-width, initial-scale=1" /><title>${
|
|
31770
|
+
return `<!doctype html><html lang="en"><head><meta charset="utf-8" /><meta name="viewport" content="width=device-width, initial-scale=1" /><title>${escapeHtml46(title)}</title><style>body{background:#101316;color:#f6f2e8;font-family:ui-sans-serif,system-ui,sans-serif;margin:0}main{margin:auto;max-width:1180px;padding:32px}.hero,.contract{background:#181d22;border:1px solid #2a323a;border-radius:20px;margin-bottom:16px;padding:20px}.hero{background:linear-gradient(135deg,rgba(34,197,94,.14),rgba(14,165,233,.12))}.eyebrow{color:#7dd3fc;font-size:.78rem;font-weight:900;letter-spacing:.08em;text-transform:uppercase}h1{font-size:clamp(2.3rem,6vw,5rem);letter-spacing:-.06em;line-height:.9;margin:.2rem 0 1rem}h2{margin:.2rem 0}.summary,.grid{display:flex;flex-wrap:wrap;gap:10px}.pill,.grid span{background:#0f1217;border:1px solid #3f3f46;border-radius:999px;padding:7px 10px}.contract-header{display:flex;gap:16px;justify-content:space-between}.pass{color:#86efac}.fail{color:#fca5a5}.contract.fail{border-color:rgba(248,113,113,.45)}li{margin:8px 0}@media(max-width:800px){main{padding:18px}.contract-header{display:block}}</style></head><body><main><section class="hero"><p class="eyebrow">Business Outcome Verification</p><h1>${escapeHtml46(title)}</h1><div class="summary"><span class="pill ${report.status}">${report.status}</span><span class="pill">${String(report.passed)} passing</span><span class="pill">${String(report.failed)} failing</span><span class="pill">${String(report.total)} contracts</span></div></section>${contracts || '<section class="contract"><p>No outcome contracts configured.</p></section>'}</main></body></html>`;
|
|
31493
31771
|
};
|
|
31494
31772
|
var createVoiceOutcomeContractJSONHandler = (options) => async () => runVoiceOutcomeContractSuite(options);
|
|
31495
31773
|
var createVoiceOutcomeContractHTMLHandler = (options) => async () => {
|
|
@@ -31505,7 +31783,7 @@ var createVoiceOutcomeContractHTMLHandler = (options) => async () => {
|
|
|
31505
31783
|
var createVoiceOutcomeContractRoutes = (options) => {
|
|
31506
31784
|
const path = options.path ?? "/api/outcome-contracts";
|
|
31507
31785
|
const htmlPath = options.htmlPath === undefined ? `${path}/htmx` : options.htmlPath;
|
|
31508
|
-
const routes = new
|
|
31786
|
+
const routes = new Elysia49({
|
|
31509
31787
|
name: options.name ?? "absolutejs-voice-outcome-contracts"
|
|
31510
31788
|
}).get(path, createVoiceOutcomeContractJSONHandler(options));
|
|
31511
31789
|
if (htmlPath) {
|
|
@@ -31515,7 +31793,7 @@ var createVoiceOutcomeContractRoutes = (options) => {
|
|
|
31515
31793
|
};
|
|
31516
31794
|
|
|
31517
31795
|
// src/toolContract.ts
|
|
31518
|
-
import { Elysia as
|
|
31796
|
+
import { Elysia as Elysia50 } from "elysia";
|
|
31519
31797
|
|
|
31520
31798
|
// src/toolRuntime.ts
|
|
31521
31799
|
var toErrorMessage4 = (error) => error instanceof Error ? error.message : String(error);
|
|
@@ -31724,7 +32002,7 @@ var createDefaultTurn = (caseId) => ({
|
|
|
31724
32002
|
});
|
|
31725
32003
|
var defaultApi = {};
|
|
31726
32004
|
var sameJSON = (left, right) => JSON.stringify(left) === JSON.stringify(right);
|
|
31727
|
-
var
|
|
32005
|
+
var escapeHtml47 = (value) => value.replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">").replaceAll('"', """).replaceAll("'", "'");
|
|
31728
32006
|
var resolveSessionHref5 = (value, sessionId) => {
|
|
31729
32007
|
if (value === false) {
|
|
31730
32008
|
return;
|
|
@@ -31973,7 +32251,7 @@ var assertVoiceToolContractEvidence = (report, input = {}) => {
|
|
|
31973
32251
|
};
|
|
31974
32252
|
var renderVoiceToolContractHTML = (report, options = {}) => {
|
|
31975
32253
|
const title = options.title ?? "Voice Tool Contracts";
|
|
31976
|
-
const snippet =
|
|
32254
|
+
const snippet = escapeHtml47(`app.use(
|
|
31977
32255
|
createVoiceToolContractRoutes({
|
|
31978
32256
|
htmlPath: '/tool-contracts',
|
|
31979
32257
|
path: '/api/tool-contracts',
|
|
@@ -31999,20 +32277,20 @@ var renderVoiceToolContractHTML = (report, options = {}) => {
|
|
|
31999
32277
|
);`);
|
|
32000
32278
|
const contracts = report.contracts.map((contract) => {
|
|
32001
32279
|
const cases = contract.cases.map((testCase) => `<tr>
|
|
32002
|
-
<td>${testCase.operationsRecordHref ? `<a href="${
|
|
32280
|
+
<td>${testCase.operationsRecordHref ? `<a href="${escapeHtml47(testCase.operationsRecordHref)}">${escapeHtml47(testCase.label ?? testCase.caseId)}</a>` : escapeHtml47(testCase.label ?? testCase.caseId)}</td>
|
|
32003
32281
|
<td class="${testCase.pass ? "pass" : "fail"}">${testCase.pass ? "pass" : "fail"}</td>
|
|
32004
|
-
<td>${
|
|
32005
|
-
<td>${
|
|
32282
|
+
<td>${escapeHtml47(testCase.status)}</td>
|
|
32283
|
+
<td>${escapeHtml47(testCase.sessionId)}</td>
|
|
32006
32284
|
<td>${String(testCase.attempts)}</td>
|
|
32007
32285
|
<td>${String(testCase.elapsedMs)}ms</td>
|
|
32008
32286
|
<td>${testCase.timedOut ? "yes" : "no"}</td>
|
|
32009
|
-
<td>${
|
|
32287
|
+
<td>${escapeHtml47(testCase.issues.map((issue) => issue.message).join(" ") || testCase.error || "")}</td>
|
|
32010
32288
|
</tr>`).join("");
|
|
32011
32289
|
return `<section class="contract ${contract.pass ? "pass" : "fail"}">
|
|
32012
32290
|
<div class="contract-header">
|
|
32013
32291
|
<div>
|
|
32014
|
-
<p class="eyebrow">${
|
|
32015
|
-
<h2>${
|
|
32292
|
+
<p class="eyebrow">${escapeHtml47(contract.toolName)}</p>
|
|
32293
|
+
<h2>${escapeHtml47(contract.label ?? contract.contractId)}</h2>
|
|
32016
32294
|
</div>
|
|
32017
32295
|
<strong class="${contract.pass ? "pass" : "fail"}">${contract.pass ? "Passing" : "Failing"}</strong>
|
|
32018
32296
|
</div>
|
|
@@ -32022,7 +32300,7 @@ var renderVoiceToolContractHTML = (report, options = {}) => {
|
|
|
32022
32300
|
</table>
|
|
32023
32301
|
</section>`;
|
|
32024
32302
|
}).join("");
|
|
32025
|
-
return `<!doctype html><html lang="en"><head><meta charset="utf-8" /><meta name="viewport" content="width=device-width, initial-scale=1" /><title>${
|
|
32303
|
+
return `<!doctype html><html lang="en"><head><meta charset="utf-8" /><meta name="viewport" content="width=device-width, initial-scale=1" /><title>${escapeHtml47(title)}</title><style>body{background:#101316;color:#f6f2e8;font-family:ui-sans-serif,system-ui,sans-serif;margin:0}main{margin:auto;max-width:1180px;padding:32px}.hero,.primitive,.contract{background:#181d22;border:1px solid #2a323a;border-radius:20px;margin-bottom:16px;padding:20px}.hero{background:linear-gradient(135deg,rgba(34,197,94,.14),rgba(245,158,11,.12))}.primitive{background:#151b20;border-color:#5a4421}.eyebrow{color:#fbbf24;font-size:.78rem;font-weight:900;letter-spacing:.08em;text-transform:uppercase}h1{font-size:clamp(2.3rem,6vw,5rem);letter-spacing:-.06em;line-height:.9;margin:.2rem 0 1rem}.summary{display:flex;flex-wrap:wrap;gap:10px}.pill{background:#0f1217;border:1px solid #3f3f46;border-radius:999px;padding:7px 10px}.contract-header{align-items:flex-start;display:flex;gap:16px;justify-content:space-between}h2{margin:.2rem 0 1rem}.pass{color:#86efac}.fail{color:#fca5a5}.contract.fail{border-color:rgba(248,113,113,.45)}.primitive p{color:#d8dee6;line-height:1.55}.primitive pre{background:#0f1217;border:1px solid #2a323a;border-radius:16px;color:#fef3c7;overflow:auto;padding:14px}.primitive code{color:#fef3c7}table{border-collapse:collapse;width:100%}td,th{border-bottom:1px solid #2a323a;padding:12px;text-align:left;vertical-align:top}th{color:#a8b0b8;font-size:.82rem}@media(max-width:800px){main{padding:18px}table{display:block;overflow:auto}.contract-header{display:block}}</style></head><body><main><section class="hero"><p class="eyebrow">Tool Reliability</p><h1>${escapeHtml47(title)}</h1><div class="summary"><span class="pill ${report.status === "pass" ? "pass" : "fail"}">${escapeHtml47(report.status)}</span><span class="pill">${String(report.passed)} passing</span><span class="pill">${String(report.failed)} failing</span><span class="pill">${String(report.total)} contracts</span></div></section><section class="primitive"><p class="eyebrow">Copy into your app</p><h2><code>createVoiceToolContractRoutes(...)</code> certifies tool behavior</h2><p>Define deterministic tool cases for retries, idempotency, timeouts, result shape, and error handling so assistant tools fail in pre-production instead of live calls.</p><pre><code>${snippet}</code></pre></section>${contracts || '<section class="contract"><p>No tool contracts configured.</p></section>'}</main></body></html>`;
|
|
32026
32304
|
};
|
|
32027
32305
|
var createVoiceToolContractJSONHandler = (options) => () => runVoiceToolContractSuite(options);
|
|
32028
32306
|
var createVoiceToolContractHTMLHandler = (options) => async () => {
|
|
@@ -32039,7 +32317,7 @@ var createVoiceToolContractHTMLHandler = (options) => async () => {
|
|
|
32039
32317
|
var createVoiceToolContractRoutes = (options) => {
|
|
32040
32318
|
const path = options.path ?? "/api/tool-contracts";
|
|
32041
32319
|
const htmlPath = options.htmlPath === undefined ? `${path}/htmx` : options.htmlPath;
|
|
32042
|
-
const routes = new
|
|
32320
|
+
const routes = new Elysia50({
|
|
32043
32321
|
name: options.name ?? "absolutejs-voice-tool-contracts"
|
|
32044
32322
|
}).get(path, createVoiceToolContractJSONHandler(options));
|
|
32045
32323
|
if (htmlPath) {
|
|
@@ -32049,7 +32327,7 @@ var createVoiceToolContractRoutes = (options) => {
|
|
|
32049
32327
|
};
|
|
32050
32328
|
|
|
32051
32329
|
// src/simulationSuite.ts
|
|
32052
|
-
var
|
|
32330
|
+
var escapeHtml48 = (value) => value.replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">").replaceAll('"', """).replaceAll("'", "'");
|
|
32053
32331
|
var summarizeSection = (report) => ({
|
|
32054
32332
|
failed: report.failed,
|
|
32055
32333
|
passed: report.passed,
|
|
@@ -32245,15 +32523,15 @@ var renderSection = (label, summary) => {
|
|
|
32245
32523
|
if (!summary) {
|
|
32246
32524
|
return "";
|
|
32247
32525
|
}
|
|
32248
|
-
return `<article class="${
|
|
32526
|
+
return `<article class="${escapeHtml48(summary.status)}"><span>${escapeHtml48(label)}</span><strong>${escapeHtml48(summary.status)}</strong><p>${summary.passed}/${summary.total} passed, ${summary.failed} failed.</p></article>`;
|
|
32249
32527
|
};
|
|
32250
32528
|
var renderAction = (action) => {
|
|
32251
|
-
const content = `<strong>${
|
|
32252
|
-
return action.href ? `<a class="action" href="${
|
|
32529
|
+
const content = `<strong>${escapeHtml48(action.label)}</strong><p>${escapeHtml48(action.description)}</p><span>${escapeHtml48(action.section)} / ${escapeHtml48(action.severity)}</span>`;
|
|
32530
|
+
return action.href ? `<a class="action" href="${escapeHtml48(action.href)}">${content}</a>` : `<article class="action">${content}</article>`;
|
|
32253
32531
|
};
|
|
32254
32532
|
var renderVoiceSimulationSuiteHTML = (report, options = {}) => {
|
|
32255
32533
|
const title = options.title ?? "Voice Simulation Suite";
|
|
32256
|
-
const snippet =
|
|
32534
|
+
const snippet = escapeHtml48(`app.use(
|
|
32257
32535
|
createVoiceSimulationSuiteRoutes({
|
|
32258
32536
|
htmlPath: '/voice/simulations',
|
|
32259
32537
|
path: '/api/voice/simulations',
|
|
@@ -32286,12 +32564,12 @@ app.use(
|
|
|
32286
32564
|
store: traceStore
|
|
32287
32565
|
})
|
|
32288
32566
|
);`);
|
|
32289
|
-
return `<!doctype html><html lang="en"><head><meta charset="utf-8" /><meta name="viewport" content="width=device-width, initial-scale=1" /><title>${
|
|
32567
|
+
return `<!doctype html><html lang="en"><head><meta charset="utf-8" /><meta name="viewport" content="width=device-width, initial-scale=1" /><title>${escapeHtml48(title)}</title><style>body{background:#10151c;color:#f8f3e7;font-family:ui-sans-serif,system-ui,sans-serif;margin:0}main{margin:auto;max-width:1080px;padding:32px}.hero,.primitive{background:linear-gradient(135deg,rgba(34,197,94,.18),rgba(59,130,246,.12));border:1px solid #283544;border-radius:28px;margin-bottom:18px;padding:28px}.primitive{background:#151d27;border-color:#355078}.eyebrow{color:#93c5fd;font-weight:900;letter-spacing:.12em;text-transform:uppercase}h1{font-size:clamp(2.4rem,6vw,5rem);line-height:.9;margin:.2rem 0 1rem}.badge{border:1px solid #3f3f46;border-radius:999px;display:inline-flex;padding:8px 12px}.pass{color:#86efac}.fail{color:#fca5a5}.grid,.actions{display:grid;gap:14px;grid-template-columns:repeat(auto-fit,minmax(190px,1fr));margin:18px 0}.grid article,.action{background:#151d27;border:1px solid #283544;border-radius:18px;color:inherit;padding:16px;text-decoration:none}.grid span,.action span{color:#aab5c0}.grid strong{display:block;font-size:2rem;margin:.25rem 0;text-transform:uppercase}.action strong{display:block;color:#f8f3e7;margin-bottom:.35rem}.action p,.primitive p{color:#d8dee6;line-height:1.55;margin:.3rem 0 .6rem}pre{background:#151d27;border:1px solid #283544;border-radius:18px;overflow:auto;padding:16px}.primitive pre{background:#0b1118;color:#dbeafe}.primitive code{color:#bfdbfe}</style></head><body><main><section class="hero"><p class="eyebrow">Pre-production proof</p><h1>${escapeHtml48(title)}</h1><p>One report for session quality, scenario evals, fixture simulations, tool contracts, and outcome contracts.</p><p class="badge ${escapeHtml48(report.status)}">Status: ${escapeHtml48(report.status)}</p><section class="grid">${renderSection("Sessions", report.summary.sessions)}${renderSection("Scenarios", report.summary.scenarios)}${renderSection("Fixtures", report.summary.fixtures)}${renderSection("Tools", report.summary.tools)}${renderSection("Outcomes", report.summary.outcomes)}</section></section><section class="primitive"><p class="eyebrow">Copy into your app</p><h2><code>createVoiceSimulationSuiteRoutes(...)</code> builds this pre-production proof surface</h2><p>Run session quality checks, scenario evals, fixture-backed simulations, tool contracts, and outcome contracts from one route group before live traffic sees a regression.</p><pre><code>${snippet}</code></pre></section><h2>Actions</h2><section class="actions">${report.actions.length > 0 ? report.actions.map(renderAction).join("") : '<article class="action"><strong>No action required</strong><p>All enabled simulation sections are passing.</p></article>'}</section><pre>${escapeHtml48(JSON.stringify({ summary: report.summary, actions: report.actions }, null, 2))}</pre></main></body></html>`;
|
|
32290
32568
|
};
|
|
32291
32569
|
var createVoiceSimulationSuiteRoutes = (options) => {
|
|
32292
32570
|
const path = options.path ?? "/api/voice/simulations";
|
|
32293
32571
|
const htmlPath = options.htmlPath === undefined ? "/voice/simulations" : options.htmlPath;
|
|
32294
|
-
const app = new
|
|
32572
|
+
const app = new Elysia51({
|
|
32295
32573
|
name: options.name ?? "absolutejs-voice-simulation-suite"
|
|
32296
32574
|
}).get(path, () => runVoiceSimulationSuite(options));
|
|
32297
32575
|
if (htmlPath) {
|
|
@@ -32908,10 +33186,10 @@ var assertVoiceAgentSquadContractEvidence = (reports, input = {}) => {
|
|
|
32908
33186
|
return report;
|
|
32909
33187
|
};
|
|
32910
33188
|
// src/turnLatency.ts
|
|
32911
|
-
import { Elysia as
|
|
33189
|
+
import { Elysia as Elysia52 } from "elysia";
|
|
32912
33190
|
var DEFAULT_WARN_AFTER_MS2 = 1800;
|
|
32913
33191
|
var DEFAULT_FAIL_AFTER_MS2 = 3200;
|
|
32914
|
-
var
|
|
33192
|
+
var escapeHtml49 = (value) => value.replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">").replaceAll('"', """).replaceAll("'", "'");
|
|
32915
33193
|
var firstNumber4 = (values) => values.filter((value) => typeof value === "number").sort((left, right) => left - right)[0];
|
|
32916
33194
|
var getString19 = (value) => typeof value === "string" && value.trim() ? value : undefined;
|
|
32917
33195
|
var createTraceStageIndex = (events) => {
|
|
@@ -33043,11 +33321,11 @@ await traceStore.append({
|
|
|
33043
33321
|
turnId,
|
|
33044
33322
|
type: 'turn_latency.stage'
|
|
33045
33323
|
});`;
|
|
33046
|
-
const turns = report.turns.map((turn) => `<article class="turn ${
|
|
33047
|
-
<header><div><p class="eyebrow">${
|
|
33048
|
-
<dl>${turn.stages.map((stage) => `<div><dt>${
|
|
33324
|
+
const turns = report.turns.map((turn) => `<article class="turn ${escapeHtml49(turn.status)}">
|
|
33325
|
+
<header><div><p class="eyebrow">${escapeHtml49(turn.sessionId)} \xB7 ${escapeHtml49(turn.turnId)}</p><h2>${escapeHtml49(turn.text || "Empty turn")}</h2></div><strong>${escapeHtml49(turn.status)}</strong></header>
|
|
33326
|
+
<dl>${turn.stages.map((stage) => `<div><dt>${escapeHtml49(stage.label)}</dt><dd>${escapeHtml49(formatMs4(stage.valueMs))}</dd></div>`).join("")}</dl>
|
|
33049
33327
|
</article>`).join("");
|
|
33050
|
-
return `<!doctype html><html lang="en"><head><meta charset="utf-8" /><meta name="viewport" content="width=device-width, initial-scale=1" /><title>${
|
|
33328
|
+
return `<!doctype html><html lang="en"><head><meta charset="utf-8" /><meta name="viewport" content="width=device-width, initial-scale=1" /><title>${escapeHtml49(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>${escapeHtml49(title)}</h1><div class="summary"><span class="pill ${escapeHtml49(report.status)}">${escapeHtml49(report.status)}</span><span class="pill">${String(report.total)} turns</span><span class="pill">avg ${escapeHtml49(formatMs4(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>${escapeHtml49(snippet)}</code></pre></section>${turns || '<section class="turn"><p>No committed turns found.</p></section>'}</main></body></html>`;
|
|
33051
33329
|
};
|
|
33052
33330
|
var createVoiceTurnLatencyJSONHandler = (options) => async () => summarizeVoiceTurnLatency(options);
|
|
33053
33331
|
var createVoiceTurnLatencyHTMLHandler = (options) => async () => {
|
|
@@ -33064,7 +33342,7 @@ var createVoiceTurnLatencyHTMLHandler = (options) => async () => {
|
|
|
33064
33342
|
var createVoiceTurnLatencyRoutes = (options) => {
|
|
33065
33343
|
const path = options.path ?? "/api/turn-latency";
|
|
33066
33344
|
const htmlPath = options.htmlPath === undefined ? `${path}/htmx` : options.htmlPath;
|
|
33067
|
-
const routes = new
|
|
33345
|
+
const routes = new Elysia52({
|
|
33068
33346
|
name: options.name ?? "absolutejs-voice-turn-latency"
|
|
33069
33347
|
}).get(path, createVoiceTurnLatencyJSONHandler(options));
|
|
33070
33348
|
if (htmlPath) {
|
|
@@ -33073,8 +33351,8 @@ var createVoiceTurnLatencyRoutes = (options) => {
|
|
|
33073
33351
|
return routes;
|
|
33074
33352
|
};
|
|
33075
33353
|
// src/liveLatency.ts
|
|
33076
|
-
import { Elysia as
|
|
33077
|
-
var
|
|
33354
|
+
import { Elysia as Elysia53 } from "elysia";
|
|
33355
|
+
var escapeHtml50 = (value) => value.replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">").replaceAll('"', """).replaceAll("'", "'");
|
|
33078
33356
|
var percentile6 = (values, percentileValue) => {
|
|
33079
33357
|
if (values.length === 0) {
|
|
33080
33358
|
return;
|
|
@@ -33141,13 +33419,13 @@ await traceStore.append({
|
|
|
33141
33419
|
sessionId,
|
|
33142
33420
|
type: 'client.live_latency'
|
|
33143
33421
|
});`;
|
|
33144
|
-
const rows = report.recent.map((sample) => `<tr><td>${
|
|
33145
|
-
return `<!doctype html><html lang="en"><head><meta charset="utf-8" /><meta name="viewport" content="width=device-width, initial-scale=1" /><title>${
|
|
33422
|
+
const rows = report.recent.map((sample) => `<tr><td>${escapeHtml50(sample.sessionId)}</td><td>${escapeHtml50(formatMs5(sample.latencyMs))}</td><td>${escapeHtml50(sample.status ?? "unknown")}</td><td>${escapeHtml50(new Date(sample.at).toLocaleString())}</td></tr>`).join("");
|
|
33423
|
+
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:#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>${escapeHtml50(title)}</h1><p>Recent real browser speech-to-assistant response measurements from persisted <code>client.live_latency</code> traces.</p><p class="status ${escapeHtml50(report.status)}">Status: ${escapeHtml50(report.status)}</p><section class="metrics"><article><span>p50</span><strong>${escapeHtml50(formatMs5(report.p50LatencyMs))}</strong></article><article><span>p95</span><strong>${escapeHtml50(formatMs5(report.p95LatencyMs))}</strong></article><article><span>Average</span><strong>${escapeHtml50(formatMs5(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>${escapeHtml50(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>`;
|
|
33146
33424
|
};
|
|
33147
33425
|
var createVoiceLiveLatencyRoutes = (options) => {
|
|
33148
33426
|
const path = options.path ?? "/api/live-latency";
|
|
33149
33427
|
const htmlPath = options.htmlPath === undefined ? "/live-latency" : options.htmlPath;
|
|
33150
|
-
const routes = new
|
|
33428
|
+
const routes = new Elysia53({
|
|
33151
33429
|
name: options.name ?? "absolutejs-voice-live-latency"
|
|
33152
33430
|
}).get(path, () => summarizeVoiceLiveLatency(options));
|
|
33153
33431
|
if (htmlPath) {
|
|
@@ -33164,9 +33442,9 @@ var createVoiceLiveLatencyRoutes = (options) => {
|
|
|
33164
33442
|
return routes;
|
|
33165
33443
|
};
|
|
33166
33444
|
// src/turnQuality.ts
|
|
33167
|
-
import { Elysia as
|
|
33445
|
+
import { Elysia as Elysia54 } from "elysia";
|
|
33168
33446
|
var DEFAULT_CONFIDENCE_WARN_THRESHOLD = 0.72;
|
|
33169
|
-
var
|
|
33447
|
+
var escapeHtml51 = (value) => value.replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">").replaceAll('"', """).replaceAll("'", "'");
|
|
33170
33448
|
var getTurnLatencyMs = (turn) => {
|
|
33171
33449
|
const firstTranscriptAt = turn.transcripts.map((transcript) => transcript.endedAtMs ?? transcript.startedAtMs).filter((value) => typeof value === "number").sort((left, right) => left - right)[0];
|
|
33172
33450
|
if (firstTranscriptAt === undefined) {
|
|
@@ -33236,24 +33514,24 @@ var summarizeVoiceTurnQuality = async (options) => {
|
|
|
33236
33514
|
};
|
|
33237
33515
|
var renderVoiceTurnQualityHTML = (report, options = {}) => {
|
|
33238
33516
|
const title = options.title ?? "Voice Turn Quality";
|
|
33239
|
-
const turns = report.turns.map((turn) => `<article class="turn ${
|
|
33517
|
+
const turns = report.turns.map((turn) => `<article class="turn ${escapeHtml51(turn.status)}">
|
|
33240
33518
|
<div class="turn-header">
|
|
33241
33519
|
<div>
|
|
33242
|
-
<p class="eyebrow">${
|
|
33243
|
-
<h2>${
|
|
33520
|
+
<p class="eyebrow">${escapeHtml51(turn.sessionId)} \xB7 ${escapeHtml51(turn.turnId)}</p>
|
|
33521
|
+
<h2>${escapeHtml51(turn.text || "Empty turn")}</h2>
|
|
33244
33522
|
</div>
|
|
33245
|
-
<strong>${
|
|
33523
|
+
<strong>${escapeHtml51(turn.status)}</strong>
|
|
33246
33524
|
</div>
|
|
33247
33525
|
<dl>
|
|
33248
|
-
<div><dt>Source</dt><dd>${
|
|
33526
|
+
<div><dt>Source</dt><dd>${escapeHtml51(turn.source ?? "unknown")}</dd></div>
|
|
33249
33527
|
<div><dt>Confidence</dt><dd>${turn.averageConfidence === undefined ? "n/a" : `${Math.round(turn.averageConfidence * 100)}%`}</dd></div>
|
|
33250
|
-
<div><dt>Fallback</dt><dd>${turn.fallbackUsed ? `yes (${
|
|
33251
|
-
<div><dt>Correction</dt><dd>${turn.correctionChanged ? `changed${turn.correctionProvider ? ` by ${
|
|
33528
|
+
<div><dt>Fallback</dt><dd>${turn.fallbackUsed ? `yes (${escapeHtml51(turn.fallbackSelectionReason ?? "selected")})` : "no"}</dd></div>
|
|
33529
|
+
<div><dt>Correction</dt><dd>${turn.correctionChanged ? `changed${turn.correctionProvider ? ` by ${escapeHtml51(turn.correctionProvider)}` : ""}` : "none"}</dd></div>
|
|
33252
33530
|
<div><dt>Transcripts</dt><dd>${String(turn.selectedTranscriptCount)} selected \xB7 ${String(turn.finalTranscriptCount)} final \xB7 ${String(turn.partialTranscriptCount)} partial</dd></div>
|
|
33253
33531
|
<div><dt>Cost</dt><dd>${turn.costUnits === undefined ? "n/a" : String(turn.costUnits)}</dd></div>
|
|
33254
33532
|
</dl>
|
|
33255
33533
|
</article>`).join("");
|
|
33256
|
-
return `<!doctype html><html lang="en"><head><meta charset="utf-8" /><meta name="viewport" content="width=device-width, initial-scale=1" /><title>${
|
|
33534
|
+
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{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>${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">${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>`;
|
|
33257
33535
|
};
|
|
33258
33536
|
var createVoiceTurnQualityJSONHandler = (options) => async () => summarizeVoiceTurnQuality(options);
|
|
33259
33537
|
var createVoiceTurnQualityHTMLHandler = (options) => async () => {
|
|
@@ -33270,7 +33548,7 @@ var createVoiceTurnQualityHTMLHandler = (options) => async () => {
|
|
|
33270
33548
|
var createVoiceTurnQualityRoutes = (options) => {
|
|
33271
33549
|
const path = options.path ?? "/api/turn-quality";
|
|
33272
33550
|
const htmlPath = options.htmlPath === undefined ? `${path}/htmx` : options.htmlPath;
|
|
33273
|
-
const routes = new
|
|
33551
|
+
const routes = new Elysia54({
|
|
33274
33552
|
name: options.name ?? "absolutejs-voice-turn-quality"
|
|
33275
33553
|
}).get(path, createVoiceTurnQualityJSONHandler(options));
|
|
33276
33554
|
if (htmlPath) {
|
|
@@ -33279,10 +33557,10 @@ var createVoiceTurnQualityRoutes = (options) => {
|
|
|
33279
33557
|
return routes;
|
|
33280
33558
|
};
|
|
33281
33559
|
// src/phoneAgent.ts
|
|
33282
|
-
import { Elysia as
|
|
33560
|
+
import { Elysia as Elysia56 } from "elysia";
|
|
33283
33561
|
|
|
33284
33562
|
// src/phoneAgentProductionSmoke.ts
|
|
33285
|
-
import { Elysia as
|
|
33563
|
+
import { Elysia as Elysia55 } from "elysia";
|
|
33286
33564
|
var defaultRequirements = [
|
|
33287
33565
|
"media-started",
|
|
33288
33566
|
"transcript",
|
|
@@ -33290,7 +33568,7 @@ var defaultRequirements = [
|
|
|
33290
33568
|
"lifecycle-outcome",
|
|
33291
33569
|
"no-session-error"
|
|
33292
33570
|
];
|
|
33293
|
-
var
|
|
33571
|
+
var escapeHtml52 = (value) => value.replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">").replaceAll('"', """).replaceAll("'", "'");
|
|
33294
33572
|
var payloadType = (event) => typeof event.payload.type === "string" ? event.payload.type : undefined;
|
|
33295
33573
|
var hasTextPayload = (event) => ["text", "assistantText", "transcript"].some((key) => {
|
|
33296
33574
|
const value = event.payload[key];
|
|
@@ -33399,10 +33677,10 @@ var resolveHandlerOptions = async (options, input) => ({
|
|
|
33399
33677
|
});
|
|
33400
33678
|
var renderVoicePhoneAgentProductionSmokeHTML = (report, options = {}) => {
|
|
33401
33679
|
const title = options.title ?? "AbsoluteJS Voice Phone Smoke Contract";
|
|
33402
|
-
const issues = report.issues.map((issue) => `<li><strong>${
|
|
33403
|
-
const outcomes = report.observed.lifecycleOutcomes.map((outcome) => `<span class="pill">${
|
|
33404
|
-
const requirements = report.required.map((requirement) => `<span class="pill">${
|
|
33405
|
-
return `<!doctype html><html lang="en"><head><meta charset="utf-8" /><meta name="viewport" content="width=device-width, initial-scale=1" /><title>${
|
|
33680
|
+
const issues = report.issues.map((issue) => `<li><strong>${escapeHtml52(issue.requirement)}</strong>: ${escapeHtml52(issue.message)}</li>`).join("");
|
|
33681
|
+
const outcomes = report.observed.lifecycleOutcomes.map((outcome) => `<span class="pill">${escapeHtml52(outcome)}</span>`).join("");
|
|
33682
|
+
const requirements = report.required.map((requirement) => `<span class="pill">${escapeHtml52(requirement)}</span>`).join("");
|
|
33683
|
+
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:#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>${escapeHtml52(title)}</h1><p class="status ${report.pass ? "pass" : "fail"}">${report.pass ? "PASS" : "FAIL"}</p><p>Contract <code>${escapeHtml52(report.contractId)}</code>${report.provider ? ` for <code>${escapeHtml52(report.provider)}</code>` : ""}${report.sessionId ? ` on session <code>${escapeHtml52(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>`;
|
|
33406
33684
|
};
|
|
33407
33685
|
var createVoicePhoneAgentProductionSmokeJSONHandler = (options) => async ({
|
|
33408
33686
|
query,
|
|
@@ -33425,7 +33703,7 @@ var createVoicePhoneAgentProductionSmokeHTMLHandler = (options) => async ({
|
|
|
33425
33703
|
var createVoicePhoneAgentProductionSmokeRoutes = (options) => {
|
|
33426
33704
|
const path = options.path ?? "/api/voice/phone/smoke-contract";
|
|
33427
33705
|
const htmlPath = options.htmlPath === undefined ? "/voice/phone/smoke-contract" : options.htmlPath;
|
|
33428
|
-
const routes = new
|
|
33706
|
+
const routes = new Elysia55({
|
|
33429
33707
|
name: options.name ?? "absolutejs-voice-phone-smoke-contract"
|
|
33430
33708
|
}).get(path, createVoicePhoneAgentProductionSmokeJSONHandler(options));
|
|
33431
33709
|
if (htmlPath) {
|
|
@@ -33468,7 +33746,7 @@ var PHONE_AGENT_LIFECYCLE_STAGES = [
|
|
|
33468
33746
|
"completed",
|
|
33469
33747
|
"failed"
|
|
33470
33748
|
];
|
|
33471
|
-
var
|
|
33749
|
+
var escapeHtml53 = (value) => value.replaceAll("&", "&").replaceAll('"', """).replaceAll("'", "'").replaceAll("<", "<").replaceAll(">", ">");
|
|
33472
33750
|
var loadRouteJson = async (input) => {
|
|
33473
33751
|
const response = await input.app.handle(new Request(new URL(input.path, input.origin).toString(), {
|
|
33474
33752
|
headers: {
|
|
@@ -33706,10 +33984,10 @@ var renderVoicePhoneAgentSetupHTML = (report) => {
|
|
|
33706
33984
|
const entry = findCarrierMatrixEntry(report.matrix, carrier);
|
|
33707
33985
|
const urls = entry?.setup.urls;
|
|
33708
33986
|
const primaryUrl = carrier.provider === "plivo" ? urls?.twiml : urls?.twiml;
|
|
33709
|
-
return `<tr><td>${
|
|
33987
|
+
return `<tr><td>${escapeHtml53(carrier.name ?? carrier.provider)}</td><td>${escapeHtml53(carrier.provider)}</td><td><code>${escapeHtml53(carrier.setupPath || "disabled")}</code></td><td><code>${escapeHtml53(carrier.smokePath || "disabled")}</code></td><td>${entry ? `<span class="${escapeHtml53(entry.status)}">${escapeHtml53(entry.status.toUpperCase())}</span>` : "unknown"}</td><td>${primaryUrl ? `<code>${escapeHtml53(primaryUrl)}</code>` : '<span class="muted">missing</span>'}</td><td>${urls?.webhook ? `<code>${escapeHtml53(urls.webhook)}</code>` : '<span class="muted">missing</span>'}</td><td>${urls?.stream ? `<code>${escapeHtml53(urls.stream)}</code>` : '<span class="muted">missing</span>'}</td></tr>`;
|
|
33710
33988
|
}).join("");
|
|
33711
|
-
const stageList = report.lifecycleStages.map((stage) => `<li><code>${
|
|
33712
|
-
const snippet =
|
|
33989
|
+
const stageList = report.lifecycleStages.map((stage) => `<li><code>${escapeHtml53(stage)}</code></li>`).join("");
|
|
33990
|
+
const snippet = escapeHtml53(`const phoneAgent = createVoicePhoneAgent({
|
|
33713
33991
|
carriers: [
|
|
33714
33992
|
{
|
|
33715
33993
|
provider: 'twilio',
|
|
@@ -33743,11 +34021,11 @@ app.use(
|
|
|
33743
34021
|
);`);
|
|
33744
34022
|
const checklist = report.carriers.map((carrier) => {
|
|
33745
34023
|
const instruction = report.setupInstructions.find((candidate) => candidate.provider === carrier.provider && candidate.carrierName === (carrier.name ?? carrier.provider));
|
|
33746
|
-
const issueList = instruction?.issues.map((issue) => `<li>${
|
|
33747
|
-
const steps = instruction?.steps.map((step) => `<li>${
|
|
33748
|
-
return `<article><h3>${
|
|
34024
|
+
const issueList = instruction?.issues.map((issue) => `<li>${escapeHtml53(issue)}</li>`).join("") ?? "";
|
|
34025
|
+
const steps = instruction?.steps.map((step) => `<li>${escapeHtml53(step)}</li>`).join("") ?? "";
|
|
34026
|
+
return `<article><h3>${escapeHtml53(carrier.name ?? carrier.provider)}</h3><ol>${steps}</ol>${issueList ? `<ul class="issues">${issueList}</ul>` : '<p class="pass">No carrier contract issues.</p>'}</article>`;
|
|
33749
34027
|
}).join("");
|
|
33750
|
-
return `<!doctype html><html lang="en"><head><meta charset="utf-8" /><meta name="viewport" content="width=device-width, initial-scale=1" /><title>${
|
|
34028
|
+
return `<!doctype html><html lang="en"><head><meta charset="utf-8" /><meta name="viewport" content="width=device-width, initial-scale=1" /><title>${escapeHtml53(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>${escapeHtml53(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="${escapeHtml53(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>`;
|
|
33751
34029
|
};
|
|
33752
34030
|
var createVoicePhoneAgent = (options) => {
|
|
33753
34031
|
const carrierSummaries = options.carriers.map((carrier) => ({
|
|
@@ -33756,7 +34034,7 @@ var createVoicePhoneAgent = (options) => {
|
|
|
33756
34034
|
setupPath: resolveSetupPath(carrier),
|
|
33757
34035
|
smokePath: resolveSmokePath(carrier)
|
|
33758
34036
|
}));
|
|
33759
|
-
const app = new
|
|
34037
|
+
const app = new Elysia56({
|
|
33760
34038
|
name: options.name ?? "absolutejs-voice-phone-agent"
|
|
33761
34039
|
});
|
|
33762
34040
|
for (const carrier of options.carriers) {
|
|
@@ -35503,8 +35781,8 @@ var createOpenAIVoiceTTS = (options) => {
|
|
|
35503
35781
|
};
|
|
35504
35782
|
};
|
|
35505
35783
|
// src/providerCapabilities.ts
|
|
35506
|
-
import { Elysia as
|
|
35507
|
-
var
|
|
35784
|
+
import { Elysia as Elysia57 } from "elysia";
|
|
35785
|
+
var escapeHtml54 = (value) => value.replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">").replaceAll('"', """).replaceAll("'", "'");
|
|
35508
35786
|
var fromProviderList = (kind, providers, options) => (providers ?? []).map((provider) => ({
|
|
35509
35787
|
configured: true,
|
|
35510
35788
|
features: options.features?.[provider],
|
|
@@ -35567,27 +35845,27 @@ var summarizeVoiceProviderCapabilities = async (options) => {
|
|
|
35567
35845
|
var renderVoiceProviderCapabilityHTML = (report, options = {}) => {
|
|
35568
35846
|
const title = options.title ?? "Voice Provider Capabilities";
|
|
35569
35847
|
const cards = report.capabilities.map((capability) => {
|
|
35570
|
-
const features = (capability.features ?? []).map((feature) => `<span class="pill">${
|
|
35571
|
-
return `<article class="card ${
|
|
35848
|
+
const features = (capability.features ?? []).map((feature) => `<span class="pill">${escapeHtml54(feature)}</span>`).join("");
|
|
35849
|
+
return `<article class="card ${escapeHtml54(capability.status)}">
|
|
35572
35850
|
<div class="card-header">
|
|
35573
35851
|
<div>
|
|
35574
|
-
<p class="eyebrow">${
|
|
35575
|
-
<h2>${
|
|
35852
|
+
<p class="eyebrow">${escapeHtml54(capability.kind)}</p>
|
|
35853
|
+
<h2>${escapeHtml54(capability.label ?? capability.provider)}</h2>
|
|
35576
35854
|
</div>
|
|
35577
|
-
<strong>${
|
|
35855
|
+
<strong>${escapeHtml54(capability.status)}</strong>
|
|
35578
35856
|
</div>
|
|
35579
|
-
${capability.description ? `<p>${
|
|
35857
|
+
${capability.description ? `<p>${escapeHtml54(capability.description)}</p>` : ""}
|
|
35580
35858
|
<dl>
|
|
35581
35859
|
<div><dt>Configured</dt><dd>${capability.configured ? "yes" : "no"}</dd></div>
|
|
35582
35860
|
<div><dt>Selected</dt><dd>${capability.selected ? "yes" : "no"}</dd></div>
|
|
35583
|
-
<div><dt>Model</dt><dd>${
|
|
35861
|
+
<div><dt>Model</dt><dd>${escapeHtml54(capability.model ?? "default")}</dd></div>
|
|
35584
35862
|
<div><dt>Runs</dt><dd>${String(capability.health?.runCount ?? 0)}</dd></div>
|
|
35585
35863
|
<div><dt>Errors</dt><dd>${String(capability.health?.errorCount ?? 0)}</dd></div>
|
|
35586
35864
|
</dl>
|
|
35587
35865
|
${features ? `<div class="features">${features}</div>` : ""}
|
|
35588
35866
|
</article>`;
|
|
35589
35867
|
}).join("");
|
|
35590
|
-
return `<!doctype html><html lang="en"><head><meta charset="utf-8" /><meta name="viewport" content="width=device-width, initial-scale=1" /><title>${
|
|
35868
|
+
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:#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>${escapeHtml54(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>`;
|
|
35591
35869
|
};
|
|
35592
35870
|
var createVoiceProviderCapabilityJSONHandler = (options) => async () => summarizeVoiceProviderCapabilities(options);
|
|
35593
35871
|
var createVoiceProviderCapabilityHTMLHandler = (options) => async () => {
|
|
@@ -35604,7 +35882,7 @@ var createVoiceProviderCapabilityHTMLHandler = (options) => async () => {
|
|
|
35604
35882
|
var createVoiceProviderCapabilityRoutes = (options) => {
|
|
35605
35883
|
const path = options.path ?? "/api/provider-capabilities";
|
|
35606
35884
|
const htmlPath = options.htmlPath === undefined ? `${path}/htmx` : options.htmlPath;
|
|
35607
|
-
const routes = new
|
|
35885
|
+
const routes = new Elysia57({
|
|
35608
35886
|
name: options.name ?? "absolutejs-voice-provider-capabilities"
|
|
35609
35887
|
}).get(path, createVoiceProviderCapabilityJSONHandler(options));
|
|
35610
35888
|
if (htmlPath) {
|
|
@@ -35613,7 +35891,7 @@ var createVoiceProviderCapabilityRoutes = (options) => {
|
|
|
35613
35891
|
return routes;
|
|
35614
35892
|
};
|
|
35615
35893
|
// src/providerOrchestration.ts
|
|
35616
|
-
import { Elysia as
|
|
35894
|
+
import { Elysia as Elysia58 } from "elysia";
|
|
35617
35895
|
var defaultRequirement = {
|
|
35618
35896
|
minProviders: 1,
|
|
35619
35897
|
requireBudgetPolicy: false,
|
|
@@ -35626,7 +35904,7 @@ var statusRank6 = {
|
|
|
35626
35904
|
warn: 1,
|
|
35627
35905
|
fail: 2
|
|
35628
35906
|
};
|
|
35629
|
-
var
|
|
35907
|
+
var escapeHtml55 = (value) => value.replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">").replaceAll('"', """).replaceAll("'", "'");
|
|
35630
35908
|
var isProviderList = (value) => Array.isArray(value) && value.every((entry) => typeof entry === "string");
|
|
35631
35909
|
var uniqueSorted8 = (values) => [
|
|
35632
35910
|
...new Set(values.filter((value) => typeof value === "string"))
|
|
@@ -35769,27 +36047,27 @@ var renderVoiceProviderOrchestrationMarkdown = (report) => {
|
|
|
35769
36047
|
};
|
|
35770
36048
|
var renderVoiceProviderOrchestrationHTML = (report, options = {}) => {
|
|
35771
36049
|
const title = options.title ?? "Voice Provider Orchestration";
|
|
35772
|
-
const cards = report.surfaces.map((surface) => `<article class="card ${
|
|
35773
|
-
<div class="card-header"><div><p class="eyebrow">${
|
|
36050
|
+
const cards = report.surfaces.map((surface) => `<article class="card ${escapeHtml55(surface.status)}">
|
|
36051
|
+
<div class="card-header"><div><p class="eyebrow">${escapeHtml55(surface.surface)}</p><h2>${escapeHtml55(surface.strategy ?? "default policy")}</h2></div><strong>${escapeHtml55(surface.status)}</strong></div>
|
|
35774
36052
|
<dl>
|
|
35775
|
-
<div><dt>Providers</dt><dd>${
|
|
35776
|
-
<div><dt>Fallback</dt><dd>${
|
|
36053
|
+
<div><dt>Providers</dt><dd>${escapeHtml55(surface.providers.join(", ") || "none")}</dd></div>
|
|
36054
|
+
<div><dt>Fallback</dt><dd>${escapeHtml55(surface.fallbackProviders.join(" -> ") || "none")}</dd></div>
|
|
35777
36055
|
<div><dt>Circuit breaker</dt><dd>${surface.circuitBreaker ? "yes" : "no"}</dd></div>
|
|
35778
36056
|
<div><dt>Timeout</dt><dd>${surface.timeoutBudget ? `${String(surface.timeoutMs)}ms` : "none"}</dd></div>
|
|
35779
36057
|
<div><dt>Max cost</dt><dd>${surface.budgetPolicy.maxCost ?? "none"}</dd></div>
|
|
35780
36058
|
<div><dt>Max latency</dt><dd>${surface.budgetPolicy.maxLatencyMs ? `${String(surface.budgetPolicy.maxLatencyMs)}ms` : "none"}</dd></div>
|
|
35781
36059
|
<div><dt>Min quality</dt><dd>${surface.budgetPolicy.minQuality ?? "none"}</dd></div>
|
|
35782
|
-
<div><dt>Fallback mode</dt><dd>${
|
|
36060
|
+
<div><dt>Fallback mode</dt><dd>${escapeHtml55(surface.fallbackMode || "default")}</dd></div>
|
|
35783
36061
|
</dl>
|
|
35784
|
-
${surface.issues.length ? `<ul>${surface.issues.map((issue) => `<li><strong>${
|
|
36062
|
+
${surface.issues.length ? `<ul>${surface.issues.map((issue) => `<li><strong>${escapeHtml55(issue.status)}</strong> ${escapeHtml55(issue.message)}</li>`).join("")}</ul>` : "<p>No orchestration issues.</p>"}
|
|
35785
36063
|
</article>`).join("");
|
|
35786
|
-
return `<!doctype html><html lang="en"><head><meta charset="utf-8" /><meta name="viewport" content="width=device-width, initial-scale=1" /><title>${
|
|
36064
|
+
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:#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>${escapeHtml55(title)}</h1><div class="summary"><span class="pill">${escapeHtml55(report.profileId)}</span><span class="pill">${escapeHtml55(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>`;
|
|
35787
36065
|
};
|
|
35788
36066
|
var createVoiceProviderOrchestrationRoutes = (options) => {
|
|
35789
36067
|
const path = options.path ?? "/api/voice/provider-orchestration";
|
|
35790
36068
|
const htmlPath = options.htmlPath === undefined ? "/voice/provider-orchestration" : options.htmlPath;
|
|
35791
36069
|
const markdownPath = options.markdownPath === undefined ? "/voice/provider-orchestration.md" : options.markdownPath;
|
|
35792
|
-
const routes = new
|
|
36070
|
+
const routes = new Elysia58({
|
|
35793
36071
|
name: options.name ?? "absolutejs-voice-provider-orchestration"
|
|
35794
36072
|
}).get(path, () => buildVoiceProviderOrchestrationReport(options));
|
|
35795
36073
|
if (htmlPath) {
|
|
@@ -35960,8 +36238,8 @@ var assertVoiceProviderRoutingContractEvidence = (reports, input = {}) => {
|
|
|
35960
36238
|
return report;
|
|
35961
36239
|
};
|
|
35962
36240
|
// src/voiceMonitoring.ts
|
|
35963
|
-
import { Elysia as
|
|
35964
|
-
var
|
|
36241
|
+
import { Elysia as Elysia59 } from "elysia";
|
|
36242
|
+
var escapeHtml56 = (value) => value.replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">").replaceAll('"', """).replaceAll("'", "'");
|
|
35965
36243
|
var issueIdForRun = (run) => `voice-monitor:${run.id}:${run.impactedSessions?.[0] ?? "global"}`;
|
|
35966
36244
|
var rollupStatus5 = (runs) => runs.some((run) => run.status === "fail") ? "fail" : runs.some((run) => run.status === "warn") ? "warn" : "pass";
|
|
35967
36245
|
var createVoiceMemoryMonitorIssueStore = (initial = []) => {
|
|
@@ -36214,14 +36492,14 @@ ${rows || "| none | pass | info | | | No monitors configured. |"}
|
|
|
36214
36492
|
};
|
|
36215
36493
|
var renderVoiceMonitorHTML = (report, options = {}) => {
|
|
36216
36494
|
const title = options.title ?? "Voice Monitors";
|
|
36217
|
-
const runs = report.runs.map((run) => `<tr><td>${
|
|
36218
|
-
const issues = report.issues.map((issue) => `<li><strong>${
|
|
36219
|
-
const snippet =
|
|
36495
|
+
const runs = report.runs.map((run) => `<tr><td>${escapeHtml56(run.label)}</td><td class="${escapeHtml56(run.status)}">${escapeHtml56(run.status)}</td><td>${escapeHtml56(run.severity)}</td><td>${escapeHtml56(String(run.value ?? ""))}</td><td>${escapeHtml56(String(run.threshold ?? ""))}</td><td>${escapeHtml56(run.detail ?? "")}</td></tr>`).join("");
|
|
36496
|
+
const issues = report.issues.map((issue) => `<li><strong>${escapeHtml56(issue.label)}</strong> <span class="${escapeHtml56(issue.status)}">${escapeHtml56(issue.status)}</span> ${escapeHtml56(issue.detail ?? "")}</li>`).join("");
|
|
36497
|
+
const snippet = escapeHtml56(`app.use(createVoiceMonitorRoutes({
|
|
36220
36498
|
evidence,
|
|
36221
36499
|
issueStore,
|
|
36222
36500
|
monitors: [defineVoiceMonitor(...)]
|
|
36223
36501
|
}));`);
|
|
36224
|
-
return `<!doctype html><html lang="en"><head><meta charset="utf-8" /><meta name="viewport" content="width=device-width, initial-scale=1" /><title>${
|
|
36502
|
+
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:#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>${escapeHtml56(title)}</h1><p class="pill ${escapeHtml56(report.status)}">Status: ${escapeHtml56(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>`;
|
|
36225
36503
|
};
|
|
36226
36504
|
var actorFromRequest = async (request) => {
|
|
36227
36505
|
if (!request.headers.get("content-type")?.includes("application/json")) {
|
|
@@ -36245,7 +36523,7 @@ var createVoiceMonitorRoutes = (options) => {
|
|
|
36245
36523
|
monitors: options.monitors,
|
|
36246
36524
|
now: options.now
|
|
36247
36525
|
});
|
|
36248
|
-
const routes = new
|
|
36526
|
+
const routes = new Elysia59({
|
|
36249
36527
|
name: options.name ?? "absolutejs-voice-monitoring"
|
|
36250
36528
|
}).get(path, report).get(`${path}.md`, async () => {
|
|
36251
36529
|
return new Response(renderVoiceMonitorMarkdown(await report()), {
|
|
@@ -36292,7 +36570,7 @@ var createVoiceMonitorRoutes = (options) => {
|
|
|
36292
36570
|
};
|
|
36293
36571
|
var createVoiceMonitorRunnerRoutes = (options) => {
|
|
36294
36572
|
const path = options.path ?? "/api/voice/monitor-runner";
|
|
36295
|
-
return new
|
|
36573
|
+
return new Elysia59({
|
|
36296
36574
|
name: options.name ?? "absolutejs-voice-monitor-runner"
|
|
36297
36575
|
}).get(path, () => ({
|
|
36298
36576
|
isRunning: options.runner.isRunning()
|
|
@@ -36668,8 +36946,8 @@ var recommendVoiceReadinessProfile = (options) => {
|
|
|
36668
36946
|
};
|
|
36669
36947
|
};
|
|
36670
36948
|
// src/providerStackRecommendations.ts
|
|
36671
|
-
import { Elysia as
|
|
36672
|
-
var
|
|
36949
|
+
import { Elysia as Elysia60 } from "elysia";
|
|
36950
|
+
var escapeHtml57 = (value) => value.replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">").replaceAll('"', """).replaceAll("'", "'");
|
|
36673
36951
|
var profileProviderPriorities = {
|
|
36674
36952
|
"meeting-recorder": {
|
|
36675
36953
|
llm: ["openai", "anthropic", "gemini"],
|
|
@@ -36988,17 +37266,17 @@ var resolveProviderContractMatrixInput = async (matrix) => typeof matrix === "fu
|
|
|
36988
37266
|
var renderVoiceProviderContractMatrixHTML = (report, options = {}) => {
|
|
36989
37267
|
const title = options.title ?? "Voice Provider Contract Matrix";
|
|
36990
37268
|
const rows = report.rows.map((row) => {
|
|
36991
|
-
const checks = row.checks.map((check) => `<li class="${
|
|
36992
|
-
return `<article class="row ${
|
|
37269
|
+
const checks = row.checks.map((check) => `<li class="${escapeHtml57(check.status)}"><strong>${escapeHtml57(check.label)}</strong><span>${escapeHtml57(check.detail ?? check.status)}</span>${check.remediation ? `<em>${check.remediation.href ? `<a href="${escapeHtml57(check.remediation.href)}">${escapeHtml57(check.remediation.label)}</a>` : escapeHtml57(check.remediation.label)}: ${escapeHtml57(check.remediation.detail)}</em>` : ""}</li>`).join("");
|
|
37270
|
+
return `<article class="row ${escapeHtml57(row.status)}">
|
|
36993
37271
|
<div>
|
|
36994
|
-
<p class="eyebrow">${
|
|
36995
|
-
<h2>${
|
|
36996
|
-
<p class="status ${
|
|
37272
|
+
<p class="eyebrow">${escapeHtml57(row.kind)}${row.selected ? " \xB7 selected" : ""}</p>
|
|
37273
|
+
<h2>${escapeHtml57(row.provider)}</h2>
|
|
37274
|
+
<p class="status ${escapeHtml57(row.status)}">${escapeHtml57(row.status.toUpperCase())}</p>
|
|
36997
37275
|
</div>
|
|
36998
37276
|
<ul>${checks}</ul>
|
|
36999
37277
|
</article>`;
|
|
37000
37278
|
}).join("");
|
|
37001
|
-
const snippet =
|
|
37279
|
+
const snippet = escapeHtml57(`const providerContracts = () =>
|
|
37002
37280
|
createVoiceProviderContractMatrixPreset('phone-agent', {
|
|
37003
37281
|
env: process.env,
|
|
37004
37282
|
providers: {
|
|
@@ -37019,7 +37297,7 @@ createVoiceProductionReadinessRoutes({
|
|
|
37019
37297
|
providerContractMatrix: () =>
|
|
37020
37298
|
buildVoiceProviderContractMatrix(providerContracts())
|
|
37021
37299
|
});`);
|
|
37022
|
-
return `<!doctype html><html lang="en"><head><meta charset="utf-8" /><meta name="viewport" content="width=device-width, initial-scale=1" /><title>${
|
|
37300
|
+
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:#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>${escapeHtml57(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>`;
|
|
37023
37301
|
};
|
|
37024
37302
|
var createVoiceProviderContractMatrixJSONHandler = (matrix) => async () => buildVoiceProviderContractMatrix(await resolveProviderContractMatrixInput(matrix));
|
|
37025
37303
|
var createVoiceProviderContractMatrixHTMLHandler = (options) => async () => {
|
|
@@ -37034,7 +37312,7 @@ var createVoiceProviderContractMatrixHTMLHandler = (options) => async () => {
|
|
|
37034
37312
|
var createVoiceProviderContractMatrixRoutes = (options) => {
|
|
37035
37313
|
const path = options.path ?? "/api/provider-contracts";
|
|
37036
37314
|
const htmlPath = options.htmlPath ?? "/provider-contracts";
|
|
37037
|
-
const routes = new
|
|
37315
|
+
const routes = new Elysia60({
|
|
37038
37316
|
name: options.name ?? "absolutejs-voice-provider-contract-matrix"
|
|
37039
37317
|
});
|
|
37040
37318
|
const jsonHandler = createVoiceProviderContractMatrixJSONHandler(options.matrix);
|
|
@@ -37152,7 +37430,7 @@ var assertVoiceProviderStackEvidence = (report, input = {}) => {
|
|
|
37152
37430
|
return assertion;
|
|
37153
37431
|
};
|
|
37154
37432
|
// src/opsConsoleRoutes.ts
|
|
37155
|
-
import { Elysia as
|
|
37433
|
+
import { Elysia as Elysia61 } from "elysia";
|
|
37156
37434
|
var DEFAULT_LINKS = [
|
|
37157
37435
|
{
|
|
37158
37436
|
description: "Quality gates for CI, deploy checks, and production readiness.",
|
|
@@ -37187,7 +37465,7 @@ var DEFAULT_LINKS = [
|
|
|
37187
37465
|
label: "Handoffs"
|
|
37188
37466
|
}
|
|
37189
37467
|
];
|
|
37190
|
-
var
|
|
37468
|
+
var escapeHtml58 = (value) => value.replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">").replaceAll('"', """).replaceAll("'", "'");
|
|
37191
37469
|
var countProviderStatuses = (providers) => {
|
|
37192
37470
|
const degradedStatuses = new Set(["degraded", "rate-limited", "suppressed"]);
|
|
37193
37471
|
const healthy = providers.filter((provider) => provider.status === "healthy").length;
|
|
@@ -37256,20 +37534,20 @@ var buildVoiceOpsConsoleReport = async (options) => {
|
|
|
37256
37534
|
trace
|
|
37257
37535
|
};
|
|
37258
37536
|
};
|
|
37259
|
-
var renderMetricCard = (input) => `<article class="metric"><span>${
|
|
37537
|
+
var renderMetricCard = (input) => `<article class="metric"><span>${escapeHtml58(input.label)}</span><strong>${escapeHtml58(String(input.value))}</strong>${input.status ? `<p class="${escapeHtml58(input.status)}">${escapeHtml58(input.status)}</p>` : ""}${input.href ? `<a href="${escapeHtml58(input.href)}">Open</a>` : ""}</article>`;
|
|
37260
37538
|
var renderVoiceOpsConsoleHTML = (report, options = {}) => {
|
|
37261
37539
|
const links = report.links.map((link) => `<article class="surface">
|
|
37262
|
-
<div><h2>${
|
|
37263
|
-
<p><a href="${
|
|
37540
|
+
<div><h2>${escapeHtml58(link.label)}</h2>${link.description ? `<p>${escapeHtml58(link.description)}</p>` : ""}</div>
|
|
37541
|
+
<p><a href="${escapeHtml58(link.href)}">Open ${escapeHtml58(link.label)}</a>${link.statusHref ? ` \xB7 <a href="${escapeHtml58(link.statusHref)}">Status</a>` : ""}</p>
|
|
37264
37542
|
</article>`).join("");
|
|
37265
|
-
const sessions = report.recentSessions.length ? report.recentSessions.map((session) => `<tr><td>${
|
|
37266
|
-
const routing = report.recentRoutingEvents.length ? report.recentRoutingEvents.map((event) => `<tr><td>${
|
|
37543
|
+
const sessions = report.recentSessions.length ? report.recentSessions.map((session) => `<tr><td>${escapeHtml58(session.sessionId)}</td><td>${escapeHtml58(session.status)}</td><td>${session.turnCount}</td><td>${session.errorCount}</td><td>${session.replayHref ? `<a href="${escapeHtml58(session.replayHref)}">Replay</a>` : ""}</td></tr>`).join("") : '<tr><td colspan="5">No sessions yet.</td></tr>';
|
|
37544
|
+
const routing = report.recentRoutingEvents.length ? report.recentRoutingEvents.map((event) => `<tr><td>${escapeHtml58(event.kind)}</td><td>${escapeHtml58(event.provider ?? "unknown")}</td><td>${escapeHtml58(event.status ?? "unknown")}</td><td>${event.elapsedMs ?? 0}ms</td><td>${escapeHtml58(event.sessionId)}</td></tr>`).join("") : '<tr><td colspan="5">No provider routing events yet.</td></tr>';
|
|
37267
37545
|
const title = options.title ?? "AbsoluteJS Voice Ops Console";
|
|
37268
|
-
return `<!doctype html><html lang="en"><head><meta charset="utf-8" /><meta name="viewport" content="width=device-width, initial-scale=1" /><title>${
|
|
37546
|
+
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{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>${escapeHtml58(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 ${escapeHtml58(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>`;
|
|
37269
37547
|
};
|
|
37270
37548
|
var createVoiceOpsConsoleRoutes = (options) => {
|
|
37271
37549
|
const path = options.path ?? "/ops-console";
|
|
37272
|
-
const routes = new
|
|
37550
|
+
const routes = new Elysia61({
|
|
37273
37551
|
name: options.name ?? "absolutejs-voice-ops-console"
|
|
37274
37552
|
});
|
|
37275
37553
|
const getReport = () => buildVoiceOpsConsoleReport(options);
|
|
@@ -37286,7 +37564,7 @@ var createVoiceOpsConsoleRoutes = (options) => {
|
|
|
37286
37564
|
return routes;
|
|
37287
37565
|
};
|
|
37288
37566
|
// src/incidentBundle.ts
|
|
37289
|
-
import { Elysia as
|
|
37567
|
+
import { Elysia as Elysia62 } from "elysia";
|
|
37290
37568
|
var filterIncidentBundleArtifacts = (artifacts, filter = {}) => artifacts.filter((artifact) => {
|
|
37291
37569
|
if (filter.sessionId && artifact.sessionId !== filter.sessionId) {
|
|
37292
37570
|
return false;
|
|
@@ -37487,7 +37765,7 @@ var buildVoiceIncidentBundle = async (options) => {
|
|
|
37487
37765
|
var createVoiceIncidentBundleRoutes = (options) => {
|
|
37488
37766
|
const path = options.path ?? "/api/voice-incidents/:sessionId";
|
|
37489
37767
|
const markdownPath = options.markdownPath === undefined ? "/voice-incidents/:sessionId/markdown" : options.markdownPath;
|
|
37490
|
-
const routes = new
|
|
37768
|
+
const routes = new Elysia62({
|
|
37491
37769
|
name: options.name ?? "absolutejs-voice-incident-bundle"
|
|
37492
37770
|
});
|
|
37493
37771
|
const getSessionId = (params) => params.sessionId ?? "";
|
|
@@ -37688,19 +37966,19 @@ var summarizeVoiceOpsStatus = async (options) => {
|
|
|
37688
37966
|
};
|
|
37689
37967
|
};
|
|
37690
37968
|
// src/opsStatusRoutes.ts
|
|
37691
|
-
import { Elysia as
|
|
37692
|
-
var
|
|
37969
|
+
import { Elysia as Elysia63 } from "elysia";
|
|
37970
|
+
var escapeHtml59 = (value) => value.replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">").replaceAll('"', """).replaceAll("'", "'");
|
|
37693
37971
|
var renderVoiceOpsStatusHTML = (report, options = {}) => {
|
|
37694
37972
|
const title = options.title ?? "AbsoluteJS Voice Ops Status";
|
|
37695
37973
|
const surfaces = Object.entries(report.surfaces).map(([key, surface]) => {
|
|
37696
37974
|
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;
|
|
37697
|
-
return `<article class="surface ${
|
|
37975
|
+
return `<article class="surface ${escapeHtml59(surface.status)}"><span>${escapeHtml59(surface.status.toUpperCase())}</span><h2>${escapeHtml59(key)}</h2><strong>${escapeHtml59(value)}</strong></article>`;
|
|
37698
37976
|
}).join("");
|
|
37699
|
-
return `<!doctype html><html lang="en"><head><meta charset="utf-8" /><meta name="viewport" content="width=device-width, initial-scale=1" /><title>${
|
|
37977
|
+
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:#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>${escapeHtml59(title)}</h1><p>Compact pass/fail status for framework widgets, demos, and small customer-facing health badges.</p><p class="status ${escapeHtml59(report.status)}">Overall: ${escapeHtml59(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>`;
|
|
37700
37978
|
};
|
|
37701
37979
|
var createVoiceOpsStatusRoutes = (options) => {
|
|
37702
37980
|
const path = options.path ?? "/api/voice/ops-status";
|
|
37703
|
-
const routes = new
|
|
37981
|
+
const routes = new Elysia63({
|
|
37704
37982
|
name: options.name ?? "absolutejs-voice-ops-status"
|
|
37705
37983
|
});
|
|
37706
37984
|
routes.get(path, async () => summarizeVoiceOpsStatus(options));
|
|
@@ -38133,8 +38411,8 @@ var createVoiceTTSProviderRouter = (options) => {
|
|
|
38133
38411
|
};
|
|
38134
38412
|
};
|
|
38135
38413
|
// src/traceDeliveryRoutes.ts
|
|
38136
|
-
import { Elysia as
|
|
38137
|
-
var
|
|
38414
|
+
import { Elysia as Elysia64 } from "elysia";
|
|
38415
|
+
var escapeHtml60 = (value) => value.replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">").replaceAll('"', """).replaceAll("'", "'");
|
|
38138
38416
|
var getString20 = (value) => typeof value === "string" && value.trim() ? value.trim() : undefined;
|
|
38139
38417
|
var getNumber12 = (value) => {
|
|
38140
38418
|
if (typeof value === "number" && Number.isFinite(value)) {
|
|
@@ -38215,14 +38493,14 @@ var renderSinkResults2 = (delivery) => {
|
|
|
38215
38493
|
if (entries.length === 0) {
|
|
38216
38494
|
return "<p>No sink delivery attempts recorded yet.</p>";
|
|
38217
38495
|
}
|
|
38218
|
-
return `<ul>${entries.map(([sinkId, result]) => `<li><strong>${
|
|
38496
|
+
return `<ul>${entries.map(([sinkId, result]) => `<li><strong>${escapeHtml60(sinkId)}</strong>: ${escapeHtml60(result.status)}${result.deliveredTo ? ` to ${escapeHtml60(result.deliveredTo)}` : ""}${result.error ? ` (${escapeHtml60(result.error)})` : ""}</li>`).join("")}</ul>`;
|
|
38219
38497
|
};
|
|
38220
|
-
var renderEventList2 = (delivery) => delivery.events.length === 0 ? "<p>No trace events in this delivery.</p>" : `<ul>${delivery.events.map((event) => `<li>${
|
|
38498
|
+
var renderEventList2 = (delivery) => delivery.events.length === 0 ? "<p>No trace events in this delivery.</p>" : `<ul>${delivery.events.map((event) => `<li>${escapeHtml60(event.type)} <small>${escapeHtml60(event.id)}</small>${event.sessionId ? ` session=${escapeHtml60(event.sessionId)}` : ""}</li>`).join("")}</ul>`;
|
|
38221
38499
|
var renderVoiceTraceDeliveryHTML = (report, options = {}) => {
|
|
38222
38500
|
const title = options.title ?? "AbsoluteJS Voice Trace Deliveries";
|
|
38223
|
-
const drainAction = options.workerPath === false ? "" : `<form method="post" action="${
|
|
38224
|
-
const rows = report.deliveries.map((delivery) => `<article class="delivery ${
|
|
38225
|
-
return `<!doctype html><html lang="en"><head><meta charset="utf-8" /><meta name="viewport" content="width=device-width, initial-scale=1" /><title>${
|
|
38501
|
+
const drainAction = options.workerPath === false ? "" : `<form method="post" action="${escapeHtml60(options.workerPath ?? "/api/voice-trace-deliveries/drain")}"><button type="submit">Drain trace deliveries</button></form>`;
|
|
38502
|
+
const rows = report.deliveries.map((delivery) => `<article class="delivery ${escapeHtml60(delivery.deliveryStatus)}"><div class="head"><div><span>${escapeHtml60(delivery.deliveryStatus)}</span><h2>${escapeHtml60(delivery.id)}</h2><p>${escapeHtml60(new Date(delivery.createdAt).toLocaleString())}${delivery.deliveredAt ? ` \xB7 delivered ${escapeHtml60(new Date(delivery.deliveredAt).toLocaleString())}` : ""}</p></div><strong>${String(delivery.deliveryAttempts ?? 0)} attempt(s)</strong></div>${delivery.deliveryError ? `<p class="error">${escapeHtml60(delivery.deliveryError)}</p>` : ""}<h3>Sinks</h3>${renderSinkResults2(delivery)}<h3>Events</h3>${renderEventList2(delivery)}</article>`).join("");
|
|
38503
|
+
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:#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>${escapeHtml60(title)}</h1><p>Checked ${escapeHtml60(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>`;
|
|
38226
38504
|
};
|
|
38227
38505
|
var createVoiceTraceDeliveryJSONHandler = (options) => async ({ query }) => buildVoiceTraceDeliveryReport(options, resolveVoiceTraceDeliveryFilter(query, options.filter));
|
|
38228
38506
|
var createVoiceTraceDeliveryHTMLHandler = (options) => async ({ query }) => {
|
|
@@ -38242,7 +38520,7 @@ var createVoiceTraceDeliveryRoutes = (options) => {
|
|
|
38242
38520
|
const path = options.path ?? "/api/voice-trace-deliveries";
|
|
38243
38521
|
const htmlPath = options.htmlPath === undefined ? "/traces/deliveries" : options.htmlPath;
|
|
38244
38522
|
const workerPath = options.workerPath === undefined ? `${path}/drain` : options.workerPath;
|
|
38245
|
-
const routes = new
|
|
38523
|
+
const routes = new Elysia64({
|
|
38246
38524
|
name: options.name ?? "absolutejs-voice-trace-deliveries"
|
|
38247
38525
|
}).get(path, createVoiceTraceDeliveryJSONHandler(options));
|
|
38248
38526
|
if (htmlPath !== false) {
|
|
@@ -38339,7 +38617,7 @@ var createVoiceMemoryStore = () => {
|
|
|
38339
38617
|
return { get, getOrCreate, list, remove, set };
|
|
38340
38618
|
};
|
|
38341
38619
|
// src/opsWebhook.ts
|
|
38342
|
-
import { Elysia as
|
|
38620
|
+
import { Elysia as Elysia65 } from "elysia";
|
|
38343
38621
|
var toHex6 = (bytes) => Array.from(bytes, (byte) => byte.toString(16).padStart(2, "0")).join("");
|
|
38344
38622
|
var signVoiceOpsWebhookBody = async (input) => {
|
|
38345
38623
|
const encoder2 = new TextEncoder;
|
|
@@ -38469,7 +38747,7 @@ var verifyVoiceOpsWebhookSignature = async (input) => {
|
|
|
38469
38747
|
};
|
|
38470
38748
|
var createVoiceOpsWebhookReceiverRoutes = (options = {}) => {
|
|
38471
38749
|
const path = options.path ?? "/api/voice-ops/webhook";
|
|
38472
|
-
return new
|
|
38750
|
+
return new Elysia65().post(path, async ({ body, request, set }) => {
|
|
38473
38751
|
const bodyText = typeof body === "string" ? body : JSON.stringify(body);
|
|
38474
38752
|
if (options.signingSecret) {
|
|
38475
38753
|
const verification = await verifyVoiceOpsWebhookSignature({
|
|
@@ -38924,7 +39202,7 @@ var resolveVoiceOpsPreset = (name, overrides = {}) => {
|
|
|
38924
39202
|
};
|
|
38925
39203
|
};
|
|
38926
39204
|
// src/postCallAnalysis.ts
|
|
38927
|
-
import { Elysia as
|
|
39205
|
+
import { Elysia as Elysia66 } from "elysia";
|
|
38928
39206
|
var isStore = (value) => Boolean(value) && typeof value === "object" && value !== null && ("list" in value);
|
|
38929
39207
|
var asArray = async (value) => Array.isArray(value) ? value : isStore(value) ? await value.list() : [];
|
|
38930
39208
|
var getPathValue3 = (source, path) => {
|
|
@@ -39103,7 +39381,7 @@ var resolvePostCallAnalysisReport = async (options, input) => {
|
|
|
39103
39381
|
};
|
|
39104
39382
|
var createVoicePostCallAnalysisRoutes = (options = {}) => {
|
|
39105
39383
|
const path = options.path ?? "/api/voice/post-call-analysis";
|
|
39106
|
-
const routes = new
|
|
39384
|
+
const routes = new Elysia66({
|
|
39107
39385
|
name: options.name ?? "absolutejs-voice-post-call-analysis"
|
|
39108
39386
|
});
|
|
39109
39387
|
routes.get(path, async ({ query }) => {
|
|
@@ -39128,7 +39406,7 @@ var createVoicePostCallAnalysisRoutes = (options = {}) => {
|
|
|
39128
39406
|
return routes;
|
|
39129
39407
|
};
|
|
39130
39408
|
// src/guardrails.ts
|
|
39131
|
-
import { Elysia as
|
|
39409
|
+
import { Elysia as Elysia67 } from "elysia";
|
|
39132
39410
|
var stringifyContent = (value) => typeof value === "string" ? value : JSON.stringify(value) ?? "";
|
|
39133
39411
|
var appliesToStage = (rule, stage) => !rule.stages || rule.stages.length === 0 || rule.stages.includes(stage);
|
|
39134
39412
|
var matchesRule = async (rule, input) => {
|
|
@@ -39430,7 +39708,7 @@ var resolveGuardrailReport = async (options, input) => {
|
|
|
39430
39708
|
};
|
|
39431
39709
|
var createVoiceGuardrailRoutes = (options = {}) => {
|
|
39432
39710
|
const path = options.path ?? "/api/voice/guardrails";
|
|
39433
|
-
const routes = new
|
|
39711
|
+
const routes = new Elysia67({
|
|
39434
39712
|
name: options.name ?? "absolutejs-voice-guardrails"
|
|
39435
39713
|
});
|
|
39436
39714
|
routes.all(path, async ({ request }) => {
|
|
@@ -40212,7 +40490,7 @@ var shapeTelephonyAssistantText = (text, options = {}) => {
|
|
|
40212
40490
|
return ensureTerminalPunctuation(normalizeWhitespace(limitedChars));
|
|
40213
40491
|
};
|
|
40214
40492
|
// src/proofPack.ts
|
|
40215
|
-
import { Elysia as
|
|
40493
|
+
import { Elysia as Elysia68 } from "elysia";
|
|
40216
40494
|
import { mkdir as mkdir5 } from "fs/promises";
|
|
40217
40495
|
import { dirname as dirname3, join as join4 } from "path";
|
|
40218
40496
|
var toGeneratedAt = (value) => value === undefined ? new Date().toISOString() : typeof value === "number" ? new Date(value).toISOString() : value;
|
|
@@ -40779,7 +41057,7 @@ var createVoiceProofPackArtifacts = (input) => [
|
|
|
40779
41057
|
var createVoiceProofPackRoutes = (options) => {
|
|
40780
41058
|
const jsonPath = options.jsonPath ?? "/api/voice/proof-pack";
|
|
40781
41059
|
const markdownPath = options.markdownPath ?? "/voice/proof-pack.md";
|
|
40782
|
-
const app = new
|
|
41060
|
+
const app = new Elysia68({ name: options.name ?? "voice-proof-pack" });
|
|
40783
41061
|
if (jsonPath !== false) {
|
|
40784
41062
|
app.get(jsonPath, async () => new Response(JSON.stringify(await resolveProofPack(options.source), null, 2), {
|
|
40785
41063
|
headers: {
|
|
@@ -40959,6 +41237,8 @@ export {
|
|
|
40959
41237
|
renderVoiceMediaPipelineHTML,
|
|
40960
41238
|
renderVoiceLiveLatencyHTML,
|
|
40961
41239
|
renderVoiceLatencySLOMarkdown,
|
|
41240
|
+
renderVoiceIncidentTimelineMarkdown,
|
|
41241
|
+
renderVoiceIncidentTimelineHTML,
|
|
40962
41242
|
renderVoiceHandoffHealthHTML,
|
|
40963
41243
|
renderVoiceGuardrailMarkdown,
|
|
40964
41244
|
renderVoiceFailureReplayMarkdown,
|
|
@@ -41291,6 +41571,7 @@ export {
|
|
|
41291
41571
|
createVoiceIntegrationSinkWorker,
|
|
41292
41572
|
createVoiceIntegrationHTTPSink,
|
|
41293
41573
|
createVoiceIntegrationEvent,
|
|
41574
|
+
createVoiceIncidentTimelineRoutes,
|
|
41294
41575
|
createVoiceIncidentBundleRoutes,
|
|
41295
41576
|
createVoiceInMemoryRealCallProfileRecoveryJobStore,
|
|
41296
41577
|
createVoiceHubSpotTaskUpdateSink,
|
|
@@ -41458,6 +41739,7 @@ export {
|
|
|
41458
41739
|
buildVoiceMediaPipelineReport,
|
|
41459
41740
|
buildVoiceLiveOpsControlState,
|
|
41460
41741
|
buildVoiceLatencySLOGate,
|
|
41742
|
+
buildVoiceIncidentTimelineReport,
|
|
41461
41743
|
buildVoiceIncidentBundle,
|
|
41462
41744
|
buildVoiceIOProviderRouterTraceEvent,
|
|
41463
41745
|
buildVoiceGuardrailReport,
|