@absolutejs/voice 0.0.22-beta.361 → 0.0.22-beta.363

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
@@ -31,8 +31,8 @@ export { assertVoiceCompetitiveCoverage, buildVoiceCompetitiveCoverageReport, cr
31
31
  export type { VoiceCompetitiveCoverageAssertionInput, VoiceCompetitiveCoverageAssertionReport, VoiceCompetitiveCoverageIssue, VoiceCompetitiveCoverageLevel, VoiceCompetitiveCoverageReport, VoiceCompetitiveCoverageReportInput, VoiceCompetitiveCoverageRoutesOptions, VoiceCompetitiveCoverageStatus, VoiceCompetitiveCoverageSummary, VoiceCompetitiveDepthLevel, VoiceCompetitiveEvidence, VoiceCompetitiveSurface } from './competitiveCoverage';
32
32
  export type { VoicePlatformCoverageAssertionInput, VoicePlatformCoverageAssertionReport, VoicePlatformCoverageEvidence, VoicePlatformCoverageRoutesOptions, VoicePlatformCoverageStatus, VoicePlatformCoverageSummary, VoicePlatformCoverageSummaryInput, VoicePlatformCoverageSurface } from './platformCoverage';
33
33
  export { assertVoiceProofTrendEvidence, buildEmptyVoiceProofTrendReport, buildVoiceProofTrendProfileSummaries, buildVoiceProofTrendRecommendationReport, buildVoiceProofTrendReportFromRealCallProfiles, buildVoiceProofTrendReport, buildVoiceRealCallProfileDefaults, buildVoiceRealCallProfileHistoryReport, createVoiceProofTrendRecommendationRoutes, createVoiceProofTrendRoutes, createVoiceRealCallProfileHistoryRoutes, DEFAULT_VOICE_PROOF_TREND_PROFILE_DEFINITIONS, DEFAULT_VOICE_PROOF_TRENDS_MAX_AGE_MS, evaluateVoiceProofTrendEvidence, formatVoiceProofTrendAge, normalizeVoiceProofTrendReport, readVoiceProofTrendReportFile, renderVoiceProofTrendRecommendationHTML, renderVoiceProofTrendRecommendationMarkdown, renderVoiceRealCallProfileHistoryHTML, renderVoiceRealCallProfileHistoryMarkdown, resolveVoiceRealCallProfileProviderRoute } from './proofTrends';
34
- export { applyVoiceProfileSwitchGuard, buildVoiceProfileSwitchLiveDecisionReport, createVoiceProfileSwitchLiveDecisionRoutes, createVoiceProfileSwitchPolicyProofRoutes, recommendVoiceProfileSwitch, renderVoiceProfileSwitchLiveDecisionHTML, renderVoiceProfileSwitchPolicyProofHTML, runVoiceProfileSwitchPolicyProof } from './profileSwitchRecommendation';
35
- export type { VoiceProfileSwitchGuardAction, VoiceProfileSwitchGuardDecision, VoiceProfileSwitchGuardMode, VoiceProfileSwitchGuardOptions, VoiceProfileSwitchObservedSignals, VoiceProfileSwitchLiveDecisionEvidence, VoiceProfileSwitchLiveDecisionReport, VoiceProfileSwitchLiveDecisionReportOptions, VoiceProfileSwitchLiveDecisionRoutesOptions, VoiceProfileSwitchLiveDecisionSession, VoiceProfileSwitchPolicyProofCase, VoiceProfileSwitchPolicyProofCaseResult, VoiceProfileSwitchPolicyProofOptions, VoiceProfileSwitchPolicyProofReport, VoiceProfileSwitchPolicyProofRoutesOptions, VoiceProfileSwitchRecommendation, VoiceProfileSwitchRecommendationOptions } from './profileSwitchRecommendation';
34
+ export { applyVoiceProfileSwitchGuard, buildVoiceProfileSwitchReadinessReport, buildVoiceProfileSwitchLiveDecisionReport, createVoiceProfileSwitchLiveDecisionRoutes, createVoiceProfileSwitchPolicyProofRoutes, createVoiceProfileSwitchReadinessRoutes, recommendVoiceProfileSwitch, renderVoiceProfileSwitchLiveDecisionHTML, renderVoiceProfileSwitchPolicyProofHTML, renderVoiceProfileSwitchReadinessHTML, runVoiceProfileSwitchPolicyProof } from './profileSwitchRecommendation';
35
+ export type { VoiceProfileSwitchGuardAction, VoiceProfileSwitchGuardDecision, VoiceProfileSwitchGuardMode, VoiceProfileSwitchGuardOptions, VoiceProfileSwitchObservedSignals, VoiceProfileSwitchLiveDecisionEvidence, VoiceProfileSwitchLiveDecisionReport, VoiceProfileSwitchLiveDecisionReportOptions, VoiceProfileSwitchLiveDecisionRoutesOptions, VoiceProfileSwitchLiveDecisionSession, VoiceProfileSwitchPolicyProofCase, VoiceProfileSwitchPolicyProofCaseResult, VoiceProfileSwitchPolicyProofOptions, VoiceProfileSwitchPolicyProofReport, VoiceProfileSwitchPolicyProofRoutesOptions, VoiceProfileSwitchReadinessIssue, VoiceProfileSwitchReadinessOptions, VoiceProfileSwitchReadinessReport, VoiceProfileSwitchReadinessRoutesOptions, VoiceProfileSwitchReadinessStatus, VoiceProfileSwitchRecommendation, VoiceProfileSwitchRecommendationOptions } from './profileSwitchRecommendation';
36
36
  export { buildVoiceProviderDecisionTraceReport, createVoiceProviderDecisionTraceEvent, createVoiceProviderDecisionTraceRoutes, listVoiceProviderDecisionTraces, renderVoiceProviderDecisionTraceHTML, renderVoiceProviderDecisionTraceMarkdown } from './providerDecisionTraces';
37
37
  export type { VoiceProviderDecisionStatus, VoiceProviderDecisionSurfaceReport, VoiceProviderDecisionTrace, VoiceProviderDecisionTraceInput, VoiceProviderDecisionTraceIssue, VoiceProviderDecisionTraceReport, VoiceProviderDecisionTraceReportOptions, VoiceProviderDecisionTraceRoutesOptions } from './providerDecisionTraces';
38
38
  export type { VoiceProofTrendAssertionInput, VoiceProofTrendAssertionReport, VoiceProofTrendCycle, VoiceProofTrendProfileDefinition, VoiceProofTrendProfileRecommendation, VoiceProofTrendProfileSummaryOptions, VoiceProofTrendProfileSummary, VoiceProofTrendProviderRecommendation, VoiceProofTrendProviderSummary, VoiceProofTrendRecommendation, VoiceProofTrendRecommendationOptions, VoiceProofTrendRecommendationReport, VoiceProofTrendRecommendationRoutesOptions, VoiceProofTrendRecommendationStatus, VoiceProofTrendRecommendationSurface, VoiceProofTrendRealCallProfileEvidence, VoiceProofTrendRealCallProfileReportOptions, VoiceProofTrendReport, VoiceProofTrendReportInput, VoiceProofTrendRoutesOptions, VoiceProofTrendRuntimeChannelSummary, VoiceProofTrendStatus, VoiceProofTrendSummary, VoiceRealCallProfileDefault, VoiceRealCallProfileDefaultsOptions, VoiceRealCallProfileDefaultsReport, VoiceRealCallProfileHistoryOptions, VoiceRealCallProfileHistoryReport, VoiceRealCallProfileHistoryRoutesOptions, VoiceRealCallProfileProviderRouteOptions } from './proofTrends';
package/dist/index.js CHANGED
@@ -5844,6 +5844,126 @@ var createVoiceProfileSwitchLiveDecisionRoutes = (options) => {
5844
5844
  }
5845
5845
  return routes;
5846
5846
  };
