modular-voice-agent-sdk 1.0.0

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.
Files changed (125) hide show
  1. package/README.md +102 -0
  2. package/USAGE.md +567 -0
  3. package/dist/backends/cloud/index.d.ts +7 -0
  4. package/dist/backends/cloud/index.d.ts.map +1 -0
  5. package/dist/backends/cloud/index.js +6 -0
  6. package/dist/backends/cloud/index.js.map +1 -0
  7. package/dist/backends/cloud/llm.d.ts +22 -0
  8. package/dist/backends/cloud/llm.d.ts.map +1 -0
  9. package/dist/backends/cloud/llm.js +234 -0
  10. package/dist/backends/cloud/llm.js.map +1 -0
  11. package/dist/backends/index.d.ts +2 -0
  12. package/dist/backends/index.d.ts.map +1 -0
  13. package/dist/backends/index.js +6 -0
  14. package/dist/backends/index.js.map +1 -0
  15. package/dist/backends/native/index.d.ts +5 -0
  16. package/dist/backends/native/index.d.ts.map +1 -0
  17. package/dist/backends/native/index.js +6 -0
  18. package/dist/backends/native/index.js.map +1 -0
  19. package/dist/backends/native/llm.d.ts +71 -0
  20. package/dist/backends/native/llm.d.ts.map +1 -0
  21. package/dist/backends/native/llm.js +435 -0
  22. package/dist/backends/native/llm.js.map +1 -0
  23. package/dist/backends/native/stt.d.ts +15 -0
  24. package/dist/backends/native/stt.d.ts.map +1 -0
  25. package/dist/backends/native/stt.js +94 -0
  26. package/dist/backends/native/stt.js.map +1 -0
  27. package/dist/backends/native/tts.d.ts +21 -0
  28. package/dist/backends/native/tts.d.ts.map +1 -0
  29. package/dist/backends/native/tts.js +105 -0
  30. package/dist/backends/native/tts.js.map +1 -0
  31. package/dist/backends/transformers/index.d.ts +4 -0
  32. package/dist/backends/transformers/index.d.ts.map +1 -0
  33. package/dist/backends/transformers/index.js +4 -0
  34. package/dist/backends/transformers/index.js.map +1 -0
  35. package/dist/backends/transformers/llm.d.ts +29 -0
  36. package/dist/backends/transformers/llm.d.ts.map +1 -0
  37. package/dist/backends/transformers/llm.js +117 -0
  38. package/dist/backends/transformers/llm.js.map +1 -0
  39. package/dist/backends/transformers/stt.d.ts +17 -0
  40. package/dist/backends/transformers/stt.d.ts.map +1 -0
  41. package/dist/backends/transformers/stt.js +43 -0
  42. package/dist/backends/transformers/stt.js.map +1 -0
  43. package/dist/backends/transformers/tts.d.ts +17 -0
  44. package/dist/backends/transformers/tts.d.ts.map +1 -0
  45. package/dist/backends/transformers/tts.js +40 -0
  46. package/dist/backends/transformers/tts.js.map +1 -0
  47. package/dist/cache.d.ts +37 -0
  48. package/dist/cache.d.ts.map +1 -0
  49. package/dist/cache.js +49 -0
  50. package/dist/cache.js.map +1 -0
  51. package/dist/cli.d.ts +11 -0
  52. package/dist/cli.d.ts.map +1 -0
  53. package/dist/cli.js +392 -0
  54. package/dist/cli.js.map +1 -0
  55. package/dist/client/audio-player.d.ts +45 -0
  56. package/dist/client/audio-player.d.ts.map +1 -0
  57. package/dist/client/audio-player.js +90 -0
  58. package/dist/client/audio-player.js.map +1 -0
  59. package/dist/client/audio-recorder.d.ts +42 -0
  60. package/dist/client/audio-recorder.d.ts.map +1 -0
  61. package/dist/client/audio-recorder.js +128 -0
  62. package/dist/client/audio-recorder.js.map +1 -0
  63. package/dist/client/index.d.ts +34 -0
  64. package/dist/client/index.d.ts.map +1 -0
  65. package/dist/client/index.js +33 -0
  66. package/dist/client/index.js.map +1 -0
  67. package/dist/client/protocol.d.ts +80 -0
  68. package/dist/client/protocol.d.ts.map +1 -0
  69. package/dist/client/protocol.js +29 -0
  70. package/dist/client/protocol.js.map +1 -0
  71. package/dist/client/voice-client.d.ts +249 -0
  72. package/dist/client/voice-client.d.ts.map +1 -0
  73. package/dist/client/voice-client.js +826 -0
  74. package/dist/client/voice-client.js.map +1 -0
  75. package/dist/client/web-speech-stt.d.ts +65 -0
  76. package/dist/client/web-speech-stt.d.ts.map +1 -0
  77. package/dist/client/web-speech-stt.js +122 -0
  78. package/dist/client/web-speech-stt.js.map +1 -0
  79. package/dist/client/web-speech-tts.d.ts +59 -0
  80. package/dist/client/web-speech-tts.d.ts.map +1 -0
  81. package/dist/client/web-speech-tts.js +145 -0
  82. package/dist/client/web-speech-tts.js.map +1 -0
  83. package/dist/index.d.ts +10 -0
  84. package/dist/index.d.ts.map +1 -0
  85. package/dist/index.js +13 -0
  86. package/dist/index.js.map +1 -0
  87. package/dist/server/encoding.d.ts +18 -0
  88. package/dist/server/encoding.d.ts.map +1 -0
  89. package/dist/server/encoding.js +41 -0
  90. package/dist/server/encoding.js.map +1 -0
  91. package/dist/server/handler.d.ts +86 -0
  92. package/dist/server/handler.d.ts.map +1 -0
  93. package/dist/server/handler.js +224 -0
  94. package/dist/server/handler.js.map +1 -0
  95. package/dist/server/index.d.ts +31 -0
  96. package/dist/server/index.d.ts.map +1 -0
  97. package/dist/server/index.js +32 -0
  98. package/dist/server/index.js.map +1 -0
  99. package/dist/services/function-service.d.ts +17 -0
  100. package/dist/services/function-service.d.ts.map +1 -0
  101. package/dist/services/function-service.js +82 -0
  102. package/dist/services/function-service.js.map +1 -0
  103. package/dist/services/index.d.ts +4 -0
  104. package/dist/services/index.d.ts.map +1 -0
  105. package/dist/services/index.js +3 -0
  106. package/dist/services/index.js.map +1 -0
  107. package/dist/services/llm-logger.d.ts +136 -0
  108. package/dist/services/llm-logger.d.ts.map +1 -0
  109. package/dist/services/llm-logger.js +275 -0
  110. package/dist/services/llm-logger.js.map +1 -0
  111. package/dist/services/text-normalizer.d.ts +17 -0
  112. package/dist/services/text-normalizer.d.ts.map +1 -0
  113. package/dist/services/text-normalizer.js +100 -0
  114. package/dist/services/text-normalizer.js.map +1 -0
  115. package/dist/types.d.ts +195 -0
  116. package/dist/types.d.ts.map +1 -0
  117. package/dist/types.js +48 -0
  118. package/dist/types.js.map +1 -0
  119. package/dist/voice-pipeline.d.ts +125 -0
  120. package/dist/voice-pipeline.d.ts.map +1 -0
  121. package/dist/voice-pipeline.js +390 -0
  122. package/dist/voice-pipeline.js.map +1 -0
  123. package/package.json +96 -0
  124. package/scripts/setup-binaries.sh +159 -0
  125. package/scripts/setup.sh +201 -0
