@absolutejs/voice 0.0.22-beta.124 → 0.0.22-beta.126
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 +34 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +111 -2
- package/dist/productionReadiness.d.ts +24 -0
- package/dist/providerRoutingContract.d.ts +38 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1534,6 +1534,40 @@ const policy = resolveVoiceProviderRoutingPolicyPreset('cost-cap', {
|
|
|
1534
1534
|
});
|
|
1535
1535
|
```
|
|
1536
1536
|
|
|
1537
|
+
Use `runVoiceProviderRoutingContract(...)` when provider fallback needs to be certified before production. The contract reads provider routing trace events and verifies the expected selected provider, fallback provider, status, and kind in order.
|
|
1538
|
+
|
|
1539
|
+
```ts
|
|
1540
|
+
import { runVoiceProviderRoutingContract } from '@absolutejs/voice';
|
|
1541
|
+
|
|
1542
|
+
const report = await runVoiceProviderRoutingContract({
|
|
1543
|
+
store: runtime.traces,
|
|
1544
|
+
contract: {
|
|
1545
|
+
id: 'openai-to-anthropic-fallback',
|
|
1546
|
+
expect: [
|
|
1547
|
+
{
|
|
1548
|
+
kind: 'llm',
|
|
1549
|
+
provider: 'openai',
|
|
1550
|
+
selectedProvider: 'openai',
|
|
1551
|
+
fallbackProvider: 'anthropic',
|
|
1552
|
+
status: 'error'
|
|
1553
|
+
},
|
|
1554
|
+
{
|
|
1555
|
+
kind: 'llm',
|
|
1556
|
+
provider: 'anthropic',
|
|
1557
|
+
selectedProvider: 'openai',
|
|
1558
|
+
status: 'fallback'
|
|
1559
|
+
}
|
|
1560
|
+
]
|
|
1561
|
+
}
|
|
1562
|
+
});
|
|
1563
|
+
|
|
1564
|
+
if (!report.pass) {
|
|
1565
|
+
throw new Error(report.issues.map((issue) => issue.message).join('\n'));
|
|
1566
|
+
}
|
|
1567
|
+
```
|
|
1568
|
+
|
|
1569
|
+
Pass provider routing contract reports into production readiness through `providerRoutingContracts`. Readiness fails when a fallback contract fails, so model-routing regressions become deploy blockers instead of dashboard-only surprises.
|
|
1570
|
+
|
|
1537
1571
|
For full control, pass an object policy:
|
|
1538
1572
|
|
|
1539
1573
|
```ts
|
package/dist/index.d.ts
CHANGED
|
@@ -26,6 +26,7 @@ export { createAnthropicVoiceAssistantModel, createGeminiVoiceAssistantModel, cr
|
|
|
26
26
|
export { createOpenAIVoiceTTS } from './openaiTTS';
|
|
27
27
|
export { createVoiceProviderHealthHTMLHandler, createVoiceProviderHealthJSONHandler, createVoiceProviderHealthRoutes, renderVoiceProviderHealthHTML, summarizeVoiceProviderHealth } from './providerHealth';
|
|
28
28
|
export { createVoiceProviderCapabilityHTMLHandler, createVoiceProviderCapabilityJSONHandler, createVoiceProviderCapabilityRoutes, renderVoiceProviderCapabilityHTML, summarizeVoiceProviderCapabilities } from './providerCapabilities';
|
|
29
|
+
export { assertVoiceProviderRoutingContract, runVoiceProviderRoutingContract } from './providerRoutingContract';
|
|
29
30
|
export { buildVoiceProductionReadinessReport, createVoiceProductionReadinessRoutes, renderVoiceProductionReadinessHTML } from './productionReadiness';
|
|
30
31
|
export { buildVoiceOpsConsoleReport, createVoiceOpsConsoleRoutes, renderVoiceOpsConsoleHTML } from './opsConsoleRoutes';
|
|
31
32
|
export { createVoiceQualityRoutes, evaluateVoiceQuality, renderVoiceQualityHTML } from './qualityRoutes';
|
|
@@ -71,6 +72,7 @@ export type { AnthropicVoiceAssistantModelOptions, GeminiVoiceAssistantModelOpti
|
|
|
71
72
|
export type { OpenAIVoiceTTSOptions, OpenAIVoiceTTSVoice } from './openaiTTS';
|
|
72
73
|
export type { VoiceProviderHealthStatus, VoiceProviderHealthSummary, VoiceProviderHealthSummaryOptions } from './providerHealth';
|
|
73
74
|
export type { VoiceProviderCapabilityDefinition, VoiceProviderCapabilityHandlerOptions, VoiceProviderCapabilityHTMLHandlerOptions, VoiceProviderCapabilityKind, VoiceProviderCapabilityOptions, VoiceProviderCapabilityReport, VoiceProviderCapabilityRoutesOptions, VoiceProviderCapabilitySummary } from './providerCapabilities';
|
|
75
|
+
export type { VoiceProviderRoutingContractDefinition, VoiceProviderRoutingContractIssue, VoiceProviderRoutingContractReport, VoiceProviderRoutingContractRunOptions, VoiceProviderRoutingExpectation, VoiceProviderRoutingStatus } from './providerRoutingContract';
|
|
74
76
|
export type { VoiceTurnLatencyHTMLHandlerOptions, VoiceTurnLatencyItem, VoiceTurnLatencyOptions, VoiceTurnLatencyReport, VoiceTurnLatencyRoutesOptions, VoiceTurnLatencyStage, VoiceTurnLatencyStatus } from './turnLatency';
|
|
75
77
|
export type { VoiceLiveLatencyOptions, VoiceLiveLatencyReport, VoiceLiveLatencyRoutesOptions, VoiceLiveLatencySample, VoiceLiveLatencyStatus } from './liveLatency';
|
|
76
78
|
export type { VoiceTurnQualityHTMLHandlerOptions, VoiceTurnQualityItem, VoiceTurnQualityOptions, VoiceTurnQualityReport, VoiceTurnQualityRoutesOptions, VoiceTurnQualityStatus } from './turnQuality';
|
package/dist/index.js
CHANGED
|
@@ -9831,6 +9831,18 @@ var resolveCarriers = async (options, input) => {
|
|
|
9831
9831
|
providers: [...providers]
|
|
9832
9832
|
});
|
|
9833
9833
|
};
|
|
9834
|
+
var resolveAgentSquadContracts = async (options, input) => {
|
|
9835
|
+
if (options.agentSquadContracts === false || options.agentSquadContracts === undefined) {
|
|
9836
|
+
return;
|
|
9837
|
+
}
|
|
9838
|
+
return typeof options.agentSquadContracts === "function" ? await options.agentSquadContracts(input) : options.agentSquadContracts;
|
|
9839
|
+
};
|
|
9840
|
+
var resolveProviderRoutingContracts = async (options, input) => {
|
|
9841
|
+
if (options.providerRoutingContracts === false || options.providerRoutingContracts === undefined) {
|
|
9842
|
+
return;
|
|
9843
|
+
}
|
|
9844
|
+
return typeof options.providerRoutingContracts === "function" ? await options.providerRoutingContracts(input) : options.providerRoutingContracts;
|
|
9845
|
+
};
|
|
9834
9846
|
var summarizeLiveLatency = (events, options) => {
|
|
9835
9847
|
const warnAfterMs = options.liveLatencyWarnAfterMs ?? 1800;
|
|
9836
9848
|
const failAfterMs = options.liveLatencyFailAfterMs ?? 3200;
|
|
@@ -9853,7 +9865,15 @@ var buildVoiceProductionReadinessReport = async (options, input = {}) => {
|
|
|
9853
9865
|
const routingEvents = listVoiceRoutingEvents(events);
|
|
9854
9866
|
const routingSessions = summarizeVoiceRoutingSessions(routingEvents);
|
|
9855
9867
|
const liveLatency = summarizeLiveLatency(events, options);
|
|
9856
|
-
const [
|
|
9868
|
+
const [
|
|
9869
|
+
quality,
|
|
9870
|
+
providers,
|
|
9871
|
+
sessions,
|
|
9872
|
+
handoffs,
|
|
9873
|
+
carriers,
|
|
9874
|
+
agentSquadContracts,
|
|
9875
|
+
providerRoutingContracts
|
|
9876
|
+
] = await Promise.all([
|
|
9857
9877
|
evaluateVoiceQuality({ events }),
|
|
9858
9878
|
Promise.all([
|
|
9859
9879
|
summarizeVoiceProviderHealth({
|
|
@@ -9871,7 +9891,9 @@ var buildVoiceProductionReadinessReport = async (options, input = {}) => {
|
|
|
9871
9891
|
]).then((groups) => groups.flat()),
|
|
9872
9892
|
summarizeVoiceSessions({ events, status: "all" }),
|
|
9873
9893
|
summarizeVoiceHandoffHealth({ events }),
|
|
9874
|
-
resolveCarriers(options, { query, request })
|
|
9894
|
+
resolveCarriers(options, { query, request }),
|
|
9895
|
+
resolveAgentSquadContracts(options, { query, request }),
|
|
9896
|
+
resolveProviderRoutingContracts(options, { query, request })
|
|
9875
9897
|
]);
|
|
9876
9898
|
const degradedProviders = providers.filter((provider) => provider.status === "degraded" || provider.status === "rate-limited" || provider.status === "suppressed").length;
|
|
9877
9899
|
const failedSessions = sessions.filter((session) => session.status === "failed").length;
|
|
@@ -9980,6 +10002,50 @@ var buildVoiceProductionReadinessReport = async (options, input = {}) => {
|
|
|
9980
10002
|
status: carrierStatus(carriers),
|
|
9981
10003
|
warnings: carriers.summary.warnings
|
|
9982
10004
|
} : undefined;
|
|
10005
|
+
const agentSquadContractSummary = agentSquadContracts ? {
|
|
10006
|
+
failed: agentSquadContracts.filter((report) => !report.pass).length,
|
|
10007
|
+
passed: agentSquadContracts.filter((report) => report.pass).length,
|
|
10008
|
+
status: agentSquadContracts.some((report) => !report.pass) ? "fail" : agentSquadContracts.length === 0 ? "warn" : "pass",
|
|
10009
|
+
total: agentSquadContracts.length
|
|
10010
|
+
} : undefined;
|
|
10011
|
+
const providerRoutingContractSummary = providerRoutingContracts ? {
|
|
10012
|
+
failed: providerRoutingContracts.filter((report) => !report.pass).length,
|
|
10013
|
+
passed: providerRoutingContracts.filter((report) => report.pass).length,
|
|
10014
|
+
status: providerRoutingContracts.some((report) => !report.pass) ? "fail" : providerRoutingContracts.length === 0 ? "warn" : "pass",
|
|
10015
|
+
total: providerRoutingContracts.length
|
|
10016
|
+
} : undefined;
|
|
10017
|
+
if (agentSquadContractSummary) {
|
|
10018
|
+
checks.push({
|
|
10019
|
+
detail: agentSquadContractSummary.status === "pass" ? `${agentSquadContractSummary.passed} agent squad contract(s) are passing.` : agentSquadContractSummary.total === 0 ? "No agent squad contracts are configured." : `${agentSquadContractSummary.failed} agent squad contract(s) failed.`,
|
|
10020
|
+
href: options.links?.agentSquadContracts ?? "/agent-squad-contract",
|
|
10021
|
+
label: "Agent squad contracts",
|
|
10022
|
+
status: agentSquadContractSummary.status,
|
|
10023
|
+
value: `${agentSquadContractSummary.passed}/${agentSquadContractSummary.total}`,
|
|
10024
|
+
actions: agentSquadContractSummary.status === "pass" ? [] : [
|
|
10025
|
+
{
|
|
10026
|
+
description: "Open the specialist routing contract report and inspect failing handoff paths.",
|
|
10027
|
+
href: options.links?.agentSquadContracts ?? "/agent-squad-contract",
|
|
10028
|
+
label: "Open squad contracts"
|
|
10029
|
+
}
|
|
10030
|
+
]
|
|
10031
|
+
});
|
|
10032
|
+
}
|
|
10033
|
+
if (providerRoutingContractSummary) {
|
|
10034
|
+
checks.push({
|
|
10035
|
+
detail: providerRoutingContractSummary.status === "pass" ? `${providerRoutingContractSummary.passed} provider routing contract(s) are passing.` : providerRoutingContractSummary.total === 0 ? "No provider routing contracts are configured." : `${providerRoutingContractSummary.failed} provider routing contract(s) failed.`,
|
|
10036
|
+
href: options.links?.providerRoutingContracts ?? options.links?.resilience ?? "/resilience",
|
|
10037
|
+
label: "Provider routing contracts",
|
|
10038
|
+
status: providerRoutingContractSummary.status,
|
|
10039
|
+
value: `${providerRoutingContractSummary.passed}/${providerRoutingContractSummary.total}`,
|
|
10040
|
+
actions: providerRoutingContractSummary.status === "pass" ? [] : [
|
|
10041
|
+
{
|
|
10042
|
+
description: "Open provider routing evidence and inspect failed fallback expectations.",
|
|
10043
|
+
href: options.links?.providerRoutingContracts ?? options.links?.resilience ?? "/resilience",
|
|
10044
|
+
label: "Open provider routing contracts"
|
|
10045
|
+
}
|
|
10046
|
+
]
|
|
10047
|
+
});
|
|
10048
|
+
}
|
|
9983
10049
|
if (carriers && carrierSummary) {
|
|
9984
10050
|
checks.push({
|
|
9985
10051
|
detail: carrierSummary.status === "pass" ? "Configured carrier setup and contract checks are passing." : `${carrierSummary.failing} carrier(s) failing, ${carrierSummary.warnings} warning(s).`,
|
|
@@ -10000,10 +10066,12 @@ var buildVoiceProductionReadinessReport = async (options, input = {}) => {
|
|
|
10000
10066
|
checkedAt: Date.now(),
|
|
10001
10067
|
checks,
|
|
10002
10068
|
links: {
|
|
10069
|
+
agentSquadContracts: "/agent-squad-contract",
|
|
10003
10070
|
carriers: "/carriers",
|
|
10004
10071
|
handoffs: "/handoffs",
|
|
10005
10072
|
handoffRetry: "/api/voice-handoffs/retry",
|
|
10006
10073
|
liveLatency: "/traces",
|
|
10074
|
+
providerRoutingContracts: "/resilience",
|
|
10007
10075
|
quality: "/quality",
|
|
10008
10076
|
resilience: "/resilience",
|
|
10009
10077
|
sessions: "/sessions",
|
|
@@ -10011,6 +10079,7 @@ var buildVoiceProductionReadinessReport = async (options, input = {}) => {
|
|
|
10011
10079
|
},
|
|
10012
10080
|
status: rollupStatus(checks),
|
|
10013
10081
|
summary: {
|
|
10082
|
+
agentSquadContracts: agentSquadContractSummary,
|
|
10014
10083
|
carriers: carrierSummary,
|
|
10015
10084
|
handoffs: {
|
|
10016
10085
|
failed: handoffs.failed,
|
|
@@ -10021,6 +10090,7 @@ var buildVoiceProductionReadinessReport = async (options, input = {}) => {
|
|
|
10021
10090
|
degraded: degradedProviders,
|
|
10022
10091
|
total: providers.length
|
|
10023
10092
|
},
|
|
10093
|
+
providerRoutingContracts: providerRoutingContractSummary,
|
|
10024
10094
|
quality: {
|
|
10025
10095
|
status: quality.status
|
|
10026
10096
|
},
|
|
@@ -17035,6 +17105,43 @@ var createOpenAIVoiceTTS = (options) => {
|
|
|
17035
17105
|
}
|
|
17036
17106
|
};
|
|
17037
17107
|
};
|
|
17108
|
+
// src/providerRoutingContract.ts
|
|
17109
|
+
var isRoutingEvent = (event) => Boolean(event && typeof event === "object" && "status" in event && "kind" in event && "sessionId" in event);
|
|
17110
|
+
var normalizeEvents = (events) => (events.every(isRoutingEvent) ? [...events] : listVoiceRoutingEvents(events)).sort((left, right) => left.at - right.at);
|
|
17111
|
+
var matchesExpectation = (event, expectation) => (expectation.kind === undefined || event.kind === expectation.kind) && (expectation.operation === undefined || event.operation === expectation.operation) && (expectation.provider === undefined || event.provider === expectation.provider) && (expectation.selectedProvider === undefined || event.selectedProvider === expectation.selectedProvider) && (expectation.fallbackProvider === undefined || event.fallbackProvider === expectation.fallbackProvider) && (expectation.status === undefined || event.status === expectation.status);
|
|
17112
|
+
var describeExpectation = (expectation) => Object.entries(expectation).map(([key, value]) => `${key}=${String(value)}`).join(", ");
|
|
17113
|
+
var runVoiceProviderRoutingContract = async (options) => {
|
|
17114
|
+
const rawEvents = options.events ?? await options.store?.list() ?? [];
|
|
17115
|
+
const events = normalizeEvents(rawEvents).filter((event) => (!options.contract.sessionId || event.sessionId === options.contract.sessionId) && (!options.contract.scenarioId || event.sessionId === options.contract.scenarioId || rawEvents.some((rawEvent) => !isRoutingEvent(rawEvent) && rawEvent.sessionId === event.sessionId && rawEvent.scenarioId === options.contract.scenarioId)));
|
|
17116
|
+
const issues = [];
|
|
17117
|
+
let searchFrom = 0;
|
|
17118
|
+
for (const [index, expectation] of options.contract.expect.entries()) {
|
|
17119
|
+
const matchIndex = events.findIndex((event, eventIndex) => eventIndex >= searchFrom && matchesExpectation(event, expectation));
|
|
17120
|
+
if (matchIndex === -1) {
|
|
17121
|
+
issues.push({
|
|
17122
|
+
code: "provider_routing.expected_event_missing",
|
|
17123
|
+
message: `Expected provider routing event ${index + 1}: ${describeExpectation(expectation)}.`
|
|
17124
|
+
});
|
|
17125
|
+
continue;
|
|
17126
|
+
}
|
|
17127
|
+
searchFrom = matchIndex + 1;
|
|
17128
|
+
}
|
|
17129
|
+
return {
|
|
17130
|
+
contractId: options.contract.id,
|
|
17131
|
+
events,
|
|
17132
|
+
issues,
|
|
17133
|
+
pass: issues.length === 0,
|
|
17134
|
+
scenarioId: options.contract.scenarioId,
|
|
17135
|
+
sessionId: options.contract.sessionId
|
|
17136
|
+
};
|
|
17137
|
+
};
|
|
17138
|
+
var assertVoiceProviderRoutingContract = async (options) => {
|
|
17139
|
+
const report = await runVoiceProviderRoutingContract(options);
|
|
17140
|
+
if (!report.pass) {
|
|
17141
|
+
throw new Error(`Voice provider routing contract ${report.contractId} failed: ${report.issues.map((issue) => issue.message).join(" ")}`);
|
|
17142
|
+
}
|
|
17143
|
+
return report;
|
|
17144
|
+
};
|
|
17038
17145
|
// src/providerAdapters.ts
|
|
17039
17146
|
class VoiceIOProviderTimeoutError extends Error {
|
|
17040
17147
|
provider;
|
|
@@ -19934,6 +20041,7 @@ export {
|
|
|
19934
20041
|
runVoiceSessionEvals,
|
|
19935
20042
|
runVoiceScenarioFixtureEvals,
|
|
19936
20043
|
runVoiceScenarioEvals,
|
|
20044
|
+
runVoiceProviderRoutingContract,
|
|
19937
20045
|
runVoiceOutcomeContractSuite,
|
|
19938
20046
|
runVoiceCampaignProof,
|
|
19939
20047
|
runVoiceCampaignDialerProof,
|
|
@@ -20215,6 +20323,7 @@ export {
|
|
|
20215
20323
|
buildVoiceDiagnosticsMarkdown,
|
|
20216
20324
|
buildVoiceCampaignObservabilityReport,
|
|
20217
20325
|
assignVoiceOpsTask,
|
|
20326
|
+
assertVoiceProviderRoutingContract,
|
|
20218
20327
|
assertVoiceAgentSquadContract,
|
|
20219
20328
|
applyVoiceTelephonyOutcome,
|
|
20220
20329
|
applyVoiceOpsTaskPolicy,
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { Elysia } from 'elysia';
|
|
2
2
|
import { type VoiceTelephonyCarrierMatrixInput } from './telephony/matrix';
|
|
3
3
|
import type { VoiceTraceEventStore } from './trace';
|
|
4
|
+
import type { VoiceAgentSquadContractReport } from './agentSquadContract';
|
|
5
|
+
import type { VoiceProviderRoutingContractReport } from './providerRoutingContract';
|
|
4
6
|
export type VoiceProductionReadinessStatus = 'fail' | 'pass' | 'warn';
|
|
5
7
|
export type VoiceProductionReadinessAction = {
|
|
6
8
|
description?: string;
|
|
@@ -20,16 +22,24 @@ export type VoiceProductionReadinessReport = {
|
|
|
20
22
|
checkedAt: number;
|
|
21
23
|
checks: VoiceProductionReadinessCheck[];
|
|
22
24
|
links: {
|
|
25
|
+
agentSquadContracts?: string;
|
|
23
26
|
carriers?: string;
|
|
24
27
|
handoffs?: string;
|
|
25
28
|
handoffRetry?: string;
|
|
26
29
|
liveLatency?: string;
|
|
30
|
+
providerRoutingContracts?: string;
|
|
27
31
|
quality?: string;
|
|
28
32
|
resilience?: string;
|
|
29
33
|
sessions?: string;
|
|
30
34
|
};
|
|
31
35
|
status: VoiceProductionReadinessStatus;
|
|
32
36
|
summary: {
|
|
37
|
+
agentSquadContracts?: {
|
|
38
|
+
failed: number;
|
|
39
|
+
passed: number;
|
|
40
|
+
status: VoiceProductionReadinessStatus;
|
|
41
|
+
total: number;
|
|
42
|
+
};
|
|
33
43
|
carriers?: {
|
|
34
44
|
failing: number;
|
|
35
45
|
providers: number;
|
|
@@ -52,6 +62,12 @@ export type VoiceProductionReadinessReport = {
|
|
|
52
62
|
degraded: number;
|
|
53
63
|
total: number;
|
|
54
64
|
};
|
|
65
|
+
providerRoutingContracts?: {
|
|
66
|
+
failed: number;
|
|
67
|
+
passed: number;
|
|
68
|
+
status: VoiceProductionReadinessStatus;
|
|
69
|
+
total: number;
|
|
70
|
+
};
|
|
55
71
|
quality: {
|
|
56
72
|
status: 'fail' | 'pass';
|
|
57
73
|
};
|
|
@@ -66,6 +82,10 @@ export type VoiceProductionReadinessReport = {
|
|
|
66
82
|
};
|
|
67
83
|
};
|
|
68
84
|
export type VoiceProductionReadinessRoutesOptions = {
|
|
85
|
+
agentSquadContracts?: false | readonly VoiceAgentSquadContractReport[] | ((input: {
|
|
86
|
+
query: Record<string, unknown>;
|
|
87
|
+
request: Request;
|
|
88
|
+
}) => Promise<readonly VoiceAgentSquadContractReport[]> | readonly VoiceAgentSquadContractReport[]);
|
|
69
89
|
carriers?: false | readonly VoiceTelephonyCarrierMatrixInput[] | ((input: {
|
|
70
90
|
query: Record<string, unknown>;
|
|
71
91
|
request: Request;
|
|
@@ -76,6 +96,10 @@ export type VoiceProductionReadinessRoutesOptions = {
|
|
|
76
96
|
llmProviders?: readonly string[];
|
|
77
97
|
name?: string;
|
|
78
98
|
path?: string;
|
|
99
|
+
providerRoutingContracts?: false | readonly VoiceProviderRoutingContractReport[] | ((input: {
|
|
100
|
+
query: Record<string, unknown>;
|
|
101
|
+
request: Request;
|
|
102
|
+
}) => Promise<readonly VoiceProviderRoutingContractReport[]> | readonly VoiceProviderRoutingContractReport[]);
|
|
79
103
|
render?: (report: VoiceProductionReadinessReport) => string | Promise<string>;
|
|
80
104
|
store: VoiceTraceEventStore;
|
|
81
105
|
sttProviders?: readonly string[];
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { type VoiceRoutingEvent, type VoiceRoutingEventKind } from './resilienceRoutes';
|
|
2
|
+
import type { StoredVoiceTraceEvent, VoiceTraceEventStore } from './trace';
|
|
3
|
+
export type VoiceProviderRoutingStatus = 'error' | 'fallback' | 'success';
|
|
4
|
+
export type VoiceProviderRoutingExpectation = {
|
|
5
|
+
fallbackProvider?: string;
|
|
6
|
+
kind?: VoiceRoutingEventKind;
|
|
7
|
+
operation?: string;
|
|
8
|
+
provider?: string;
|
|
9
|
+
selectedProvider?: string;
|
|
10
|
+
status?: VoiceProviderRoutingStatus;
|
|
11
|
+
};
|
|
12
|
+
export type VoiceProviderRoutingContractDefinition = {
|
|
13
|
+
description?: string;
|
|
14
|
+
expect: VoiceProviderRoutingExpectation[];
|
|
15
|
+
id: string;
|
|
16
|
+
label?: string;
|
|
17
|
+
scenarioId?: string;
|
|
18
|
+
sessionId?: string;
|
|
19
|
+
};
|
|
20
|
+
export type VoiceProviderRoutingContractIssue = {
|
|
21
|
+
code: string;
|
|
22
|
+
message: string;
|
|
23
|
+
};
|
|
24
|
+
export type VoiceProviderRoutingContractReport = {
|
|
25
|
+
contractId: string;
|
|
26
|
+
events: VoiceRoutingEvent[];
|
|
27
|
+
issues: VoiceProviderRoutingContractIssue[];
|
|
28
|
+
pass: boolean;
|
|
29
|
+
scenarioId?: string;
|
|
30
|
+
sessionId?: string;
|
|
31
|
+
};
|
|
32
|
+
export type VoiceProviderRoutingContractRunOptions = {
|
|
33
|
+
contract: VoiceProviderRoutingContractDefinition;
|
|
34
|
+
events?: StoredVoiceTraceEvent[] | VoiceRoutingEvent[];
|
|
35
|
+
store?: VoiceTraceEventStore;
|
|
36
|
+
};
|
|
37
|
+
export declare const runVoiceProviderRoutingContract: (options: VoiceProviderRoutingContractRunOptions) => Promise<VoiceProviderRoutingContractReport>;
|
|
38
|
+
export declare const assertVoiceProviderRoutingContract: (options: VoiceProviderRoutingContractRunOptions) => Promise<VoiceProviderRoutingContractReport>;
|