@absolutejs/voice 0.0.22-beta.142 → 0.0.22-beta.143
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +35 -5
- package/dist/opsConsoleRoutes.d.ts +3 -0
- package/dist/opsStatus.d.ts +8 -0
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -20286,14 +20286,26 @@ var buildVoiceOpsConsoleReport = async (options) => {
|
|
|
20286
20286
|
const quality = await evaluateVoiceQuality({ events });
|
|
20287
20287
|
const routingEvents = listVoiceRoutingEvents(events).slice(0, 10);
|
|
20288
20288
|
const trace = summarizeVoiceTrace(events);
|
|
20289
|
+
const deliverySinkOptions = options.deliverySinks || undefined;
|
|
20290
|
+
const deliverySinks = deliverySinkOptions ? await buildVoiceDeliverySinkReport(deliverySinkOptions) : undefined;
|
|
20291
|
+
const links = options.links ?? (deliverySinks ? [
|
|
20292
|
+
...DEFAULT_LINKS,
|
|
20293
|
+
{
|
|
20294
|
+
description: "Configured audit and trace delivery sinks with queue health.",
|
|
20295
|
+
href: deliverySinkOptions?.htmlPath === false ? deliverySinkOptions.path ?? "/api/voice-delivery-sinks" : deliverySinkOptions?.htmlPath ?? "/delivery-sinks",
|
|
20296
|
+
label: "Delivery Sinks",
|
|
20297
|
+
statusHref: deliverySinkOptions?.path ?? "/api/voice-delivery-sinks"
|
|
20298
|
+
}
|
|
20299
|
+
] : DEFAULT_LINKS);
|
|
20289
20300
|
return {
|
|
20290
20301
|
checkedAt: Date.now(),
|
|
20302
|
+
deliverySinks,
|
|
20291
20303
|
eventCount: events.length,
|
|
20292
20304
|
handoffs: {
|
|
20293
20305
|
failed: handoffs.failed,
|
|
20294
20306
|
total: handoffs.total
|
|
20295
20307
|
},
|
|
20296
|
-
links
|
|
20308
|
+
links,
|
|
20297
20309
|
providers: countProviderStatuses(providers),
|
|
20298
20310
|
quality,
|
|
20299
20311
|
recentRoutingEvents: routingEvents,
|
|
@@ -20382,7 +20394,7 @@ var summarizeVoiceOpsStatus = async (options) => {
|
|
|
20382
20394
|
const shouldInclude = (surface) => include?.[surface] !== false;
|
|
20383
20395
|
const evals = options.evals === false ? undefined : options.evals;
|
|
20384
20396
|
const events = filterVoiceTraceEvents(await options.store.list());
|
|
20385
|
-
const [quality, workflows, providers, sessions, handoffs] = await Promise.all([
|
|
20397
|
+
const [quality, workflows, providers, sessions, handoffs, deliverySinks] = await Promise.all([
|
|
20386
20398
|
options.quality === false || !shouldInclude("quality") ? undefined : evaluateVoiceQuality({
|
|
20387
20399
|
events,
|
|
20388
20400
|
thresholds: options.quality?.thresholds
|
|
@@ -20431,7 +20443,8 @@ var summarizeVoiceOpsStatus = async (options) => {
|
|
|
20431
20443
|
}),
|
|
20432
20444
|
!shouldInclude("handoffs") ? undefined : summarizeVoiceHandoffHealth({
|
|
20433
20445
|
events
|
|
20434
|
-
})
|
|
20446
|
+
}),
|
|
20447
|
+
!options.deliverySinks || !shouldInclude("deliverySinks") ? undefined : buildVoiceDeliverySinkReport(options.deliverySinks)
|
|
20435
20448
|
]);
|
|
20436
20449
|
const providerRecovery = shouldInclude("providerRecovery") ? summarizeVoiceProviderFallbackRecovery(events) : undefined;
|
|
20437
20450
|
const surfaces = {};
|
|
@@ -20477,9 +20490,26 @@ var summarizeVoiceOpsStatus = async (options) => {
|
|
|
20477
20490
|
};
|
|
20478
20491
|
statuses.push(status);
|
|
20479
20492
|
}
|
|
20493
|
+
if (deliverySinks) {
|
|
20494
|
+
const status = deliverySinks.status === "fail" ? "fail" : "pass";
|
|
20495
|
+
surfaces.deliverySinks = {
|
|
20496
|
+
auditTotal: deliverySinks.auditDeliveries?.summary.total ?? 0,
|
|
20497
|
+
status,
|
|
20498
|
+
traceTotal: deliverySinks.traceDeliveries?.summary.total ?? 0
|
|
20499
|
+
};
|
|
20500
|
+
statuses.push(status);
|
|
20501
|
+
}
|
|
20480
20502
|
return {
|
|
20481
20503
|
checkedAt: Date.now(),
|
|
20482
|
-
links: options.links ??
|
|
20504
|
+
links: options.links ?? (options.deliverySinks ? [
|
|
20505
|
+
...DEFAULT_LINKS2,
|
|
20506
|
+
{
|
|
20507
|
+
description: "Audit and trace delivery sink health.",
|
|
20508
|
+
href: options.deliverySinks.htmlPath === false ? options.deliverySinks.path ?? "/api/voice-delivery-sinks" : options.deliverySinks.htmlPath ?? "/delivery-sinks",
|
|
20509
|
+
label: "Delivery Sinks",
|
|
20510
|
+
statusHref: options.deliverySinks.path ?? "/api/voice-delivery-sinks"
|
|
20511
|
+
}
|
|
20512
|
+
] : DEFAULT_LINKS2),
|
|
20483
20513
|
status: statuses.includes("fail") ? "fail" : "pass",
|
|
20484
20514
|
surfaces,
|
|
20485
20515
|
...countStatus(statuses)
|
|
@@ -20491,7 +20521,7 @@ var escapeHtml35 = (value) => value.replaceAll("&", "&").replaceAll("<", "&l
|
|
|
20491
20521
|
var renderVoiceOpsStatusHTML = (report, options = {}) => {
|
|
20492
20522
|
const title = options.title ?? "AbsoluteJS Voice Ops Status";
|
|
20493
20523
|
const surfaces = Object.entries(report.surfaces).map(([key, surface]) => {
|
|
20494
|
-
const value = "recovered" in surface ? surface.total === 0 ? "0 events" : `${surface.recovered}/${surface.total}` : ("total" in surface) ? `${Math.max(surface.total - ("failed" in surface ? surface.failed : ("degraded" in surface) ? surface.degraded : 0), 0)}/${surface.total}` : surface.status;
|
|
20524
|
+
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;
|
|
20495
20525
|
return `<article class="surface ${escapeHtml35(surface.status)}"><span>${escapeHtml35(surface.status.toUpperCase())}</span><h2>${escapeHtml35(key)}</h2><strong>${escapeHtml35(value)}</strong></article>`;
|
|
20496
20526
|
}).join("");
|
|
20497
20527
|
return `<!doctype html><html lang="en"><head><meta charset="utf-8" /><meta name="viewport" content="width=device-width, initial-scale=1" /><title>${escapeHtml35(title)}</title><style>body{background:#0d141b;color:#f8f3e7;font-family:ui-sans-serif,system-ui,sans-serif;margin:0}main{margin:auto;max-width:980px;padding:32px}.hero{background:linear-gradient(135deg,rgba(20,184,166,.2),rgba(245,158,11,.12));border:1px solid #283544;border-radius:28px;margin-bottom:18px;padding:28px}.eyebrow{color:#5eead4;font-weight:900;letter-spacing:.12em;text-transform:uppercase}h1{font-size:clamp(2.4rem,6vw,5rem);line-height:.9;margin:.2rem 0 1rem}.status{border:1px solid #3f3f46;border-radius:999px;display:inline-flex;font-weight:900;padding:8px 12px}.surfaces{display:grid;gap:14px;grid-template-columns:repeat(auto-fit,minmax(180px,1fr))}.surface{background:#151d26;border:1px solid #283544;border-radius:20px;padding:18px}.surface span{color:#aab5c0;font-size:.78rem;font-weight:900;letter-spacing:.08em}.surface strong{font-size:1.5rem}.pass{border-color:rgba(34,197,94,.55)}.fail{border-color:rgba(239,68,68,.75)}a{color:#5eead4}</style></head><body><main><section class="hero"><p class="eyebrow">Ops status</p><h1>${escapeHtml35(title)}</h1><p>Compact pass/fail status for framework widgets, demos, and small customer-facing health badges.</p><p class="status ${escapeHtml35(report.status)}">Overall: ${escapeHtml35(report.status.toUpperCase())}</p><p>${report.passed}/${report.total} checks passing</p></section><section class="surfaces">${surfaces || '<article class="surface pass"><span>PASS</span><h2>No checks configured</h2><strong>0/0</strong></article>'}</section></main></body></html>`;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { Elysia } from 'elysia';
|
|
2
|
+
import { type VoiceDeliverySinkReport, type VoiceDeliverySinkRoutesOptions } from './deliverySinkRoutes';
|
|
2
3
|
import { type VoiceQualityReport } from './qualityRoutes';
|
|
3
4
|
import { type VoiceRoutingEvent } from './resilienceRoutes';
|
|
4
5
|
import { type VoiceSessionListItem } from './sessionReplay';
|
|
@@ -17,6 +18,7 @@ export type VoiceOpsConsoleReport = {
|
|
|
17
18
|
total: number;
|
|
18
19
|
};
|
|
19
20
|
links: VoiceOpsConsoleLink[];
|
|
21
|
+
deliverySinks?: VoiceDeliverySinkReport;
|
|
20
22
|
providers: {
|
|
21
23
|
degraded: number;
|
|
22
24
|
healthy: number;
|
|
@@ -34,6 +36,7 @@ export type VoiceOpsConsoleReport = {
|
|
|
34
36
|
};
|
|
35
37
|
export type VoiceOpsConsoleRoutesOptions = {
|
|
36
38
|
headers?: HeadersInit;
|
|
39
|
+
deliverySinks?: false | VoiceDeliverySinkRoutesOptions;
|
|
37
40
|
links?: VoiceOpsConsoleLink[];
|
|
38
41
|
llmProviders?: readonly string[];
|
|
39
42
|
name?: string;
|
package/dist/opsStatus.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { type VoiceEvalLink, type VoiceEvalRoutesOptions } from './evalRoutes';
|
|
2
|
+
import { type VoiceDeliverySinkRoutesOptions } from './deliverySinkRoutes';
|
|
2
3
|
import { type VoiceQualityRoutesOptions } from './qualityRoutes';
|
|
3
4
|
import { type VoiceProviderFallbackRecoverySummary } from './sessionReplay';
|
|
4
5
|
import { type VoiceTraceEventStore } from './trace';
|
|
@@ -8,8 +9,10 @@ export type VoiceOpsStatusLink = VoiceEvalLink & {
|
|
|
8
9
|
statusHref?: string;
|
|
9
10
|
};
|
|
10
11
|
export type VoiceOpsStatusOptions<TProvider extends string = string> = {
|
|
12
|
+
deliverySinks?: false | VoiceDeliverySinkRoutesOptions;
|
|
11
13
|
evals?: false | Partial<VoiceEvalRoutesOptions>;
|
|
12
14
|
include?: {
|
|
15
|
+
deliverySinks?: boolean;
|
|
13
16
|
handoffs?: boolean;
|
|
14
17
|
providers?: boolean;
|
|
15
18
|
providerRecovery?: boolean;
|
|
@@ -37,6 +40,11 @@ export type VoiceOpsStatusReport = {
|
|
|
37
40
|
status: VoiceOpsStatus;
|
|
38
41
|
total: number;
|
|
39
42
|
};
|
|
43
|
+
deliverySinks?: {
|
|
44
|
+
auditTotal: number;
|
|
45
|
+
status: VoiceOpsStatus;
|
|
46
|
+
traceTotal: number;
|
|
47
|
+
};
|
|
40
48
|
providers?: {
|
|
41
49
|
degraded: number;
|
|
42
50
|
status: VoiceOpsStatus;
|