package/dist/cli.js ADDED
@@ -0,0 +1,392 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * Modular Voice Agent SDK CLI
4
+ *
5
+ * Usage:
6
+ * npx mvas setup <config.json> - Download models from config file
7
+ * npx mvas setup --binaries-only - Set up native binaries only
8
+ * npx mvas help - Show help
9
+ */
10
+ import { spawn, execSync, spawnSync } from 'child_process';
11
+ import { existsSync, readFileSync, mkdirSync, unlinkSync, readdirSync, statSync, createReadStream } from 'fs';
12
+ import { createHash } from 'crypto';
13
+ import { fileURLToPath } from 'url';
14
+ import { dirname, join, basename } from 'path';
15
+ import { homedir } from 'os';
16
+ const __filename = fileURLToPath(import.meta.url);
17
+ const __dirname = dirname(__filename);
18
+ // ============ Cache Paths ============
19
+ function getCacheDir() {
20
+ return process.env.MVAS_CACHE || join(homedir(), '.cache', 'mvas');
21
+ }
22
+ function getModelsDir() {
23
+ return join(getCacheDir(), 'models');
24
+ }
25
+ // ============ Hash Verification ============
26
+ async function computeSha256(filePath) {
27
+ return new Promise((resolve, reject) => {
28
+ const hash = createHash('sha256');
29
+ const stream = createReadStream(filePath);
30
+ stream.on('data', (data) => hash.update(data));
31
+ stream.on('end', () => resolve(hash.digest('hex')));
32
+ stream.on('error', reject);
33
+ });
34
+ }
35
+ async function verifyFile(filePath, config) {
36
+ if (!existsSync(filePath)) {
37
+ return { valid: false, reason: 'file does not exist' };
38
+ }
39
+ const stats = statSync(filePath);
40
+ // Check size if provided
41
+ if (config.size !== undefined) {
42
+ if (stats.size !== config.size) {
43
+ return {
44
+ valid: false,
45
+ reason: `size mismatch (got ${formatBytes(stats.size)}, expected ${formatBytes(config.size)})`
46
+ };
47
+ }
48
+ }
49
+ else {
50
+ // No size specified - check if file is suspiciously small (< 1MB for models)
51
+ if (stats.size < 1024 * 1024) {
52
+ return { valid: false, reason: `file too small (${formatBytes(stats.size)})` };
53
+ }
54
+ }
55
+ // Check hash if provided
56
+ if (config.sha256) {
57
+ console.log(' Verifying checksum...');
58
+ const actualHash = await computeSha256(filePath);
59
+ if (actualHash !== config.sha256.toLowerCase()) {
60
+ return {
61
+ valid: false,
62
+ reason: `checksum mismatch`
63
+ };
64
+ }
65
+ }
66
+ return { valid: true };
67
+ }
68
+ // ============ Download Helpers ============
69
+ function formatBytes(bytes) {
70
+ if (bytes < 1024)
71
+ return `${bytes} B`;
72
+ if (bytes < 1024 * 1024)
73
+ return `${(bytes / 1024).toFixed(1)} KB`;
74
+ if (bytes < 1024 * 1024 * 1024)
75
+ return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;
76
+ return `${(bytes / (1024 * 1024 * 1024)).toFixed(2)} GB`;
77
+ }
78
+ /**
79
+ * Download a file using curl with resume support.
80
+ * curl -C - automatically resumes partial downloads.
81
+ */
82
+ function downloadWithCurl(url, destPath) {
83
+ return new Promise((resolve, reject) => {
84
+ // Check if partial file exists
85
+ const isResume = existsSync(destPath);
86
+ if (isResume) {
87
+ const stats = statSync(destPath);
88
+ console.log(` Resuming from ${formatBytes(stats.size)}...`);
89
+ }
90
+ // curl with:
91
+ // -L: follow redirects
92
+ // -C -: auto-resume from where it left off
93
+ // --progress-bar: show progress
94
+ // -o: output file
95
+ const child = spawn('curl', [
96
+ '-L',
97
+ '-C', '-',
98
+ '--progress-bar',
99
+ '-o', destPath,
100
+ url
101
+ ], {
102
+ stdio: ['inherit', 'inherit', 'inherit'],
103
+ });
104
+ child.on('close', (code) => {
105
+ if (code === 0) {
106
+ resolve();
107
+ }
108
+ else if (code === 33) {
109
+ // curl exit 33 = range request not supported, but file may be complete
110
+ // Check if this is because file is already complete
111
+ resolve();
112
+ }
113
+ else {
114
+ reject(new Error(`curl exited with code ${code}`));
115
+ }
116
+ });
117
+ child.on('error', (err) => {
118
+ reject(new Error(`Failed to run curl: ${err.message}. Make sure curl is installed.`));
119
+ });
120
+ });
121
+ }
122
+ function extractArchive(archivePath, destDir) {
123
+ const ext = archivePath.toLowerCase();
124
+ if (ext.endsWith('.tar.bz2') || ext.endsWith('.tbz2')) {
125
+ execSync(`tar -xjf "${archivePath}" -C "${destDir}"`, { stdio: 'inherit' });
126
+ }
127
+ else if (ext.endsWith('.tar.gz') || ext.endsWith('.tgz')) {
128
+ execSync(`tar -xzf "${archivePath}" -C "${destDir}"`, { stdio: 'inherit' });
129
+ }
130
+ else if (ext.endsWith('.zip')) {
131
+ execSync(`unzip -o "${archivePath}" -d "${destDir}"`, { stdio: 'inherit' });
132
+ }
133
+ else {
134
+ throw new Error(`Unknown archive format: ${archivePath}`);
135
+ }
136
+ }
137
+ // ============ Model Download ============
138
+ async function downloadModel(type, config, modelsDir) {
139
+ console.log(`\n==> ${type.toUpperCase()} model`);
140
+ const url = config.url;
141
+ const urlFilename = basename(new URL(url).pathname);
142
+ if (config.extract) {
143
+ // Archive - download, extract, cleanup
144
+ const archivePath = join(modelsDir, urlFilename);
145
+ const targetDir = config.directory || urlFilename.replace(/\.(tar\.bz2|tar\.gz|tbz2|tgz|zip)$/, '');
146
+ const finalPath = join(modelsDir, targetDir);
147
+ if (existsSync(finalPath)) {
148
+ console.log(` ✓ Already exists: ${targetDir}`);
149
+ return;
150
+ }
151
+ console.log(` Downloading: ${url}`);
152
+ console.log(` Extracting to: ${targetDir}`);
153
+ await downloadWithCurl(url, archivePath);
154
+ // Verify archive if hash provided
155
+ if (config.sha256 || config.size) {
156
+ const result = await verifyFile(archivePath, config);
157
+ if (!result.valid) {
158
+ console.log(` ⚠️ Verification failed: ${result.reason}`);
159
+ console.log(` Deleting partial file and retrying...`);
160
+ unlinkSync(archivePath);
161
+ await downloadWithCurl(url, archivePath);
162
+ }
163
+ }
164
+ extractArchive(archivePath, modelsDir);
165
+ // Cleanup archive
166
+ try {
167
+ unlinkSync(archivePath);
168
+ }
169
+ catch { /* ignore */ }
170
+ console.log(` ✓ Done!`);
171
+ }
172
+ else {
173
+ // Single file
174
+ const filename = config.filename || urlFilename;
175
+ const destPath = join(modelsDir, filename);
176
+ // Check if file exists and is valid
177
+ if (existsSync(destPath)) {
178
+ const result = await verifyFile(destPath, config);
179
+ if (result.valid) {
180
+ console.log(` ✓ Already exists: ${filename}`);
181
+ return;
182
+ }
183
+ console.log(` Existing file invalid: ${result.reason}`);
184
+ console.log(` Re-downloading...`);
185
+ }
186
+ console.log(` URL: ${url}`);
187
+ console.log(` Saving as: ${filename}`);
188
+ if (config.size) {
189
+ console.log(` Expected size: ${formatBytes(config.size)}`);
190
+ }
191
+ await downloadWithCurl(url, destPath);
192
+ // Verify after download
193
+ if (config.sha256 || config.size) {
194
+ const result = await verifyFile(destPath, config);
195
+ if (!result.valid) {
196
+ console.log(` ⚠️ Verification failed: ${result.reason}`);
197
+ console.log(` You may need to delete the file and re-run setup.`);
198
+ return;
199
+ }
200
+ if (config.sha256) {
201
+ console.log(` ✓ Checksum verified`);
202
+ }
203
+ }
204
+ console.log(` ✓ Done!`);
205
+ }
206
+ }
207
+ async function setupFromConfig(configPath) {
208
+ if (!existsSync(configPath)) {
209
+ console.error(`Error: Config file not found: ${configPath}`);
210
+ process.exit(1);
211
+ }
212
+ let config;
213
+ try {
214
+ const content = readFileSync(configPath, 'utf-8');
215
+ config = JSON.parse(content);
216
+ }
217
+ catch (err) {
218
+ console.error(`Error: Invalid JSON in config file: ${configPath}`);
219
+ console.error(err instanceof Error ? err.message : err);
220
+ process.exit(1);
221
+ }
222
+ if (!config.models || typeof config.models !== 'object') {
223
+ console.error('Error: Config must have a "models" object');
224
+ process.exit(1);
225
+ }
226
+ // Check curl is available
227
+ const curlCheck = spawnSync('curl', ['--version']);
228
+ if (curlCheck.error) {
229
+ console.error('Error: curl is required but not found. Please install curl.');
230
+ process.exit(1);
231
+ }
232
+ const modelsDir = getModelsDir();
233
+ mkdirSync(modelsDir, { recursive: true });
234
+ console.log('Modular Voice Agent SDK Setup');
235
+ console.log('====================');
236
+ console.log(`Config: ${configPath}`);
237
+ console.log(`Models directory: ${modelsDir}`);
238
+ const modelTypes = ['stt', 'llm', 'tts'];
239
+ for (const type of modelTypes) {
240
+ const modelConfig = config.models[type];
241
+ if (modelConfig) {
242
+ await downloadModel(type, modelConfig, modelsDir);
243
+ }
244
+ }
245
+ console.log('\n============================================================');
246
+ console.log('Setup complete!');
247
+ console.log('============================================================');
248
+ console.log(`\nModels location: ${modelsDir}`);
249
+ // List what's there with sizes
250
+ const files = readdirSync(modelsDir);
251
+ if (files.length > 0) {
252
+ console.log('\nDownloaded models:');
253
+ for (const file of files) {
254
+ const filePath = join(modelsDir, file);
255
+ const stats = statSync(filePath);
256
+ const size = stats.isDirectory() ? '(dir)' : formatBytes(stats.size);
257
+ console.log(` - ${file} ${size}`);
258
+ }
259
+ }
260
+ console.log('\n💡 To set up native binaries (whisper-cli, llama-completion, sherpa-onnx):');
261
+ console.log(' npx mvas setup --binaries-only');
262
+ }
263
+ // ============ Binaries Setup ============
264
+ async function setupBinaries() {
265
+ // Find and run the setup script for binaries only
266
+ const scriptPath = join(__dirname, '..', 'scripts', 'setup-binaries.sh');
267
+ // Check if the binaries-only script exists, otherwise use original script with a message
268
+ const originalScript = join(__dirname, '..', 'scripts', 'setup.sh');
269
+ const targetScript = existsSync(scriptPath) ? scriptPath : originalScript;
270
+ if (!existsSync(targetScript)) {
271
+ console.error('Error: Setup script not found');
272
+ process.exit(1);
273
+ }
274
+ console.log('Setting up native binaries...');
275
+ console.log('This will configure: whisper-cli, llama-completion, sherpa-onnx');
276
+ console.log('');
277
+ const child = spawn('bash', [targetScript, '--binaries-only'], {
278
+ stdio: 'inherit',
279
+ });
280
+ child.on('error', (err) => {
281
+ if (err.message.includes('ENOENT')) {
282
+ console.error('Error: bash not found. Please run the setup script manually:');
283
+ console.error(` bash ${targetScript}`);
284
+ }
285
+ else {
286
+ console.error('Error running setup:', err.message);
287
+ }
288
+ process.exit(1);
289
+ });
290
+ return new Promise((resolve) => {
291
+ child.on('close', (code) => {
292
+ if (code !== 0) {
293
+ process.exit(code ?? 1);
294
+ }
295
+ resolve();
296
+ });
297
+ });
298
+ }
299
+ // ============ Help ============
300
+ function printHelp() {
301
+ console.log(`
302
+ mvas - Modular Voice Agent SDK CLI
303
+
304
+ Commands:
305
+ setup <config.json> Download models specified in config file
306
+ setup --binaries-only Set up native binaries (whisper-cli, llama-completion, sherpa-onnx)
307
+ help Show this help message
308
+
309
+ Config file format (JSON):
310
+ {
311
+ "models": {
312
+ "stt": {
313
+ "url": "https://huggingface.co/.../model.bin",
314
+ "filename": "whisper-model.bin",
315
+ "size": 874123456,
316
+ "sha256": "abc123..."
317
+ },
318
+ "llm": {
319
+ "url": "https://huggingface.co/.../model.gguf",
320
+ "filename": "llm-model.gguf"
321
+ },
322
+ "tts": {
323
+ "url": "https://github.com/.../model.tar.bz2",
324
+ "extract": true,
325
+ "directory": "tts-model"
326
+ }
327
+ }
328
+ }
329
+
330
+ Options for each model:
331
+ url - Download URL (required)
332
+ filename - Local filename (defaults to URL filename)
333
+ size - Expected file size in bytes (for verification)
334
+ sha256 - Expected SHA256 hash (for verification)
335
+ extract - Set to true for archives (.tar.bz2, .tar.gz, .zip)
336
+ directory - Directory name after extraction
337
+
338
+ Features:
339
+ • Automatic resume of interrupted downloads
340
+ • File integrity verification (size + optional SHA256)
341
+ • Skips already-downloaded valid files
342
+
343
+ Examples:
344
+ npx mvas setup ./models.json # Download models from config
345
+ npx mvas setup --binaries-only # Just set up native binaries
346
+
347
+ Cache location: ${getCacheDir()}
348
+ Override with: export MVAS_CACHE=/path/to/cache
349
+
350
+ For more info: https://github.com/bigfive/modular-voice-agent-sdk
351
+ `);
352
+ }
353
+ // ============ Main ============
354
+ async function main() {
355
+ const args = process.argv.slice(2);
356
+ const command = args[0];
357
+ switch (command) {
358
+ case 'setup': {
359
+ const arg = args[1];
360
+ if (!arg) {
361
+ console.error('Error: setup requires a config file or --binaries-only flag');
362
+ console.error('');
363
+ console.error('Usage:');
364
+ console.error(' npx mvas setup <config.json>');
365
+ console.error(' npx mvas setup --binaries-only');
366
+ process.exit(1);
367
+ }
368
+ if (arg === '--binaries-only' || arg === '--binaries') {
369
+ await setupBinaries();
370
+ }
371
+ else {
372
+ await setupFromConfig(arg);
373
+ }
374
+ break;
375
+ }
376
+ case 'help':
377
+ case '--help':
378
+ case '-h':
379
+ case undefined:
380
+ printHelp();
381
+ break;
382
+ default:
383
+ console.error(`Unknown command: ${command}`);
384
+ printHelp();
385
+ process.exit(1);
386
+ }
387
+ }
388
+ main().catch((err) => {
389
+ console.error('Error:', err.message || err);
390
+ process.exit(1);
391
+ });
392
+ //# sourceMappingURL=cli.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,45 @@
1
+ /**
2
+ * Audio Player
3
+ *
4
+ * Manages a queue of audio chunks and plays them in order.
5
+ */
6
+ export interface AudioPlayerConfig {
7
+ /** Callback when playback starts */
8
+ onStart?: () => void;
9
+ /** Callback when all queued audio finishes */
10
+ onEnd?: () => void;
11
+ }
12
+ export declare class AudioPlayer {
13
+ private audioContext;
14
+ private queue;
15
+ private isPlaying;
16
+ private onStartCallback?;
17
+ private onEndCallback?;
18
+ constructor(config?: AudioPlayerConfig);
19
+ /**
20
+ * Check if currently playing
21
+ */
22
+ get playing(): boolean;
23
+ /**
24
+ * Number of items in the queue
25
+ */
26
+ get queueLength(): number;
27
+ /**
28
+ * Enqueue audio for playback
29
+ */
30
+ enqueue(audio: Float32Array, sampleRate: number): void;
31
+ /**
32
+ * Clear the queue and stop playback
33
+ */
34
+ clear(): void;
35
+ /**
36
+ * Stop playback and clear queue
37
+ */
38
+ stop(): void;
39
+ private playNext;
40
+ /**
41
+ * Clean up resources
42
+ */
43
+ dispose(): void;
44
+ }
45
+ //# sourceMappingURL=audio-player.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"audio-player.d.ts","sourceRoot":"","sources":["../../src/client/audio-player.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,MAAM,WAAW,iBAAiB;IAChC,oCAAoC;IACpC,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IACrB,8CAA8C;IAC9C,KAAK,CAAC,EAAE,MAAM,IAAI,CAAC;CACpB;AAOD,qBAAa,WAAW;IACtB,OAAO,CAAC,YAAY,CAA6B;IACjD,OAAO,CAAC,KAAK,CAAqB;IAClC,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,eAAe,CAAC,CAAa;IACrC,OAAO,CAAC,aAAa,CAAC,CAAa;gBAEvB,MAAM,GAAE,iBAAsB;IAK1C;;OAEG;IACH,IAAI,OAAO,IAAI,OAAO,CAErB;IAED;;OAEG;IACH,IAAI,WAAW,IAAI,MAAM,CAExB;IAED;;OAEG;IACH,OAAO,CAAC,KAAK,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,GAAG,IAAI;IAKtD;;OAEG;IACH,KAAK,IAAI,IAAI;IAKb;;OAEG;IACH,IAAI,IAAI,IAAI;YASE,QAAQ;IAkCtB;;OAEG;IACH,OAAO,IAAI,IAAI;CAKhB"}
@@ -0,0 +1,90 @@
1
+ /**
2
+ * Audio Player
3
+ *
4
+ * Manages a queue of audio chunks and plays them in order.
5
+ */
6
+ export class AudioPlayer {
7
+ audioContext = null;
8
+ queue = [];
9
+ isPlaying = false;
10
+ onStartCallback;
11
+ onEndCallback;
12
+ constructor(config = {}) {
13
+ this.onStartCallback = config.onStart;
14
+ this.onEndCallback = config.onEnd;
15
+ }
16
+ /**
17
+ * Check if currently playing
18
+ */
19
+ get playing() {
20
+ return this.isPlaying;
21
+ }
22
+ /**
23
+ * Number of items in the queue
24
+ */
25
+ get queueLength() {
26
+ return this.queue.length;
27
+ }
28
+ /**
29
+ * Enqueue audio for playback
30
+ */
31
+ enqueue(audio, sampleRate) {
32
+ this.queue.push({ audio, sampleRate });
33
+ this.playNext();
34
+ }
35
+ /**
36
+ * Clear the queue and stop playback
37
+ */
38
+ clear() {
39
+ this.queue = [];
40
+ // Note: current playback will finish, but nothing else will play
41
+ }
42
+ /**
43
+ * Stop playback and clear queue
44
+ */
45
+ stop() {
46
+ this.clear();
47
+ if (this.audioContext) {
48
+ this.audioContext.close();
49
+ this.audioContext = null;
50
+ }
51
+ this.isPlaying = false;
52
+ }
53
+ async playNext() {
54
+ if (this.isPlaying || this.queue.length === 0)
55
+ return;
56
+ this.isPlaying = true;
57
+ this.onStartCallback?.();
58
+ const { audio, sampleRate } = this.queue.shift();
59
+ // Create or reuse audio context
60
+ if (!this.audioContext || this.audioContext.state === 'closed') {
61
+ this.audioContext = new AudioContext();
62
+ }
63
+ // Create buffer and source
64
+ const buffer = this.audioContext.createBuffer(1, audio.length, sampleRate);
65
+ buffer.getChannelData(0).set(audio);
66
+ const source = this.audioContext.createBufferSource();
67
+ source.buffer = buffer;
68
+ source.connect(this.audioContext.destination);
69
+ // Handle completion
70
+ source.onended = () => {
71
+ this.isPlaying = false;
72
+ if (this.queue.length > 0) {
73
+ this.playNext();
74
+ }
75
+ else {
76
+ this.onEndCallback?.();
77
+ }
78
+ };
79
+ source.start();
80
+ }
81
+ /**
82
+ * Clean up resources
83
+ */
84
+ dispose() {
85
+ this.stop();
86
+ this.onStartCallback = undefined;
87
+ this.onEndCallback = undefined;
88
+ }
89
+ }
90
+ //# sourceMappingURL=audio-player.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"audio-player.js","sourceRoot":"","sources":["../../src/client/audio-player.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAcH,MAAM,OAAO,WAAW;IACd,YAAY,GAAwB,IAAI,CAAC;IACzC,KAAK,GAAkB,EAAE,CAAC;IAC1B,SAAS,GAAG,KAAK,CAAC;IAClB,eAAe,CAAc;IAC7B,aAAa,CAAc;IAEnC,YAAY,SAA4B,EAAE;QACxC,IAAI,CAAC,eAAe,GAAG,MAAM,CAAC,OAAO,CAAC;QACtC,IAAI,CAAC,aAAa,GAAG,MAAM,CAAC,KAAK,CAAC;IACpC,CAAC;IAED;;OAEG;IACH,IAAI,OAAO;QACT,OAAO,IAAI,CAAC,SAAS,CAAC;IACxB,CAAC;IAED;;OAEG;IACH,IAAI,WAAW;QACb,OAAO,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC;IAC3B,CAAC;IAED;;OAEG;IACH,OAAO,CAAC,KAAmB,EAAE,UAAkB;QAC7C,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,UAAU,EAAE,CAAC,CAAC;QACvC,IAAI,CAAC,QAAQ,EAAE,CAAC;IAClB,CAAC;IAED;;OAEG;IACH,KAAK;QACH,IAAI,CAAC,KAAK,GAAG,EAAE,CAAC;QAChB,iEAAiE;IACnE,CAAC;IAED;;OAEG;IACH,IAAI;QACF,IAAI,CAAC,KAAK,EAAE,CAAC;QACb,IAAI,IAAI,CAAC,YAAY,EAAE,CAAC;YACtB,IAAI,CAAC,YAAY,CAAC,KAAK,EAAE,CAAC;YAC1B,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC;QAC3B,CAAC;QACD,IAAI,CAAC,SAAS,GAAG,KAAK,CAAC;IACzB,CAAC;IAEO,KAAK,CAAC,QAAQ;QACpB,IAAI,IAAI,CAAC,SAAS,IAAI,IAAI,CAAC,KAAK,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO;QAEtD,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC;QACtB,IAAI,CAAC,eAAe,EAAE,EAAE,CAAC;QAEzB,MAAM,EAAE,KAAK,EAAE,UAAU,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,EAAG,CAAC;QAElD,gCAAgC;QAChC,IAAI,CAAC,IAAI,CAAC,YAAY,IAAI,IAAI,CAAC,YAAY,CAAC,KAAK,KAAK,QAAQ,EAAE,CAAC;YAC/D,IAAI,CAAC,YAAY,GAAG,IAAI,YAAY,EAAE,CAAC;QACzC,CAAC;QAED,2BAA2B;QAC3B,MAAM,MAAM,GAAG,IAAI,CAAC,YAAY,CAAC,YAAY,CAAC,CAAC,EAAE,KAAK,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;QAC3E,MAAM,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;QAEpC,MAAM,MAAM,GAAG,IAAI,CAAC,YAAY,CAAC,kBAAkB,EAAE,CAAC;QACtD,MAAM,CAAC,MAAM,GAAG,MAAM,CAAC;QACvB,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,YAAY,CAAC,WAAW,CAAC,CAAC;QAE9C,oBAAoB;QACpB,MAAM,CAAC,OAAO,GAAG,GAAG,EAAE;YACpB,IAAI,CAAC,SAAS,GAAG,KAAK,CAAC;YACvB,IAAI,IAAI,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBAC1B,IAAI,CAAC,QAAQ,EAAE,CAAC;YAClB,CAAC;iBAAM,CAAC;gBACN,IAAI,CAAC,aAAa,EAAE,EAAE,CAAC;YACzB,CAAC;QACH,CAAC,CAAC;QAEF,MAAM,CAAC,KAAK,EAAE,CAAC;IACjB,CAAC;IAED;;OAEG;IACH,OAAO;QACL,IAAI,CAAC,IAAI,EAAE,CAAC;QACZ,IAAI,CAAC,eAAe,GAAG,SAAS,CAAC;QACjC,IAAI,CAAC,aAAa,GAAG,SAAS,CAAC;IACjC,CAAC;CACF"}
@@ -0,0 +1,42 @@
1
+ /**
2
+ * Audio Recorder
3
+ *
4
+ * Handles microphone capture with AudioWorklet for real-time PCM streaming.
5
+ */
6
+ export interface AudioRecorderConfig {
7
+ /** Sample rate for recording (default: 16000) */
8
+ sampleRate?: number;
9
+ }
10
+ export type AudioChunkCallback = (chunk: Float32Array) => void;
11
+ export declare class AudioRecorder {
12
+ private sampleRate;
13
+ private audioContext;
14
+ private mediaStream;
15
+ private mediaStreamSource;
16
+ private workletNode;
17
+ private workletRegistered;
18
+ private isRecording;
19
+ private onChunkCallback;
20
+ constructor(config?: AudioRecorderConfig);
21
+ /**
22
+ * Check if currently recording
23
+ */
24
+ get recording(): boolean;
25
+ /**
26
+ * Set callback for audio chunks (called during streaming recording)
27
+ */
28
+ onChunk(callback: AudioChunkCallback): void;
29
+ /**
30
+ * Start recording from microphone
31
+ */
32
+ start(): Promise<void>;
33
+ /**
34
+ * Stop recording and clean up resources
35
+ */
36
+ stop(): Promise<void>;
37
+ /**
38
+ * Clean up all resources
39
+ */
40
+ dispose(): Promise<void>;
41
+ }
42
+ //# sourceMappingURL=audio-recorder.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"audio-recorder.d.ts","sourceRoot":"","sources":["../../src/client/audio-recorder.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,MAAM,WAAW,mBAAmB;IAClC,iDAAiD;IACjD,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,MAAM,kBAAkB,GAAG,CAAC,KAAK,EAAE,YAAY,KAAK,IAAI,CAAC;AAoB/D,qBAAa,aAAa;IACxB,OAAO,CAAC,UAAU,CAAS;IAC3B,OAAO,CAAC,YAAY,CAA6B;IACjD,OAAO,CAAC,WAAW,CAA4B;IAC/C,OAAO,CAAC,iBAAiB,CAA2C;IACpE,OAAO,CAAC,WAAW,CAAiC;IACpD,OAAO,CAAC,iBAAiB,CAAS;IAClC,OAAO,CAAC,WAAW,CAAS;IAC5B,OAAO,CAAC,eAAe,CAAmC;gBAE9C,MAAM,GAAE,mBAAwB;IAI5C;;OAEG;IACH,IAAI,SAAS,IAAI,OAAO,CAEvB;IAED;;OAEG;IACH,OAAO,CAAC,QAAQ,EAAE,kBAAkB,GAAG,IAAI;IAI3C;;OAEG;IACG,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAgD5B;;OAEG;IACG,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IA4B3B;;OAEG;IACG,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;CAI/B"}