@absolutejs/voice 0.0.22-beta.163 → 0.0.22-beta.165
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 +2 -0
- package/dist/index.js +144 -0
- package/dist/productionReadiness.d.ts +6 -0
- package/dist/providerStackRecommendations.d.ts +39 -0
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -46,6 +46,7 @@ export { assertVoiceProviderRoutingContract, runVoiceProviderRoutingContract } f
|
|
|
46
46
|
export { createVoicePhoneAgentProductionSmokeHTMLHandler, createVoicePhoneAgentProductionSmokeJSONHandler, createVoicePhoneAgentProductionSmokeRoutes, renderVoicePhoneAgentProductionSmokeHTML, runVoicePhoneAgentProductionSmokeContract } from './phoneAgentProductionSmoke';
|
|
47
47
|
export { buildVoiceProductionReadinessGate, buildVoiceProductionReadinessReport, createVoiceProductionReadinessRoutes, renderVoiceProductionReadinessHTML, summarizeVoiceProductionReadinessGate } from './productionReadiness';
|
|
48
48
|
export { createVoiceReadinessProfile, recommendVoiceReadinessProfile } from './readinessProfiles';
|
|
49
|
+
export { evaluateVoiceProviderStackGaps, recommendVoiceProviderStack } from './providerStackRecommendations';
|
|
49
50
|
export { buildVoiceOpsConsoleReport, createVoiceOpsConsoleRoutes, renderVoiceOpsConsoleHTML } from './opsConsoleRoutes';
|
|
50
51
|
export { summarizeVoiceOpsStatus } from './opsStatus';
|
|
51
52
|
export { createVoiceOpsStatusRoutes, renderVoiceOpsStatusHTML } from './opsStatusRoutes';
|
|
@@ -105,6 +106,7 @@ export type { VoiceOpsConsoleLink, VoiceOpsConsoleReport, VoiceOpsConsoleRoutesO
|
|
|
105
106
|
export type { VoiceOpsStatus, VoiceOpsStatusLink, VoiceOpsStatusOptions, VoiceOpsStatusReport, VoiceOpsStatusRoutesOptions } from './opsStatus';
|
|
106
107
|
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
108
|
export type { VoiceReadinessProfileName, VoiceReadinessProfileOptions, VoiceReadinessProfileRecommendation, VoiceReadinessProfileRecommendationScore, VoiceReadinessProfileRoutesOptions } from './readinessProfiles';
|
|
109
|
+
export type { VoiceProviderStackChoice, VoiceProviderStackCapabilities, VoiceProviderStackCapabilityGap, VoiceProviderStackCapabilityGapInput, VoiceProviderStackCapabilityGapReport, VoiceProviderStackInput, VoiceProviderStackKind, VoiceProviderStackRecommendation } from './providerStackRecommendations';
|
|
108
110
|
export type { VoiceQualityLink, VoiceQualityMetric, VoiceQualityReport, VoiceQualityRoutesOptions, VoiceQualityStatus, VoiceQualityThresholds } from './qualityRoutes';
|
|
109
111
|
export type { VoiceResilienceIOSimulator, VoiceResilienceLink, VoiceResiliencePageData, VoiceResilienceRoutesOptions, VoiceResilienceSimulationProvider, VoiceRoutingKindSummary, VoiceRoutingDecisionSummary, VoiceRoutingDecisionSummaryOptions, VoiceRoutingEvent, VoiceRoutingEventKind, VoiceRoutingSessionSummary, VoiceRoutingSessionSummaryOptions } from './resilienceRoutes';
|
|
110
112
|
export type { VoiceIOProviderRouterEvent, VoiceIOProviderRouterOptions, VoiceIOProviderRouterPolicy, VoiceIOProviderRouterPolicyConfig, VoiceSTTProviderRouterOptions, VoiceTTSProviderRouterOptions } from './providerAdapters';
|
package/dist/index.js
CHANGED
|
@@ -20142,6 +20142,7 @@ var readinessGateCodes = {
|
|
|
20142
20142
|
"Provider fallback recovery": "voice.readiness.provider_fallback_recovery",
|
|
20143
20143
|
"Provider health": "voice.readiness.provider_health",
|
|
20144
20144
|
"Provider routing contracts": "voice.readiness.provider_routing_contracts",
|
|
20145
|
+
"Provider stack capabilities": "voice.readiness.provider_stack_capabilities",
|
|
20145
20146
|
"Quality gates": "voice.readiness.quality_gates",
|
|
20146
20147
|
"Reconnect recovery contracts": "voice.readiness.reconnect_contracts",
|
|
20147
20148
|
"Routing evidence": "voice.readiness.routing_evidence",
|
|
@@ -20213,6 +20214,12 @@ var resolveProviderRoutingContracts = async (options, input) => {
|
|
|
20213
20214
|
}
|
|
20214
20215
|
return typeof options.providerRoutingContracts === "function" ? await options.providerRoutingContracts(input) : options.providerRoutingContracts;
|
|
20215
20216
|
};
|
|
20217
|
+
var resolveProviderStack = async (options, input) => {
|
|
20218
|
+
if (options.providerStack === false || options.providerStack === undefined) {
|
|
20219
|
+
return;
|
|
20220
|
+
}
|
|
20221
|
+
return typeof options.providerStack === "function" ? await options.providerStack(input) : options.providerStack;
|
|
20222
|
+
};
|
|
20216
20223
|
var resolvePhoneAgentSmokes = async (options, input) => {
|
|
20217
20224
|
if (options.phoneAgentSmokes === false || options.phoneAgentSmokes === undefined) {
|
|
20218
20225
|
return;
|
|
@@ -20472,6 +20479,7 @@ var buildVoiceProductionReadinessReport = async (options, input = {}) => {
|
|
|
20472
20479
|
carriers,
|
|
20473
20480
|
agentSquadContracts,
|
|
20474
20481
|
providerRoutingContracts,
|
|
20482
|
+
providerStack,
|
|
20475
20483
|
phoneAgentSmokes,
|
|
20476
20484
|
reconnectContracts,
|
|
20477
20485
|
bargeInReports,
|
|
@@ -20502,6 +20510,7 @@ var buildVoiceProductionReadinessReport = async (options, input = {}) => {
|
|
|
20502
20510
|
resolveCarriers(options, { query, request }),
|
|
20503
20511
|
resolveAgentSquadContracts(options, { query, request }),
|
|
20504
20512
|
resolveProviderRoutingContracts(options, { query, request }),
|
|
20513
|
+
resolveProviderStack(options, { query, request }),
|
|
20505
20514
|
resolvePhoneAgentSmokes(options, { query, request }),
|
|
20506
20515
|
resolveReconnectContracts(options, { query, request }),
|
|
20507
20516
|
resolveBargeInReports(options, { query, request }),
|
|
@@ -20695,6 +20704,23 @@ var buildVoiceProductionReadinessReport = async (options, input = {}) => {
|
|
|
20695
20704
|
]
|
|
20696
20705
|
});
|
|
20697
20706
|
}
|
|
20707
|
+
if (providerStack) {
|
|
20708
|
+
const missingLanes = providerStack.gaps.filter((gap) => gap.status !== "pass");
|
|
20709
|
+
checks.push({
|
|
20710
|
+
detail: providerStack.status === "pass" ? `${providerStack.profile} provider stack has declared capability coverage.` : missingLanes.length > 0 ? missingLanes.map((gap) => gap.provider ? `${gap.kind.toUpperCase()} ${gap.provider} missing ${gap.missing.join(", ")}` : `${gap.kind.toUpperCase()} provider is not configured`).join("; ") + "." : "Provider stack capability coverage needs review.",
|
|
20711
|
+
href: options.links?.providerRoutingContracts ?? options.links?.resilience ?? "/resilience",
|
|
20712
|
+
label: "Provider stack capabilities",
|
|
20713
|
+
status: providerStack.status,
|
|
20714
|
+
value: providerStack.status === "pass" ? "covered" : `${providerStack.missing} missing`,
|
|
20715
|
+
actions: providerStack.status === "pass" ? [] : [
|
|
20716
|
+
{
|
|
20717
|
+
description: "Open provider capabilities and confirm the selected stack covers this readiness profile.",
|
|
20718
|
+
href: options.links?.providerRoutingContracts ?? options.links?.resilience ?? "/resilience",
|
|
20719
|
+
label: "Open provider capabilities"
|
|
20720
|
+
}
|
|
20721
|
+
]
|
|
20722
|
+
});
|
|
20723
|
+
}
|
|
20698
20724
|
if (phoneAgentSmokeSummary) {
|
|
20699
20725
|
checks.push({
|
|
20700
20726
|
detail: phoneAgentSmokeSummary.status === "pass" ? `${phoneAgentSmokeSummary.passed} phone-agent smoke contract(s) are passing.` : phoneAgentSmokeSummary.total === 0 ? "No phone-agent production smoke contracts are configured." : `${phoneAgentSmokeSummary.failed} phone-agent production smoke contract(s) failed.`,
|
|
@@ -20889,6 +20915,7 @@ var buildVoiceProductionReadinessReport = async (options, input = {}) => {
|
|
|
20889
20915
|
degraded: degradedProviders,
|
|
20890
20916
|
total: providers.length
|
|
20891
20917
|
},
|
|
20918
|
+
providerStack,
|
|
20892
20919
|
providerRecovery,
|
|
20893
20920
|
phoneAgentSmokes: phoneAgentSmokeSummary,
|
|
20894
20921
|
providerRoutingContracts: providerRoutingContractSummary,
|
|
@@ -21284,6 +21311,121 @@ var recommendVoiceReadinessProfile = (options) => {
|
|
|
21284
21311
|
scores
|
|
21285
21312
|
};
|
|
21286
21313
|
};
|
|
21314
|
+
// src/providerStackRecommendations.ts
|
|
21315
|
+
var profileProviderPriorities = {
|
|
21316
|
+
"meeting-recorder": {
|
|
21317
|
+
llm: ["openai", "anthropic", "gemini"],
|
|
21318
|
+
stt: ["deepgram", "assemblyai", "openai"],
|
|
21319
|
+
tts: ["openai", "elevenlabs"]
|
|
21320
|
+
},
|
|
21321
|
+
"ops-heavy": {
|
|
21322
|
+
llm: ["anthropic", "openai", "gemini"],
|
|
21323
|
+
stt: ["deepgram", "assemblyai", "openai"],
|
|
21324
|
+
tts: ["openai", "elevenlabs"]
|
|
21325
|
+
},
|
|
21326
|
+
"phone-agent": {
|
|
21327
|
+
llm: ["openai", "anthropic", "gemini"],
|
|
21328
|
+
stt: ["deepgram", "assemblyai", "openai"],
|
|
21329
|
+
tts: ["openai", "elevenlabs"]
|
|
21330
|
+
}
|
|
21331
|
+
};
|
|
21332
|
+
var profileProviderReasons = {
|
|
21333
|
+
"meeting-recorder": {
|
|
21334
|
+
llm: "meeting-recorder favors strong summarization and extraction quality",
|
|
21335
|
+
stt: "meeting-recorder favors accurate long-form transcription",
|
|
21336
|
+
tts: "meeting-recorder usually needs optional, low-friction spoken playback"
|
|
21337
|
+
},
|
|
21338
|
+
"ops-heavy": {
|
|
21339
|
+
llm: "ops-heavy deployments favor dependable reasoning for review and escalation flows",
|
|
21340
|
+
stt: "ops-heavy deployments keep STT recommendation available for live proof surfaces",
|
|
21341
|
+
tts: "ops-heavy deployments keep TTS recommendation available for operator demos"
|
|
21342
|
+
},
|
|
21343
|
+
"phone-agent": {
|
|
21344
|
+
llm: "phone-agent favors low-latency turn handling and tool orchestration",
|
|
21345
|
+
stt: "phone-agent favors low-latency realtime transcription",
|
|
21346
|
+
tts: "phone-agent favors low-latency spoken response"
|
|
21347
|
+
}
|
|
21348
|
+
};
|
|
21349
|
+
var profileRequiredCapabilities = {
|
|
21350
|
+
"meeting-recorder": {
|
|
21351
|
+
llm: ["JSON result shaping", "summarization"],
|
|
21352
|
+
stt: ["realtime STT", "smart formatting"],
|
|
21353
|
+
tts: ["spoken playback"]
|
|
21354
|
+
},
|
|
21355
|
+
"ops-heavy": {
|
|
21356
|
+
llm: ["tool calling", "JSON result shaping", "fallback routing"],
|
|
21357
|
+
stt: ["realtime STT"],
|
|
21358
|
+
tts: ["spoken playback"]
|
|
21359
|
+
},
|
|
21360
|
+
"phone-agent": {
|
|
21361
|
+
llm: ["tool calling", "JSON result shaping", "fallback routing"],
|
|
21362
|
+
stt: ["realtime STT", "VAD events"],
|
|
21363
|
+
tts: ["streaming speech", "barge-in friendly"]
|
|
21364
|
+
}
|
|
21365
|
+
};
|
|
21366
|
+
var chooseProvider = (available, priorities) => priorities.find((provider) => available.includes(provider)) ?? available[0];
|
|
21367
|
+
var recommendVoiceProviderStack = (input) => {
|
|
21368
|
+
const priorities = profileProviderPriorities[input.profile];
|
|
21369
|
+
const stacks = {};
|
|
21370
|
+
const recommended = {};
|
|
21371
|
+
const reasons = [];
|
|
21372
|
+
for (const kind of ["llm", "stt", "tts"]) {
|
|
21373
|
+
const available = input.providers[kind] ?? [];
|
|
21374
|
+
const provider = chooseProvider(available, priorities[kind]);
|
|
21375
|
+
const alternatives = provider ? available.filter((candidate) => candidate !== provider) : [...available];
|
|
21376
|
+
const kindReasons = [
|
|
21377
|
+
profileProviderReasons[input.profile][kind],
|
|
21378
|
+
provider ? `${provider} is the recommended ${kind.toUpperCase()} provider from the configured set` : `no ${kind.toUpperCase()} providers are configured`
|
|
21379
|
+
];
|
|
21380
|
+
if (provider) {
|
|
21381
|
+
recommended[kind] = provider;
|
|
21382
|
+
}
|
|
21383
|
+
stacks[kind] = {
|
|
21384
|
+
alternatives,
|
|
21385
|
+
provider,
|
|
21386
|
+
reasons: kindReasons
|
|
21387
|
+
};
|
|
21388
|
+
reasons.push(...kindReasons);
|
|
21389
|
+
}
|
|
21390
|
+
return {
|
|
21391
|
+
profile: input.profile,
|
|
21392
|
+
reasons,
|
|
21393
|
+
recommended,
|
|
21394
|
+
stacks
|
|
21395
|
+
};
|
|
21396
|
+
};
|
|
21397
|
+
var normalizeCapability = (value) => value.toLowerCase().replace(/[^a-z0-9]+/g, "");
|
|
21398
|
+
var includesCapability = (capabilities, required) => {
|
|
21399
|
+
const normalizedRequired = normalizeCapability(required);
|
|
21400
|
+
return capabilities.some((capability) => {
|
|
21401
|
+
const normalizedCapability = normalizeCapability(capability);
|
|
21402
|
+
return normalizedCapability === normalizedRequired || normalizedCapability.includes(normalizedRequired) || normalizedRequired.includes(normalizedCapability);
|
|
21403
|
+
});
|
|
21404
|
+
};
|
|
21405
|
+
var evaluateVoiceProviderStackGaps = (input) => {
|
|
21406
|
+
const recommendation = input.recommendation ?? recommendVoiceProviderStack(input);
|
|
21407
|
+
const gaps = ["llm", "stt", "tts"].map((kind) => {
|
|
21408
|
+
const required = input.required?.[kind] ?? profileRequiredCapabilities[input.profile][kind];
|
|
21409
|
+
const provider = recommendation.recommended[kind];
|
|
21410
|
+
const present = provider ? [...input.capabilities?.[kind]?.[provider] ?? []] : [];
|
|
21411
|
+
const missing2 = provider ? required.filter((capability) => !includesCapability(present, capability)) : [...required];
|
|
21412
|
+
return {
|
|
21413
|
+
kind,
|
|
21414
|
+
missing: missing2,
|
|
21415
|
+
present,
|
|
21416
|
+
provider,
|
|
21417
|
+
required: [...required],
|
|
21418
|
+
status: !provider ? "fail" : missing2.length > 0 ? "warn" : "pass"
|
|
21419
|
+
};
|
|
21420
|
+
});
|
|
21421
|
+
const missing = gaps.reduce((total, gap) => total + gap.missing.length, 0);
|
|
21422
|
+
return {
|
|
21423
|
+
gaps,
|
|
21424
|
+
missing,
|
|
21425
|
+
profile: input.profile,
|
|
21426
|
+
status: gaps.some((gap) => gap.status === "fail") ? "fail" : gaps.some((gap) => gap.status === "warn") ? "warn" : "pass"
|
|
21427
|
+
};
|
|
21428
|
+
};
|
|
21287
21429
|
// src/opsConsoleRoutes.ts
|
|
21288
21430
|
import { Elysia as Elysia34 } from "elysia";
|
|
21289
21431
|
var DEFAULT_LINKS = [
|
|
@@ -24100,6 +24242,7 @@ export {
|
|
|
24100
24242
|
recordVoiceHandoffAuditEvent,
|
|
24101
24243
|
recordVoiceAuditEvent,
|
|
24102
24244
|
recommendVoiceReadinessProfile,
|
|
24245
|
+
recommendVoiceProviderStack,
|
|
24103
24246
|
pruneVoiceTraceEvents,
|
|
24104
24247
|
parseVoiceTelephonyWebhookEvent,
|
|
24105
24248
|
matchesVoiceOpsTaskAssignmentRule,
|
|
@@ -24118,6 +24261,7 @@ export {
|
|
|
24118
24261
|
evaluateVoiceTrace,
|
|
24119
24262
|
evaluateVoiceTelephonyContract,
|
|
24120
24263
|
evaluateVoiceQuality,
|
|
24264
|
+
evaluateVoiceProviderStackGaps,
|
|
24121
24265
|
encodeTwilioMulawBase64,
|
|
24122
24266
|
deliverVoiceTraceEventsToSinks,
|
|
24123
24267
|
deliverVoiceIntegrationEventToSinks,
|
|
@@ -11,6 +11,7 @@ import type { VoicePhoneAgentProductionSmokeReport } from './phoneAgentProductio
|
|
|
11
11
|
import type { VoiceReconnectContractReport } from './reconnectContract';
|
|
12
12
|
import type { VoiceAuditEventStore, VoiceAuditEventType, VoiceAuditOutcome } from './audit';
|
|
13
13
|
import { type VoiceAuditSinkDeliveryStore } from './auditSinks';
|
|
14
|
+
import type { VoiceProviderStackCapabilityGapReport } from './providerStackRecommendations';
|
|
14
15
|
export type VoiceProductionReadinessStatus = 'fail' | 'pass' | 'warn';
|
|
15
16
|
export type VoiceProductionReadinessAction = {
|
|
16
17
|
description?: string;
|
|
@@ -137,6 +138,7 @@ export type VoiceProductionReadinessReport = {
|
|
|
137
138
|
degraded: number;
|
|
138
139
|
total: number;
|
|
139
140
|
};
|
|
141
|
+
providerStack?: VoiceProviderStackCapabilityGapReport;
|
|
140
142
|
providerRecovery: VoiceProviderFallbackRecoverySummary;
|
|
141
143
|
phoneAgentSmokes?: {
|
|
142
144
|
failed: number;
|
|
@@ -297,6 +299,10 @@ export type VoiceProductionReadinessRoutesOptions = {
|
|
|
297
299
|
query: Record<string, unknown>;
|
|
298
300
|
request: Request;
|
|
299
301
|
}) => Promise<readonly VoiceProviderRoutingContractReport[]> | readonly VoiceProviderRoutingContractReport[]);
|
|
302
|
+
providerStack?: false | VoiceProviderStackCapabilityGapReport | ((input: {
|
|
303
|
+
query: Record<string, unknown>;
|
|
304
|
+
request: Request;
|
|
305
|
+
}) => Promise<VoiceProviderStackCapabilityGapReport> | VoiceProviderStackCapabilityGapReport);
|
|
300
306
|
reconnectContracts?: false | readonly VoiceReconnectContractReport[] | ((input: {
|
|
301
307
|
query: Record<string, unknown>;
|
|
302
308
|
request: Request;
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import type { VoiceReadinessProfileName } from './readinessProfiles';
|
|
2
|
+
export type VoiceProviderStackKind = 'llm' | 'stt' | 'tts';
|
|
3
|
+
export type VoiceProviderStackInput<TProvider extends string = string> = {
|
|
4
|
+
profile: VoiceReadinessProfileName;
|
|
5
|
+
providers: Partial<Record<VoiceProviderStackKind, readonly TProvider[]>>;
|
|
6
|
+
};
|
|
7
|
+
export type VoiceProviderStackChoice<TProvider extends string = string> = {
|
|
8
|
+
alternatives: TProvider[];
|
|
9
|
+
provider?: TProvider;
|
|
10
|
+
reasons: string[];
|
|
11
|
+
};
|
|
12
|
+
export type VoiceProviderStackRecommendation<TProvider extends string = string> = {
|
|
13
|
+
profile: VoiceReadinessProfileName;
|
|
14
|
+
reasons: string[];
|
|
15
|
+
recommended: Partial<Record<VoiceProviderStackKind, TProvider>>;
|
|
16
|
+
stacks: Partial<Record<VoiceProviderStackKind, VoiceProviderStackChoice<TProvider>>>;
|
|
17
|
+
};
|
|
18
|
+
export type VoiceProviderStackCapabilities<TProvider extends string = string> = Partial<Record<VoiceProviderStackKind, Partial<Record<TProvider, readonly string[]>>>>;
|
|
19
|
+
export type VoiceProviderStackCapabilityGap<TProvider extends string = string> = {
|
|
20
|
+
kind: VoiceProviderStackKind;
|
|
21
|
+
missing: string[];
|
|
22
|
+
present: string[];
|
|
23
|
+
provider?: TProvider;
|
|
24
|
+
required: string[];
|
|
25
|
+
status: 'fail' | 'pass' | 'warn';
|
|
26
|
+
};
|
|
27
|
+
export type VoiceProviderStackCapabilityGapReport<TProvider extends string = string> = {
|
|
28
|
+
gaps: VoiceProviderStackCapabilityGap<TProvider>[];
|
|
29
|
+
missing: number;
|
|
30
|
+
profile: VoiceReadinessProfileName;
|
|
31
|
+
status: 'fail' | 'pass' | 'warn';
|
|
32
|
+
};
|
|
33
|
+
export type VoiceProviderStackCapabilityGapInput<TProvider extends string = string> = VoiceProviderStackInput<TProvider> & {
|
|
34
|
+
capabilities?: VoiceProviderStackCapabilities<TProvider>;
|
|
35
|
+
recommendation?: VoiceProviderStackRecommendation<TProvider>;
|
|
36
|
+
required?: Partial<Record<VoiceProviderStackKind, readonly string[]>>;
|
|
37
|
+
};
|
|
38
|
+
export declare const recommendVoiceProviderStack: <TProvider extends string = string>(input: VoiceProviderStackInput<TProvider>) => VoiceProviderStackRecommendation<TProvider>;
|
|
39
|
+
export declare const evaluateVoiceProviderStackGaps: <TProvider extends string = string>(input: VoiceProviderStackCapabilityGapInput<TProvider>) => VoiceProviderStackCapabilityGapReport<TProvider>;
|