5847
+ var statusFromIssues = (issues) => issues.some((issue) => issue.status === "fail") ? "fail" : issues.length > 0 ? "warn" : "pass";
5848
+ var buildVoiceProfileSwitchReadinessReport = async (options) => {
5849
+ const live = await buildVoiceProfileSwitchLiveDecisionReport(options);
5850
+ const policy = options.policyProof === false || options.policyProof === undefined ? undefined : await runVoiceProfileSwitchPolicyProof(options.policyProof);
5851
+ const issues = [];
5852
+ const requireLiveDecisions = options.requireLiveDecisions ?? true;
5853
+ const requireAudit = options.requireAudit ?? Boolean(options.autoMode);
5854
+ const requireTrace = options.requireTrace ?? true;
5855
+ const requirePolicyProof = options.requirePolicyProof ?? Boolean(options.policyProof);
5856
+ const requireAllowedProfilePolicy = options.requireAllowedProfilePolicy ?? Boolean(options.autoMode);
5857
+ const maxBlockedRatio = options.maxBlockedRatio ?? 0.5;
5858
+ const maxAutoAppliedRatio = options.maxAutoAppliedRatio ?? 0.75;
5859
+ const decisions = live.summary.decisions;
5860
+ const blockedRatio = decisions > 0 ? live.summary.blocked / decisions : 0;
5861
+ const autoAppliedRatio = decisions > 0 ? live.summary.autoApplied / decisions : 0;
5862
+ if (requireLiveDecisions && decisions === 0) {
5863
+ issues.push({
5864
+ code: "voice.profile_switch.live_decisions_missing",
5865
+ message: "No live profile switch guard decisions have been recorded.",
5866
+ status: "fail"
5867
+ });
5868
+ }
5869
+ if (requireAudit && live.summary.auditEvents === 0) {
5870
+ issues.push({
5871
+ code: "voice.profile_switch.audit_missing",
5872
+ message: "Profile switch guard readiness requires audit evidence.",
5873
+ status: "fail"
5874
+ });
5875
+ }
5876
+ if (requireTrace && live.summary.traceEvents === 0) {
5877
+ issues.push({
5878
+ code: "voice.profile_switch.trace_missing",
5879
+ message: "Profile switch guard readiness requires trace evidence.",
5880
+ status: "warn"
5881
+ });
5882
+ }
5883
+ if (requirePolicyProof && !policy) {
5884
+ issues.push({
5885
+ code: "voice.profile_switch.policy_proof_missing",
5886
+ message: "Profile switch policy proof was not configured.",
5887
+ status: "fail"
5888
+ });
5889
+ }
5890
+ if (policy && !policy.ok) {
5891
+ issues.push({
5892
+ code: "voice.profile_switch.policy_proof_failed",
5893
+ message: "Profile switch policy proof has failing cases.",
5894
+ status: "fail"
5895
+ });
5896
+ }
5897
+ if (requireAllowedProfilePolicy && (options.policyProof === false || !options.policyProof?.allowedProfileIds || options.policyProof.allowedProfileIds.length === 0)) {
5898
+ issues.push({
5899
+ code: "voice.profile_switch.allowed_policy_missing",
5900
+ message: "Auto profile switching should declare an allowedProfileIds policy.",
5901
+ status: "warn"
5902
+ });
5903
+ }
5904
+ if (decisions > 0 && blockedRatio > maxBlockedRatio) {
5905
+ issues.push({
5906
+ code: "voice.profile_switch.blocked_ratio_high",
5907
+ message: `Blocked profile switch decisions are ${Math.round(blockedRatio * 100)}%, above the ${Math.round(maxBlockedRatio * 100)}% threshold.`,
5908
+ status: "warn"
5909
+ });
5910
+ }
5911
+ if (decisions > 0 && autoAppliedRatio > maxAutoAppliedRatio) {
5912
+ issues.push({
5913
+ code: "voice.profile_switch.auto_applied_ratio_high",
5914
+ message: `Auto-applied profile switch decisions are ${Math.round(autoAppliedRatio * 100)}%, above the ${Math.round(maxAutoAppliedRatio * 100)}% threshold.`,
5915
+ status: "warn"
5916
+ });
5917
+ }
5918
+ return {
5919
+ generatedAt: new Date().toISOString(),
5920
+ issues,
5921
+ live,
5922
+ policy,
5923
+ status: statusFromIssues(issues),
5924
+ summary: {
5925
+ auditEvents: live.summary.auditEvents,
5926
+ autoApplied: live.summary.autoApplied,
5927
+ blocked: live.summary.blocked,
5928
+ decisions,
5929
+ policyCases: policy?.summary.total,
5930
+ sessions: live.summary.sessions,
5931
+ switches: live.summary.switches,
5932
+ traceEvents: live.summary.traceEvents
5933
+ }
5934
+ };
5935
+ };
5936
+ var renderVoiceProfileSwitchReadinessHTML = (report, options = {}) => {
5937
+ const title = options.title ?? "Voice Profile Switch Readiness";
5938
+ const issues = report.issues.map((issue) => `<li class="${escapeHtml3(issue.status)}"><strong>${escapeHtml3(issue.code)}</strong><p>${escapeHtml3(issue.message)}</p></li>`).join("");
5939
+ const sessions = report.live.sessions.map((session) => `<tr><td>${escapeHtml3(session.sessionId)}</td><td>${escapeHtml3(session.actions.join(", ") || "none")}</td><td>${String(session.decisions.length)}</td><td>${String(session.autoApplied)}</td><td>${escapeHtml3(session.blockedByPolicy.join(", ") || "none")}</td></tr>`).join("");
5940
+ return `<!doctype html><html lang="en"><head><meta charset="utf-8" /><meta name="viewport" content="width=device-width, initial-scale=1" /><title>${escapeHtml3(title)}</title><style>:root{color-scheme:dark;background:#0b1020;color:#eff6ff;font-family:ui-sans-serif,system-ui,sans-serif}body{margin:0;padding:32px;background:radial-gradient(circle at top left,rgba(59,130,246,.2),transparent 34%),#0b1020}main{max-width:1140px;margin:0 auto}.hero,.card{background:rgba(15,23,42,.82);border:1px solid rgba(147,197,253,.24);border-radius:24px;margin-bottom:18px;padding:24px}.status{border-radius:999px;display:inline-flex;font-weight:900;padding:8px 12px}.pass{background:rgba(34,197,94,.18);color:#bbf7d0}.warn{background:rgba(245,158,11,.18);color:#fde68a}.fail{background:rgba(239,68,68,.18);color:#fecaca}.grid{display:grid;gap:12px;grid-template-columns:repeat(auto-fit,minmax(160px,1fr));margin-top:16px}.metric{background:#0f172a;border:1px solid rgba(147,197,253,.2);border-radius:18px;padding:16px}.metric span{color:#93c5fd;display:block;font-size:.75rem;font-weight:900;letter-spacing:.08em;text-transform:uppercase}.metric strong{display:block;font-size:1.8rem;margin-top:8px}ul{display:grid;gap:10px;list-style:none;padding:0}li{border-radius:16px;padding:14px}li p{margin:.35rem 0 0}table{border-collapse:collapse;width:100%}td,th{border-bottom:1px solid rgba(147,197,253,.18);padding:12px;text-align:left}pre{background:#020617;border-radius:18px;color:#dbeafe;overflow:auto;padding:18px}</style></head><body><main><section class="hero"><h1>${escapeHtml3(title)}</h1><p>Deploy-facing readiness for profile switching: policy proof, audit evidence, trace evidence, and live session behavior.</p><p class="status ${escapeHtml3(report.status)}">${escapeHtml3(report.status.toUpperCase())}</p><div class="grid"><div class="metric"><span>Sessions</span><strong>${String(report.summary.sessions)}</strong></div><div class="metric"><span>Decisions</span><strong>${String(report.summary.decisions)}</strong></div><div class="metric"><span>Policy cases</span><strong>${String(report.summary.policyCases ?? 0)}</strong></div><div class="metric"><span>Audit</span><strong>${String(report.summary.auditEvents)}</strong></div><div class="metric"><span>Trace</span><strong>${String(report.summary.traceEvents)}</strong></div></div></section><section class="card"><h2>Issues</h2>${issues ? `<ul>${issues}</ul>` : '<p class="pass status">No readiness issues.</p>'}</section><section class="card"><h2>Live Sessions</h2>${sessions ? `<table><thead><tr><th>Session</th><th>Actions</th><th>Decisions</th><th>Auto applied</th><th>Blocked by</th></tr></thead><tbody>${sessions}</tbody></table>` : "<p>No live guard sessions found.</p>"}</section><section class="card"><h2>Raw Report</h2><pre>${stringifyForHtml(report)}</pre></section></main></body></html>`;
5941
+ };
5942
+ var createVoiceProfileSwitchReadinessRoutes = (options) => {
5943
+ const path = options.path ?? "/api/voice/profile-switch-readiness";
5944
+ const htmlPath = options.htmlPath === undefined ? "/voice/profile-switch-readiness" : options.htmlPath;
5945
+ const routes = new Elysia({
5946
+ name: options.name ?? "absolutejs-voice-profile-switch-readiness"
5947
+ }).get(path, async ({ query }) => buildVoiceProfileSwitchReadinessReport({
5948
+ ...options,
5949
+ limit: typeof query.limit === "string" && Number.isFinite(Number(query.limit)) ? Number(query.limit) : options.limit,
5950
+ sessionId: typeof query.sessionId === "string" && query.sessionId.trim() ? query.sessionId.trim() : options.sessionId
5951
+ }));
5952
+ if (htmlPath) {
5953
+ routes.get(htmlPath, async ({ query }) => {
5954
+ const report = await buildVoiceProfileSwitchReadinessReport({
5955
+ ...options,
5956
+ limit: typeof query.limit === "string" && Number.isFinite(Number(query.limit)) ? Number(query.limit) : options.limit,
5957
+ sessionId: typeof query.sessionId === "string" && query.sessionId.trim() ? query.sessionId.trim() : options.sessionId
5958
+ });
5959
+ const render = options.render ?? ((input) => renderVoiceProfileSwitchReadinessHTML(input, { title: options.title }));
5960
+ return new Response(await render(report), {
5961
+ headers: { "Content-Type": "text/html; charset=utf-8" }
5962
+ });
5963
+ });
5964
+ }
5965
+ return routes;
5966
+ };
5847
5967
 
