@absolutejs/voice 0.0.22-beta.262 → 0.0.22-beta.264

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.
@@ -4299,6 +4299,58 @@ var assertVoiceLiveOpsEvidence = (input = {}) => {
4299
4299
  }
4300
4300
  return assertion;
4301
4301
  };
4302
+ var evaluateVoiceLiveOpsControlEvidence = (input = {}) => {
4303
+ const issues = [];
4304
+ const results = input.results ?? [];
4305
+ const controls = results.map((result) => result.control).filter((control) => Boolean(control));
4306
+ const finalControl = input.finalControl ?? controls.at(-1);
4307
+ const actions = uniqueSorted(results.map((result) => result.action).filter((action) => isVoiceLiveOpsAction(action)));
4308
+ const statuses = uniqueSorted(controls.map((control) => control.status));
4309
+ const failedActions = results.filter((result) => result.ok === false).length;
4310
+ if (results.length === 0) {
4311
+ issues.push("Expected live-ops control action result(s) to be present.");
4312
+ }
4313
+ if (input.minSnapshots !== undefined && controls.length < input.minSnapshots) {
4314
+ issues.push(`Expected at least ${String(input.minSnapshots)} live-ops control snapshot(s), found ${String(controls.length)}.`);
4315
+ }
4316
+ if (input.maxFailedActions !== undefined && failedActions > input.maxFailedActions) {
4317
+ issues.push(`Expected at most ${String(input.maxFailedActions)} failed live-ops control action(s), found ${String(failedActions)}.`);
4318
+ }
4319
+ for (const action of findMissing(actions, input.requiredActions)) {
4320
+ issues.push(`Missing live-ops control action: ${action}.`);
4321
+ }
4322
+ for (const status of findMissing(statuses, input.requiredStatuses)) {
4323
+ issues.push(`Missing live-ops control status: ${status}.`);
4324
+ }
4325
+ if (!finalControl) {
4326
+ issues.push("Expected final live-ops control state to be present.");
4327
+ } else {
4328
+ if (input.requireFinalAssistantPaused !== undefined && finalControl.assistantPaused !== input.requireFinalAssistantPaused) {
4329
+ issues.push(`Expected final live-ops assistantPaused ${String(input.requireFinalAssistantPaused)}, found ${String(finalControl.assistantPaused)}.`);
4330
+ }
4331
+ if (input.requireFinalOperatorTakeover !== undefined && finalControl.operatorTakeover !== input.requireFinalOperatorTakeover) {
4332
+ issues.push(`Expected final live-ops operatorTakeover ${String(input.requireFinalOperatorTakeover)}, found ${String(finalControl.operatorTakeover)}.`);
4333
+ }
4334
+ }
4335
+ return {
4336
+ actionCount: results.length,
4337
+ actions,
4338
+ failedActions,
4339
+ finalControl: finalControl ?? undefined,
4340
+ finalStatus: finalControl?.status,
4341
+ issues,
4342
+ ok: issues.length === 0,
4343
+ snapshots: controls.length,
4344
+ statuses
4345
+ };
4346
+ };
4347
+ var assertVoiceLiveOpsControlEvidence = (input = {}) => {
4348
+ const assertion = evaluateVoiceLiveOpsControlEvidence(input);
4349
+ if (!assertion.ok) {
4350
+ throw new Error(`Voice live-ops control evidence assertion failed: ${assertion.issues.join(" ")}`);
4351
+ }
4352
+ return assertion;
4353
+ };
4302
4354
  var createVoiceMemoryLiveOpsControlStore = () => {
4303
4355
  const states = new Map;
4304
4356
  return {
package/dist/index.d.ts CHANGED
@@ -18,8 +18,8 @@ export { assertVoicePlatformCoverage, buildVoicePlatformCoverageSummary, createV
18
18
  export type { VoicePlatformCoverageAssertionInput, VoicePlatformCoverageAssertionReport, VoicePlatformCoverageEvidence, VoicePlatformCoverageRoutesOptions, VoicePlatformCoverageStatus, VoicePlatformCoverageSummary, VoicePlatformCoverageSummaryInput, VoicePlatformCoverageSurface } from './platformCoverage';
19
19
  export { assertVoiceProofTrendEvidence, buildEmptyVoiceProofTrendReport, buildVoiceProofTrendReport, createVoiceProofTrendRoutes, DEFAULT_VOICE_PROOF_TRENDS_MAX_AGE_MS, evaluateVoiceProofTrendEvidence, formatVoiceProofTrendAge, normalizeVoiceProofTrendReport, readVoiceProofTrendReportFile } from './proofTrends';
20
20
  export type { VoiceProofTrendAssertionInput, VoiceProofTrendAssertionReport, VoiceProofTrendCycle, VoiceProofTrendReport, VoiceProofTrendReportInput, VoiceProofTrendRoutesOptions, VoiceProofTrendStatus, VoiceProofTrendSummary } from './proofTrends';
21
- export { assertVoiceLiveOpsEvidence, buildVoiceLiveOpsControlState, createVoiceLiveOpsController, createVoiceLiveOpsRoutes, createVoiceMemoryLiveOpsControlStore, evaluateVoiceLiveOpsEvidence, getVoiceLiveOpsControlStatus, VOICE_LIVE_OPS_ACTIONS } from './liveOps';
22
- export type { VoiceLiveOpsAction, VoiceLiveOpsActionInput, VoiceLiveOpsActionResult, VoiceLiveOpsControllerOptions, VoiceLiveOpsControlState, VoiceLiveOpsControlStatus, VoiceLiveOpsControlStore, VoiceLiveOpsEvidenceInput, VoiceLiveOpsEvidenceReport, VoiceLiveOpsRoutesOptions } from './liveOps';
21
+ export { assertVoiceLiveOpsControlEvidence, assertVoiceLiveOpsEvidence, buildVoiceLiveOpsControlState, createVoiceLiveOpsController, createVoiceLiveOpsRoutes, createVoiceMemoryLiveOpsControlStore, evaluateVoiceLiveOpsControlEvidence, evaluateVoiceLiveOpsEvidence, getVoiceLiveOpsControlStatus, VOICE_LIVE_OPS_ACTIONS } from './liveOps';
22
+ export type { VoiceLiveOpsAction, VoiceLiveOpsActionInput, VoiceLiveOpsActionResult, VoiceLiveOpsControllerOptions, VoiceLiveOpsControlState, VoiceLiveOpsControlStatus, VoiceLiveOpsControlStore, VoiceLiveOpsControlEvidenceInput, VoiceLiveOpsControlEvidenceReport, VoiceLiveOpsEvidenceInput, VoiceLiveOpsEvidenceReport, VoiceLiveOpsRoutesOptions } from './liveOps';
23
23
  export { buildVoiceDeliveryRuntimeReport, createVoiceDeliveryRuntime, createVoiceDeliveryRuntimePresetConfig, createVoiceDeliveryRuntimeRoutes, renderVoiceDeliveryRuntimeHTML } from './deliveryRuntime';
24
24
  export { applyVoiceDataRetentionPolicy, assertVoiceDataControlEvidence, buildVoiceDataControlReport, buildVoiceDataRetentionPlan, createVoiceDataControlRoutes, createVoiceZeroRetentionPolicy, evaluateVoiceDataControlEvidence, renderVoiceDataControlHTML, renderVoiceDataControlMarkdown, voiceComplianceRedactionDefaults } from './dataControl';
25
25
  export type { VoiceDataControlAssertionInput, VoiceDataControlAssertionReport, VoiceDataControlProviderKeySurface, VoiceDataControlReport, VoiceDataControlRoutesOptions, VoiceDataControlStorageSurface, VoiceDataRetentionPolicy, VoiceDataRetentionReport, VoiceDataRetentionScope, VoiceDataRetentionScopeReport, VoiceDataRetentionStores } from './dataControl';
@@ -41,7 +41,7 @@ export { assertVoiceLatencySLOGate, buildVoiceLatencySLOGate, renderVoiceLatency
41
41
  export { createVoiceTurnQualityHTMLHandler, createVoiceTurnQualityJSONHandler, createVoiceTurnQualityRoutes, renderVoiceTurnQualityHTML, summarizeVoiceTurnQuality } from './turnQuality';
42
42
  export { assertVoiceOutcomeContractEvidence, createVoiceOutcomeContractHTMLHandler, createVoiceOutcomeContractJSONHandler, createVoiceOutcomeContractRoutes, evaluateVoiceOutcomeContractEvidence, renderVoiceOutcomeContractHTML, runVoiceOutcomeContractSuite } from './outcomeContract';
43
43
  export { applyVoiceTelephonyOutcome, createMemoryVoiceTelephonyWebhookIdempotencyStore, createVoiceTelephonyOutcomePolicy, createVoiceTelephonyWebhookHandler, createVoiceTelephonyWebhookRoutes, parseVoiceTelephonyWebhookEvent, resolveVoiceTelephonyOutcome, signVoiceTwilioWebhook, verifyVoiceTwilioWebhookSignature, voiceTelephonyOutcomeToRouteResult } from './telephonyOutcome';
44
- export { assertVoicePhoneAssistantEvidence, createVoicePhoneAgent, evaluateVoicePhoneAssistantEvidence } from './phoneAgent';
44
+ export { assertVoicePhoneCallControlEvidence, assertVoicePhoneAssistantEvidence, createVoicePhoneAgent, evaluateVoicePhoneCallControlEvidence, evaluateVoicePhoneAssistantEvidence } from './phoneAgent';
45
45
  export { createStoredVoiceCallReviewArtifact, createStoredVoiceExternalObjectMap, createStoredVoiceIntegrationEvent, createStoredVoiceOpsTask, createVoiceFileIncidentBundleStore, createVoiceFileExternalObjectMapStore, createVoiceFileAssistantMemoryStore, createVoiceFileAuditEventStore, createVoiceFileAuditSinkDeliveryStore, createVoiceFileCampaignStore, createVoiceFileIntegrationEventStore, createVoiceFileReviewStore, createVoiceFileRuntimeStorage, createVoiceFileSessionStore, createVoiceFileTaskStore, createVoiceFileTraceSinkDeliveryStore, createVoiceFileTraceEventStore } from './fileStore';
46
46
  export { createVoiceAssistantMemoryHandle, createVoiceAssistantMemoryRecord, createVoiceMemoryAssistantMemoryStore, resolveVoiceAssistantMemoryNamespace } from './assistantMemory';
47
47
  export { createAnthropicVoiceAssistantModel, createGeminiVoiceAssistantModel, createJSONVoiceAssistantModel, createOpenAIVoiceAssistantModel, resolveVoiceProviderRoutingPolicyPreset, createVoiceProviderRouter } from './modelAdapters';
@@ -116,7 +116,7 @@ export type { VoiceLatencySLOBudget, VoiceLatencySLOGateError, VoiceLatencySLOGa
116
116
  export type { VoiceTurnQualityHTMLHandlerOptions, VoiceTurnQualityItem, VoiceTurnQualityOptions, VoiceTurnQualityReport, VoiceTurnQualityRoutesOptions, VoiceTurnQualityStatus } from './turnQuality';
117
117
  export type { VoiceOutcomeContractAssertionInput, VoiceOutcomeContractAssertionReport, VoiceOutcomeContractDefinition, VoiceOutcomeContractHTMLHandlerOptions, VoiceOutcomeContractIssue, VoiceOutcomeContractOptions, VoiceOutcomeContractReport, VoiceOutcomeContractRoutesOptions, VoiceOutcomeContractStatus, VoiceOutcomeContractSuiteReport } from './outcomeContract';
118
118
  export type { VoiceTelephonyOutcomeAction, VoiceTelephonyOutcomeDecision, VoiceTelephonyOutcomePolicy, VoiceTelephonyOutcomeProviderEvent, VoiceTelephonyOutcomeRouteResult, VoiceTelephonyOutcomeStatusDecision, VoiceTelephonyWebhookDecision, VoiceTelephonyWebhookHandlerOptions, VoiceTelephonyWebhookIdempotencyStore, VoiceTelephonyWebhookParseInput, VoiceTelephonyWebhookProvider, VoiceTelephonyWebhookRoutesOptions, VoiceTelephonyWebhookVerificationResult, StoredVoiceTelephonyWebhookDecision } from './telephonyOutcome';
119
- export type { VoicePhoneAgentCarrier, VoicePhoneAgentCarrierSummary, VoicePhoneAssistantEvidenceInput, VoicePhoneAssistantEvidenceReport, VoicePhoneAgentLifecycleStage, VoicePhoneAgentPlivoCarrier, VoicePhoneAgentRoutes, VoicePhoneAgentRoutesOptions, VoicePhoneAgentSetupReport, VoicePhoneAgentTelnyxCarrier, VoicePhoneAgentTwilioCarrier } from './phoneAgent';
119
+ export type { VoicePhoneAgentCarrier, VoicePhoneAgentCarrierSummary, VoicePhoneAssistantEvidenceInput, VoicePhoneAssistantEvidenceReport, VoicePhoneCallControlEvidenceInput, VoicePhoneCallControlEvidenceReport, VoicePhoneAgentLifecycleStage, VoicePhoneAgentPlivoCarrier, VoicePhoneAgentRoutes, VoicePhoneAgentRoutesOptions, VoicePhoneAgentSetupReport, VoicePhoneAgentTelnyxCarrier, VoicePhoneAgentTwilioCarrier } from './phoneAgent';
120
120
  export type { VoicePhoneAgentProductionSmokeIssue, VoicePhoneAgentProductionSmokeHandlerOptions, VoicePhoneAgentProductionSmokeHTMLHandlerOptions, VoicePhoneAgentProductionSmokeOptions, VoicePhoneAgentProductionSmokeReport, VoicePhoneAgentProductionSmokeRoutesOptions, VoicePhoneAgentProductionSmokeRequirement } from './phoneAgentProductionSmoke';
121
121
  export type { VoiceOpsConsoleLink, VoiceOpsConsoleReport, VoiceOpsConsoleRoutesOptions } from './opsConsoleRoutes';
122
122
  export type { VoiceOpsStatus, VoiceOpsStatusLink, VoiceOpsStatusOptions, VoiceOpsStatusReport, VoiceOpsStatusRoutesOptions } from './opsStatus';
package/dist/index.js CHANGED
@@ -12729,6 +12729,58 @@ var assertVoiceLiveOpsEvidence = (input = {}) => {
12729
12729
  }
12730
12730
  return assertion;
12731
12731
  };
12732
+ var evaluateVoiceLiveOpsControlEvidence = (input = {}) => {
12733
+ const issues = [];
12734
+ const results = input.results ?? [];
12735
+ const controls = results.map((result) => result.control).filter((control) => Boolean(control));
12736
+ const finalControl = input.finalControl ?? controls.at(-1);
12737
+ const actions = uniqueSorted(results.map((result) => result.action).filter((action) => isVoiceLiveOpsAction(action)));
12738
+ const statuses = uniqueSorted(controls.map((control) => control.status));
12739
+ const failedActions = results.filter((result) => result.ok === false).length;
12740
+ if (results.length === 0) {
12741
+ issues.push("Expected live-ops control action result(s) to be present.");
12742
+ }
12743
+ if (input.minSnapshots !== undefined && controls.length < input.minSnapshots) {
12744
+ issues.push(`Expected at least ${String(input.minSnapshots)} live-ops control snapshot(s), found ${String(controls.length)}.`);
12745
+ }
12746
+ if (input.maxFailedActions !== undefined && failedActions > input.maxFailedActions) {
12747
+ issues.push(`Expected at most ${String(input.maxFailedActions)} failed live-ops control action(s), found ${String(failedActions)}.`);
12748
+ }
12749
+ for (const action of findMissing(actions, input.requiredActions)) {
12750
+ issues.push(`Missing live-ops control action: ${action}.`);
12751
+ }
12752
+ for (const status of findMissing(statuses, input.requiredStatuses)) {
12753
+ issues.push(`Missing live-ops control status: ${status}.`);
12754
+ }
12755
+ if (!finalControl) {
12756
+ issues.push("Expected final live-ops control state to be present.");
12757
+ } else {
12758
+ if (input.requireFinalAssistantPaused !== undefined && finalControl.assistantPaused !== input.requireFinalAssistantPaused) {
12759
+ issues.push(`Expected final live-ops assistantPaused ${String(input.requireFinalAssistantPaused)}, found ${String(finalControl.assistantPaused)}.`);
12760
+ }
12761
+ if (input.requireFinalOperatorTakeover !== undefined && finalControl.operatorTakeover !== input.requireFinalOperatorTakeover) {
12762
+ issues.push(`Expected final live-ops operatorTakeover ${String(input.requireFinalOperatorTakeover)}, found ${String(finalControl.operatorTakeover)}.`);
12763
+ }
12764
+ }
12765
+ return {
12766
+ actionCount: results.length,
12767
+ actions,
12768
+ failedActions,
12769
+ finalControl: finalControl ?? undefined,
12770
+ finalStatus: finalControl?.status,
12771
+ issues,
12772
+ ok: issues.length === 0,
12773
+ snapshots: controls.length,
12774
+ statuses
12775
+ };
12776
+ };
12777
+ var assertVoiceLiveOpsControlEvidence = (input = {}) => {
12778
+ const assertion = evaluateVoiceLiveOpsControlEvidence(input);
12779
+ if (!assertion.ok) {
12780
+ throw new Error(`Voice live-ops control evidence assertion failed: ${assertion.issues.join(" ")}`);
12781
+ }
12782
+ return assertion;
12783
+ };
12732
12784
  var createVoiceMemoryLiveOpsControlStore = () => {
12733
12785
  const states = new Map;
12734
12786
  return {
@@ -20061,6 +20113,56 @@ var assertVoicePhoneAssistantEvidence = (report, input = {}) => {
20061
20113
  }
20062
20114
  return assertion;
20063
20115
  };
20116
+ var evaluateVoicePhoneCallControlEvidence = (input = {}) => {
20117
+ const issues = [];
20118
+ const setup = input.setup;
20119
+ const productionSmokes = input.productionSmokes ?? [];
20120
+ const lifecycleStages = uniqueSorted3(setup?.lifecycleStages ?? []);
20121
+ const providers = uniqueSorted3(productionSmokes.map((report) => report.provider).filter((provider) => Boolean(provider)));
20122
+ const outcomes = uniqueSorted3(productionSmokes.flatMap((report) => report.observed.lifecycleOutcomes));
20123
+ const failedSmokeReports = productionSmokes.filter((report) => !report.pass).length;
20124
+ const passingSmokeReports = productionSmokes.length - failedSmokeReports;
20125
+ if (productionSmokes.length === 0) {
20126
+ issues.push("Expected phone call-control smoke report(s) to be present.");
20127
+ }
20128
+ if (input.requireSetupLifecycleStages ?? true) {
20129
+ if (!setup) {
20130
+ issues.push("Expected phone setup report to be present.");
20131
+ }
20132
+ for (const stage of findMissing3(lifecycleStages, input.requiredLifecycleStages)) {
20133
+ issues.push(`Missing phone call-control lifecycle stage: ${stage}.`);
20134
+ }
20135
+ }
20136
+ if (input.minPassingSmokeReports !== undefined && passingSmokeReports < input.minPassingSmokeReports) {
20137
+ issues.push(`Expected at least ${String(input.minPassingSmokeReports)} passing phone call-control smoke report(s), found ${String(passingSmokeReports)}.`);
20138
+ }
20139
+ if (input.maxFailedSmokeReports !== undefined && failedSmokeReports > input.maxFailedSmokeReports) {
20140
+ issues.push(`Expected at most ${String(input.maxFailedSmokeReports)} failing phone call-control smoke report(s), found ${String(failedSmokeReports)}.`);
20141
+ }
20142
+ for (const provider of findMissing3(providers, input.requiredProviders)) {
20143
+ issues.push(`Missing phone call-control provider: ${provider}.`);
20144
+ }
20145
+ for (const outcome of findMissing3(outcomes, input.requiredOutcomes)) {
20146
+ issues.push(`Missing phone call-control outcome: ${outcome}.`);
20147
+ }
20148
+ return {
20149
+ failedSmokeReports,
20150
+ issues,
20151
+ lifecycleStages,
20152
+ ok: issues.length === 0,
20153
+ outcomes,
20154
+ passingSmokeReports,
20155
+ providers,
20156
+ smokeReports: productionSmokes.length
20157
+ };
20158
+ };
20159
+ var assertVoicePhoneCallControlEvidence = (input = {}) => {
20160
+ const assertion = evaluateVoicePhoneCallControlEvidence(input);
20161
+ if (!assertion.ok) {
20162
+ throw new Error(`Voice phone call-control evidence assertion failed: ${assertion.issues.join(" ")}`);
20163
+ }
20164
+ return assertion;
20165
+ };
20064
20166
  var buildVoicePhoneAgentSetupInstructions = (input) => input.carriers.map((carrier) => {
20065
20167
  const entry = findCarrierMatrixEntry(input.matrix, carrier);
20066
20168
  const urls = entry?.setup.urls;
@@ -31328,12 +31430,14 @@ export {
31328
31430
  evaluateVoiceProofTrendEvidence,
31329
31431
  evaluateVoiceProductionReadinessEvidence,
31330
31432
  evaluateVoicePlatformCoverage,
31433
+ evaluateVoicePhoneCallControlEvidence,
31331
31434
  evaluateVoicePhoneAssistantEvidence,
31332
31435
  evaluateVoiceOutcomeContractEvidence,
31333
31436
  evaluateVoiceOperationsRecordGuardrails,
31334
31437
  evaluateVoiceObservabilityExportReplayEvidence,
31335
31438
  evaluateVoiceObservabilityExportDeliveryEvidence,
31336
31439
  evaluateVoiceLiveOpsEvidence,
31440
+ evaluateVoiceLiveOpsControlEvidence,
31337
31441
  evaluateVoiceGuardrailPolicy,
31338
31442
  evaluateVoiceDataControlEvidence,
31339
31443
  evaluateVoiceCampaignReadinessEvidence,
@@ -31660,6 +31764,7 @@ export {
31660
31764
  assertVoiceProofTrendEvidence,
31661
31765
  assertVoiceProductionReadinessEvidence,
31662
31766
  assertVoicePlatformCoverage,
31767
+ assertVoicePhoneCallControlEvidence,
31663
31768
  assertVoicePhoneAssistantEvidence,
31664
31769
  assertVoiceOutcomeContractEvidence,
31665
31770
  assertVoiceOperationsRecordGuardrails,
@@ -31668,6 +31773,7 @@ export {
31668
31773
  assertVoiceObservabilityExportRecord,
31669
31774
  assertVoiceObservabilityExportDeliveryEvidence,
31670
31775
  assertVoiceLiveOpsEvidence,
31776
+ assertVoiceLiveOpsControlEvidence,
31671
31777
  assertVoiceLatencySLOGate,
31672
31778
  assertVoiceDataControlEvidence,
31673
31779
  assertVoiceCampaignReadinessEvidence,
package/dist/liveOps.d.ts CHANGED
@@ -69,6 +69,29 @@ export type VoiceLiveOpsEvidenceReport = {
69
69
  opsRecoveryStatus?: VoiceOpsRecoveryStatus;
70
70
  opsStatus?: VoiceOpsStatusReport['status'];
71
71
  };
72
+ export type VoiceLiveOpsControlEvidenceInput = {
73
+ finalControl?: VoiceLiveOpsControlState | null;
74
+ maxFailedActions?: number;
75
+ minSnapshots?: number;
76
+ requireFinalAssistantPaused?: boolean;
77
+ requireFinalOperatorTakeover?: boolean;
78
+ requiredActions?: VoiceLiveOpsAction[];
79
+ requiredStatuses?: VoiceLiveOpsControlStatus[];
80
+ results?: Array<Partial<Omit<VoiceLiveOpsActionResult, 'ok'>> & {
81
+ ok?: boolean;
82
+ }>;
83
+ };
84
+ export type VoiceLiveOpsControlEvidenceReport = {
85
+ actionCount: number;
86
+ actions: VoiceLiveOpsAction[];
87
+ failedActions: number;
88
+ finalControl?: VoiceLiveOpsControlState;
89
+ finalStatus?: VoiceLiveOpsControlStatus;
90
+ issues: string[];
91
+ ok: boolean;
92
+ snapshots: number;
93
+ statuses: VoiceLiveOpsControlStatus[];
94
+ };
72
95
  export type VoiceLiveOpsControlStore = {
73
96
  get: (sessionId: string) => Promise<VoiceLiveOpsControlState | undefined> | VoiceLiveOpsControlState | undefined;
74
97
  set: (sessionId: string, state: VoiceLiveOpsControlState) => Promise<void> | void;
@@ -93,6 +116,8 @@ export type VoiceLiveOpsRoutesOptions = VoiceLiveOpsControllerOptions & {
93
116
  };
94
117
  export declare const evaluateVoiceLiveOpsEvidence: (input?: VoiceLiveOpsEvidenceInput) => VoiceLiveOpsEvidenceReport;
95
118
  export declare const assertVoiceLiveOpsEvidence: (input?: VoiceLiveOpsEvidenceInput) => VoiceLiveOpsEvidenceReport;
119
+ export declare const evaluateVoiceLiveOpsControlEvidence: (input?: VoiceLiveOpsControlEvidenceInput) => VoiceLiveOpsControlEvidenceReport;
120
+ export declare const assertVoiceLiveOpsControlEvidence: (input?: VoiceLiveOpsControlEvidenceInput) => VoiceLiveOpsControlEvidenceReport;
96
121
  export declare const createVoiceMemoryLiveOpsControlStore: () => VoiceLiveOpsControlStore;
97
122
  export declare const getVoiceLiveOpsControlStatus: (action: VoiceLiveOpsAction) => VoiceLiveOpsControlStatus;
98
123
  export declare const buildVoiceLiveOpsControlState: (input: VoiceLiveOpsActionInput & {
@@ -6,6 +6,7 @@ import { type VoiceTelephonyCarrierMatrix, type VoiceTelephonyCarrierMatrixRoute
6
6
  import { type VoicePhoneAgentProductionSmokeRoutesOptions } from './phoneAgentProductionSmoke';
7
7
  import { type VoiceCampaignDialerProofAssertionReport, type VoiceCampaignDialerProofProvider, type VoiceCampaignDialerProofReport } from './campaignDialers';
8
8
  import type { VoiceTelephonyProvider } from './telephony/contract';
9
+ import type { VoicePhoneAgentProductionSmokeReport } from './phoneAgentProductionSmoke';
9
10
  import type { VoiceSessionRecord } from './types';
10
11
  export type VoicePhoneAgentLifecycleStage = 'ringing' | 'answered' | 'media-started' | 'transcript' | 'assistant-response' | 'transfer' | 'voicemail' | 'no-answer' | 'completed' | 'failed';
11
12
  type VoicePhoneAgentCarrierBase = {
@@ -110,7 +111,29 @@ export type VoicePhoneAssistantEvidenceReport = {
110
111
  setupPath?: string;
111
112
  smokePassing: number;
112
113
  };
114
+ export type VoicePhoneCallControlEvidenceInput = {
115
+ maxFailedSmokeReports?: number;
116
+ minPassingSmokeReports?: number;
117
+ productionSmokes?: VoicePhoneAgentProductionSmokeReport[];
118
+ requiredLifecycleStages?: VoicePhoneAgentLifecycleStage[];
119
+ requiredOutcomes?: string[];
120
+ requiredProviders?: VoiceTelephonyProvider[];
121
+ requireSetupLifecycleStages?: boolean;
122
+ setup?: VoicePhoneAgentSetupReport;
123
+ };
124
+ export type VoicePhoneCallControlEvidenceReport = {
125
+ failedSmokeReports: number;
126
+ issues: string[];
127
+ lifecycleStages: VoicePhoneAgentLifecycleStage[];
128
+ ok: boolean;
129
+ outcomes: string[];
130
+ passingSmokeReports: number;
131
+ providers: VoiceTelephonyProvider[];
132
+ smokeReports: number;
133
+ };
113
134
  export declare const evaluateVoicePhoneAssistantEvidence: (report: VoicePhoneAgentSetupReport, input?: VoicePhoneAssistantEvidenceInput) => VoicePhoneAssistantEvidenceReport;
114
135
  export declare const assertVoicePhoneAssistantEvidence: (report: VoicePhoneAgentSetupReport, input?: VoicePhoneAssistantEvidenceInput) => VoicePhoneAssistantEvidenceReport;
136
+ export declare const evaluateVoicePhoneCallControlEvidence: (input?: VoicePhoneCallControlEvidenceInput) => VoicePhoneCallControlEvidenceReport;
137
+ export declare const assertVoicePhoneCallControlEvidence: (input?: VoicePhoneCallControlEvidenceInput) => VoicePhoneCallControlEvidenceReport;
115
138
  export declare const createVoicePhoneAgent: <TContext = unknown, TSession extends VoiceSessionRecord = VoiceSessionRecord, TResult = unknown>(options: VoicePhoneAgentRoutesOptions<TContext, TSession, TResult>) => VoicePhoneAgentRoutes;
116
139
  export {};
@@ -1837,6 +1837,58 @@ var assertVoiceLiveOpsEvidence = (input = {}) => {
1837
1837
  }
1838
1838
  return assertion;
1839
1839
  };
1840
+ var evaluateVoiceLiveOpsControlEvidence = (input = {}) => {
1841
+ const issues = [];
1842
+ const results = input.results ?? [];
1843
+ const controls = results.map((result) => result.control).filter((control) => Boolean(control));
1844
+ const finalControl = input.finalControl ?? controls.at(-1);
1845
+ const actions = uniqueSorted(results.map((result) => result.action).filter((action) => isVoiceLiveOpsAction(action)));
1846
+ const statuses = uniqueSorted(controls.map((control) => control.status));
1847
+ const failedActions = results.filter((result) => result.ok === false).length;
1848
+ if (results.length === 0) {
1849
+ issues.push("Expected live-ops control action result(s) to be present.");
1850
+ }
1851
+ if (input.minSnapshots !== undefined && controls.length < input.minSnapshots) {
1852
+ issues.push(`Expected at least ${String(input.minSnapshots)} live-ops control snapshot(s), found ${String(controls.length)}.`);
1853
+ }
1854
+ if (input.maxFailedActions !== undefined && failedActions > input.maxFailedActions) {
1855
+ issues.push(`Expected at most ${String(input.maxFailedActions)} failed live-ops control action(s), found ${String(failedActions)}.`);
1856
+ }
1857
+ for (const action of findMissing(actions, input.requiredActions)) {
1858
+ issues.push(`Missing live-ops control action: ${action}.`);
1859
+ }
1860
+ for (const status of findMissing(statuses, input.requiredStatuses)) {
1861
+ issues.push(`Missing live-ops control status: ${status}.`);
1862
+ }
1863
+ if (!finalControl) {
1864
+ issues.push("Expected final live-ops control state to be present.");
1865
+ } else {
1866
+ if (input.requireFinalAssistantPaused !== undefined && finalControl.assistantPaused !== input.requireFinalAssistantPaused) {
1867
+ issues.push(`Expected final live-ops assistantPaused ${String(input.requireFinalAssistantPaused)}, found ${String(finalControl.assistantPaused)}.`);
1868
+ }
1869
+ if (input.requireFinalOperatorTakeover !== undefined && finalControl.operatorTakeover !== input.requireFinalOperatorTakeover) {
1870
+ issues.push(`Expected final live-ops operatorTakeover ${String(input.requireFinalOperatorTakeover)}, found ${String(finalControl.operatorTakeover)}.`);
1871
+ }
1872
+ }
1873
+ return {
1874
+ actionCount: results.length,
1875
+ actions,
1876
+ failedActions,
1877
+ finalControl: finalControl ?? undefined,
1878
+ finalStatus: finalControl?.status,
1879
+ issues,
1880
+ ok: issues.length === 0,
1881
+ snapshots: controls.length,
1882
+ statuses
1883
+ };
1884
+ };
1885
+ var assertVoiceLiveOpsControlEvidence = (input = {}) => {
1886
+ const assertion = evaluateVoiceLiveOpsControlEvidence(input);
1887
+ if (!assertion.ok) {
1888
+ throw new Error(`Voice live-ops control evidence assertion failed: ${assertion.issues.join(" ")}`);
1889
+ }
1890
+ return assertion;
1891
+ };
1840
1892
  var createVoiceMemoryLiveOpsControlStore = () => {
1841
1893
  const states = new Map;
1842
1894
  return {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@absolutejs/voice",
3
- "version": "0.0.22-beta.262",
3
+ "version": "0.0.22-beta.264",
4
4
  "description": "Voice primitives and Elysia plugin for AbsoluteJS",
5
5
  "repository": {
6
6
  "type": "git",