@absolutejs/voice 0.0.22-beta.139 → 0.0.22-beta.140

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.d.ts CHANGED
@@ -96,7 +96,7 @@ export type { VoicePhoneAgentCarrier, VoicePhoneAgentCarrierSummary, VoicePhoneA
96
96
  export type { VoicePhoneAgentProductionSmokeIssue, VoicePhoneAgentProductionSmokeHandlerOptions, VoicePhoneAgentProductionSmokeHTMLHandlerOptions, VoicePhoneAgentProductionSmokeOptions, VoicePhoneAgentProductionSmokeReport, VoicePhoneAgentProductionSmokeRoutesOptions, VoicePhoneAgentProductionSmokeRequirement } from './phoneAgentProductionSmoke';
97
97
  export type { VoiceOpsConsoleLink, VoiceOpsConsoleReport, VoiceOpsConsoleRoutesOptions } from './opsConsoleRoutes';
98
98
  export type { VoiceOpsStatus, VoiceOpsStatusLink, VoiceOpsStatusOptions, VoiceOpsStatusReport, VoiceOpsStatusRoutesOptions } from './opsStatus';
99
- export type { VoiceProductionReadinessAction, VoiceProductionReadinessAuditOptions, VoiceProductionReadinessAuditRequirement, VoiceProductionReadinessAuditSummary, VoiceProductionReadinessCheck, VoiceProductionReadinessReport, VoiceProductionReadinessRoutesOptions, VoiceProductionReadinessTraceDeliverySummary, VoiceProductionReadinessAuditDeliveryOptions, VoiceProductionReadinessAuditDeliverySummary, VoiceProductionReadinessTraceDeliveryOptions, VoiceProductionReadinessStatus } from './productionReadiness';
99
+ export type { VoiceProductionReadinessAction, VoiceProductionReadinessAuditOptions, VoiceProductionReadinessAuditRequirement, VoiceProductionReadinessAuditSummary, VoiceProductionReadinessCheck, VoiceProductionReadinessProofSource, VoiceProductionReadinessReport, VoiceProductionReadinessRoutesOptions, VoiceProductionReadinessTraceDeliverySummary, VoiceProductionReadinessAuditDeliveryOptions, VoiceProductionReadinessAuditDeliverySummary, VoiceProductionReadinessTraceDeliveryOptions, VoiceProductionReadinessStatus } from './productionReadiness';
100
100
  export type { VoiceQualityLink, VoiceQualityMetric, VoiceQualityReport, VoiceQualityRoutesOptions, VoiceQualityStatus, VoiceQualityThresholds } from './qualityRoutes';
101
101
  export type { VoiceResilienceIOSimulator, VoiceResilienceLink, VoiceResiliencePageData, VoiceResilienceRoutesOptions, VoiceResilienceSimulationProvider, VoiceRoutingKindSummary, VoiceRoutingDecisionSummary, VoiceRoutingDecisionSummaryOptions, VoiceRoutingEvent, VoiceRoutingEventKind, VoiceRoutingSessionSummary, VoiceRoutingSessionSummaryOptions } from './resilienceRoutes';
102
102
  export type { VoiceIOProviderRouterEvent, VoiceIOProviderRouterOptions, VoiceIOProviderRouterPolicy, VoiceIOProviderRouterPolicyConfig, VoiceSTTProviderRouterOptions, VoiceTTSProviderRouterOptions } from './providerAdapters';
package/dist/index.js CHANGED
@@ -19531,6 +19531,12 @@ var resolveBargeInReports = async (options, input) => {
19531
19531
  }
19532
19532
  return typeof options.bargeInReports === "function" ? await options.bargeInReports(input) : options.bargeInReports;
19533
19533
  };
