@absolutejs/voice 0.0.22-beta.85 → 0.0.22-beta.87
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 -2
- package/dist/index.js +111 -7
- package/dist/resilienceRoutes.d.ts +25 -0
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -20,7 +20,7 @@ export { createVoiceProviderHealthHTMLHandler, createVoiceProviderHealthJSONHand
|
|
|
20
20
|
export { createVoiceProviderCapabilityHTMLHandler, createVoiceProviderCapabilityJSONHandler, createVoiceProviderCapabilityRoutes, renderVoiceProviderCapabilityHTML, summarizeVoiceProviderCapabilities } from './providerCapabilities';
|
|
21
21
|
export { buildVoiceOpsConsoleReport, createVoiceOpsConsoleRoutes, renderVoiceOpsConsoleHTML } from './opsConsoleRoutes';
|
|
22
22
|
export { createVoiceQualityRoutes, evaluateVoiceQuality, renderVoiceQualityHTML } from './qualityRoutes';
|
|
23
|
-
export { createVoiceResilienceRoutes, createVoiceRoutingDecisionSummary, listVoiceRoutingEvents, renderVoiceResilienceHTML, summarizeVoiceRoutingDecision } from './resilienceRoutes';
|
|
23
|
+
export { createVoiceResilienceRoutes, createVoiceRoutingDecisionSummary, listVoiceRoutingEvents, renderVoiceResilienceHTML, summarizeVoiceRoutingDecision, summarizeVoiceRoutingSessions } from './resilienceRoutes';
|
|
24
24
|
export { createVoiceSTTProviderRouter, createVoiceTTSProviderRouter } from './providerAdapters';
|
|
25
25
|
export { buildVoiceTraceReplay, createVoiceMemoryTraceSinkDeliveryStore, createVoiceTraceHTTPSink, createVoiceMemoryTraceEventStore, createVoiceTraceSinkDeliveryId, createVoiceTraceSinkDeliveryRecord, createVoiceTraceSinkStore, createVoiceTraceEvent, createVoiceTraceEventId, deliverVoiceTraceEventsToSinks, evaluateVoiceTrace, exportVoiceTrace, filterVoiceTraceEvents, pruneVoiceTraceEvents, redactVoiceTraceEvent, redactVoiceTraceEvents, redactVoiceTraceText, renderVoiceTraceHTML, renderVoiceTraceMarkdown, resolveVoiceTraceRedactionOptions, selectVoiceTraceEventsForPrune, summarizeVoiceTrace } from './trace';
|
|
26
26
|
export { createVoiceSQLiteExternalObjectMapStore, createVoiceSQLiteIntegrationEventStore, createVoiceSQLiteReviewStore, createVoiceSQLiteRuntimeStorage, createVoiceSQLiteSessionStore, createVoiceSQLiteTaskStore, createVoiceSQLiteTelephonyWebhookIdempotencyStore, createVoiceSQLiteTraceSinkDeliveryStore, createVoiceSQLiteTraceEventStore } from './sqliteStore';
|
|
@@ -62,7 +62,7 @@ export type { VoiceOutcomeContractDefinition, VoiceOutcomeContractHTMLHandlerOpt
|
|
|
62
62
|
export type { VoiceTelephonyOutcomeAction, VoiceTelephonyOutcomeDecision, VoiceTelephonyOutcomePolicy, VoiceTelephonyOutcomeProviderEvent, VoiceTelephonyOutcomeRouteResult, VoiceTelephonyOutcomeStatusDecision, VoiceTelephonyWebhookDecision, VoiceTelephonyWebhookHandlerOptions, VoiceTelephonyWebhookIdempotencyStore, VoiceTelephonyWebhookParseInput, VoiceTelephonyWebhookProvider, VoiceTelephonyWebhookRoutesOptions, VoiceTelephonyWebhookVerificationResult, StoredVoiceTelephonyWebhookDecision } from './telephonyOutcome';
|
|
63
63
|
export type { VoiceOpsConsoleLink, VoiceOpsConsoleReport, VoiceOpsConsoleRoutesOptions } from './opsConsoleRoutes';
|
|
64
64
|
export type { VoiceQualityLink, VoiceQualityMetric, VoiceQualityReport, VoiceQualityRoutesOptions, VoiceQualityStatus, VoiceQualityThresholds } from './qualityRoutes';
|
|
65
|
-
export type { VoiceResilienceIOSimulator, VoiceResilienceLink, VoiceResiliencePageData, VoiceResilienceRoutesOptions, VoiceResilienceSimulationProvider, VoiceRoutingDecisionSummary, VoiceRoutingDecisionSummaryOptions, VoiceRoutingEvent, VoiceRoutingEventKind } from './resilienceRoutes';
|
|
65
|
+
export type { VoiceResilienceIOSimulator, VoiceResilienceLink, VoiceResiliencePageData, VoiceResilienceRoutesOptions, VoiceResilienceSimulationProvider, VoiceRoutingKindSummary, VoiceRoutingDecisionSummary, VoiceRoutingDecisionSummaryOptions, VoiceRoutingEvent, VoiceRoutingEventKind, VoiceRoutingSessionSummary, VoiceRoutingSessionSummaryOptions } from './resilienceRoutes';
|
|
66
66
|
export type { VoiceIOProviderRouterEvent, VoiceIOProviderRouterOptions, VoiceIOProviderRouterPolicy, VoiceIOProviderRouterPolicyConfig, VoiceSTTProviderRouterOptions, VoiceTTSProviderRouterOptions } from './providerAdapters';
|
|
67
67
|
export type { VoiceAgent, VoiceAgentMessage, VoiceAgentMessageRole, VoiceAgentModel, VoiceAgentModelInput, VoiceAgentModelOutput, VoiceAgentOptions, VoiceAgentRunResult, VoiceAgentSquadOptions, VoiceAgentTool, VoiceAgentToolCall, VoiceAgentToolResult } from './agent';
|
|
68
68
|
export type { VoiceToolRetryDelay, VoiceToolRuntime, VoiceToolRuntimeExecuteInput, VoiceToolRuntimeOptions, VoiceToolRuntimeResult } from './toolRuntime';
|
package/dist/index.js
CHANGED
|
@@ -8539,6 +8539,68 @@ var summarizeVoiceRoutingDecision = (events, options = {}) => {
|
|
|
8539
8539
|
const limited = typeof options.limit === "number" && options.limit >= 0 ? routingEvents.slice(0, options.limit) : routingEvents;
|
|
8540
8540
|
return limited[0] ?? null;
|
|
8541
8541
|
};
|
|
8542
|
+
var createEmptyKindSummary = () => ({
|
|
8543
|
+
errorCount: 0,
|
|
8544
|
+
fallbackCount: 0,
|
|
8545
|
+
providers: [],
|
|
8546
|
+
runCount: 0,
|
|
8547
|
+
timeoutCount: 0
|
|
8548
|
+
});
|
|
8549
|
+
var summarizeVoiceRoutingSessions = (events, options = {}) => {
|
|
8550
|
+
const routingEvents = (events.some((event) => ("payload" in event)) ? listVoiceRoutingEvents(events) : [...events]).filter((event) => !options.sessionId || event.sessionId === options.sessionId);
|
|
8551
|
+
const sessions = new Map;
|
|
8552
|
+
for (const event of routingEvents) {
|
|
8553
|
+
const existing = sessions.get(event.sessionId);
|
|
8554
|
+
const summary = existing ?? {
|
|
8555
|
+
errorCount: 0,
|
|
8556
|
+
eventCount: 0,
|
|
8557
|
+
fallbackCount: 0,
|
|
8558
|
+
kinds: {
|
|
8559
|
+
llm: createEmptyKindSummary(),
|
|
8560
|
+
stt: createEmptyKindSummary(),
|
|
8561
|
+
tts: createEmptyKindSummary()
|
|
8562
|
+
},
|
|
8563
|
+
lastEventAt: event.at,
|
|
8564
|
+
sessionId: event.sessionId,
|
|
8565
|
+
startedAt: event.at,
|
|
8566
|
+
status: "healthy",
|
|
8567
|
+
timeoutCount: 0
|
|
8568
|
+
};
|
|
8569
|
+
summary.eventCount += 1;
|
|
8570
|
+
summary.startedAt = Math.min(summary.startedAt, event.at);
|
|
8571
|
+
summary.lastEventAt = Math.max(summary.lastEventAt, event.at);
|
|
8572
|
+
if (event.status === "error") {
|
|
8573
|
+
summary.errorCount += 1;
|
|
8574
|
+
}
|
|
8575
|
+
if (event.status === "fallback") {
|
|
8576
|
+
summary.fallbackCount += 1;
|
|
8577
|
+
}
|
|
8578
|
+
if (event.timedOut) {
|
|
8579
|
+
summary.timeoutCount += 1;
|
|
8580
|
+
}
|
|
8581
|
+
const kind = summary.kinds[event.kind];
|
|
8582
|
+
kind.runCount += 1;
|
|
8583
|
+
if (event.status === "error") {
|
|
8584
|
+
kind.errorCount += 1;
|
|
8585
|
+
}
|
|
8586
|
+
if (event.status === "fallback") {
|
|
8587
|
+
kind.fallbackCount += 1;
|
|
8588
|
+
}
|
|
8589
|
+
if (event.timedOut) {
|
|
8590
|
+
kind.timeoutCount += 1;
|
|
8591
|
+
}
|
|
8592
|
+
if (event.provider && !kind.providers.includes(event.provider)) {
|
|
8593
|
+
kind.providers.push(event.provider);
|
|
8594
|
+
}
|
|
8595
|
+
if (!kind.latest || event.at > kind.latest.at) {
|
|
8596
|
+
kind.latest = event;
|
|
8597
|
+
}
|
|
8598
|
+
summary.status = summary.errorCount > 0 || summary.timeoutCount > 0 ? "degraded" : summary.fallbackCount > 0 ? "fallback" : "healthy";
|
|
8599
|
+
sessions.set(event.sessionId, summary);
|
|
8600
|
+
}
|
|
8601
|
+
const sorted = [...sessions.values()].sort((left, right) => right.lastEventAt - left.lastEventAt);
|
|
8602
|
+
return typeof options.limit === "number" && options.limit >= 0 ? sorted.slice(0, options.limit) : sorted;
|
|
8603
|
+
};
|
|
8542
8604
|
var createVoiceRoutingDecisionSummary = async (options) => {
|
|
8543
8605
|
const events = await options.store.list({
|
|
8544
8606
|
sessionId: options.sessionId,
|
|
@@ -8618,6 +8680,41 @@ var renderTimeline2 = (events) => {
|
|
|
8618
8680
|
</article>
|
|
8619
8681
|
`).join("")}</div>`;
|
|
8620
8682
|
};
|
|
8683
|
+
var renderSessionKind = (kind, summary) => {
|
|
8684
|
+
const latest = summary.latest;
|
|
8685
|
+
const provider = latest?.provider ?? summary.providers[0] ?? "none";
|
|
8686
|
+
const status = latest?.status ?? "idle";
|
|
8687
|
+
const fallback = latest?.fallbackProvider && latest.fallbackProvider !== provider ? ` -> ${latest.fallbackProvider}` : "";
|
|
8688
|
+
return `<div>
|
|
8689
|
+
<dt>${escapeHtml10(kind.toUpperCase())}</dt>
|
|
8690
|
+
<dd>${escapeHtml10(provider)}${escapeHtml10(fallback)}</dd>
|
|
8691
|
+
<small>${escapeHtml10(status)} \xB7 ${summary.runCount} event${summary.runCount === 1 ? "" : "s"} \xB7 ${summary.errorCount} error${summary.errorCount === 1 ? "" : "s"} \xB7 ${summary.fallbackCount} fallback${summary.fallbackCount === 1 ? "" : "s"}</small>
|
|
8692
|
+
</div>`;
|
|
8693
|
+
};
|
|
8694
|
+
var renderSessionSummaries = (sessions) => {
|
|
8695
|
+
if (sessions.length === 0) {
|
|
8696
|
+
return '<p class="muted">No call-level routing summaries yet. Run a voice session or provider simulation.</p>';
|
|
8697
|
+
}
|
|
8698
|
+
return `<div class="session-grid">${sessions.slice(0, 12).map((session) => `
|
|
8699
|
+
<article class="card session ${escapeHtml10(session.status)}">
|
|
8700
|
+
<div class="card-header">
|
|
8701
|
+
<strong>${escapeHtml10(session.sessionId)}</strong>
|
|
8702
|
+
<span>${escapeHtml10(session.status)}</span>
|
|
8703
|
+
</div>
|
|
8704
|
+
<p>
|
|
8705
|
+
<span class="pill">${session.eventCount} routing events</span>
|
|
8706
|
+
<span class="pill">${session.fallbackCount} fallbacks</span>
|
|
8707
|
+
<span class="pill">${session.errorCount} errors</span>
|
|
8708
|
+
<span class="pill">${session.timeoutCount} timeouts</span>
|
|
8709
|
+
</p>
|
|
8710
|
+
<dl>
|
|
8711
|
+
${renderSessionKind("llm", session.kinds.llm)}
|
|
8712
|
+
${renderSessionKind("stt", session.kinds.stt)}
|
|
8713
|
+
${renderSessionKind("tts", session.kinds.tts)}
|
|
8714
|
+
</dl>
|
|
8715
|
+
</article>
|
|
8716
|
+
`).join("")}</div>`;
|
|
8717
|
+
};
|
|
8621
8718
|
var renderSimulationControls = (kind, simulation) => {
|
|
8622
8719
|
if (!simulation) {
|
|
8623
8720
|
return "";
|
|
@@ -8656,6 +8753,7 @@ var renderVoiceResilienceHTML = (input) => {
|
|
|
8656
8753
|
section, .card { background: rgba(19, 22, 27, 0.92); border: 1px solid #27272a; border-radius: 20px; padding: 20px; }
|
|
8657
8754
|
.hero { background: linear-gradient(135deg, rgba(14, 165, 233, 0.18), rgba(245, 158, 11, 0.12)); }
|
|
8658
8755
|
.grid, .provider-grid { display: grid; gap: 14px; grid-template-columns: repeat(4, minmax(0, 1fr)); }
|
|
8756
|
+
.session-grid { display: grid; gap: 14px; grid-template-columns: repeat(2, minmax(0, 1fr)); }
|
|
8659
8757
|
.timeline { display: grid; gap: 12px; }
|
|
8660
8758
|
.card-header { align-items: center; display: flex; gap: 12px; justify-content: space-between; }
|
|
8661
8759
|
.card-header strong { font-size: 1.05rem; }
|
|
@@ -8667,8 +8765,9 @@ var renderVoiceResilienceHTML = (input) => {
|
|
|
8667
8765
|
.pill { background: #0f1217; border: 1px solid #3f3f46; border-radius: 999px; color: #d4d4d8; display: inline-flex; margin: 3px 4px 3px 0; padding: 5px 9px; }
|
|
8668
8766
|
.danger { border-color: rgba(239, 68, 68, 0.75); color: #fecaca; }
|
|
8669
8767
|
.event.error { border-color: rgba(239, 68, 68, 0.7); }
|
|
8670
|
-
.event.fallback { border-color: rgba(245, 158, 11, 0.7); }
|
|
8671
|
-
.event.success, .provider.healthy { border-color: rgba(34, 197, 94, 0.5); }
|
|
8768
|
+
.event.fallback, .session.fallback { border-color: rgba(245, 158, 11, 0.7); }
|
|
8769
|
+
.event.success, .provider.healthy, .session.healthy { border-color: rgba(34, 197, 94, 0.5); }
|
|
8770
|
+
.session.degraded { border-color: rgba(239, 68, 68, 0.7); }
|
|
8672
8771
|
.provider.suppressed, .provider.degraded, .provider.rate-limited { border-color: rgba(239, 68, 68, 0.7); }
|
|
8673
8772
|
.provider.recoverable { border-color: rgba(59, 130, 246, 0.7); }
|
|
8674
8773
|
button { background: #f59e0b; border: 0; border-radius: 999px; color: #111827; cursor: pointer; font-weight: 800; padding: 10px 14px; }
|
|
@@ -8676,7 +8775,7 @@ var renderVoiceResilienceHTML = (input) => {
|
|
|
8676
8775
|
.simulate-actions { display: flex; flex-wrap: wrap; gap: 10px; margin-top: 12px; }
|
|
8677
8776
|
.simulate-output { background: #050505; border: 1px solid #27272a; border-radius: 14px; color: #d4d4d8; overflow: auto; padding: 12px; white-space: pre-wrap; }
|
|
8678
8777
|
a { color: #f59e0b; }
|
|
8679
|
-
@media (max-width: 850px) { .grid, .provider-grid, dl { grid-template-columns: 1fr; } }
|
|
8778
|
+
@media (max-width: 850px) { .grid, .provider-grid, .session-grid, dl { grid-template-columns: 1fr; } }
|
|
8680
8779
|
</style>
|
|
8681
8780
|
</head>
|
|
8682
8781
|
<body>
|
|
@@ -8693,6 +8792,11 @@ var renderVoiceResilienceHTML = (input) => {
|
|
|
8693
8792
|
<article class="card metric"><span>Errors</span><strong>${summary.errors}</strong></article>
|
|
8694
8793
|
<article class="card metric"><span>Timeouts</span><strong>${summary.timeouts}</strong></article>
|
|
8695
8794
|
</section>
|
|
8795
|
+
<section>
|
|
8796
|
+
<h2>Call-level routing summaries</h2>
|
|
8797
|
+
<p class="muted">A compact per-call view of which LLM, STT, and TTS providers handled the session, including fallback and timeout counts.</p>
|
|
8798
|
+
${renderSessionSummaries(input.routingSessions)}
|
|
8799
|
+
</section>
|
|
8696
8800
|
<section>
|
|
8697
8801
|
<h2>LLM provider health</h2>
|
|
8698
8802
|
${renderProviderCards("LLM", input.llmProviderHealth)}
|
|
@@ -8790,13 +8894,15 @@ var createVoiceResilienceRoutes = (options) => {
|
|
|
8790
8894
|
const events = await options.store.list();
|
|
8791
8895
|
const sttEvents = events.filter((event) => event.payload.kind === "stt");
|
|
8792
8896
|
const ttsEvents = events.filter((event) => event.payload.kind === "tts");
|
|
8897
|
+
const routingEvents = listVoiceRoutingEvents(events);
|
|
8793
8898
|
const data = {
|
|
8794
8899
|
links: options.links,
|
|
8795
8900
|
llmProviderHealth: await summarizeVoiceProviderHealth({
|
|
8796
8901
|
events,
|
|
8797
8902
|
providers: options.llmProviders ?? []
|
|
8798
8903
|
}),
|
|
8799
|
-
routingEvents
|
|
8904
|
+
routingEvents,
|
|
8905
|
+
routingSessions: summarizeVoiceRoutingSessions(routingEvents),
|
|
8800
8906
|
sttProviderHealth: await summarizeVoiceProviderHealth({
|
|
8801
8907
|
events: sttEvents,
|
|
8802
8908
|
providers: options.sttProviders ?? []
|
|
@@ -12845,9 +12951,6 @@ var createVoiceTTSProviderRouter = (options) => {
|
|
|
12845
12951
|
session.on("error", (event) => {
|
|
12846
12952
|
emitter.emit("error", event);
|
|
12847
12953
|
});
|
|
12848
|
-
session.on("close", (event) => {
|
|
12849
|
-
emitter.emit("close", event);
|
|
12850
|
-
});
|
|
12851
12954
|
};
|
|
12852
12955
|
const openProvider = async (provider, attempt) => {
|
|
12853
12956
|
const adapter = options.adapters[provider];
|
|
@@ -17190,6 +17293,7 @@ export {
|
|
|
17190
17293
|
summarizeVoiceTrace,
|
|
17191
17294
|
summarizeVoiceSessions,
|
|
17192
17295
|
summarizeVoiceSessionReplay,
|
|
17296
|
+
summarizeVoiceRoutingSessions,
|
|
17193
17297
|
summarizeVoiceRoutingDecision,
|
|
17194
17298
|
summarizeVoiceProviderHealth,
|
|
17195
17299
|
summarizeVoiceProviderCapabilities,
|
|
@@ -28,6 +28,29 @@ export type VoiceRoutingDecisionSummaryOptions = {
|
|
|
28
28
|
sessionId?: string;
|
|
29
29
|
store: VoiceTraceEventStore;
|
|
30
30
|
};
|
|
31
|
+
export type VoiceRoutingKindSummary = {
|
|
32
|
+
errorCount: number;
|
|
33
|
+
fallbackCount: number;
|
|
34
|
+
latest?: VoiceRoutingEvent;
|
|
35
|
+
providers: string[];
|
|
36
|
+
runCount: number;
|
|
37
|
+
timeoutCount: number;
|
|
38
|
+
};
|
|
39
|
+
export type VoiceRoutingSessionSummary = {
|
|
40
|
+
errorCount: number;
|
|
41
|
+
eventCount: number;
|
|
42
|
+
fallbackCount: number;
|
|
43
|
+
kinds: Record<VoiceRoutingEventKind, VoiceRoutingKindSummary>;
|
|
44
|
+
lastEventAt: number;
|
|
45
|
+
sessionId: string;
|
|
46
|
+
startedAt: number;
|
|
47
|
+
status: 'healthy' | 'fallback' | 'degraded';
|
|
48
|
+
timeoutCount: number;
|
|
49
|
+
};
|
|
50
|
+
export type VoiceRoutingSessionSummaryOptions = {
|
|
51
|
+
limit?: number;
|
|
52
|
+
sessionId?: string;
|
|
53
|
+
};
|
|
31
54
|
export type VoiceResilienceLink = {
|
|
32
55
|
href: string;
|
|
33
56
|
label: string;
|
|
@@ -51,6 +74,7 @@ export type VoiceResiliencePageData = {
|
|
|
51
74
|
links?: readonly VoiceResilienceLink[];
|
|
52
75
|
llmProviderHealth: VoiceProviderHealthSummary<string>[];
|
|
53
76
|
routingEvents: VoiceRoutingEvent[];
|
|
77
|
+
routingSessions: VoiceRoutingSessionSummary[];
|
|
54
78
|
sttProviderHealth: VoiceProviderHealthSummary<string>[];
|
|
55
79
|
sttSimulation?: VoiceResilienceIOSimulator<string>;
|
|
56
80
|
title?: string;
|
|
@@ -73,6 +97,7 @@ export type VoiceResilienceRoutesOptions = {
|
|
|
73
97
|
};
|
|
74
98
|
export declare const listVoiceRoutingEvents: (events: StoredVoiceTraceEvent[]) => VoiceRoutingEvent[];
|
|
75
99
|
export declare const summarizeVoiceRoutingDecision: (events: StoredVoiceTraceEvent[], options?: Omit<VoiceRoutingDecisionSummaryOptions, "store">) => VoiceRoutingDecisionSummary | null;
|
|
100
|
+
export declare const summarizeVoiceRoutingSessions: (events: StoredVoiceTraceEvent[] | VoiceRoutingEvent[], options?: VoiceRoutingSessionSummaryOptions) => VoiceRoutingSessionSummary[];
|
|
76
101
|
export declare const createVoiceRoutingDecisionSummary: (options: VoiceRoutingDecisionSummaryOptions) => Promise<VoiceRoutingDecisionSummary | null>;
|
|
77
102
|
export declare const renderVoiceResilienceHTML: (input: VoiceResiliencePageData) => string;
|
|
78
103
|
export declare const createVoiceResilienceRoutes: (options: VoiceResilienceRoutesOptions) => Elysia<"", {
|