agentgui 1.0.278 → 1.0.280
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/package.json +1 -1
- package/server.js +81 -79
package/package.json
CHANGED
package/server.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import http from 'http';
|
|
2
|
+
import https from 'https';
|
|
2
3
|
import fs from 'fs';
|
|
3
4
|
import path from 'path';
|
|
4
5
|
import os from 'os';
|
|
@@ -63,6 +64,45 @@ function broadcastModelProgress(progress) {
|
|
|
63
64
|
broadcastSync(broadcastData);
|
|
64
65
|
}
|
|
65
66
|
|
|
67
|
+
const LIGHTHOUSE_STT_BASE = 'https://gateway.lighthouse.storage/ipfs/bafybeidyw252ecy4vs46bbmezrtw325gl2ymdltosmzqgx4edjsc3fbofy/stt/onnx-community/whisper-base/';
|
|
68
|
+
const LIGHTHOUSE_STT_ONNX_BASE = 'https://gateway.lighthouse.storage/ipfs/bafybeidyw252ecy4vs46bbmezrtw325gl2ymdltosmzqgx4edjsc3fbofy/stt/onnx-community/whisper-base/onnx/';
|
|
69
|
+
const LIGHTHOUSE_TTS_BASE = 'https://gateway.lighthouse.storage/ipfs/bafybeidyw252ecy4vs46bbmezrtw325gl2ymdltosmzqgx4edjsc3fbofy/tts/';
|
|
70
|
+
|
|
71
|
+
const STT_BASE_FILES = ['config.json', 'preprocessor_config.json', 'tokenizer.json', 'tokenizer_config.json', 'vocab.json', 'merges.txt', 'model_quantized.onnx'];
|
|
72
|
+
const STT_ONNX_FILES = ['encoder_model.onnx', 'decoder_model_merged_q4.onnx', 'decoder_model_merged.onnx'];
|
|
73
|
+
const TTS_FILES = ['mimi_encoder.onnx', 'text_conditioner.onnx', 'flow_lm_main_int8.onnx', 'flow_lm_flow_int8.onnx', 'mimi_decoder_int8.onnx', 'tokenizer.model'];
|
|
74
|
+
|
|
75
|
+
function lighthouseDownload(url, dest, retries = 3, attempt = 1) {
|
|
76
|
+
return new Promise((resolve, reject) => {
|
|
77
|
+
const req = https.get(url, { timeout: 120000 }, (res) => {
|
|
78
|
+
if ([301, 302, 307, 308].includes(res.statusCode)) {
|
|
79
|
+
return lighthouseDownload(res.headers.location, dest, retries, attempt).then(resolve).catch(reject);
|
|
80
|
+
}
|
|
81
|
+
if (res.statusCode !== 200) {
|
|
82
|
+
res.resume();
|
|
83
|
+
const err = new Error(`Lighthouse HTTP ${res.statusCode} for ${url}`);
|
|
84
|
+
if (attempt < retries) return setTimeout(() => lighthouseDownload(url, dest, retries, attempt + 1).then(resolve).catch(reject), 2000 * attempt);
|
|
85
|
+
return reject(err);
|
|
86
|
+
}
|
|
87
|
+
fs.mkdirSync(path.dirname(dest), { recursive: true });
|
|
88
|
+
const file = fs.createWriteStream(dest);
|
|
89
|
+
res.pipe(file);
|
|
90
|
+
file.on('finish', () => { file.close(); resolve(); });
|
|
91
|
+
file.on('error', (e) => { try { fs.unlinkSync(dest); } catch (_) {} reject(e); });
|
|
92
|
+
res.on('error', (e) => { try { fs.unlinkSync(dest); } catch (_) {} reject(e); });
|
|
93
|
+
});
|
|
94
|
+
req.on('timeout', () => {
|
|
95
|
+
req.destroy();
|
|
96
|
+
if (attempt < retries) return setTimeout(() => lighthouseDownload(url, dest, retries, attempt + 1).then(resolve).catch(reject), 2000 * attempt);
|
|
97
|
+
reject(new Error(`Lighthouse timeout for ${url}`));
|
|
98
|
+
});
|
|
99
|
+
req.on('error', (e) => {
|
|
100
|
+
if (attempt < retries) return setTimeout(() => lighthouseDownload(url, dest, retries, attempt + 1).then(resolve).catch(reject), 2000 * attempt);
|
|
101
|
+
reject(e);
|
|
102
|
+
});
|
|
103
|
+
});
|
|
104
|
+
}
|
|
105
|
+
|
|
66
106
|
async function ensureModelsDownloaded() {
|
|
67
107
|
if (modelDownloadState.downloading) {
|
|
68
108
|
while (modelDownloadState.downloading) {
|
|
@@ -76,8 +116,10 @@ async function ensureModelsDownloaded() {
|
|
|
76
116
|
const sttDir = path.join(gmguiModels, 'onnx-community', 'whisper-base');
|
|
77
117
|
const ttsDir = path.join(gmguiModels, 'tts');
|
|
78
118
|
|
|
79
|
-
const
|
|
80
|
-
const
|
|
119
|
+
const sttOnnxDir = path.join(sttDir, 'onnx');
|
|
120
|
+
const sttOk = STT_BASE_FILES.every(f => fs.existsSync(path.join(sttDir, f))) &&
|
|
121
|
+
STT_ONNX_FILES.some(f => fs.existsSync(path.join(sttOnnxDir, f)));
|
|
122
|
+
const ttsOk = TTS_FILES.every(f => fs.existsSync(path.join(ttsDir, f)));
|
|
81
123
|
|
|
82
124
|
if (sttOk && ttsOk) {
|
|
83
125
|
console.log('[MODELS] All model files present');
|
|
@@ -88,94 +130,54 @@ async function ensureModelsDownloaded() {
|
|
|
88
130
|
modelDownloadState.downloading = true;
|
|
89
131
|
modelDownloadState.error = null;
|
|
90
132
|
|
|
91
|
-
const totalFiles =
|
|
133
|
+
const totalFiles = STT_BASE_FILES.length + STT_ONNX_FILES.length + TTS_FILES.length;
|
|
92
134
|
let completedFiles = 0;
|
|
93
135
|
|
|
94
|
-
const require = createRequire(import.meta.url);
|
|
95
|
-
|
|
96
136
|
if (!sttOk) {
|
|
97
|
-
broadcastModelProgress({ started: true, done: false, downloading: true, type: 'stt', source: '
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
await IPFSDownloader.downloadWithProgress(sttUrl, sttFile, (progress) => {
|
|
108
|
-
broadcastModelProgress({ started: true, done: false, downloading: true, type: 'stt', source: 'lighthouse-ipfs', gateway: 'gateway.lighthouse.storage', ...progress, completedFiles, totalFiles });
|
|
109
|
-
});
|
|
110
|
-
console.log('[MODELS] STT model downloaded from Lighthouse IPFS');
|
|
111
|
-
sttDownloaded = true;
|
|
112
|
-
} catch (err) {
|
|
113
|
-
console.error('[MODELS] IPFS STT download failed:', err.message, '- falling back to HuggingFace');
|
|
137
|
+
broadcastModelProgress({ started: true, done: false, downloading: true, type: 'stt', source: 'lighthouse', completedFiles, totalFiles });
|
|
138
|
+
console.log('[MODELS] Downloading STT from Lighthouse IPFS...');
|
|
139
|
+
fs.mkdirSync(sttDir, { recursive: true });
|
|
140
|
+
fs.mkdirSync(sttOnnxDir, { recursive: true });
|
|
141
|
+
try {
|
|
142
|
+
for (const file of STT_BASE_FILES) {
|
|
143
|
+
const dest = path.join(sttDir, file);
|
|
144
|
+
if (!fs.existsSync(dest)) await lighthouseDownload(LIGHTHOUSE_STT_BASE + file, dest);
|
|
145
|
+
completedFiles++;
|
|
146
|
+
broadcastModelProgress({ started: true, done: false, downloading: true, type: 'stt', source: 'lighthouse', completedFiles, totalFiles });
|
|
114
147
|
}
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
console.log('[MODELS] Downloading STT model via HuggingFace...');
|
|
121
|
-
broadcastModelProgress({ started: true, done: false, downloading: true, type: 'stt', source: 'huggingface', completedFiles, totalFiles });
|
|
122
|
-
try {
|
|
123
|
-
const whisperModels = require('webtalk/whisper-models');
|
|
124
|
-
const modelsDir = path.join(dataDir, 'models');
|
|
125
|
-
fs.mkdirSync(modelsDir, { recursive: true });
|
|
126
|
-
await whisperModels.ensureModel('onnx-community/whisper-base', {
|
|
127
|
-
modelsDir,
|
|
128
|
-
whisperBaseUrl: 'https://huggingface.co/',
|
|
129
|
-
});
|
|
130
|
-
console.log('[MODELS] STT model downloaded from HuggingFace');
|
|
131
|
-
} catch (hfErr) {
|
|
132
|
-
console.error('[MODELS] HuggingFace STT download failed:', hfErr.message);
|
|
133
|
-
broadcastModelProgress({ done: true, error: `STT download failed: ${hfErr.message}`, type: 'stt', completedFiles, totalFiles });
|
|
148
|
+
for (const file of STT_ONNX_FILES) {
|
|
149
|
+
const dest = path.join(sttOnnxDir, file);
|
|
150
|
+
if (!fs.existsSync(dest)) await lighthouseDownload(LIGHTHOUSE_STT_ONNX_BASE + file, dest);
|
|
151
|
+
completedFiles++;
|
|
152
|
+
broadcastModelProgress({ started: true, done: false, downloading: true, type: 'stt', source: 'lighthouse', completedFiles, totalFiles });
|
|
134
153
|
}
|
|
154
|
+
console.log('[MODELS] STT model downloaded from Lighthouse IPFS');
|
|
155
|
+
} catch (err) {
|
|
156
|
+
const msg = `STT download failed from Lighthouse IPFS: ${err.message}. Check your internet connection and try again.`;
|
|
157
|
+
console.error('[MODELS]', msg);
|
|
158
|
+
broadcastModelProgress({ done: true, error: msg, type: 'stt', completedFiles, totalFiles });
|
|
159
|
+
throw new Error(msg);
|
|
135
160
|
}
|
|
136
|
-
completedFiles += 10;
|
|
137
161
|
}
|
|
138
162
|
|
|
139
163
|
if (!ttsOk) {
|
|
140
|
-
broadcastModelProgress({ started: true, done: false, downloading: true, type: 'tts', source: '
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
try {
|
|
150
|
-
await IPFSDownloader.downloadWithProgress(ttsUrl, ttsFile, (progress) => {
|
|
151
|
-
broadcastModelProgress({ started: true, done: false, downloading: true, type: 'tts', source: 'lighthouse-ipfs', gateway: 'gateway.lighthouse.storage', ...progress, completedFiles, totalFiles });
|
|
152
|
-
});
|
|
153
|
-
console.log('[MODELS] TTS models downloaded from Lighthouse IPFS');
|
|
154
|
-
ttsDownloaded = true;
|
|
155
|
-
} catch (err) {
|
|
156
|
-
console.error('[MODELS] IPFS TTS download failed:', err.message, '- falling back to HuggingFace');
|
|
157
|
-
}
|
|
158
|
-
} else {
|
|
159
|
-
console.warn('[MODELS] No TTS IPFS CID registered - using HuggingFace directly');
|
|
160
|
-
}
|
|
161
|
-
|
|
162
|
-
if (!ttsDownloaded) {
|
|
163
|
-
console.log('[MODELS] Downloading TTS models via HuggingFace...');
|
|
164
|
-
broadcastModelProgress({ started: true, done: false, downloading: true, type: 'tts', source: 'huggingface', completedFiles, totalFiles });
|
|
165
|
-
try {
|
|
166
|
-
const ttsModels = require('webtalk/tts-models');
|
|
167
|
-
await ttsModels.ensureTTSModels({
|
|
168
|
-
ttsModelsDir: ttsDir,
|
|
169
|
-
ttsDir: path.join(dataDir, 'models', 'tts'),
|
|
170
|
-
ttsBaseUrl: 'https://huggingface.co/datasets/AnEntrypoint/sttttsmodels/resolve/main/tts/',
|
|
171
|
-
});
|
|
172
|
-
console.log('[MODELS] TTS models downloaded from HuggingFace');
|
|
173
|
-
} catch (hfErr) {
|
|
174
|
-
console.error('[MODELS] HuggingFace TTS download failed:', hfErr.message);
|
|
175
|
-
broadcastModelProgress({ done: true, error: `TTS download failed: ${hfErr.message}`, type: 'tts', completedFiles, totalFiles });
|
|
164
|
+
broadcastModelProgress({ started: true, done: false, downloading: true, type: 'tts', source: 'lighthouse', completedFiles, totalFiles });
|
|
165
|
+
console.log('[MODELS] Downloading TTS from Lighthouse IPFS...');
|
|
166
|
+
fs.mkdirSync(ttsDir, { recursive: true });
|
|
167
|
+
try {
|
|
168
|
+
for (const file of TTS_FILES) {
|
|
169
|
+
const dest = path.join(ttsDir, file);
|
|
170
|
+
if (!fs.existsSync(dest)) await lighthouseDownload(LIGHTHOUSE_TTS_BASE + file, dest);
|
|
171
|
+
completedFiles++;
|
|
172
|
+
broadcastModelProgress({ started: true, done: false, downloading: true, type: 'tts', source: 'lighthouse', completedFiles, totalFiles });
|
|
176
173
|
}
|
|
174
|
+
console.log('[MODELS] TTS models downloaded from Lighthouse IPFS');
|
|
175
|
+
} catch (err) {
|
|
176
|
+
const msg = `TTS download failed from Lighthouse IPFS: ${err.message}. Check your internet connection and try again.`;
|
|
177
|
+
console.error('[MODELS]', msg);
|
|
178
|
+
broadcastModelProgress({ done: true, error: msg, type: 'tts', completedFiles, totalFiles });
|
|
179
|
+
throw new Error(msg);
|
|
177
180
|
}
|
|
178
|
-
completedFiles += 6;
|
|
179
181
|
}
|
|
180
182
|
|
|
181
183
|
modelDownloadState.complete = true;
|