@absolutejs/voice 0.0.22-beta.142 → 0.0.22-beta.144

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -20286,14 +20286,27 @@ 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 baseLinks = options.links ?? DEFAULT_LINKS;
20292
+ const links = deliverySinks && !baseLinks.some((link) => link.href === (deliverySinkOptions?.htmlPath ?? "/delivery-sinks") || link.statusHref === (deliverySinkOptions?.path ?? "/api/voice-delivery-sinks")) ? [
20293
+ ...baseLinks,
20294
+ {
20295
+ description: "Configured audit and trace delivery sinks with queue health.",
20296
+ href: deliverySinkOptions?.htmlPath === false ? deliverySinkOptions.path ?? "/api/voice-delivery-sinks" : deliverySinkOptions?.htmlPath ?? "/delivery-sinks",
20297
+ label: "Delivery Sinks",
20298
+ statusHref: deliverySinkOptions?.path ?? "/api/voice-delivery-sinks"
20299
+ }
20300
+ ] : baseLinks;
20289
20301
  return {
20290
20302
  checkedAt: Date.now(),
20303
+ deliverySinks,
20291
20304
  eventCount: events.length,
20292
20305
  handoffs: {
20293
20306
  failed: handoffs.failed,
20294
20307
  total: handoffs.total
20295
20308
  },
20296
- links: options.links ?? DEFAULT_LINKS,
20309
+ links,
20297
20310
  providers: countProviderStatuses(providers),
20298
20311
  quality,
20299
20312
  recentRoutingEvents: routingEvents,
@@ -20382,7 +20395,7 @@ var summarizeVoiceOpsStatus = async (options) => {
20382
20395
  const shouldInclude = (surface) => include?.[surface] !== false;
20383
20396
  const evals = options.evals === false ? undefined : options.evals;
20384
20397
  const events = filterVoiceTraceEvents(await options.store.list());
20385
- const [quality, workflows, providers, sessions, handoffs] = await Promise.all([
20398
+ const [quality, workflows, providers, sessions, handoffs, deliverySinks] = await Promise.all([
20386
20399
  options.quality === false || !shouldInclude("quality") ? undefined : evaluateVoiceQuality({
20387
20400
  events,
20388
20401
  thresholds: options.quality?.thresholds
@@ -20431,7 +20444,8 @@ var summarizeVoiceOpsStatus = async (options) => {
20431
20444
  }),
20432
20445
  !shouldInclude("handoffs") ? undefined : summarizeVoiceHandoffHealth({
20433
20446
  events
20434
- })
20447
+ }),
20448
+ !options.deliverySinks || !shouldInclude("deliverySinks") ? undefined : buildVoiceDeliverySinkReport(options.deliverySinks)
20435
20449
  ]);
20436
20450
  const providerRecovery = shouldInclude("providerRecovery") ? summarizeVoiceProviderFallbackRecovery(events) : undefined;
20437
20451
  const surfaces = {};
@@ -20477,9 +20491,29 @@ var summarizeVoiceOpsStatus = async (options) => {
20477
20491
  };
20478
20492
  statuses.push(status);
20479
20493
  }
20494
+ if (deliverySinks) {
20495
+ const status = deliverySinks.status === "fail" ? "fail" : "pass";
20496
+ surfaces.deliverySinks = {
20497
+ auditTotal: deliverySinks.auditDeliveries?.summary.total ?? 0,
20498
+ status,
20499
+ traceTotal: deliverySinks.traceDeliveries?.summary.total ?? 0
20500
+ };
20501
+ statuses.push(status);
20502
+ }
20503
+ const baseLinks = options.links ?? DEFAULT_LINKS2;
20504
+ const deliverySinkOptions = options.deliverySinks || undefined;
20505
+ const links = deliverySinkOptions && !baseLinks.some((link) => link.href === (deliverySinkOptions.htmlPath ?? "/delivery-sinks") || link.statusHref === (deliverySinkOptions.path ?? "/api/voice-delivery-sinks")) ? [
20506
+ ...baseLinks,
20507
+ {
20508
+ description: "Audit and trace delivery sink health.",
20509
+ href: deliverySinkOptions.htmlPath === false ? deliverySinkOptions.path ?? "/api/voice-delivery-sinks" : deliverySinkOptions.htmlPath ?? "/delivery-sinks",
20510
+ label: "Delivery Sinks",
20511
+ statusHref: deliverySinkOptions.path ?? "/api/voice-delivery-sinks"
20512
+ }
20513
+ ] : baseLinks;
20480
20514
  return {
20481
20515
  checkedAt: Date.now(),
20482
- links: options.links ?? DEFAULT_LINKS2,
20516
+ links,
20483
20517
  status: statuses.includes("fail") ? "fail" : "pass",
20484
20518
  surfaces,
20485
20519
  ...countStatus(statuses)
@@ -20491,7 +20525,7 @@ var escapeHtml35 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&l
20491
20525
  var renderVoiceOpsStatusHTML = (report, options = {}) => {
20492
20526
  const title = options.title ?? "AbsoluteJS Voice Ops Status";
20493
20527
  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;
20528
+ 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
20529
  return `<article class="surface ${escapeHtml35(surface.status)}"><span>${escapeHtml35(surface.status.toUpperCase())}</span><h2>${escapeHtml35(key)}</h2><strong>${escapeHtml35(value)}</strong></article>`;
20496
20530
  }).join("");
20497
20531
  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;
@@ -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;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@absolutejs/voice",
3
- "version": "0.0.22-beta.142",
3
+ "version": "0.0.22-beta.144",
4
4
  "description": "Voice primitives and Elysia plugin for AbsoluteJS",
5
5
  "repository": {
6
6
  "type": "git",