5848
5968
  // src/plugin.ts
5849
5969
  var resolveQueryScenario = (query) => {
@@ -31866,6 +31986,14 @@ var resolveProviderOrchestration = async (options, input) => {
31866
31986
  }
31867
31987
  return typeof options.providerOrchestration === "function" ? await options.providerOrchestration(input) : options.providerOrchestration;
31868
31988
  };
31989
+ var isVoiceProfileSwitchReadinessReport = (value) => typeof value.status === "string" && typeof value.generatedAt === "string" && typeof value.summary === "object";
31990
+ var resolveProfileSwitchReadiness = async (options, input) => {
31991
+ if (options.profileSwitchReadiness === false || options.profileSwitchReadiness === undefined) {
31992
+ return;
31993
+ }
31994
+ const value = typeof options.profileSwitchReadiness === "function" ? await options.profileSwitchReadiness(input) : options.profileSwitchReadiness;
31995
+ return isVoiceProfileSwitchReadinessReport(value) ? value : buildVoiceProfileSwitchReadinessReport(value);
31996
+ };
31869
31997
  var resolveProviderStack = async (options, input) => {
31870
31998
  if (options.providerStack === false || options.providerStack === undefined) {
31871
31999
  return;
@@ -32314,6 +32442,7 @@ var buildVoiceProductionReadinessReport = async (options, input = {}) => {
32314
32442
  providerRoutingContracts,
32315
32443
  providerSlo,
32316
32444
  providerOrchestration,
32445
+ profileSwitchReadiness,
32317
32446
  providerStack,
32318
32447
  providerContractMatrix,
32319
32448
  phoneAgentSmokes,
@@ -32360,6 +32489,7 @@ var buildVoiceProductionReadinessReport = async (options, input = {}) => {
32360
32489
  resolveProviderRoutingContracts(options, { query, request }),
32361
32490
  resolveProviderSlo(options, { query, request }),
32362
32491
  resolveProviderOrchestration(options, { query, request }),
32492
+ resolveProfileSwitchReadiness(options, { query, request }),
32363
32493
  resolveProviderStack(options, { query, request }),
32364
32494
  resolveProviderContractMatrix(options, { query, request }),
32365
32495
  resolvePhoneAgentSmokes(options, { query, request }),
@@ -33088,6 +33218,28 @@ var buildVoiceProductionReadinessReport = async (options, input = {}) => {
33088
33218
  ]
33089
33219
  });
33090
33220
  }
33221
+ if (profileSwitchReadiness) {
33222
+ const issueLabels = profileSwitchReadiness.issues.map((issue) => issue.code);
33223
+ checks.push({
33224
+ detail: profileSwitchReadiness.status === "pass" ? `${profileSwitchReadiness.summary.decisions} profile switch guard decision(s) are backed by readiness evidence.` : issueLabels.length > 0 ? `Profile switch readiness issues: ${issueLabels.join(", ")}.` : "Profile switch readiness needs attention.",
33225
+ href: options.links?.profileSwitchReadiness ?? "/voice/profile-switch-readiness",
33226
+ label: "Profile switch readiness",
33227
+ status: profileSwitchReadiness.status,
33228
+ value: `${profileSwitchReadiness.summary.sessions}/${profileSwitchReadiness.summary.decisions}`,
33229
+ actions: profileSwitchReadiness.status === "pass" ? [] : [
33230
+ {
33231
+ description: "Open profile switch readiness to inspect policy proof, audit evidence, trace evidence, and live decisions.",
33232
+ href: options.links?.profileSwitchReadiness ?? "/voice/profile-switch-readiness",
33233
+ label: "Open profile readiness"
33234
+ },
33235
+ {
33236
+ description: "Open live profile switch decisions recorded from audit and trace stores.",
33237
+ href: options.links?.profileSwitchLiveDecisions ?? "/voice/profile-switch-live-decisions",
33238
+ label: "Open live decisions"
33239
+ }
33240
+ ]
33241
+ });
33242
+ }
33091
33243
  if (audit) {
33092
33244
  const missingLabels = audit.missing.map((requirement) => requirement.label ?? requirement.type);
33093
33245
  checks.push({
@@ -33279,6 +33431,9 @@ var buildVoiceProductionReadinessReport = async (options, input = {}) => {
33279
33431
  opsActions: "/voice/ops-actions",
33280
33432
  opsRecovery: "/ops-recovery",
33281
33433
  phoneAgentSmoke: "/sessions",
33434
+ profileSwitchLiveDecisions: "/voice/profile-switch-live-decisions",
33435
+ profileSwitchPolicy: "/voice/profile-switch-policy",
33436
+ profileSwitchReadiness: "/voice/profile-switch-readiness",
33282
33437
  telephonyMedia: "/voice/telephony-media",
33283
33438
  telephonyWebhookSecurity: "/api/voice/telephony/webhook-security",
33284
33439
  providerContracts: "/provider-contracts",
@@ -33332,6 +33487,15 @@ var buildVoiceProductionReadinessReport = async (options, input = {}) => {
33332
33487
  providerContractMatrix,
33333
33488
  providerOrchestration: providerOrchestrationSummary,
33334
33489
  providerRecovery,
33490
+ profileSwitchReadiness: profileSwitchReadiness ? {
33491
+ auditEvents: profileSwitchReadiness.summary.auditEvents,
33492
+ decisions: profileSwitchReadiness.summary.decisions,
33493
+ issues: profileSwitchReadiness.issues.length,
33494
+ policyCases: profileSwitchReadiness.summary.policyCases,
33495
+ sessions: profileSwitchReadiness.summary.sessions,
33496
+ status: profileSwitchReadiness.status,
33497
+ traceEvents: profileSwitchReadiness.summary.traceEvents
33498
+ } : undefined,
33335
33499
  phoneAgentSmokes: phoneAgentSmokeSummary,
33336
33500
  telephonyMedia: telephonyMediaSummary,
33337
33501
  telephonyWebhookSecurity: telephonyWebhookSecuritySummary,
@@ -37824,6 +37988,7 @@ export {
37824
37988
  renderVoiceProviderCapabilityHTML,
37825
37989
  renderVoiceProofTrendRecommendationMarkdown,
37826
37990
  renderVoiceProofTrendRecommendationHTML,
37991
+ renderVoiceProfileSwitchReadinessHTML,
37827
37992
  renderVoiceProfileSwitchPolicyProofHTML,
37828
37993
  renderVoiceProfileSwitchLiveDecisionHTML,
37829
37994
  renderVoiceProductionReadinessHTML,
@@ -38079,6 +38244,7 @@ export {
38079
38244
  createVoiceProviderCapabilityHTMLHandler,
38080
38245
  createVoiceProofTrendRoutes,
38081
38246
  createVoiceProofTrendRecommendationRoutes,
38247
+ createVoiceProfileSwitchReadinessRoutes,
38082
38248
  createVoiceProfileSwitchPolicyProofRoutes,
38083
38249
  createVoiceProfileSwitchLiveDecisionRoutes,
38084
38250
  createVoiceProductionReadinessRoutes,
@@ -38281,6 +38447,7 @@ export {
38281
38447
  buildVoiceProofTrendReport,
38282
38448
  buildVoiceProofTrendRecommendationReport,
38283
38449
  buildVoiceProofTrendProfileSummaries,
38450
+ buildVoiceProfileSwitchReadinessReport,
38284
38451
  buildVoiceProfileSwitchLiveDecisionReport,
38285
38452
  buildVoiceProductionReadinessReport,
38286
38453
  buildVoiceProductionReadinessGate,
@@ -22,6 +22,7 @@ import { type VoiceObservabilityExportDeliveryHistory, type VoiceObservabilityEx
22
22
  import type { VoiceMediaPipelineReport } from './mediaPipelineRoutes';
23
23
  import type { VoiceTelephonyMediaReport } from './telephonyMediaRoutes';
24
24
  import type { MediaWebRTCStatsReport } from '@absolutejs/media';
25
+ import { type VoiceProfileSwitchReadinessOptions, type VoiceProfileSwitchReadinessReport } from './profileSwitchRecommendation';
25
26
  export type VoiceProductionReadinessObservabilityExportDeliveryHistoryOptions = {
26
27
  failOnMissing?: boolean;
27
28
  failOnStale?: boolean;
@@ -140,6 +141,9 @@ export type VoiceProductionReadinessReport = {
140
141
  opsActions?: string;
141
142
  opsRecovery?: string;
142
143
  phoneAgentSmoke?: string;
144
+ profileSwitchLiveDecisions?: string;
145
+ profileSwitchPolicy?: string;
146
+ profileSwitchReadiness?: string;
143
147
  telephonyWebhookSecurity?: string;
144
148
  telephonyMedia?: string;
145
149
  providerContracts?: string;
@@ -283,6 +287,15 @@ export type VoiceProductionReadinessReport = {
283
287
  warned: number;
284
288
  };
285
289
  providerRecovery: VoiceProviderFallbackRecoverySummary;
290
+ profileSwitchReadiness?: {
291
+ auditEvents: number;
292
+ decisions: number;
293
+ issues: number;
294
+ policyCases?: number;
295
+ sessions: number;
296
+ status: VoiceProductionReadinessStatus;
297
+ traceEvents: number;
298
+ };
286
299
  phoneAgentSmokes?: {
287
300
  failed: number;
288
301
  passed: number;
@@ -540,6 +553,10 @@ export type VoiceProductionReadinessRoutesOptions = {
540
553
  query: Record<string, unknown>;
541
554
  request: Request;
542
555
  }) => Promise<VoiceProviderOrchestrationReport> | VoiceProviderOrchestrationReport);
556
+ profileSwitchReadiness?: false | VoiceProfileSwitchReadinessReport | VoiceProfileSwitchReadinessOptions | ((input: {
557
+ query: Record<string, unknown>;
558
+ request: Request;
559
+ }) => Promise<VoiceProfileSwitchReadinessReport | VoiceProfileSwitchReadinessOptions> | VoiceProfileSwitchReadinessReport | VoiceProfileSwitchReadinessOptions);
543
560
  providerStack?: false | VoiceProviderStackCapabilityGapReport | ((input: {
544
561
  query: Record<string, unknown>;
545
562
  request: Request;
@@ -173,6 +173,47 @@ export type VoiceProfileSwitchLiveDecisionRoutesOptions = VoiceProfileSwitchLive
173
173
  render?: (report: VoiceProfileSwitchLiveDecisionReport) => string | Promise<string>;
174
174
  title?: string;
175
175
  };
176
+ export type VoiceProfileSwitchReadinessStatus = 'fail' | 'pass' | 'warn';
177
+ export type VoiceProfileSwitchReadinessIssue = {
178
+ code: string;
179
+ message: string;
180
+ status: Exclude<VoiceProfileSwitchReadinessStatus, 'pass'>;
181
+ };
182
+ export type VoiceProfileSwitchReadinessReport = {
183
+ generatedAt: string;
184
+ issues: VoiceProfileSwitchReadinessIssue[];
185
+ live: VoiceProfileSwitchLiveDecisionReport;
186
+ policy?: VoiceProfileSwitchPolicyProofReport;
187
+ status: VoiceProfileSwitchReadinessStatus;
188
+ summary: {
189
+ auditEvents: number;
190
+ autoApplied: number;
191
+ blocked: number;
192
+ decisions: number;
193
+ policyCases?: number;
194
+ sessions: number;
195
+ switches: number;
196
+ traceEvents: number;
197
+ };
198
+ };
199
+ export type VoiceProfileSwitchReadinessOptions = VoiceProfileSwitchLiveDecisionReportOptions & {
200
+ autoMode?: boolean;
201
+ maxBlockedRatio?: number;
202
+ maxAutoAppliedRatio?: number;
203
+ policyProof?: false | VoiceProfileSwitchPolicyProofOptions;
204
+ requireAudit?: boolean;
205
+ requireAllowedProfilePolicy?: boolean;
206
+ requireLiveDecisions?: boolean;
207
+ requirePolicyProof?: boolean;
208
+ requireTrace?: boolean;
209
+ };
210
+ export type VoiceProfileSwitchReadinessRoutesOptions = VoiceProfileSwitchReadinessOptions & {
211
+ htmlPath?: false | string;
212
+ name?: string;
213
+ path?: string;
214
+ render?: (report: VoiceProfileSwitchReadinessReport) => string | Promise<string>;
215
+ title?: string;
216
+ };
176
217
  export declare const recommendVoiceProfileSwitch: (options: VoiceProfileSwitchRecommendationOptions) => VoiceProfileSwitchRecommendation;
177
218
  export declare const applyVoiceProfileSwitchGuard: (options: VoiceProfileSwitchGuardOptions) => Promise<VoiceProfileSwitchGuardDecision>;
178
219
  export declare const runVoiceProfileSwitchPolicyProof: (options: VoiceProfileSwitchPolicyProofOptions) => Promise<VoiceProfileSwitchPolicyProofReport>;
@@ -263,3 +304,47 @@ export declare const createVoiceProfileSwitchLiveDecisionRoutes: (options: Voice
263
304
  standaloneSchema: {};
264
305
  response: {};
265
306
  }>;
307
+ export declare const buildVoiceProfileSwitchReadinessReport: (options: VoiceProfileSwitchReadinessOptions) => Promise<VoiceProfileSwitchReadinessReport>;
308
+ export declare const renderVoiceProfileSwitchReadinessHTML: (report: VoiceProfileSwitchReadinessReport, options?: {
309
+ title?: string;
310
+ }) => string;
311
+ export declare const createVoiceProfileSwitchReadinessRoutes: (options: VoiceProfileSwitchReadinessRoutesOptions) => Elysia<"", {
312
+ decorator: {};
313
+ store: {};
314
+ derive: {};
315
+ resolve: {};
316
+ }, {
317
+ typebox: {};
318
+ error: {};
319
+ }, {
320
+ schema: {};
321
+ standaloneSchema: {};
322
+ macro: {};
323
+ macroFn: {};
324
+ parser: {};
325
+ response: {};
326
+ }, {
327
+ [x: string]: {
328
+ get: {
329
+ body: unknown;
330
+ params: {};
331
+ query: unknown;
332
+ headers: unknown;
333
+ response: {
334
+ 200: VoiceProfileSwitchReadinessReport;
335
+ };
336
+ };
337
+ };
338
+ }, {
339
+ derive: {};
340
+ resolve: {};
341
+ schema: {};
342
+ standaloneSchema: {};
343
+ response: {};
344
+ }, {
345
+ derive: {};
346
+ resolve: {};
347
+ schema: {};
348
+ standaloneSchema: {};
349
+ response: {};
350
+ }>;
@@ -56,6 +56,9 @@ export declare const useVoiceReadinessFailures: (path?: string, options?: VoiceR
56
56
  readonly opsActions?: string | undefined;
57
57
  readonly opsRecovery?: string | undefined;
58
58
  readonly phoneAgentSmoke?: string | undefined;
59
+ readonly profileSwitchLiveDecisions?: string | undefined;
60
+ readonly profileSwitchPolicy?: string | undefined;
61
+ readonly profileSwitchReadiness?: string | undefined;
59
62
  readonly telephonyWebhookSecurity?: string | undefined;
60
63
  readonly telephonyMedia?: string | undefined;
61
64
  readonly providerContracts?: string | undefined;
@@ -369,6 +372,15 @@ export declare const useVoiceReadinessFailures: (path?: string, options?: VoiceR
369
372
  readonly unresolvedErrors: number;
370
373
  readonly unresolvedSessions: number;
371
374
  };
375
+ readonly profileSwitchReadiness?: {
376
+ readonly auditEvents: number;
377
+ readonly decisions: number;
378
+ readonly issues: number;
379
+ readonly policyCases?: number | undefined;
380
+ readonly sessions: number;
381
+ readonly status: import("..").VoiceProductionReadinessStatus;
382
+ readonly traceEvents: number;
383
+ } | undefined;
372
384
  readonly phoneAgentSmokes?: {
373
385
  readonly failed: number;
374
386
  readonly passed: number;
@@ -489,6 +501,9 @@ export declare const useVoiceReadinessFailures: (path?: string, options?: VoiceR
489
501
  readonly opsActions?: string | undefined;
490
502
  readonly opsRecovery?: string | undefined;
491
503
  readonly phoneAgentSmoke?: string | undefined;
504
+ readonly profileSwitchLiveDecisions?: string | undefined;
505
+ readonly profileSwitchPolicy?: string | undefined;
506
+ readonly profileSwitchReadiness?: string | undefined;
492
507
  readonly telephonyWebhookSecurity?: string | undefined;
493
508
  readonly telephonyMedia?: string | undefined;
494
509
  readonly providerContracts?: string | undefined;
@@ -802,6 +817,15 @@ export declare const useVoiceReadinessFailures: (path?: string, options?: VoiceR
802
817
  readonly unresolvedErrors: number;
803
818
  readonly unresolvedSessions: number;
804
819
  };
820
+ readonly profileSwitchReadiness?: {
821
+ readonly auditEvents: number;
822
+ readonly decisions: number;
823
+ readonly issues: number;
824
+ readonly policyCases?: number | undefined;
825
+ readonly sessions: number;
826
+ readonly status: import("..").VoiceProductionReadinessStatus;
827
+ readonly traceEvents: number;
828
+ } | undefined;
805
829
  readonly phoneAgentSmokes?: {
806
830
  readonly failed: number;
807
831
  readonly passed: number;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@absolutejs/voice",
3
- "version": "0.0.22-beta.361",
3
+ "version": "0.0.22-beta.363",
4
4
  "description": "Voice primitives and Elysia plugin for AbsoluteJS",
5
5
  "repository": {
6
6
  "type": "git",