@framers/agentos 0.1.226 → 0.1.228
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/core/llm/providers/implementations/AnthropicProvider.d.ts.map +1 -1
- package/dist/core/llm/providers/implementations/AnthropicProvider.js +71 -12
- package/dist/core/llm/providers/implementations/AnthropicProvider.js.map +1 -1
- package/dist/core/llm/providers/implementations/OpenAIProvider.d.ts.map +1 -1
- package/dist/core/llm/providers/implementations/OpenAIProvider.js +38 -11
- package/dist/core/llm/providers/implementations/OpenAIProvider.js.map +1 -1
- package/dist/media/images/face/ReplicateFaceEmbeddingService.d.ts +7 -0
- package/dist/media/images/face/ReplicateFaceEmbeddingService.d.ts.map +1 -1
- package/dist/media/images/face/ReplicateFaceEmbeddingService.js +32 -5
- package/dist/media/images/face/ReplicateFaceEmbeddingService.js.map +1 -1
- package/dist/voice-pipeline/AudioRingBuffer.d.ts +28 -0
- package/dist/voice-pipeline/AudioRingBuffer.d.ts.map +1 -0
- package/dist/voice-pipeline/AudioRingBuffer.js +43 -0
- package/dist/voice-pipeline/AudioRingBuffer.js.map +1 -0
- package/dist/voice-pipeline/CircuitBreaker.d.ts +42 -0
- package/dist/voice-pipeline/CircuitBreaker.d.ts.map +1 -0
- package/dist/voice-pipeline/CircuitBreaker.js +96 -0
- package/dist/voice-pipeline/CircuitBreaker.js.map +1 -0
- package/dist/voice-pipeline/HealthyProvider.d.ts +44 -0
- package/dist/voice-pipeline/HealthyProvider.d.ts.map +1 -0
- package/dist/voice-pipeline/HealthyProvider.js +29 -0
- package/dist/voice-pipeline/HealthyProvider.js.map +1 -0
- package/dist/voice-pipeline/TranscriptDedupe.d.ts +43 -0
- package/dist/voice-pipeline/TranscriptDedupe.d.ts.map +1 -0
- package/dist/voice-pipeline/TranscriptDedupe.js +96 -0
- package/dist/voice-pipeline/TranscriptDedupe.js.map +1 -0
- package/dist/voice-pipeline/VoiceMetricsReporter.d.ts +48 -0
- package/dist/voice-pipeline/VoiceMetricsReporter.d.ts.map +1 -0
- package/dist/voice-pipeline/VoiceMetricsReporter.js +33 -0
- package/dist/voice-pipeline/VoiceMetricsReporter.js.map +1 -0
- package/dist/voice-pipeline/VoicePipelineError.d.ts +44 -0
- package/dist/voice-pipeline/VoicePipelineError.d.ts.map +1 -0
- package/dist/voice-pipeline/VoicePipelineError.js +74 -0
- package/dist/voice-pipeline/VoicePipelineError.js.map +1 -0
- package/dist/voice-pipeline/env-constructor.d.ts +48 -0
- package/dist/voice-pipeline/env-constructor.d.ts.map +1 -0
- package/dist/voice-pipeline/env-constructor.js +85 -0
- package/dist/voice-pipeline/env-constructor.js.map +1 -0
- package/dist/voice-pipeline/index.d.ts +8 -1
- package/dist/voice-pipeline/index.d.ts.map +1 -1
- package/dist/voice-pipeline/index.js +9 -1
- package/dist/voice-pipeline/index.js.map +1 -1
- package/dist/voice-pipeline/providers/DeepgramStreamingSTT.d.ts +24 -1
- package/dist/voice-pipeline/providers/DeepgramStreamingSTT.d.ts.map +1 -1
- package/dist/voice-pipeline/providers/DeepgramStreamingSTT.js +51 -0
- package/dist/voice-pipeline/providers/DeepgramStreamingSTT.js.map +1 -1
- package/dist/voice-pipeline/providers/ElevenLabsBatchTTS.d.ts +17 -1
- package/dist/voice-pipeline/providers/ElevenLabsBatchTTS.d.ts.map +1 -1
- package/dist/voice-pipeline/providers/ElevenLabsBatchTTS.js +46 -0
- package/dist/voice-pipeline/providers/ElevenLabsBatchTTS.js.map +1 -1
- package/dist/voice-pipeline/providers/ElevenLabsStreamingSTT.d.ts +16 -1
- package/dist/voice-pipeline/providers/ElevenLabsStreamingSTT.d.ts.map +1 -1
- package/dist/voice-pipeline/providers/ElevenLabsStreamingSTT.js +46 -0
- package/dist/voice-pipeline/providers/ElevenLabsStreamingSTT.js.map +1 -1
- package/dist/voice-pipeline/providers/ElevenLabsStreamingTTS.d.ts +16 -1
- package/dist/voice-pipeline/providers/ElevenLabsStreamingTTS.d.ts.map +1 -1
- package/dist/voice-pipeline/providers/ElevenLabsStreamingTTS.js +46 -0
- package/dist/voice-pipeline/providers/ElevenLabsStreamingTTS.js.map +1 -1
- package/dist/voice-pipeline/providers/OpenAIBatchTTS.d.ts +16 -1
- package/dist/voice-pipeline/providers/OpenAIBatchTTS.d.ts.map +1 -1
- package/dist/voice-pipeline/providers/OpenAIBatchTTS.js +46 -0
- package/dist/voice-pipeline/providers/OpenAIBatchTTS.js.map +1 -1
- package/dist/voice-pipeline/providers/OpenAIRealtimeTTS.d.ts +16 -1
- package/dist/voice-pipeline/providers/OpenAIRealtimeTTS.d.ts.map +1 -1
- package/dist/voice-pipeline/providers/OpenAIRealtimeTTS.js +46 -0
- package/dist/voice-pipeline/providers/OpenAIRealtimeTTS.js.map +1 -1
- package/dist/voice-pipeline/providers/StreamingSTTChain.d.ts +78 -0
- package/dist/voice-pipeline/providers/StreamingSTTChain.d.ts.map +1 -0
- package/dist/voice-pipeline/providers/StreamingSTTChain.js +225 -0
- package/dist/voice-pipeline/providers/StreamingSTTChain.js.map +1 -0
- package/dist/voice-pipeline/providers/StreamingTTSChain.d.ts +67 -0
- package/dist/voice-pipeline/providers/StreamingTTSChain.d.ts.map +1 -0
- package/dist/voice-pipeline/providers/StreamingTTSChain.js +212 -0
- package/dist/voice-pipeline/providers/StreamingTTSChain.js.map +1 -0
- package/dist/voice-pipeline/providers/index.d.ts +2 -0
- package/dist/voice-pipeline/providers/index.d.ts.map +1 -1
- package/dist/voice-pipeline/providers/index.js +2 -0
- package/dist/voice-pipeline/providers/index.js.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,225 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @module voice-pipeline/providers/StreamingSTTChain
|
|
3
|
+
*
|
|
4
|
+
* Priority-ordered fallback wrapper around multiple `IStreamingSTT`
|
|
5
|
+
* providers. On `startSession()` the chain tries providers in priority
|
|
6
|
+
* order; the first one whose `startSession()` resolves wins.
|
|
7
|
+
* Init-failure classification records to the circuit breaker so future
|
|
8
|
+
* sessions skip recently-tripped providers without the retry-latency
|
|
9
|
+
* penalty.
|
|
10
|
+
*
|
|
11
|
+
* This file implements Layer 2 of the resilience plan (init-time
|
|
12
|
+
* fallback). Layer 3 (mid-utterance failover via ring buffer) is added
|
|
13
|
+
* in a later task and plugs into the `wrapSession` seam exposed here.
|
|
14
|
+
*/
|
|
15
|
+
import { EventEmitter } from 'node:events';
|
|
16
|
+
import { VoicePipelineError, AggregateVoiceError, } from '../VoicePipelineError.js';
|
|
17
|
+
import { AudioRingBuffer } from '../AudioRingBuffer.js';
|
|
18
|
+
import { TranscriptDedupe } from '../TranscriptDedupe.js';
|
|
19
|
+
export class StreamingSTTChain {
|
|
20
|
+
constructor(providers, opts = {}) {
|
|
21
|
+
this.providerId = 'chain';
|
|
22
|
+
this.isStreaming = false;
|
|
23
|
+
if (providers.length === 0) {
|
|
24
|
+
throw new Error('StreamingSTTChain requires at least one provider');
|
|
25
|
+
}
|
|
26
|
+
this._providers = [...providers].sort((a, b) => a.priority - b.priority);
|
|
27
|
+
this.opts = opts;
|
|
28
|
+
}
|
|
29
|
+
/** Providers in priority order (primary first). Exposed for
|
|
30
|
+
* introspection by host apps and tests. */
|
|
31
|
+
get providers() {
|
|
32
|
+
return this._providers;
|
|
33
|
+
}
|
|
34
|
+
get currentProviderId() {
|
|
35
|
+
return this.activeProviderId;
|
|
36
|
+
}
|
|
37
|
+
async startSession(config) {
|
|
38
|
+
const candidates = this.filterCandidates();
|
|
39
|
+
if (candidates.length === 0) {
|
|
40
|
+
this.emitMetric({
|
|
41
|
+
type: 'provider_unavailable',
|
|
42
|
+
kind: 'stt',
|
|
43
|
+
checkedProviders: this._providers.map((p) => p.providerId),
|
|
44
|
+
});
|
|
45
|
+
throw new Error('No STT providers available (all tripped or filtered)');
|
|
46
|
+
}
|
|
47
|
+
const attempts = [];
|
|
48
|
+
for (let i = 0; i < candidates.length; i++) {
|
|
49
|
+
const provider = candidates[i];
|
|
50
|
+
try {
|
|
51
|
+
const session = await provider.startSession(config);
|
|
52
|
+
this.activeProviderId = provider.providerId;
|
|
53
|
+
const evt = {
|
|
54
|
+
kind: 'stt',
|
|
55
|
+
providerId: provider.providerId,
|
|
56
|
+
attempt: i + 1,
|
|
57
|
+
};
|
|
58
|
+
this.opts.onProviderSelected?.(evt);
|
|
59
|
+
this.emitMetric({ type: 'provider_selected', ...evt });
|
|
60
|
+
this.opts.breaker?.recordSuccess(provider.providerId);
|
|
61
|
+
return this.wrapSession(session, provider, candidates.slice(i + 1), config);
|
|
62
|
+
}
|
|
63
|
+
catch (err) {
|
|
64
|
+
const classified = VoicePipelineError.classifyError(err, {
|
|
65
|
+
kind: 'stt',
|
|
66
|
+
provider: provider.providerId,
|
|
67
|
+
});
|
|
68
|
+
attempts.push(classified);
|
|
69
|
+
const failEvt = {
|
|
70
|
+
kind: 'stt',
|
|
71
|
+
providerId: provider.providerId,
|
|
72
|
+
errorClass: classified.errorClass,
|
|
73
|
+
message: classified.message,
|
|
74
|
+
};
|
|
75
|
+
this.opts.onProviderFailed?.(failEvt);
|
|
76
|
+
this.emitMetric({ type: 'provider_failed', ...failEvt });
|
|
77
|
+
this.opts.breaker?.recordFailure(provider.providerId, classified.errorClass);
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
this.emitMetric({
|
|
81
|
+
type: 'provider_unavailable',
|
|
82
|
+
kind: 'stt',
|
|
83
|
+
checkedProviders: candidates.map((p) => p.providerId),
|
|
84
|
+
});
|
|
85
|
+
throw new AggregateVoiceError(attempts);
|
|
86
|
+
}
|
|
87
|
+
filterCandidates() {
|
|
88
|
+
if (!this.opts.breaker)
|
|
89
|
+
return this._providers;
|
|
90
|
+
return this._providers.filter((p) => this.opts.breaker.isAvailable(p.providerId));
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* Wraps the session returned by a healthy provider. In init-time-only
|
|
94
|
+
* mode (enableMidUtteranceFailover=false) this is a pass-through. In
|
|
95
|
+
* failover mode the session is replaced with a facade that tees audio
|
|
96
|
+
* into a ring buffer, dedupes transcripts across providers, and on
|
|
97
|
+
* session error re-routes to the next candidate.
|
|
98
|
+
*/
|
|
99
|
+
wrapSession(initial, initialProvider, candidates, config) {
|
|
100
|
+
if (!this.opts.enableMidUtteranceFailover)
|
|
101
|
+
return initial;
|
|
102
|
+
const ring = new AudioRingBuffer({
|
|
103
|
+
capacityMs: this.opts.ringBufferCapacityMs ?? 3000,
|
|
104
|
+
sampleRate: 16000,
|
|
105
|
+
});
|
|
106
|
+
const dedupe = new TranscriptDedupe();
|
|
107
|
+
const minReplayMs = this.opts.minReplayMs ?? 400;
|
|
108
|
+
const facade = new EventEmitter();
|
|
109
|
+
let currentSession = initial;
|
|
110
|
+
let currentProvider = initialProvider;
|
|
111
|
+
let remaining = [...candidates];
|
|
112
|
+
let isFailingOver = false;
|
|
113
|
+
const attach = (session, providerId) => {
|
|
114
|
+
session.on('transcript', (evt) => {
|
|
115
|
+
const r = dedupe.evaluate({
|
|
116
|
+
provider: providerId,
|
|
117
|
+
text: evt.text,
|
|
118
|
+
audioStartMs: evt.audioStartMs ?? 0,
|
|
119
|
+
audioEndMs: evt.audioEndMs ?? 0,
|
|
120
|
+
isFinal: evt.isFinal,
|
|
121
|
+
});
|
|
122
|
+
if (r.isDuplicate)
|
|
123
|
+
return;
|
|
124
|
+
facade.emit('transcript', evt);
|
|
125
|
+
});
|
|
126
|
+
for (const passthrough of ['vad', 'speech_start', 'speech_end']) {
|
|
127
|
+
session.on(passthrough, (...args) => {
|
|
128
|
+
facade.emit(passthrough, ...args);
|
|
129
|
+
});
|
|
130
|
+
}
|
|
131
|
+
session.on('error', (err) => {
|
|
132
|
+
void tryFailover(err);
|
|
133
|
+
});
|
|
134
|
+
session.on('close', () => {
|
|
135
|
+
// Natural close on the active session is a failover trigger so the
|
|
136
|
+
// user doesn't silently lose voice mid-turn. If the chain was asked
|
|
137
|
+
// to close() externally, isFailingOver stays false and the close
|
|
138
|
+
// propagates.
|
|
139
|
+
if (!isFailingOver && currentSession === session) {
|
|
140
|
+
void tryFailover(undefined);
|
|
141
|
+
}
|
|
142
|
+
});
|
|
143
|
+
};
|
|
144
|
+
const tryFailover = async (err) => {
|
|
145
|
+
if (isFailingOver)
|
|
146
|
+
return;
|
|
147
|
+
isFailingOver = true;
|
|
148
|
+
const startedAt = Date.now();
|
|
149
|
+
const classified = VoicePipelineError.classifyError(err ?? new Error('session ended'), { kind: 'stt', provider: currentProvider.providerId });
|
|
150
|
+
this.opts.breaker?.recordFailure(currentProvider.providerId, classified.errorClass);
|
|
151
|
+
const bufferedFrames = ring.snapshot();
|
|
152
|
+
const bufferedMs = ring.durationMs();
|
|
153
|
+
for (const backup of remaining) {
|
|
154
|
+
if (this.opts.breaker &&
|
|
155
|
+
!this.opts.breaker.isAvailable(backup.providerId)) {
|
|
156
|
+
continue;
|
|
157
|
+
}
|
|
158
|
+
try {
|
|
159
|
+
const session = await backup.startSession(config);
|
|
160
|
+
attach(session, backup.providerId);
|
|
161
|
+
if (bufferedMs >= minReplayMs) {
|
|
162
|
+
for (const f of bufferedFrames) {
|
|
163
|
+
try {
|
|
164
|
+
await session.pushAudio(f);
|
|
165
|
+
}
|
|
166
|
+
catch {
|
|
167
|
+
/* tolerate frame-level push failures during replay */
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
currentSession = session;
|
|
172
|
+
currentProvider = backup;
|
|
173
|
+
remaining = remaining.filter((c) => c !== backup);
|
|
174
|
+
this.activeProviderId = backup.providerId;
|
|
175
|
+
const lostMs = Date.now() - startedAt;
|
|
176
|
+
const evt = {
|
|
177
|
+
kind: 'stt',
|
|
178
|
+
from: initialProvider.providerId,
|
|
179
|
+
to: backup.providerId,
|
|
180
|
+
reason: classified.errorClass,
|
|
181
|
+
lostMs,
|
|
182
|
+
};
|
|
183
|
+
this.opts.onProviderFailover?.(evt);
|
|
184
|
+
this.emitMetric({ type: 'provider_failover', ...evt });
|
|
185
|
+
isFailingOver = false;
|
|
186
|
+
return;
|
|
187
|
+
}
|
|
188
|
+
catch (backupErr) {
|
|
189
|
+
const backClass = VoicePipelineError.classifyError(backupErr, {
|
|
190
|
+
kind: 'stt',
|
|
191
|
+
provider: backup.providerId,
|
|
192
|
+
});
|
|
193
|
+
this.opts.breaker?.recordFailure(backup.providerId, backClass.errorClass);
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
// All backups exhausted — propagate to the facade consumer.
|
|
197
|
+
facade.emit('error', new AggregateVoiceError([classified]));
|
|
198
|
+
isFailingOver = false;
|
|
199
|
+
};
|
|
200
|
+
attach(initial, initialProvider.providerId);
|
|
201
|
+
// The returned object must conform to StreamingSTTSession (EventEmitter
|
|
202
|
+
// with pushAudio + close). We build that explicitly so TS sees the
|
|
203
|
+
// right shape.
|
|
204
|
+
const wrapped = Object.assign(facade, {
|
|
205
|
+
providerId: 'chain',
|
|
206
|
+
pushAudio: async (frame) => {
|
|
207
|
+
ring.push(frame);
|
|
208
|
+
try {
|
|
209
|
+
await currentSession.pushAudio(frame);
|
|
210
|
+
}
|
|
211
|
+
catch (pushErr) {
|
|
212
|
+
void tryFailover(pushErr);
|
|
213
|
+
}
|
|
214
|
+
},
|
|
215
|
+
close: async () => {
|
|
216
|
+
await currentSession.close();
|
|
217
|
+
},
|
|
218
|
+
});
|
|
219
|
+
return wrapped;
|
|
220
|
+
}
|
|
221
|
+
emitMetric(event) {
|
|
222
|
+
this.opts.metrics?.emit(event);
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
//# sourceMappingURL=StreamingSTTChain.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"StreamingSTTChain.js","sourceRoot":"","sources":["../../../src/voice-pipeline/providers/StreamingSTTChain.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @module voice-pipeline/providers/StreamingTTSChain
|
|
3
|
+
*
|
|
4
|
+
* Priority-ordered fallback wrapper around multiple `IStreamingTTS`
|
|
5
|
+
* providers. Mirrors `StreamingSTTChain` semantics for outbound synthesis.
|
|
6
|
+
*
|
|
7
|
+
* Mid-synthesis failover is simpler than mid-utterance STT failover
|
|
8
|
+
* because TTS is one-way (text in, audio out). The chain accumulates
|
|
9
|
+
* tokens pushed to the primary and, on primary failure, re-sends them
|
|
10
|
+
* to the backup. Clients may use the first backup audio chunk's
|
|
11
|
+
* `fadeInMs` hint to crossfade between timbres.
|
|
12
|
+
*/
|
|
13
|
+
import type { IStreamingTTS, StreamingTTSSession, StreamingTTSConfig } from '../types.js';
|
|
14
|
+
import type { HealthyProvider } from '../HealthyProvider.js';
|
|
15
|
+
import { type HealthErrorClass } from '../VoicePipelineError.js';
|
|
16
|
+
import type { CircuitBreaker } from '../CircuitBreaker.js';
|
|
17
|
+
import type { VoiceMetricsReporter } from '../VoiceMetricsReporter.js';
|
|
18
|
+
export interface TTSProviderSelectedEvent {
|
|
19
|
+
kind: 'tts';
|
|
20
|
+
providerId: string;
|
|
21
|
+
attempt: number;
|
|
22
|
+
}
|
|
23
|
+
export interface TTSProviderFailedEvent {
|
|
24
|
+
kind: 'tts';
|
|
25
|
+
providerId: string;
|
|
26
|
+
errorClass: HealthErrorClass;
|
|
27
|
+
message: string;
|
|
28
|
+
}
|
|
29
|
+
export interface TTSProviderFailoverEvent {
|
|
30
|
+
kind: 'tts';
|
|
31
|
+
from: string;
|
|
32
|
+
to: string;
|
|
33
|
+
reason: HealthErrorClass;
|
|
34
|
+
lostMs: number;
|
|
35
|
+
}
|
|
36
|
+
export interface StreamingTTSChainOptions {
|
|
37
|
+
breaker?: CircuitBreaker;
|
|
38
|
+
metrics?: VoiceMetricsReporter;
|
|
39
|
+
onProviderSelected?: (event: TTSProviderSelectedEvent) => void;
|
|
40
|
+
onProviderFailed?: (event: TTSProviderFailedEvent) => void;
|
|
41
|
+
onProviderFailover?: (event: TTSProviderFailoverEvent) => void;
|
|
42
|
+
/** When true, the chain tracks accumulated tokens and re-submits them
|
|
43
|
+
* to the next backup if the primary errors mid-synthesis. */
|
|
44
|
+
enableMidSynthesisFailover?: boolean;
|
|
45
|
+
}
|
|
46
|
+
type TTSProvider = IStreamingTTS & HealthyProvider;
|
|
47
|
+
export declare class StreamingTTSChain implements IStreamingTTS {
|
|
48
|
+
readonly providerId = "chain";
|
|
49
|
+
private readonly _providers;
|
|
50
|
+
private readonly opts;
|
|
51
|
+
private activeProviderId?;
|
|
52
|
+
constructor(providers: TTSProvider[], opts?: StreamingTTSChainOptions);
|
|
53
|
+
get providers(): readonly TTSProvider[];
|
|
54
|
+
get currentProviderId(): string | undefined;
|
|
55
|
+
startSession(config?: StreamingTTSConfig): Promise<StreamingTTSSession>;
|
|
56
|
+
private filterCandidates;
|
|
57
|
+
/**
|
|
58
|
+
* Wraps a session for mid-synthesis failover. The facade tees pushTokens
|
|
59
|
+
* calls into an accumulator and, when the primary emits 'error',
|
|
60
|
+
* opens a new session on the next backup and replays the accumulator
|
|
61
|
+
* before returning control.
|
|
62
|
+
*/
|
|
63
|
+
private wrapSession;
|
|
64
|
+
private emitMetric;
|
|
65
|
+
}
|
|
66
|
+
export {};
|
|
67
|
+
//# sourceMappingURL=StreamingTTSChain.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"StreamingTTSChain.d.ts","sourceRoot":"","sources":["../../../src/voice-pipeline/providers/StreamingTTSChain.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAGH,OAAO,KAAK,EACV,aAAa,EACb,mBAAmB,EACnB,kBAAkB,EAEnB,MAAM,aAAa,CAAC;AACrB,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAC7D,OAAO,EAGL,KAAK,gBAAgB,EACtB,MAAM,0BAA0B,CAAC;AAClC,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAC3D,OAAO,KAAK,EACV,oBAAoB,EAErB,MAAM,4BAA4B,CAAC;AAEpC,MAAM,WAAW,wBAAwB;IACvC,IAAI,EAAE,KAAK,CAAC;IACZ,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,sBAAsB;IACrC,IAAI,EAAE,KAAK,CAAC;IACZ,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,gBAAgB,CAAC;IAC7B,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,wBAAwB;IACvC,IAAI,EAAE,KAAK,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,gBAAgB,CAAC;IACzB,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,wBAAwB;IACvC,OAAO,CAAC,EAAE,cAAc,CAAC;IACzB,OAAO,CAAC,EAAE,oBAAoB,CAAC;IAC/B,kBAAkB,CAAC,EAAE,CAAC,KAAK,EAAE,wBAAwB,KAAK,IAAI,CAAC;IAC/D,gBAAgB,CAAC,EAAE,CAAC,KAAK,EAAE,sBAAsB,KAAK,IAAI,CAAC;IAC3D,kBAAkB,CAAC,EAAE,CAAC,KAAK,EAAE,wBAAwB,KAAK,IAAI,CAAC;IAC/D;kEAC8D;IAC9D,0BAA0B,CAAC,EAAE,OAAO,CAAC;CACtC;AAED,KAAK,WAAW,GAAG,aAAa,GAAG,eAAe,CAAC;AAEnD,qBAAa,iBAAkB,YAAW,aAAa;IACrD,QAAQ,CAAC,UAAU,WAAW;IAE9B,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAgB;IAC3C,OAAO,CAAC,QAAQ,CAAC,IAAI,CAA2B;IAChD,OAAO,CAAC,gBAAgB,CAAC,CAAS;gBAEtB,SAAS,EAAE,WAAW,EAAE,EAAE,IAAI,GAAE,wBAA6B;IAQzE,IAAI,SAAS,IAAI,SAAS,WAAW,EAAE,CAEtC;IAED,IAAI,iBAAiB,IAAI,MAAM,GAAG,SAAS,CAE1C;IAEK,YAAY,CAAC,MAAM,CAAC,EAAE,kBAAkB,GAAG,OAAO,CAAC,mBAAmB,CAAC;IA6D7E,OAAO,CAAC,gBAAgB;IAOxB;;;;;OAKG;IACH,OAAO,CAAC,WAAW;IAsInB,OAAO,CAAC,UAAU;CAGnB"}
|
|
@@ -0,0 +1,212 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @module voice-pipeline/providers/StreamingTTSChain
|
|
3
|
+
*
|
|
4
|
+
* Priority-ordered fallback wrapper around multiple `IStreamingTTS`
|
|
5
|
+
* providers. Mirrors `StreamingSTTChain` semantics for outbound synthesis.
|
|
6
|
+
*
|
|
7
|
+
* Mid-synthesis failover is simpler than mid-utterance STT failover
|
|
8
|
+
* because TTS is one-way (text in, audio out). The chain accumulates
|
|
9
|
+
* tokens pushed to the primary and, on primary failure, re-sends them
|
|
10
|
+
* to the backup. Clients may use the first backup audio chunk's
|
|
11
|
+
* `fadeInMs` hint to crossfade between timbres.
|
|
12
|
+
*/
|
|
13
|
+
import { EventEmitter } from 'node:events';
|
|
14
|
+
import { VoicePipelineError, AggregateVoiceError, } from '../VoicePipelineError.js';
|
|
15
|
+
export class StreamingTTSChain {
|
|
16
|
+
constructor(providers, opts = {}) {
|
|
17
|
+
this.providerId = 'chain';
|
|
18
|
+
if (providers.length === 0) {
|
|
19
|
+
throw new Error('StreamingTTSChain requires at least one provider');
|
|
20
|
+
}
|
|
21
|
+
this._providers = [...providers].sort((a, b) => a.priority - b.priority);
|
|
22
|
+
this.opts = opts;
|
|
23
|
+
}
|
|
24
|
+
get providers() {
|
|
25
|
+
return this._providers;
|
|
26
|
+
}
|
|
27
|
+
get currentProviderId() {
|
|
28
|
+
return this.activeProviderId;
|
|
29
|
+
}
|
|
30
|
+
async startSession(config) {
|
|
31
|
+
const candidates = this.filterCandidates();
|
|
32
|
+
if (candidates.length === 0) {
|
|
33
|
+
this.emitMetric({
|
|
34
|
+
type: 'provider_unavailable',
|
|
35
|
+
kind: 'tts',
|
|
36
|
+
checkedProviders: this._providers.map((p) => p.providerId),
|
|
37
|
+
});
|
|
38
|
+
throw new Error('No TTS providers available (all tripped or filtered)');
|
|
39
|
+
}
|
|
40
|
+
const attempts = [];
|
|
41
|
+
for (let i = 0; i < candidates.length; i++) {
|
|
42
|
+
const provider = candidates[i];
|
|
43
|
+
try {
|
|
44
|
+
const session = await provider.startSession(config);
|
|
45
|
+
this.activeProviderId = provider.providerId;
|
|
46
|
+
const evt = {
|
|
47
|
+
kind: 'tts',
|
|
48
|
+
providerId: provider.providerId,
|
|
49
|
+
attempt: i + 1,
|
|
50
|
+
};
|
|
51
|
+
this.opts.onProviderSelected?.(evt);
|
|
52
|
+
this.emitMetric({ type: 'provider_selected', ...evt });
|
|
53
|
+
this.opts.breaker?.recordSuccess(provider.providerId);
|
|
54
|
+
return this.wrapSession(session, provider, candidates.slice(i + 1), config);
|
|
55
|
+
}
|
|
56
|
+
catch (err) {
|
|
57
|
+
const classified = VoicePipelineError.classifyError(err, {
|
|
58
|
+
kind: 'tts',
|
|
59
|
+
provider: provider.providerId,
|
|
60
|
+
});
|
|
61
|
+
attempts.push(classified);
|
|
62
|
+
const failEvt = {
|
|
63
|
+
kind: 'tts',
|
|
64
|
+
providerId: provider.providerId,
|
|
65
|
+
errorClass: classified.errorClass,
|
|
66
|
+
message: classified.message,
|
|
67
|
+
};
|
|
68
|
+
this.opts.onProviderFailed?.(failEvt);
|
|
69
|
+
this.emitMetric({ type: 'provider_failed', ...failEvt });
|
|
70
|
+
this.opts.breaker?.recordFailure(provider.providerId, classified.errorClass);
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
this.emitMetric({
|
|
74
|
+
type: 'provider_unavailable',
|
|
75
|
+
kind: 'tts',
|
|
76
|
+
checkedProviders: candidates.map((p) => p.providerId),
|
|
77
|
+
});
|
|
78
|
+
throw new AggregateVoiceError(attempts);
|
|
79
|
+
}
|
|
80
|
+
filterCandidates() {
|
|
81
|
+
if (!this.opts.breaker)
|
|
82
|
+
return this._providers;
|
|
83
|
+
return this._providers.filter((p) => this.opts.breaker.isAvailable(p.providerId));
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* Wraps a session for mid-synthesis failover. The facade tees pushTokens
|
|
87
|
+
* calls into an accumulator and, when the primary emits 'error',
|
|
88
|
+
* opens a new session on the next backup and replays the accumulator
|
|
89
|
+
* before returning control.
|
|
90
|
+
*/
|
|
91
|
+
wrapSession(initial, initialProvider, candidates, config) {
|
|
92
|
+
if (!this.opts.enableMidSynthesisFailover)
|
|
93
|
+
return initial;
|
|
94
|
+
const facade = new EventEmitter();
|
|
95
|
+
const tokensSinceFlush = [];
|
|
96
|
+
let currentSession = initial;
|
|
97
|
+
let currentProvider = initialProvider;
|
|
98
|
+
let remaining = [...candidates];
|
|
99
|
+
let isFailingOver = false;
|
|
100
|
+
const attach = (session, _providerId) => {
|
|
101
|
+
session.on('audio', (chunk) => {
|
|
102
|
+
facade.emit('audio', chunk);
|
|
103
|
+
});
|
|
104
|
+
session.on('flush_complete', () => {
|
|
105
|
+
tokensSinceFlush.length = 0;
|
|
106
|
+
facade.emit('flush_complete');
|
|
107
|
+
});
|
|
108
|
+
session.on('error', (err) => {
|
|
109
|
+
void tryFailover(err);
|
|
110
|
+
});
|
|
111
|
+
session.on('close', () => {
|
|
112
|
+
if (!isFailingOver && currentSession === session) {
|
|
113
|
+
void tryFailover(undefined);
|
|
114
|
+
}
|
|
115
|
+
});
|
|
116
|
+
};
|
|
117
|
+
const tryFailover = async (err) => {
|
|
118
|
+
if (isFailingOver)
|
|
119
|
+
return;
|
|
120
|
+
isFailingOver = true;
|
|
121
|
+
const startedAt = Date.now();
|
|
122
|
+
const classified = VoicePipelineError.classifyError(err ?? new Error('session ended'), { kind: 'tts', provider: currentProvider.providerId });
|
|
123
|
+
this.opts.breaker?.recordFailure(currentProvider.providerId, classified.errorClass);
|
|
124
|
+
for (const backup of remaining) {
|
|
125
|
+
if (this.opts.breaker &&
|
|
126
|
+
!this.opts.breaker.isAvailable(backup.providerId)) {
|
|
127
|
+
continue;
|
|
128
|
+
}
|
|
129
|
+
try {
|
|
130
|
+
const session = await backup.startSession(config);
|
|
131
|
+
attach(session, backup.providerId);
|
|
132
|
+
// Replay everything accumulated since the last successful flush.
|
|
133
|
+
for (const t of tokensSinceFlush) {
|
|
134
|
+
try {
|
|
135
|
+
session.pushTokens(t);
|
|
136
|
+
}
|
|
137
|
+
catch {
|
|
138
|
+
/* tolerate per-token failures during replay */
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
currentSession = session;
|
|
142
|
+
currentProvider = backup;
|
|
143
|
+
remaining = remaining.filter((c) => c !== backup);
|
|
144
|
+
this.activeProviderId = backup.providerId;
|
|
145
|
+
const evt = {
|
|
146
|
+
kind: 'tts',
|
|
147
|
+
from: initialProvider.providerId,
|
|
148
|
+
to: backup.providerId,
|
|
149
|
+
reason: classified.errorClass,
|
|
150
|
+
lostMs: Date.now() - startedAt,
|
|
151
|
+
};
|
|
152
|
+
this.opts.onProviderFailover?.(evt);
|
|
153
|
+
this.emitMetric({ type: 'provider_failover', ...evt });
|
|
154
|
+
isFailingOver = false;
|
|
155
|
+
return;
|
|
156
|
+
}
|
|
157
|
+
catch (backupErr) {
|
|
158
|
+
const backClass = VoicePipelineError.classifyError(backupErr, {
|
|
159
|
+
kind: 'tts',
|
|
160
|
+
provider: backup.providerId,
|
|
161
|
+
});
|
|
162
|
+
this.opts.breaker?.recordFailure(backup.providerId, backClass.errorClass);
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
facade.emit('error', new AggregateVoiceError([classified]));
|
|
166
|
+
isFailingOver = false;
|
|
167
|
+
};
|
|
168
|
+
attach(initial, initialProvider.providerId);
|
|
169
|
+
const wrapped = Object.assign(facade, {
|
|
170
|
+
providerId: 'chain',
|
|
171
|
+
pushTokens: (tokens) => {
|
|
172
|
+
tokensSinceFlush.push(tokens);
|
|
173
|
+
try {
|
|
174
|
+
currentSession.pushTokens(tokens);
|
|
175
|
+
}
|
|
176
|
+
catch (err) {
|
|
177
|
+
void tryFailover(err);
|
|
178
|
+
}
|
|
179
|
+
},
|
|
180
|
+
flush: async () => {
|
|
181
|
+
try {
|
|
182
|
+
await currentSession.flush();
|
|
183
|
+
}
|
|
184
|
+
catch (err) {
|
|
185
|
+
void tryFailover(err);
|
|
186
|
+
}
|
|
187
|
+
},
|
|
188
|
+
cancel: () => {
|
|
189
|
+
tokensSinceFlush.length = 0;
|
|
190
|
+
try {
|
|
191
|
+
currentSession.cancel();
|
|
192
|
+
}
|
|
193
|
+
catch {
|
|
194
|
+
/* best-effort */
|
|
195
|
+
}
|
|
196
|
+
},
|
|
197
|
+
close: () => {
|
|
198
|
+
try {
|
|
199
|
+
currentSession.close();
|
|
200
|
+
}
|
|
201
|
+
catch {
|
|
202
|
+
/* best-effort */
|
|
203
|
+
}
|
|
204
|
+
},
|
|
205
|
+
});
|
|
206
|
+
return wrapped;
|
|
207
|
+
}
|
|
208
|
+
emitMetric(event) {
|
|
209
|
+
this.opts.metrics?.emit(event);
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
//# sourceMappingURL=StreamingTTSChain.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"StreamingTTSChain.js","sourceRoot":"","sources":["../../../src/voice-pipeline/providers/StreamingTTSChain.ts"],"names":[],"mappings":"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"}
|
|
@@ -17,4 +17,6 @@ export { OpenAIBatchTTS, type OpenAIBatchTTSConfig } from './OpenAIBatchTTS.js';
|
|
|
17
17
|
export { ElevenLabsBatchTTS, type ElevenLabsBatchTTSConfig } from './ElevenLabsBatchTTS.js';
|
|
18
18
|
export { BatchTTSFallback } from './BatchTTSFallback.js';
|
|
19
19
|
export { OpenAIRealtimeTTS, type OpenAIRealtimeTTSConfig } from './OpenAIRealtimeTTS.js';
|
|
20
|
+
export { StreamingSTTChain, type StreamingSTTChainOptions, type ProviderSelectedEvent, type ProviderFailedEvent, type ProviderFailoverEvent, } from './StreamingSTTChain.js';
|
|
21
|
+
export { StreamingTTSChain, type StreamingTTSChainOptions, type TTSProviderSelectedEvent, type TTSProviderFailedEvent, type TTSProviderFailoverEvent, } from './StreamingTTSChain.js';
|
|
20
22
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/voice-pipeline/providers/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,EAAE,oBAAoB,EAAE,KAAK,0BAA0B,EAAE,MAAM,2BAA2B,CAAC;AAClG,OAAO,EACL,sBAAsB,EACtB,KAAK,4BAA4B,GAClC,MAAM,6BAA6B,CAAC;AACrC,OAAO,EACL,sBAAsB,EACtB,KAAK,4BAA4B,GAClC,MAAM,6BAA6B,CAAC;AACrC,OAAO,EAAE,wBAAwB,EAAE,MAAM,+BAA+B,CAAC;AACzE,OAAO,EAAE,cAAc,EAAE,KAAK,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AAChF,OAAO,EAAE,kBAAkB,EAAE,KAAK,wBAAwB,EAAE,MAAM,yBAAyB,CAAC;AAC5F,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AACzD,OAAO,EAAE,iBAAiB,EAAE,KAAK,uBAAuB,EAAE,MAAM,wBAAwB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/voice-pipeline/providers/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,EAAE,oBAAoB,EAAE,KAAK,0BAA0B,EAAE,MAAM,2BAA2B,CAAC;AAClG,OAAO,EACL,sBAAsB,EACtB,KAAK,4BAA4B,GAClC,MAAM,6BAA6B,CAAC;AACrC,OAAO,EACL,sBAAsB,EACtB,KAAK,4BAA4B,GAClC,MAAM,6BAA6B,CAAC;AACrC,OAAO,EAAE,wBAAwB,EAAE,MAAM,+BAA+B,CAAC;AACzE,OAAO,EAAE,cAAc,EAAE,KAAK,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AAChF,OAAO,EAAE,kBAAkB,EAAE,KAAK,wBAAwB,EAAE,MAAM,yBAAyB,CAAC;AAC5F,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AACzD,OAAO,EAAE,iBAAiB,EAAE,KAAK,uBAAuB,EAAE,MAAM,wBAAwB,CAAC;AACzF,OAAO,EACL,iBAAiB,EACjB,KAAK,wBAAwB,EAC7B,KAAK,qBAAqB,EAC1B,KAAK,mBAAmB,EACxB,KAAK,qBAAqB,GAC3B,MAAM,wBAAwB,CAAC;AAChC,OAAO,EACL,iBAAiB,EACjB,KAAK,wBAAwB,EAC7B,KAAK,wBAAwB,EAC7B,KAAK,sBAAsB,EAC3B,KAAK,wBAAwB,GAC9B,MAAM,wBAAwB,CAAC"}
|
|
@@ -17,4 +17,6 @@ export { OpenAIBatchTTS } from './OpenAIBatchTTS.js';
|
|
|
17
17
|
export { ElevenLabsBatchTTS } from './ElevenLabsBatchTTS.js';
|
|
18
18
|
export { BatchTTSFallback } from './BatchTTSFallback.js';
|
|
19
19
|
export { OpenAIRealtimeTTS } from './OpenAIRealtimeTTS.js';
|
|
20
|
+
export { StreamingSTTChain, } from './StreamingSTTChain.js';
|
|
21
|
+
export { StreamingTTSChain, } from './StreamingTTSChain.js';
|
|
20
22
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/voice-pipeline/providers/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,EAAE,oBAAoB,EAAmC,MAAM,2BAA2B,CAAC;AAClG,OAAO,EACL,sBAAsB,GAEvB,MAAM,6BAA6B,CAAC;AACrC,OAAO,EACL,sBAAsB,GAEvB,MAAM,6BAA6B,CAAC;AACrC,OAAO,EAAE,wBAAwB,EAAE,MAAM,+BAA+B,CAAC;AACzE,OAAO,EAAE,cAAc,EAA6B,MAAM,qBAAqB,CAAC;AAChF,OAAO,EAAE,kBAAkB,EAAiC,MAAM,yBAAyB,CAAC;AAC5F,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AACzD,OAAO,EAAE,iBAAiB,EAAgC,MAAM,wBAAwB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/voice-pipeline/providers/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,EAAE,oBAAoB,EAAmC,MAAM,2BAA2B,CAAC;AAClG,OAAO,EACL,sBAAsB,GAEvB,MAAM,6BAA6B,CAAC;AACrC,OAAO,EACL,sBAAsB,GAEvB,MAAM,6BAA6B,CAAC;AACrC,OAAO,EAAE,wBAAwB,EAAE,MAAM,+BAA+B,CAAC;AACzE,OAAO,EAAE,cAAc,EAA6B,MAAM,qBAAqB,CAAC;AAChF,OAAO,EAAE,kBAAkB,EAAiC,MAAM,yBAAyB,CAAC;AAC5F,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AACzD,OAAO,EAAE,iBAAiB,EAAgC,MAAM,wBAAwB,CAAC;AACzF,OAAO,EACL,iBAAiB,GAKlB,MAAM,wBAAwB,CAAC;AAChC,OAAO,EACL,iBAAiB,GAKlB,MAAM,wBAAwB,CAAC"}
|