use-voice-control 0.1.0 → 0.1.2

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.
@@ -0,0 +1,349 @@
1
+ # Speech Library Architecture
2
+
3
+ ## System Overview
4
+
5
+ ```
6
+ ┌─────────────────────────────────────────────────────────────┐
7
+ │ Client Layer │
8
+ ├─────────────────────────────────────────────────────────────┤
9
+ │ • React Components (client-example.tsx) │
10
+ │ • Browser Audio APIs │
11
+ │ • Fetch API │
12
+ └──────────────────────┬──────────────────────────────────────┘
13
+ │ HTTP POST
14
+ │ /api/agent/voice
15
+
16
+ ┌─────────────────────────────────────────────────────────────┐
17
+ │ API Route Layer │
18
+ ├─────────────────────────────────────────────────────────────┤
19
+ │ app/api/agent/voice/route.ts │
20
+ │ • Request validation │
21
+ │ • Rate limiting (10/day guests) │
22
+ │ • Error handling │
23
+ └──────────────────────┬──────────────────────────────────────┘
24
+
25
+ │ generateSpeech()
26
+
27
+ ┌─────────────────────────────────────────────────────────────┐
28
+ │ Speech Library Core │
29
+ ├─────────────────────────────────────────────────────────────┤
30
+ │ lib/speech/index.ts │
31
+ │ • Provider routing │
32
+ │ • Input normalization │
33
+ │ • Unified interface │
34
+ └──────────────┬──────────────────────┬───────────────────────┘
35
+ │ │
36
+ │ │
37
+ ┌───────▼────────┐ ┌───────▼────────┐
38
+ │ │ │ │
39
+ │ Kokoro Provider│ │Deepgram Provider│
40
+ │ │ │ │
41
+ │ kokoro.ts │ │ deepgram.ts │
42
+ │ │ │ │
43
+ └────────┬────────┘ └────────┬────────┘
44
+ │ │
45
+ │ │
46
+ ┌───────▼────────┐ ┌────────▼────────┐
47
+ │ │ │ │
48
+ │ kokoro-js │ │ Cloudflare AI │
49
+ │ (Node CPU) │ │ Workers AI │
50
+ │ │ │ │
51
+ │ • ONNX Runtime │ │ • Deepgram Aura │
52
+ │ • 82M params │ │ • MP3 encoder │
53
+ │ • WAV output │ │ │
54
+ └─────────────────┘ └──────────────────┘
55
+ ```
56
+
57
+ ## Data Flow
58
+
59
+ ### Request Flow
60
+ ```
61
+ 1. Client sends POST /api/agent/voice
62
+ {
63
+ "text": "Hello world",
64
+ "provider": "kokoro",
65
+ "voice": "af_heart"
66
+ }
67
+
68
+ 2. API Route validates & rate-limits
69
+
70
+ 3. Calls generateSpeech()
71
+
72
+ 4. Routes to kokoro.ts or deepgram.ts
73
+
74
+ 5. Provider generates audio
75
+
76
+ 6. Returns { audio: ArrayBuffer, contentType: string }
77
+
78
+ 7. API Route streams audio to client
79
+ ```
80
+
81
+ ### Response Flow
82
+ ```
83
+ HTTP 200 OK
84
+ Content-Type: audio/wav (Kokoro) or audio/mpeg (Deepgram)
85
+ Cache-Control: public, max-age=86400
86
+ Content-Disposition: inline; filename="speech.wav"
87
+
88
+ [Binary audio data]
89
+ ```
90
+
91
+ ## Module Dependencies
92
+
93
+ ```
94
+ route.ts
95
+ ├── @/lib/speech (unified interface)
96
+ │ ├── types.ts (shared types)
97
+ │ ├── kokoro.ts
98
+ │ │ └── kokoro-js (npm package)
99
+ │ │ └── onnxruntime-web
100
+ │ └── deepgram.ts
101
+ │ └── @/lib/cloudflare-context
102
+ ├── @/lib/auth/session (getUserId)
103
+ └── @/lib/rate-limit/guestRateLimiter
104
+ ```
105
+
106
+ ## Type System
107
+
108
+ ```ts
109
+ // Core types
110
+ type TTSProvider = "kokoro" | "deepgram";
111
+
112
+ interface TTSOptions {
113
+ text: string;
114
+ provider?: TTSProvider;
115
+ voice?: string;
116
+ }
117
+
118
+ interface TTSResult {
119
+ audio: ArrayBuffer;
120
+ contentType: string;
121
+ }
122
+
123
+ // Voice types
124
+ type KokoroVoice = "af_heart" | "af_alloy" | ... (16 total)
125
+ type DeepgramSpeaker = "angus" | "asteria" | ... (12 total)
126
+ ```
127
+
128
+ ## State Management
129
+
130
+ ### Kokoro Model Loading
131
+ ```ts
132
+ let ttsInstance: KokoroTTS | null = null;
133
+ let modelLoading: Promise<KokoroTTS> | null = null;
134
+
135
+ // Lazy singleton pattern
136
+ async function getKokoroTTS() {
137
+ if (ttsInstance) return ttsInstance;
138
+ if (modelLoading) await modelLoading;
139
+
140
+ modelLoading = KokoroTTS.from_pretrained(...);
141
+ ttsInstance = await modelLoading;
142
+ modelLoading = null;
143
+
144
+ return ttsInstance;
145
+ }
146
+ ```
147
+
148
+ **Benefits:**
149
+ - Model loads once per server instance
150
+ - Concurrent requests wait for single download
151
+ - No memory leaks or duplicate loads
152
+
153
+ ### Rate Limiting State
154
+ ```ts
155
+ // In-memory counter per IP/userId
156
+ const rateLimitMap = new Map<string, {
157
+ count: number;
158
+ resetAt: number;
159
+ }>();
160
+ ```
161
+
162
+ ## Error Handling
163
+
164
+ ```
165
+ ┌─────────────────────────────────────┐
166
+ │ Error Categories │
167
+ ├─────────────────────────────────────┤
168
+ │ │
169
+ │ 1. Client Errors (400) │
170
+ │ • Missing text │
171
+ │ • Invalid JSON │
172
+ │ │
173
+ │ 2. Rate Limiting (429) │
174
+ │ • Daily limit exceeded │
175
+ │ │
176
+ │ 3. Provider Errors (503) │
177
+ │ • Model loading failed (Kokoro) │
178
+ │ • CF binding missing (Deepgram) │
179
+ │ │
180
+ │ 4. Runtime Errors (500) │
181
+ │ • Generation failed │
182
+ │ • Unknown errors │
183
+ │ │
184
+ └─────────────────────────────────────┘
185
+ ```
186
+
187
+ ## Performance Characteristics
188
+
189
+ ### Kokoro
190
+ ```
191
+ First Request:
192
+ Model Download: ~2-3s (82MB, one-time)
193
+ Generation: ~100-300ms
194
+ Total: ~2-3s
195
+
196
+ Subsequent Requests:
197
+ Generation: ~100-300ms
198
+ (No network calls)
199
+ ```
200
+
201
+ ### Deepgram
202
+ ```
203
+ All Requests:
204
+ Network RTT: ~50-200ms
205
+ Generation: ~200-400ms
206
+ Total: ~300-500ms
207
+ (Depends on edge location)
208
+ ```
209
+
210
+ ## Deployment Considerations
211
+
212
+ ### Development
213
+ ```yaml
214
+ Environment: Node.js
215
+ Model Storage: ~/.cache/huggingface/
216
+ Network: Required for first Kokoro download
217
+ Cloudflare: Optional (Deepgram won't work)
218
+ ```
219
+
220
+ ### Production
221
+ ```yaml
222
+ Build:
223
+ - No prebuild needed
224
+ - Model downloads on first request
225
+
226
+ Runtime:
227
+ - Node.js (not Edge)
228
+ - CPU: 2+ cores recommended
229
+ - RAM: 512MB+ for Kokoro model
230
+ - Disk: 100MB for cached model
231
+
232
+ Cloudflare Workers:
233
+ - Deepgram requires AI binding
234
+ - Kokoro requires Node runtime
235
+ ```
236
+
237
+ ## Security
238
+
239
+ ### Rate Limiting
240
+ ```ts
241
+ // IP-based for guests
242
+ const rateLimitKey =
243
+ userId ??
244
+ req.headers.get("x-forwarded-for")?.split(",")[0] ??
245
+ req.headers.get("x-real-ip") ??
246
+ "unknown";
247
+ ```
248
+
249
+ ### Input Sanitization
250
+ ```ts
251
+ // Max length enforcement
252
+ text: text.slice(0, 5000)
253
+
254
+ // Type validation
255
+ if (!text || typeof text !== "string" || text.trim().length === 0) {
256
+ throw new Error("Text is required");
257
+ }
258
+
259
+ // Voice validation
260
+ const voice = VOICES.includes(requested) ? requested : DEFAULT;
261
+ ```
262
+
263
+ ### Headers
264
+ ```ts
265
+ // Cache control
266
+ "Cache-Control": "public, max-age=86400"
267
+
268
+ // Content type enforcement
269
+ "Content-Type": result.contentType // Never user-controlled
270
+
271
+ // Safe filename
272
+ "Content-Disposition": `inline; filename="speech.${ext}"`
273
+ ```
274
+
275
+ ## Testing Strategy
276
+
277
+ ### Unit Tests
278
+ ```ts
279
+ // test.ts - Basic functionality
280
+ - Model loading
281
+ - Voice generation
282
+ - File output
283
+ ```
284
+
285
+ ### Integration Tests
286
+ ```bash
287
+ # API endpoint
288
+ curl -X POST /api/agent/voice -d '{"text":"test"}'
289
+
290
+ # Expected: 200 OK, audio/wav
291
+ ```
292
+
293
+ ### Load Tests
294
+ ```bash
295
+ # Concurrent requests (model singleton)
296
+ ab -n 100 -c 10 http://localhost:3000/api/agent/voice
297
+
298
+ # Expected: All requests succeed, first is slower
299
+ ```
300
+
301
+ ## Future Enhancements
302
+
303
+ ### Potential Improvements
304
+ 1. **Streaming Audio**: Chunked transfer encoding
305
+ 2. **Voice Cloning**: Custom voice training
306
+ 3. **SSML Support**: Prosody control
307
+ 4. **Multi-language**: International voices
308
+ 5. **Caching**: Redis for repeated phrases
309
+ 6. **Metrics**: Prometheus exports
310
+ 7. **A/B Testing**: Quality comparisons
311
+
312
+ ### Provider Additions
313
+ - **ElevenLabs**: Ultra-realistic voices
314
+ - **Azure TTS**: Enterprise features
315
+ - **Google Cloud TTS**: WaveNet quality
316
+ - **AWS Polly**: Neural voices
317
+
318
+ ## Monitoring
319
+
320
+ ### Key Metrics
321
+ ```ts
322
+ // Track these in production
323
+ - Request rate (req/s)
324
+ - Error rate (%)
325
+ - P50/P95/P99 latency (ms)
326
+ - Provider distribution (kokoro vs deepgram)
327
+ - Cache hit rate (if implemented)
328
+ - Model load time (first request)
329
+ - Rate limit hits (per user)
330
+ ```
331
+
332
+ ### Logging
333
+ ```ts
334
+ console.log("[TTS]", {
335
+ provider,
336
+ voice,
337
+ textLength: text.length,
338
+ userId,
339
+ latency: Date.now() - start,
340
+ error: error?.message,
341
+ });
342
+ ```
343
+
344
+ ## References
345
+
346
+ - [Kokoro Model](https://huggingface.co/onnx-community/Kokoro-82M-v1.0-ONNX)
347
+ - [kokoro-js](https://www.npmjs.com/package/kokoro-js)
348
+ - [Deepgram Aura](https://developers.cloudflare.com/workers-ai/models/deepgram-aura/)
349
+ - [ONNX Runtime](https://onnxruntime.ai/)
@@ -0,0 +1,172 @@
1
+ # Kokoro TTS Migration: kokoro-js → Hugging Face Transformers
2
+
3
+ ## Overview
4
+
5
+ Kokoro TTS has been migrated from the `kokoro-js` package to use Hugging Face transformers library loaded from CDN, providing better flexibility and potentially improved performance.
6
+
7
+ ## What Changed
8
+
9
+ ### Browser Implementation (Client-Side)
10
+ - **Before**: Used `kokoro-js` npm package
11
+ - **After**: Uses Hugging Face transformers loaded from CDN (`https://cdn.jsdelivr.net/npm/@huggingface/transformers@3.5.1/dist/transformers.min.js`)
12
+
13
+ ### New Files Created
14
+
15
+ 1. **KokoroTTS.js** - Main TTS class implementing audio generation
16
+ - Loads model and tokenizer from Hugging Face Hub
17
+ - Generates phonemes from text
18
+ - Applies voice styling
19
+ - Produces audio output
20
+
21
+ 2. **main.js** - Main entry point for browser TTS
22
+ - Manages Web Worker for model loading
23
+ - Handles text-to-speech requests
24
+ - Provides `textToSpeech()` function
25
+ - Cleans markdown formatting from input text
26
+
27
+ 3. **worker.js** - Web Worker for model management
28
+ - Loads TTS model in background thread
29
+ - Handles audio generation without blocking UI
30
+ - Communicates via message passing
31
+
32
+ 4. **AudioPlayer.js** - Audio playback system
33
+ - Web Audio API integration
34
+ - Audio queuing and playback
35
+ - WAV format conversion
36
+ - RawAudio class for handling audio buffers
37
+
38
+ 5. **phonemize.js** - Text-to-phoneme conversion
39
+ - Converts input text to phonetic representation
40
+ - Language-specific processing (English/other)
41
+ - Can be extended with g2p-en library for better phonemization
42
+
43
+ 6. **voices.js** - Voice definitions and data management
44
+ - Voice catalog with metadata
45
+ - Voice data caching
46
+ - Fetches voice embeddings from Hugging Face
47
+
48
+ ### Updated Files
49
+
50
+ 1. **kokoro.ts** - Server-side TTS (apps/qwksearch-web)
51
+ - Updated to use Hugging Face transformers
52
+ - Currently shows placeholder (server-side needs additional setup)
53
+
54
+ 2. **kokoro.ts** - React client integration (packages/research-agent-ui)
55
+ - Updated imports to use Hugging Face transformers directly
56
+ - Simplified backend selection logic
57
+ - Removed kokoro-js specific handling
58
+
59
+ ## Model Details
60
+
61
+ - **Model**: `hexgrad/Kokoro-82M` (on Hugging Face Hub)
62
+ - **Format**: Transformers compatible
63
+ - **Backend**: WASM by default, WebGPU if available
64
+ - **Sample Rate**: 24000 Hz
65
+ - **Voice Style Dimension**: 256
66
+
67
+ ## Usage
68
+
69
+ ### Browser Usage
70
+
71
+ ```javascript
72
+ import { textToSpeech, ttsModelReadyPromise } from './main.js';
73
+
74
+ // Wait for model to load
75
+ await ttsModelReadyPromise;
76
+
77
+ // Generate and play speech
78
+ textToSpeech("Hello, world!", "af_heart");
79
+ ```
80
+
81
+ ### React Component
82
+
83
+ ```typescript
84
+ import { preloadKokoro, getKokoro } from '@lib/kokoro';
85
+
86
+ // Preload model
87
+ await preloadKokoro();
88
+
89
+ // Generate speech
90
+ const tts = await getKokoro();
91
+ const audio = await tts.generate("Hello, world!", { voice: "af_heart" });
92
+ ```
93
+
94
+ ## Available Voices
95
+
96
+ ### Female Voices (English)
97
+ - `af`, `af_heart`, `af_alloy`, `af_aoede`, `af_bella`
98
+ - `af_jessica`, `af_nicole`, `af_river`, `af_sarah`, `af_sky`
99
+
100
+ ### Male Voices (English)
101
+ - `am`, `am_adam`, `am_echo`, `am_fable`, `am_fenrir`
102
+ - `am_liam`, `am_michael`, `am_onyx`
103
+
104
+ ### Other Languages
105
+ - `bf`, `bm` (language variant 'b')
106
+
107
+ ## Backend Performance
108
+
109
+ ### WASM (Default)
110
+ - More compatible
111
+ - Lower memory usage
112
+ - Slightly slower
113
+ - Quantized to q8 for smaller model size
114
+
115
+ ### WebGPU (Fallback to WASM if unavailable)
116
+ - Faster on supported hardware
117
+ - Requires modern GPU support
118
+ - Full precision (fp32)
119
+
120
+ ## Dependencies
121
+
122
+ ### Browser
123
+ - Hugging Face transformers library (CDN)
124
+ - Web Audio API support
125
+
126
+ ### Node.js (Future)
127
+ - `@huggingface/transformers` npm package
128
+ - Additional setup required for server-side TTS
129
+
130
+ ## Migration Checklist
131
+
132
+ - [x] Create KokoroTTS class using HF transformers
133
+ - [x] Implement browser-based audio generation
134
+ - [x] Create Web Worker for background loading
135
+ - [x] Implement audio playback
136
+ - [x] Create supporting modules (phonemize, voices, AudioPlayer)
137
+ - [x] Update React client integration
138
+ - [x] Update Node.js server-side file
139
+
140
+ ## Next Steps
141
+
142
+ 1. **Testing**: Test audio generation with various voices and texts
143
+ 2. **Phonemization**: Consider using `g2p-en` library for better phoneme accuracy
144
+ 3. **Voice Data**: Verify voice embedding data loading from Hugging Face
145
+ 4. **Server-Side**: Implement server-side TTS if needed
146
+ 5. **Performance**: Monitor and optimize model loading time
147
+ 6. **Fallback**: Ensure Deepgram fallback still works if Kokoro fails
148
+
149
+ ## Known Limitations
150
+
151
+ - Voice data fetching requires internet connectivity
152
+ - Large model size (may cause initial load delay)
153
+ - Phonemization is simplified (could be improved with g2p-en)
154
+ - Server-side implementation placeholder (requires more work)
155
+
156
+ ## Troubleshooting
157
+
158
+ ### Model fails to load
159
+ - Check browser GPU/WASM support
160
+ - Verify Hugging Face Hub connectivity
161
+ - Try refreshing the page
162
+ - Check browser console for detailed error messages
163
+
164
+ ### Audio playback issues
165
+ - Ensure Web Audio API is available
166
+ - Check audio context state
167
+ - Verify speaker/audio output devices
168
+
169
+ ### Voice not found errors
170
+ - Use valid voice keys from the VOICES object
171
+ - Check for typos in voice name
172
+ - See Available Voices section above