@absolutejs/voice 0.0.22-beta.160 → 0.0.22-beta.162

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/README.md CHANGED
@@ -228,6 +228,7 @@ app.use(
228
228
  createVoiceProductionReadinessRoutes({
229
229
  ...createVoiceReadinessProfile('meeting-recorder', {
230
230
  bargeInReports: async () => [await buildBargeInReport()],
231
+ explain: true,
231
232
  providerRoutingContracts: async () => [await runProviderRoutingContract()],
232
233
  reconnectContracts: async () => [await runReconnectContract()]
233
234
  }),
@@ -251,6 +252,7 @@ app.use(
251
252
  auditDeliveries: runtime.auditDeliveries,
252
253
  carriers: loadCarrierMatrixInputs,
253
254
  deliveryRuntime,
255
+ explain: true,
254
256
  phoneAgentSmokes: async () => [await runPhoneSmoke()],
255
257
  providerRoutingContracts: async () => [await runProviderRoutingContract()],
256
258
  traceDeliveries: runtime.traceDeliveries
@@ -281,6 +283,8 @@ app.use(
281
283
 
282
284
  The profile helper intentionally does not mount routes, create storage, start workers, or prescribe a deploy workflow. It only returns readiness options so teams can standardize defaults while keeping control over proof sources and route mounting.
283
285
 
286
+ Pass `explain: true` when the readiness JSON and HTML should describe the selected profile, its purpose, and which expected proof surfaces are configured or still missing. This is useful for customer demos and internal release reviews where the readiness URL needs to explain what it certifies without sending people to docs.
287
+
284
288
  ## Delivery Runtime Presets
285
289
 
286
290
  Use `createVoiceDeliveryRuntimePresetConfig(...)` when you want one primitive to create paired audit and trace delivery workers for the same target. The preset returns a normal `VoiceDeliveryRuntimeConfig`, so you can still inspect or override worker options before passing it to `createVoiceDeliveryRuntime(...)`.
package/dist/index.d.ts CHANGED
@@ -103,7 +103,7 @@ export type { VoicePhoneAgentCarrier, VoicePhoneAgentCarrierSummary, VoicePhoneA
103
103
  export type { VoicePhoneAgentProductionSmokeIssue, VoicePhoneAgentProductionSmokeHandlerOptions, VoicePhoneAgentProductionSmokeHTMLHandlerOptions, VoicePhoneAgentProductionSmokeOptions, VoicePhoneAgentProductionSmokeReport, VoicePhoneAgentProductionSmokeRoutesOptions, VoicePhoneAgentProductionSmokeRequirement } from './phoneAgentProductionSmoke';
104
104
  export type { VoiceOpsConsoleLink, VoiceOpsConsoleReport, VoiceOpsConsoleRoutesOptions } from './opsConsoleRoutes';
105
105
  export type { VoiceOpsStatus, VoiceOpsStatusLink, VoiceOpsStatusOptions, VoiceOpsStatusReport, VoiceOpsStatusRoutesOptions } from './opsStatus';
106
- export type { VoiceProductionReadinessAction, VoiceProductionReadinessAuditOptions, VoiceProductionReadinessAuditRequirement, VoiceProductionReadinessAuditSummary, VoiceProductionReadinessCheck, VoiceProductionReadinessGateIssue, VoiceProductionReadinessGateOptions, VoiceProductionReadinessGateReport, VoiceProductionReadinessOpsActionHistoryOptions, VoiceProductionReadinessOpsActionHistorySummary, VoiceProductionReadinessProofSource, VoiceProductionReadinessReport, VoiceProductionReadinessRoutesOptions, VoiceProductionReadinessTraceDeliverySummary, VoiceProductionReadinessAuditDeliveryOptions, VoiceProductionReadinessAuditDeliverySummary, VoiceProductionReadinessTraceDeliveryOptions, VoiceProductionReadinessStatus } from './productionReadiness';
106
+ export type { VoiceProductionReadinessAction, VoiceProductionReadinessAuditOptions, VoiceProductionReadinessAuditRequirement, VoiceProductionReadinessAuditSummary, VoiceProductionReadinessCheck, VoiceProductionReadinessGateIssue, VoiceProductionReadinessGateOptions, VoiceProductionReadinessGateProfile, VoiceProductionReadinessGateProfileSurface, VoiceProductionReadinessGateReport, VoiceProductionReadinessOpsActionHistoryOptions, VoiceProductionReadinessOpsActionHistorySummary, VoiceProductionReadinessProfileExplanation, VoiceProductionReadinessProfileSurface, VoiceProductionReadinessProofSource, VoiceProductionReadinessReport, VoiceProductionReadinessRoutesOptions, VoiceProductionReadinessTraceDeliverySummary, VoiceProductionReadinessAuditDeliveryOptions, VoiceProductionReadinessAuditDeliverySummary, VoiceProductionReadinessTraceDeliveryOptions, VoiceProductionReadinessStatus } from './productionReadiness';
107
107
  export type { VoiceReadinessProfileName, VoiceReadinessProfileOptions, VoiceReadinessProfileRoutesOptions } from './readinessProfiles';
108
108
  export type { VoiceQualityLink, VoiceQualityMetric, VoiceQualityReport, VoiceQualityRoutesOptions, VoiceQualityStatus, VoiceQualityThresholds } from './qualityRoutes';
109
109
  export type { VoiceResilienceIOSimulator, VoiceResilienceLink, VoiceResiliencePageData, VoiceResilienceRoutesOptions, VoiceResilienceSimulationProvider, VoiceRoutingKindSummary, VoiceRoutingDecisionSummary, VoiceRoutingDecisionSummaryOptions, VoiceRoutingEvent, VoiceRoutingEventKind, VoiceRoutingSessionSummary, VoiceRoutingSessionSummaryOptions } from './resilienceRoutes';
package/dist/index.js CHANGED
@@ -20149,6 +20149,27 @@ var readinessGateCodes = {
20149
20149
  "Trace sink delivery": "voice.readiness.trace_sink_delivery"
20150
20150
  };
20151
20151
  var readinessGateCodeForCheck = (check) => readinessGateCodes[check.label] ?? `voice.readiness.${check.label.toLowerCase().replace(/[^a-z0-9]+/g, "_").replace(/^_+|_+$/g, "")}`;
20152
+ var normalizeReadinessLabel = (value) => value.toLowerCase().replace(/[^a-z0-9]+/g, "");
20153
+ var issueMatchesProfileSurface = (issue, surface) => normalizeReadinessLabel(issue.label) === normalizeReadinessLabel(surface.label) || issue.code.includes(surface.key.replace(/([a-z0-9])([A-Z])/g, "$1_$2").toLowerCase().replace(/[^a-z0-9]+/g, "_"));
20154
+ var summarizeProfileSurfaceStatus = (issues) => issues.some((issue) => issue.status === "fail") ? "fail" : issues.some((issue) => issue.status === "warn") ? "warn" : "pass";
20155
+ var summarizeVoiceProductionReadinessGateProfile = (report, issues) => {
20156
+ if (!report.profile) {
20157
+ return;
20158
+ }
20159
+ return {
20160
+ description: report.profile.description,
20161
+ name: report.profile.name,
20162
+ purpose: report.profile.purpose,
20163
+ surfaces: report.profile.surfaces.map((surface) => {
20164
+ const surfaceIssues = issues.filter((issue) => issueMatchesProfileSurface(issue, surface));
20165
+ return {
20166
+ ...surface,
20167
+ issues: surfaceIssues,
20168
+ status: summarizeProfileSurfaceStatus(surfaceIssues)
20169
+ };
20170
+ })
20171
+ };
20172
+ };
20152
20173
  var summarizeVoiceProductionReadinessGate = (report, options = {}) => {
20153
20174
  const issues = report.checks.filter((check) => check.status !== "pass").map((check) => ({
20154
20175
  code: readinessGateCodeForCheck(check),
@@ -20165,6 +20186,7 @@ var summarizeVoiceProductionReadinessGate = (report, options = {}) => {
20165
20186
  checkedAt: report.checkedAt,
20166
20187
  failures,
20167
20188
  ok,
20189
+ profile: summarizeVoiceProductionReadinessGateProfile(report, issues),
20168
20190
  status: ok ? report.status : "fail",
20169
20191
  warnings
20170
20192
  };
@@ -20847,6 +20869,7 @@ var buildVoiceProductionReadinessReport = async (options, input = {}) => {
20847
20869
  traceDeliveries: "/traces/deliveries",
20848
20870
  ...options.links
20849
20871
  },
20872
+ profile: options.profile || undefined,
20850
20873
  proofSources,
20851
20874
  status: rollupStatus2(checks),
20852
20875
  summary: {
@@ -20888,6 +20911,7 @@ var buildVoiceProductionReadinessReport = async (options, input = {}) => {
20888
20911
  var buildVoiceProductionReadinessGate = async (options, input = {}) => summarizeVoiceProductionReadinessGate(await buildVoiceProductionReadinessReport(options, input), options.gate || undefined);
20889
20912
  var renderVoiceProductionReadinessHTML = (report, options = {}) => {
20890
20913
  const title = options.title ?? "AbsoluteJS Voice Production Readiness";
20914
+ const profile = report.profile ? `<section class="profile"><p class="eyebrow">Readiness profile</p><h2>${escapeHtml35(report.profile.name)}</h2><p>${escapeHtml35(report.profile.description)}</p><p>${escapeHtml35(report.profile.purpose)}</p><div class="profile-surfaces">${report.profile.surfaces.map((surface) => `<article class="${surface.configured ? "pass" : "warn"}"><span>${surface.configured ? "CONFIGURED" : "EXPECTED"}</span><strong>${surface.href ? `<a href="${escapeHtml35(surface.href)}">${escapeHtml35(surface.label)}</a>` : escapeHtml35(surface.label)}</strong></article>`).join("")}</div></section>` : "";
20891
20915
  const checks = report.checks.map((check, index) => {
20892
20916
  const actions = (check.actions ?? []).map((action) => action.method === "POST" ? `<button type="button" data-readiness-action="${index}" data-action-url="${escapeHtml35(action.href)}">${escapeHtml35(action.label)}</button>` : `<a href="${escapeHtml35(action.href)}">${escapeHtml35(action.label)}</a>`).join("");
20893
20917
  return `<article class="check ${escapeHtml35(check.status)}">
@@ -20902,7 +20926,7 @@ var renderVoiceProductionReadinessHTML = (report, options = {}) => {
20902
20926
  ${check.href ? `<a href="${escapeHtml35(check.href)}">Open surface</a>` : ""}
20903
20927
  </article>`;
20904
20928
  }).join("");
20905
- 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:#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>${escapeHtml35(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 ${escapeHtml35(report.status)}">Overall: ${escapeHtml35(report.status.toUpperCase())}</p><p>Checked ${escapeHtml35(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>`;
20929
+ 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:#0c0f14;color:#f6f2e8;font-family:ui-sans-serif,system-ui,sans-serif;margin:0}main{margin:auto;max-width:1060px;padding:32px}.hero,.profile{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}.profile{background:#111722}.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,.profile-surfaces .pass{border-color:rgba(34,197,94,.55)}.status.warn,.check.warn,.profile-surfaces .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,.profile-surfaces span{color:#a8b0b8;font-size:.78rem;font-weight:900;letter-spacing:.08em}.check h2{margin:.2rem 0}.check p,.profile p{color:#b9c0c8;margin:.2rem 0 0}.check .proof-source{color:#f9d77e;font-weight:800}.check strong{font-size:1.5rem}.profile-surfaces{display:grid;gap:10px;grid-template-columns:repeat(auto-fit,minmax(190px,1fr));margin-top:16px}.profile-surfaces article{background:#141922;border:1px solid #26313d;border-radius:16px;padding:14px}.profile-surfaces strong{display:block;margin-top:6px}.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>${escapeHtml35(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 ${escapeHtml35(report.status)}">Overall: ${escapeHtml35(report.status.toUpperCase())}</p><p>Checked ${escapeHtml35(new Date(report.checkedAt).toLocaleString())}</p></section>${profile}<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>`;
20906
20930
  };
20907
20931
  var createVoiceProductionReadinessRoutes = (options) => {
20908
20932
  const path = options.path ?? "/api/production-readiness";
@@ -20956,62 +20980,207 @@ var mergeLinks = (defaults, links) => ({
20956
20980
  ...defaults,
20957
20981
  ...links
20958
20982
  });
20983
+ var isConfigured = (value) => value !== undefined && value !== false;
20984
+ var profileExplanation = (profile, options, links) => {
20985
+ if (!options.explain) {
20986
+ return;
20987
+ }
20988
+ if (profile === "meeting-recorder") {
20989
+ return {
20990
+ description: "Browser and meeting-recorder readiness for transcript capture, reconnects, barge-in, provider fallback, and live latency proof.",
20991
+ name: "meeting-recorder",
20992
+ purpose: "Certifies the browser voice surfaces a meeting recorder or browser assistant needs before users rely on captured transcripts and summaries.",
20993
+ surfaces: [
20994
+ {
20995
+ configured: true,
20996
+ href: links.liveLatency,
20997
+ key: "liveLatency",
20998
+ label: "Live latency"
20999
+ },
21000
+ {
21001
+ configured: true,
21002
+ href: links.sessions,
21003
+ key: "sessions",
21004
+ label: "Session health"
21005
+ },
21006
+ {
21007
+ configured: true,
21008
+ href: links.resilience,
21009
+ key: "providerFallback",
21010
+ label: "Provider fallback"
21011
+ },
21012
+ {
21013
+ configured: isConfigured(options.providerRoutingContracts),
21014
+ href: links.providerRoutingContracts,
21015
+ key: "providerRoutingContracts",
21016
+ label: "Provider routing contracts"
21017
+ },
21018
+ {
21019
+ configured: isConfigured(options.reconnectContracts),
21020
+ href: links.reconnectContracts,
21021
+ key: "reconnectContracts",
21022
+ label: "Reconnect contracts"
21023
+ },
21024
+ {
21025
+ configured: isConfigured(options.bargeInReports),
21026
+ href: links.bargeIn,
21027
+ key: "bargeInReports",
21028
+ label: "Barge-in proof"
21029
+ }
21030
+ ]
21031
+ };
21032
+ }
21033
+ if (profile === "phone-agent") {
21034
+ return {
21035
+ description: "Carrier-backed phone-agent readiness for setup parity, phone smoke proof, handoffs, routing contracts, and delivery queues.",
21036
+ name: "phone-agent",
21037
+ purpose: "Certifies the proof surfaces a self-hosted phone agent needs before routing real carrier calls through the app.",
21038
+ surfaces: [
21039
+ {
21040
+ configured: isConfigured(options.carriers),
21041
+ href: links.carriers,
21042
+ key: "carriers",
21043
+ label: "Carrier readiness"
21044
+ },
21045
+ {
21046
+ configured: isConfigured(options.phoneAgentSmokes),
21047
+ href: links.phoneAgentSmoke,
21048
+ key: "phoneAgentSmokes",
21049
+ label: "Phone agent smoke"
21050
+ },
21051
+ {
21052
+ configured: true,
21053
+ href: links.handoffs,
21054
+ key: "handoffs",
21055
+ label: "Handoff delivery"
21056
+ },
21057
+ {
21058
+ configured: isConfigured(options.providerRoutingContracts),
21059
+ href: links.providerRoutingContracts,
21060
+ key: "providerRoutingContracts",
21061
+ label: "Provider routing contracts"
21062
+ },
21063
+ {
21064
+ configured: isConfigured(options.deliveryRuntime),
21065
+ href: links.deliveryRuntime,
21066
+ key: "deliveryRuntime",
21067
+ label: "Delivery runtime"
21068
+ },
21069
+ {
21070
+ configured: isConfigured(options.auditDeliveries),
21071
+ href: links.auditDeliveries,
21072
+ key: "auditDeliveries",
21073
+ label: "Audit deliveries"
21074
+ },
21075
+ {
21076
+ configured: isConfigured(options.traceDeliveries),
21077
+ href: links.traceDeliveries,
21078
+ key: "traceDeliveries",
21079
+ label: "Trace deliveries"
21080
+ }
21081
+ ]
21082
+ };
21083
+ }
21084
+ return {
21085
+ description: "Operations-heavy readiness for audit evidence, operator action history, delivery health, runtime queues, and deploy gate status.",
21086
+ name: "ops-heavy",
21087
+ purpose: "Certifies the operational control-plane proof surfaces that should block releases when evidence, queues, or operator actions are unhealthy.",
21088
+ surfaces: [
21089
+ {
21090
+ configured: isConfigured(options.audit),
21091
+ href: links.audit,
21092
+ key: "audit",
21093
+ label: "Audit evidence"
21094
+ },
21095
+ {
21096
+ configured: isConfigured(options.opsActionHistory ?? options.audit),
21097
+ href: links.opsActions,
21098
+ key: "opsActionHistory",
21099
+ label: "Operator action history"
21100
+ },
21101
+ {
21102
+ configured: isConfigured(options.deliveryRuntime),
21103
+ href: links.deliveryRuntime,
21104
+ key: "deliveryRuntime",
21105
+ label: "Delivery runtime"
21106
+ },
21107
+ {
21108
+ configured: isConfigured(options.auditDeliveries),
21109
+ href: links.auditDeliveries,
21110
+ key: "auditDeliveries",
21111
+ label: "Audit deliveries"
21112
+ },
21113
+ {
21114
+ configured: isConfigured(options.traceDeliveries),
21115
+ href: links.traceDeliveries,
21116
+ key: "traceDeliveries",
21117
+ label: "Trace deliveries"
21118
+ }
21119
+ ]
21120
+ };
21121
+ };
20959
21122
  var createVoiceReadinessProfile = (profile, options = {}) => {
20960
21123
  if (profile === "meeting-recorder") {
21124
+ const links2 = mergeLinks({
21125
+ bargeIn: "/barge-in",
21126
+ liveLatency: "/live-latency",
21127
+ providerRoutingContracts: "/resilience",
21128
+ quality: "/quality",
21129
+ reconnectContracts: "/voice/reconnect-contract",
21130
+ resilience: "/resilience",
21131
+ sessions: "/sessions"
21132
+ }, options.links);
20961
21133
  return withDefined({
20962
21134
  bargeInReports: options.bargeInReports,
20963
21135
  gate: options.gate,
20964
- links: mergeLinks({
20965
- bargeIn: "/barge-in",
20966
- liveLatency: "/live-latency",
20967
- providerRoutingContracts: "/resilience",
20968
- quality: "/quality",
20969
- reconnectContracts: "/voice/reconnect-contract",
20970
- resilience: "/resilience",
20971
- sessions: "/sessions"
20972
- }, options.links),
21136
+ links: links2,
21137
+ profile: profileExplanation(profile, options, links2),
20973
21138
  proofSources: options.proofSources,
20974
21139
  providerRoutingContracts: options.providerRoutingContracts,
20975
21140
  reconnectContracts: options.reconnectContracts
20976
21141
  });
20977
21142
  }
20978
21143
  if (profile === "phone-agent") {
21144
+ const links2 = mergeLinks({
21145
+ auditDeliveries: "/audit/deliveries",
21146
+ carriers: "/carriers",
21147
+ deliveryRuntime: "/delivery-runtime",
21148
+ handoffs: "/handoffs",
21149
+ phoneAgentSmoke: "/sessions",
21150
+ providerRoutingContracts: "/resilience",
21151
+ resilience: "/resilience",
21152
+ sessions: "/sessions",
21153
+ traceDeliveries: "/traces/deliveries"
21154
+ }, options.links);
20979
21155
  return withDefined({
20980
21156
  auditDeliveries: options.auditDeliveries,
20981
21157
  carriers: options.carriers,
20982
21158
  deliveryRuntime: options.deliveryRuntime,
20983
21159
  gate: options.gate,
20984
- links: mergeLinks({
20985
- auditDeliveries: "/audit/deliveries",
20986
- carriers: "/carriers",
20987
- deliveryRuntime: "/delivery-runtime",
20988
- handoffs: "/handoffs",
20989
- phoneAgentSmoke: "/sessions",
20990
- providerRoutingContracts: "/resilience",
20991
- resilience: "/resilience",
20992
- sessions: "/sessions",
20993
- traceDeliveries: "/traces/deliveries"
20994
- }, options.links),
21160
+ links: links2,
20995
21161
  phoneAgentSmokes: options.phoneAgentSmokes,
21162
+ profile: profileExplanation(profile, options, links2),
20996
21163
  proofSources: options.proofSources,
20997
21164
  providerRoutingContracts: options.providerRoutingContracts,
20998
21165
  traceDeliveries: options.traceDeliveries
20999
21166
  });
21000
21167
  }
21001
21168
  const opsActionHistory = options.opsActionHistory ?? auditStoreFromOptions(options.audit);
21169
+ const links = mergeLinks({
21170
+ audit: "/audit",
21171
+ auditDeliveries: "/audit/deliveries",
21172
+ deliveryRuntime: "/delivery-runtime",
21173
+ opsActions: "/voice/ops-actions",
21174
+ traceDeliveries: "/traces/deliveries"
21175
+ }, options.links);
21002
21176
  return withDefined({
21003
21177
  audit: options.audit,
21004
21178
  auditDeliveries: options.auditDeliveries,
21005
21179
  deliveryRuntime: options.deliveryRuntime,
21006
21180
  gate: options.gate,
21007
- links: mergeLinks({
21008
- audit: "/audit",
21009
- auditDeliveries: "/audit/deliveries",
21010
- deliveryRuntime: "/delivery-runtime",
21011
- opsActions: "/voice/ops-actions",
21012
- traceDeliveries: "/traces/deliveries"
21013
- }, options.links),
21181
+ links,
21014
21182
  opsActionHistory,
21183
+ profile: profileExplanation(profile, options, links),
21015
21184
  proofSources: options.proofSources,
21016
21185
  traceDeliveries: options.traceDeliveries
21017
21186
  });
@@ -42,6 +42,7 @@ export type VoiceProductionReadinessGateReport = {
42
42
  checkedAt: number;
43
43
  failures: VoiceProductionReadinessGateIssue[];
44
44
  ok: boolean;
45
+ profile?: VoiceProductionReadinessGateProfile;
45
46
  status: VoiceProductionReadinessStatus;
46
47
  warnings: VoiceProductionReadinessGateIssue[];
47
48
  };
@@ -52,6 +53,25 @@ export type VoiceProductionReadinessProofSource = {
52
53
  source: string;
53
54
  sourceLabel: string;
54
55
  };
56
+ export type VoiceProductionReadinessProfileSurface = {
57
+ configured: boolean;
58
+ href?: string;
59
+ key: string;
60
+ label: string;
61
+ };
62
+ export type VoiceProductionReadinessProfileExplanation = {
63
+ description: string;
64
+ name: string;
65
+ purpose: string;
66
+ surfaces: VoiceProductionReadinessProfileSurface[];
67
+ };
68
+ export type VoiceProductionReadinessGateProfileSurface = VoiceProductionReadinessProfileSurface & {
69
+ issues: VoiceProductionReadinessGateIssue[];
70
+ status: VoiceProductionReadinessStatus;
71
+ };
72
+ export type VoiceProductionReadinessGateProfile = Omit<VoiceProductionReadinessProfileExplanation, 'surfaces'> & {
73
+ surfaces: VoiceProductionReadinessGateProfileSurface[];
74
+ };
55
75
  export type VoiceProductionReadinessReport = {
56
76
  checkedAt: number;
57
77
  checks: VoiceProductionReadinessCheck[];
@@ -74,6 +94,7 @@ export type VoiceProductionReadinessReport = {
74
94
  sessions?: string;
75
95
  traceDeliveries?: string;
76
96
  };
97
+ profile?: VoiceProductionReadinessProfileExplanation;
77
98
  proofSources?: Record<string, VoiceProductionReadinessProofSource>;
78
99
  status: VoiceProductionReadinessStatus;
79
100
  summary: {
@@ -284,6 +305,7 @@ export type VoiceProductionReadinessRoutesOptions = {
284
305
  query: Record<string, unknown>;
285
306
  request: Request;
286
307
  }) => Promise<Record<string, VoiceProductionReadinessProofSource>> | Record<string, VoiceProductionReadinessProofSource>);
308
+ profile?: false | VoiceProductionReadinessProfileExplanation;
287
309
  render?: (report: VoiceProductionReadinessReport) => string | Promise<string>;
288
310
  store: VoiceTraceEventStore;
289
311
  sttProviders?: readonly string[];
@@ -6,6 +6,7 @@ export type VoiceReadinessProfileOptions = {
6
6
  bargeInReports?: VoiceProductionReadinessRoutesOptions['bargeInReports'];
7
7
  carriers?: VoiceProductionReadinessRoutesOptions['carriers'];
8
8
  deliveryRuntime?: VoiceProductionReadinessRoutesOptions['deliveryRuntime'];
9
+ explain?: boolean;
9
10
  gate?: VoiceProductionReadinessRoutesOptions['gate'];
10
11
  links?: VoiceProductionReadinessRoutesOptions['links'];
11
12
  opsActionHistory?: VoiceProductionReadinessOpsActionHistoryOptions;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@absolutejs/voice",
3
- "version": "0.0.22-beta.160",
3
+ "version": "0.0.22-beta.162",
4
4
  "description": "Voice primitives and Elysia plugin for AbsoluteJS",
5
5
  "repository": {
6
6
  "type": "git",