19534
+ var resolveProofSources = async (options, input) => {
19535
+ if (options.proofSources === false || options.proofSources === undefined) {
19536
+ return;
19537
+ }
19538
+ return typeof options.proofSources === "function" ? await options.proofSources(input) : options.proofSources;
19539
+ };
19534
19540
  var defaultAuditRequirements = [
19535
19541
  {
19536
19542
  label: "Provider-call audit",
@@ -19691,7 +19697,8 @@ var buildVoiceProductionReadinessReport = async (options, input = {}) => {
19691
19697
  providerRoutingContracts,
19692
19698
  phoneAgentSmokes,
19693
19699
  reconnectContracts,
19694
- bargeInReports
19700
+ bargeInReports,
19701
+ proofSources
19695
19702
  ] = await Promise.all([
19696
19703
  evaluateVoiceQuality({ events }),
19697
19704
  Promise.all([
@@ -19718,7 +19725,8 @@ var buildVoiceProductionReadinessReport = async (options, input = {}) => {
19718
19725
  resolveProviderRoutingContracts(options, { query, request }),
19719
19726
  resolvePhoneAgentSmokes(options, { query, request }),
19720
19727
  resolveReconnectContracts(options, { query, request }),
19721
- resolveBargeInReports(options, { query, request })
19728
+ resolveBargeInReports(options, { query, request }),
19729
+ resolveProofSources(options, { query, request })
19722
19730
  ]);
19723
19731
  const degradedProviders = providers.filter((provider) => provider.status === "degraded" || provider.status === "rate-limited" || provider.status === "suppressed").length;
19724
19732
  const failedSessions = sessions.filter((session) => session.status === "failed").length;
@@ -19820,6 +19828,7 @@ var buildVoiceProductionReadinessReport = async (options, input = {}) => {
19820
19828
  ]
19821
19829
  }
19822
19830
  ];
19831
+ const proofSource = (...keys) => keys.map((key) => proofSources?.[key]).find((source) => source !== undefined);
19823
19832
  checks.push({
19824
19833
  detail: liveLatency.total === 0 ? "No browser live-latency measurements are recorded yet." : liveLatency.status === "pass" ? `Live browser turn latency averages ${liveLatency.averageLatencyMs}ms.` : `${liveLatency.failed} failed and ${liveLatency.warnings} warned live-latency measurement(s).`,
19825
19834
  href: options.links?.liveLatency ?? "/traces",
@@ -19925,6 +19934,7 @@ var buildVoiceProductionReadinessReport = async (options, input = {}) => {
19925
19934
  detail: reconnectContractSummary.status === "pass" ? `${reconnectContractSummary.passed} reconnect contract(s) are passing.` : reconnectContractSummary.total === 0 ? "No reconnect contracts are configured." : `${reconnectContractSummary.failed} reconnect contract(s) failed.`,
19926
19935
  href: options.links?.reconnectContracts ?? options.links?.sessions ?? "/sessions",
19927
19936
  label: "Reconnect recovery contracts",
19937
+ proofSource: proofSource("reconnectContracts", "reconnect"),
19928
19938
  status: reconnectContractSummary.status,
19929
19939
  value: `${reconnectContractSummary.passed}/${reconnectContractSummary.total}`,
19930
19940
  actions: reconnectContractSummary.status === "pass" ? [] : [
@@ -19941,6 +19951,7 @@ var buildVoiceProductionReadinessReport = async (options, input = {}) => {
19941
19951
  detail: bargeInSummary.status === "pass" ? `${bargeInSummary.passed} barge-in interruption(s) stopped within threshold.` : bargeInSummary.total === 0 ? "No barge-in interruption proof is recorded yet." : bargeInSummary.status === "fail" ? `${bargeInSummary.failed} barge-in interruption(s) exceeded threshold.` : `${bargeInSummary.warnings} barge-in proof report(s) have warnings.`,
19942
19952
  href: options.links?.bargeIn ?? "/barge-in",
19943
19953
  label: "Barge-in interruption proof",
19954
+ proofSource: proofSource("bargeInReports", "bargeIn"),
19944
19955
  status: bargeInSummary.status,
19945
19956
  value: `${bargeInSummary.passed}/${bargeInSummary.total}`,
19946
19957
  actions: bargeInSummary.status === "pass" ? [] : [
@@ -20038,6 +20049,7 @@ var buildVoiceProductionReadinessReport = async (options, input = {}) => {
20038
20049
  traceDeliveries: "/traces/deliveries",
20039
20050
  ...options.links
20040
20051
  },
20052
+ proofSources,
20041
20053
  status: rollupStatus2(checks),
20042
20054
  summary: {
20043
20055
  agentSquadContracts: agentSquadContractSummary,
@@ -20082,13 +20094,14 @@ var renderVoiceProductionReadinessHTML = (report, options = {}) => {
20082
20094
  <span>${escapeHtml32(check.status.toUpperCase())}</span>
20083
20095
  <h2>${escapeHtml32(check.label)}</h2>
20084
20096
  ${check.detail ? `<p>${escapeHtml32(check.detail)}</p>` : ""}
20097
+ ${check.proofSource ? `<p class="proof-source">Proof source: ${check.proofSource.href ? `<a href="${escapeHtml32(check.proofSource.href)}">${escapeHtml32(check.proofSource.sourceLabel)}</a>` : escapeHtml32(check.proofSource.sourceLabel)}${check.proofSource.detail ? ` \xB7 ${escapeHtml32(check.proofSource.detail)}` : ""}</p>` : ""}
20085
20098
  ${actions ? `<p class="actions">${actions}</p>` : ""}
20086
20099
  </div>
20087
20100
  <strong>${escapeHtml32(String(check.value ?? check.status))}</strong>
20088
20101
  ${check.href ? `<a href="${escapeHtml32(check.href)}">Open surface</a>` : ""}
20089
20102
  </article>`;
20090
20103
  }).join("");
20091
- return `<!doctype html><html lang="en"><head><meta charset="utf-8" /><meta name="viewport" content="width=device-width, initial-scale=1" /><title>${escapeHtml32(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(20,184,166,.18),rgba(245,158,11,.12));border:1px solid #26313d;border-radius:28px;margin-bottom:18px;padding:28px}.eyebrow{color:#fbbf24;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{display:inline-flex;border:1px solid #3f3f46;border-radius:999px;padding:8px 12px}.status.pass,.check.pass{border-color:rgba(34,197,94,.55)}.status.warn,.check.warn{border-color:rgba(245,158,11,.65)}.status.fail,.check.fail{border-color:rgba(239,68,68,.75)}.checks{display:grid;gap:14px}.check{align-items:center;background:#141922;border:1px solid #26313d;border-radius:22px;display:grid;gap:16px;grid-template-columns:1fr auto auto;padding:18px}.check span{color:#a8b0b8;font-size:.78rem;font-weight:900;letter-spacing:.08em}.check h2{margin:.2rem 0}.check p{color:#b9c0c8;margin:.2rem 0 0}.check strong{font-size:1.5rem}.actions{display:flex;flex-wrap:wrap;gap:10px}.check a,a{color:#fbbf24}button{background:#fbbf24;border:0;border-radius:999px;color:#111827;cursor:pointer;font-weight:800;padding:9px 12px}button:disabled{cursor:wait;opacity:.65}@media(max-width:760px){main{padding:20px}.check{grid-template-columns:1fr}}</style></head><body><main><section class="hero"><p class="eyebrow">Self-hosted readiness</p><h1>${escapeHtml32(title)}</h1><p>One deployable pass/fail report for quality gates, provider failover, session health, handoffs, routing evidence, and optional carrier readiness.</p><p class="status ${escapeHtml32(report.status)}">Overall: ${escapeHtml32(report.status.toUpperCase())}</p><p>Checked ${escapeHtml32(new Date(report.checkedAt).toLocaleString())}</p></section><section class="checks">${checks}</section></main><script>document.querySelectorAll("[data-readiness-action]").forEach((button)=>{button.addEventListener("click",async()=>{const url=button.getAttribute("data-action-url");if(!url)return;button.disabled=true;const original=button.textContent;button.textContent="Running...";try{const response=await fetch(url,{method:"POST"});button.textContent=response.ok?"Done. Reloading...":"Failed";if(response.ok)setTimeout(()=>location.reload(),500)}catch{button.textContent="Failed"}finally{setTimeout(()=>{button.disabled=false;button.textContent=original},1500)}})});</script></body></html>`;
20104
+ return `<!doctype html><html lang="en"><head><meta charset="utf-8" /><meta name="viewport" content="width=device-width, initial-scale=1" /><title>${escapeHtml32(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(20,184,166,.18),rgba(245,158,11,.12));border:1px solid #26313d;border-radius:28px;margin-bottom:18px;padding:28px}.eyebrow{color:#fbbf24;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{display:inline-flex;border:1px solid #3f3f46;border-radius:999px;padding:8px 12px}.status.pass,.check.pass{border-color:rgba(34,197,94,.55)}.status.warn,.check.warn{border-color:rgba(245,158,11,.65)}.status.fail,.check.fail{border-color:rgba(239,68,68,.75)}.checks{display:grid;gap:14px}.check{align-items:center;background:#141922;border:1px solid #26313d;border-radius:22px;display:grid;gap:16px;grid-template-columns:1fr auto auto;padding:18px}.check span{color:#a8b0b8;font-size:.78rem;font-weight:900;letter-spacing:.08em}.check h2{margin:.2rem 0}.check p{color:#b9c0c8;margin:.2rem 0 0}.check .proof-source{color:#f9d77e;font-weight:800}.check strong{font-size:1.5rem}.actions{display:flex;flex-wrap:wrap;gap:10px}.check a,a{color:#fbbf24}button{background:#fbbf24;border:0;border-radius:999px;color:#111827;cursor:pointer;font-weight:800;padding:9px 12px}button:disabled{cursor:wait;opacity:.65}@media(max-width:760px){main{padding:20px}.check{grid-template-columns:1fr}}</style></head><body><main><section class="hero"><p class="eyebrow">Self-hosted readiness</p><h1>${escapeHtml32(title)}</h1><p>One deployable pass/fail report for quality gates, provider failover, session health, handoffs, routing evidence, and optional carrier readiness.</p><p class="status ${escapeHtml32(report.status)}">Overall: ${escapeHtml32(report.status.toUpperCase())}</p><p>Checked ${escapeHtml32(new Date(report.checkedAt).toLocaleString())}</p></section><section class="checks">${checks}</section></main><script>document.querySelectorAll("[data-readiness-action]").forEach((button)=>{button.addEventListener("click",async()=>{const url=button.getAttribute("data-action-url");if(!url)return;button.disabled=true;const original=button.textContent;button.textContent="Running...";try{const response=await fetch(url,{method:"POST"});button.textContent=response.ok?"Done. Reloading...":"Failed";if(response.ok)setTimeout(()=>location.reload(),500)}catch{button.textContent="Failed"}finally{setTimeout(()=>{button.disabled=false;button.textContent=original},1500)}})});</script></body></html>`;
20092
20105
  };
20093
20106
  var createVoiceProductionReadinessRoutes = (options) => {
20094
20107
  const path = options.path ?? "/api/production-readiness";
@@ -22,9 +22,17 @@ export type VoiceProductionReadinessCheck = {
22
22
  detail?: string;
23
23
  href?: string;
24
24
  label: string;
25
+ proofSource?: VoiceProductionReadinessProofSource;
25
26
  status: VoiceProductionReadinessStatus;
26
27
  value?: number | string;
27
28
  };
29
+ export type VoiceProductionReadinessProofSource = {
30
+ detail?: string;
31
+ href?: string;
32
+ label?: string;
33
+ source: string;
34
+ sourceLabel: string;
35
+ };
28
36
  export type VoiceProductionReadinessReport = {
29
37
  checkedAt: number;
30
38
  checks: VoiceProductionReadinessCheck[];
@@ -45,6 +53,7 @@ export type VoiceProductionReadinessReport = {
45
53
  sessions?: string;
46
54
  traceDeliveries?: string;
47
55
  };
56
+ proofSources?: Record<string, VoiceProductionReadinessProofSource>;
48
57
  status: VoiceProductionReadinessStatus;
49
58
  summary: {
50
59
  agentSquadContracts?: {
@@ -208,6 +217,10 @@ export type VoiceProductionReadinessRoutesOptions = {
208
217
  query: Record<string, unknown>;
209
218
  request: Request;
210
219
  }) => Promise<readonly VoiceReconnectContractReport[]> | readonly VoiceReconnectContractReport[]);
220
+ proofSources?: false | Record<string, VoiceProductionReadinessProofSource> | ((input: {
221
+ query: Record<string, unknown>;
222
+ request: Request;
223
+ }) => Promise<Record<string, VoiceProductionReadinessProofSource>> | Record<string, VoiceProductionReadinessProofSource>);
211
224
  render?: (report: VoiceProductionReadinessReport) => string | Promise<string>;
212
225
  store: VoiceTraceEventStore;
213
226
  sttProviders?: readonly string[];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@absolutejs/voice",
3
- "version": "0.0.22-beta.139",
3
+ "version": "0.0.22-beta.140",
4
4
  "description": "Voice primitives and Elysia plugin for AbsoluteJS",
5
5
  "repository": {
6
6
  "type": "git",