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.
- package/README.md +102 -0
- package/USAGE.md +567 -0
- package/dist/backends/cloud/index.d.ts +7 -0
- package/dist/backends/cloud/index.d.ts.map +1 -0
- package/dist/backends/cloud/index.js +6 -0
- package/dist/backends/cloud/index.js.map +1 -0
- package/dist/backends/cloud/llm.d.ts +22 -0
- package/dist/backends/cloud/llm.d.ts.map +1 -0
- package/dist/backends/cloud/llm.js +234 -0
- package/dist/backends/cloud/llm.js.map +1 -0
- package/dist/backends/index.d.ts +2 -0
- package/dist/backends/index.d.ts.map +1 -0
- package/dist/backends/index.js +6 -0
- package/dist/backends/index.js.map +1 -0
- package/dist/backends/native/index.d.ts +5 -0
- package/dist/backends/native/index.d.ts.map +1 -0
- package/dist/backends/native/index.js +6 -0
- package/dist/backends/native/index.js.map +1 -0
- package/dist/backends/native/llm.d.ts +71 -0
- package/dist/backends/native/llm.d.ts.map +1 -0
- package/dist/backends/native/llm.js +435 -0
- package/dist/backends/native/llm.js.map +1 -0
- package/dist/backends/native/stt.d.ts +15 -0
- package/dist/backends/native/stt.d.ts.map +1 -0
- package/dist/backends/native/stt.js +94 -0
- package/dist/backends/native/stt.js.map +1 -0
- package/dist/backends/native/tts.d.ts +21 -0
- package/dist/backends/native/tts.d.ts.map +1 -0
- package/dist/backends/native/tts.js +105 -0
- package/dist/backends/native/tts.js.map +1 -0
- package/dist/backends/transformers/index.d.ts +4 -0
- package/dist/backends/transformers/index.d.ts.map +1 -0
- package/dist/backends/transformers/index.js +4 -0
- package/dist/backends/transformers/index.js.map +1 -0
- package/dist/backends/transformers/llm.d.ts +29 -0
- package/dist/backends/transformers/llm.d.ts.map +1 -0
- package/dist/backends/transformers/llm.js +117 -0
- package/dist/backends/transformers/llm.js.map +1 -0
- package/dist/backends/transformers/stt.d.ts +17 -0
- package/dist/backends/transformers/stt.d.ts.map +1 -0
- package/dist/backends/transformers/stt.js +43 -0
- package/dist/backends/transformers/stt.js.map +1 -0
- package/dist/backends/transformers/tts.d.ts +17 -0
- package/dist/backends/transformers/tts.d.ts.map +1 -0
- package/dist/backends/transformers/tts.js +40 -0
- package/dist/backends/transformers/tts.js.map +1 -0
- package/dist/cache.d.ts +37 -0
- package/dist/cache.d.ts.map +1 -0
- package/dist/cache.js +49 -0
- package/dist/cache.js.map +1 -0
- package/dist/cli.d.ts +11 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +392 -0
- package/dist/cli.js.map +1 -0
- package/dist/client/audio-player.d.ts +45 -0
- package/dist/client/audio-player.d.ts.map +1 -0
- package/dist/client/audio-player.js +90 -0
- package/dist/client/audio-player.js.map +1 -0
- package/dist/client/audio-recorder.d.ts +42 -0
- package/dist/client/audio-recorder.d.ts.map +1 -0
- package/dist/client/audio-recorder.js +128 -0
- package/dist/client/audio-recorder.js.map +1 -0
- package/dist/client/index.d.ts +34 -0
- package/dist/client/index.d.ts.map +1 -0
- package/dist/client/index.js +33 -0
- package/dist/client/index.js.map +1 -0
- package/dist/client/protocol.d.ts +80 -0
- package/dist/client/protocol.d.ts.map +1 -0
- package/dist/client/protocol.js +29 -0
- package/dist/client/protocol.js.map +1 -0
- package/dist/client/voice-client.d.ts +249 -0
- package/dist/client/voice-client.d.ts.map +1 -0
- package/dist/client/voice-client.js +826 -0
- package/dist/client/voice-client.js.map +1 -0
- package/dist/client/web-speech-stt.d.ts +65 -0
- package/dist/client/web-speech-stt.d.ts.map +1 -0
- package/dist/client/web-speech-stt.js +122 -0
- package/dist/client/web-speech-stt.js.map +1 -0
- package/dist/client/web-speech-tts.d.ts +59 -0
- package/dist/client/web-speech-tts.d.ts.map +1 -0
- package/dist/client/web-speech-tts.js +145 -0
- package/dist/client/web-speech-tts.js.map +1 -0
- package/dist/index.d.ts +10 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +13 -0
- package/dist/index.js.map +1 -0
- package/dist/server/encoding.d.ts +18 -0
- package/dist/server/encoding.d.ts.map +1 -0
- package/dist/server/encoding.js +41 -0
- package/dist/server/encoding.js.map +1 -0
- package/dist/server/handler.d.ts +86 -0
- package/dist/server/handler.d.ts.map +1 -0
- package/dist/server/handler.js +224 -0
- package/dist/server/handler.js.map +1 -0
- package/dist/server/index.d.ts +31 -0
- package/dist/server/index.d.ts.map +1 -0
- package/dist/server/index.js +32 -0
- package/dist/server/index.js.map +1 -0
- package/dist/services/function-service.d.ts +17 -0
- package/dist/services/function-service.d.ts.map +1 -0
- package/dist/services/function-service.js +82 -0
- package/dist/services/function-service.js.map +1 -0
- package/dist/services/index.d.ts +4 -0
- package/dist/services/index.d.ts.map +1 -0
- package/dist/services/index.js +3 -0
- package/dist/services/index.js.map +1 -0
- package/dist/services/llm-logger.d.ts +136 -0
- package/dist/services/llm-logger.d.ts.map +1 -0
- package/dist/services/llm-logger.js +275 -0
- package/dist/services/llm-logger.js.map +1 -0
- package/dist/services/text-normalizer.d.ts +17 -0
- package/dist/services/text-normalizer.d.ts.map +1 -0
- package/dist/services/text-normalizer.js +100 -0
- package/dist/services/text-normalizer.js.map +1 -0
- package/dist/types.d.ts +195 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +48 -0
- package/dist/types.js.map +1 -0
- package/dist/voice-pipeline.d.ts +125 -0
- package/dist/voice-pipeline.d.ts.map +1 -0
- package/dist/voice-pipeline.js +390 -0
- package/dist/voice-pipeline.js.map +1 -0
- package/package.json +96 -0
- package/scripts/setup-binaries.sh +159 -0
- 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
|
package/dist/cli.js.map
ADDED
|
@@ -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":"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"}
|
|
@@ -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"}
|