agentgui 1.0.271 → 1.0.273
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/database.js +30 -0
- package/package.json +1 -1
- package/server.js +33 -12
- package/static/index.html +10 -8
- package/static/js/streaming-renderer.js +3 -6
package/database.js
CHANGED
|
@@ -310,6 +310,36 @@ try {
|
|
|
310
310
|
console.error('[Migration] IPFS schema update warning:', err.message);
|
|
311
311
|
}
|
|
312
312
|
|
|
313
|
+
// Register official IPFS CIDs for voice models
|
|
314
|
+
try {
|
|
315
|
+
const LIGHTHOUSE_GATEWAY = 'https://gateway.lighthouse.storage/ipfs';
|
|
316
|
+
const WHISPER_CID = 'bafybeidyw252ecy4vs46bbmezrtw325gl2ymdltosmzqgx4edjsc3fbofy';
|
|
317
|
+
const TTS_CID = 'bafybeidyw252ecy4vs46bbmezrtw325gl2ymdltosmzqgx4edjsc3fbofy';
|
|
318
|
+
|
|
319
|
+
// Check if CIDs are already registered
|
|
320
|
+
const existingWhisper = db.prepare('SELECT * FROM ipfs_cids WHERE modelName = ? AND modelType = ?').get('whisper-base', 'stt');
|
|
321
|
+
if (!existingWhisper) {
|
|
322
|
+
const cidId = `cid-${Date.now()}-whisper`;
|
|
323
|
+
db.prepare(
|
|
324
|
+
`INSERT INTO ipfs_cids (id, cid, modelName, modelType, modelHash, gatewayUrl, cached_at, last_accessed_at)
|
|
325
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?)`
|
|
326
|
+
).run(cidId, WHISPER_CID, 'whisper-base', 'stt', 'sha256-verified', LIGHTHOUSE_GATEWAY, Date.now(), Date.now());
|
|
327
|
+
console.log('[MODELS] Registered Whisper STT IPFS CID:', WHISPER_CID);
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
const existingTTS = db.prepare('SELECT * FROM ipfs_cids WHERE modelName = ? AND modelType = ?').get('tts', 'voice');
|
|
331
|
+
if (!existingTTS) {
|
|
332
|
+
const cidId = `cid-${Date.now()}-tts`;
|
|
333
|
+
db.prepare(
|
|
334
|
+
`INSERT INTO ipfs_cids (id, cid, modelName, modelType, modelHash, gatewayUrl, cached_at, last_accessed_at)
|
|
335
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?)`
|
|
336
|
+
).run(cidId, TTS_CID, 'tts', 'voice', 'sha256-verified', LIGHTHOUSE_GATEWAY, Date.now(), Date.now());
|
|
337
|
+
console.log('[MODELS] Registered TTS IPFS CID:', TTS_CID);
|
|
338
|
+
}
|
|
339
|
+
} catch (err) {
|
|
340
|
+
console.warn('[MODELS] IPFS CID registration warning:', err.message);
|
|
341
|
+
}
|
|
342
|
+
|
|
313
343
|
const stmtCache = new Map();
|
|
314
344
|
function prep(sql) {
|
|
315
345
|
let s = stmtCache.get(sql);
|
package/package.json
CHANGED
package/server.js
CHANGED
|
@@ -108,11 +108,16 @@ async function ensureModelsDownloaded() {
|
|
|
108
108
|
totalFiles
|
|
109
109
|
});
|
|
110
110
|
} else {
|
|
111
|
-
console.log('[MODELS] Downloading STT from IPFS:', ipfsCid.cid);
|
|
112
|
-
const sttFile = path.join(sttDir, 'model.onnx');
|
|
111
|
+
console.log('[MODELS] Downloading STT from Lighthouse IPFS:', ipfsCid.cid);
|
|
113
112
|
fs.mkdirSync(sttDir, { recursive: true });
|
|
113
|
+
|
|
114
|
+
// Download from Lighthouse gateway: https://gateway.lighthouse.storage/ipfs/CID/stt/onnx-community/whisper-base/
|
|
115
|
+
const lighthouseGateway = 'https://gateway.lighthouse.storage/ipfs';
|
|
116
|
+
const sttUrl = `${lighthouseGateway}/${ipfsCid.cid}/stt/onnx-community/whisper-base/onnx/`;
|
|
117
|
+
const sttFile = path.join(sttDir, 'whisper-onnx.tar');
|
|
118
|
+
|
|
114
119
|
await IPFSDownloader.downloadWithProgress(
|
|
115
|
-
|
|
120
|
+
sttUrl,
|
|
116
121
|
sttFile,
|
|
117
122
|
(progress) => {
|
|
118
123
|
broadcastModelProgress({
|
|
@@ -120,14 +125,15 @@ async function ensureModelsDownloaded() {
|
|
|
120
125
|
done: false,
|
|
121
126
|
downloading: true,
|
|
122
127
|
type: 'stt',
|
|
123
|
-
source: 'ipfs',
|
|
128
|
+
source: 'lighthouse-ipfs',
|
|
129
|
+
gateway: 'gateway.lighthouse.storage',
|
|
124
130
|
...progress,
|
|
125
131
|
completedFiles,
|
|
126
132
|
totalFiles
|
|
127
133
|
});
|
|
128
134
|
}
|
|
129
135
|
);
|
|
130
|
-
console.log('[MODELS] STT model downloaded successfully from IPFS');
|
|
136
|
+
console.log('[MODELS] STT model downloaded successfully from Lighthouse IPFS');
|
|
131
137
|
}
|
|
132
138
|
} catch (err) {
|
|
133
139
|
console.error('[MODELS] IPFS STT download failed:', err.message);
|
|
@@ -159,11 +165,16 @@ async function ensureModelsDownloaded() {
|
|
|
159
165
|
totalFiles
|
|
160
166
|
});
|
|
161
167
|
} else {
|
|
162
|
-
console.log('[MODELS] Downloading TTS from IPFS:', ipfsCid.cid);
|
|
163
|
-
const ttsFile = path.join(ttsDir, 'models.tar.gz');
|
|
168
|
+
console.log('[MODELS] Downloading TTS from Lighthouse IPFS:', ipfsCid.cid);
|
|
164
169
|
fs.mkdirSync(ttsDir, { recursive: true });
|
|
170
|
+
|
|
171
|
+
// Download from Lighthouse gateway: https://gateway.lighthouse.storage/ipfs/CID/tts/
|
|
172
|
+
const lighthouseGateway = 'https://gateway.lighthouse.storage/ipfs';
|
|
173
|
+
const ttsUrl = `${lighthouseGateway}/${ipfsCid.cid}/tts/`;
|
|
174
|
+
const ttsFile = path.join(ttsDir, 'tts-models.tar');
|
|
175
|
+
|
|
165
176
|
await IPFSDownloader.downloadWithProgress(
|
|
166
|
-
|
|
177
|
+
ttsUrl,
|
|
167
178
|
ttsFile,
|
|
168
179
|
(progress) => {
|
|
169
180
|
broadcastModelProgress({
|
|
@@ -171,14 +182,15 @@ async function ensureModelsDownloaded() {
|
|
|
171
182
|
done: false,
|
|
172
183
|
downloading: true,
|
|
173
184
|
type: 'tts',
|
|
174
|
-
source: 'ipfs',
|
|
185
|
+
source: 'lighthouse-ipfs',
|
|
186
|
+
gateway: 'gateway.lighthouse.storage',
|
|
175
187
|
...progress,
|
|
176
188
|
completedFiles,
|
|
177
189
|
totalFiles
|
|
178
190
|
});
|
|
179
191
|
}
|
|
180
192
|
);
|
|
181
|
-
console.log('[MODELS] TTS models downloaded successfully from IPFS');
|
|
193
|
+
console.log('[MODELS] TTS models downloaded successfully from Lighthouse IPFS');
|
|
182
194
|
}
|
|
183
195
|
} catch (err) {
|
|
184
196
|
console.error('[MODELS] IPFS TTS download failed:', err.message);
|
|
@@ -2891,8 +2903,11 @@ async function processMessageWithStreaming(conversationId, messageId, sessionId,
|
|
|
2891
2903
|
}
|
|
2892
2904
|
|
|
2893
2905
|
if (activeExecutions.has(conversationId)) {
|
|
2894
|
-
|
|
2895
|
-
|
|
2906
|
+
const existing = activeExecutions.get(conversationId);
|
|
2907
|
+
if (existing.sessionId !== sessionId) {
|
|
2908
|
+
debugLog(`[stream] Conversation ${conversationId} already has active execution (different session), aborting duplicate`);
|
|
2909
|
+
return;
|
|
2910
|
+
}
|
|
2896
2911
|
}
|
|
2897
2912
|
|
|
2898
2913
|
if (rateLimitState.has(conversationId)) {
|
|
@@ -3237,6 +3252,9 @@ function scheduleRetry(conversationId, messageId, content, agentId, model) {
|
|
|
3237
3252
|
timestamp: Date.now()
|
|
3238
3253
|
});
|
|
3239
3254
|
|
|
3255
|
+
const startTime = Date.now();
|
|
3256
|
+
activeExecutions.set(conversationId, { pid: null, startTime, sessionId: newSession.id, lastActivity: startTime });
|
|
3257
|
+
|
|
3240
3258
|
debugLog(`[rate-limit] Calling processMessageWithStreaming for retry`);
|
|
3241
3259
|
processMessageWithStreaming(conversationId, messageId, newSession.id, content, agentId, model)
|
|
3242
3260
|
.catch(err => {
|
|
@@ -3273,6 +3291,9 @@ function drainMessageQueue(conversationId) {
|
|
|
3273
3291
|
timestamp: Date.now()
|
|
3274
3292
|
});
|
|
3275
3293
|
|
|
3294
|
+
const startTime = Date.now();
|
|
3295
|
+
activeExecutions.set(conversationId, { pid: null, startTime, sessionId: session.id, lastActivity: startTime });
|
|
3296
|
+
|
|
3276
3297
|
processMessageWithStreaming(conversationId, next.messageId, session.id, next.content, next.agentId, next.model)
|
|
3277
3298
|
.catch(err => debugLog(`[queue] Error processing queued message: ${err.message}`));
|
|
3278
3299
|
}
|
package/static/index.html
CHANGED
|
@@ -23,8 +23,8 @@
|
|
|
23
23
|
*, *::before, *::after { box-sizing: border-box; }
|
|
24
24
|
|
|
25
25
|
:root {
|
|
26
|
-
--color-primary: #
|
|
27
|
-
--color-primary-dark: #
|
|
26
|
+
--color-primary: #6b7280;
|
|
27
|
+
--color-primary-dark: #4b5563;
|
|
28
28
|
--color-bg-primary: #ffffff;
|
|
29
29
|
--color-bg-secondary: #f9fafb;
|
|
30
30
|
--color-bg-code: #1f2937;
|
|
@@ -34,18 +34,20 @@
|
|
|
34
34
|
--color-success: #10b981;
|
|
35
35
|
--color-error: #ef4444;
|
|
36
36
|
--color-warning: #f59e0b;
|
|
37
|
-
--color-info: #
|
|
37
|
+
--color-info: #6b7280;
|
|
38
38
|
--sidebar-width: 300px;
|
|
39
39
|
--header-height: 52px;
|
|
40
40
|
--msg-max-width: 100%;
|
|
41
41
|
}
|
|
42
42
|
|
|
43
43
|
html.dark {
|
|
44
|
-
--color-
|
|
45
|
-
--color-
|
|
46
|
-
--color-
|
|
47
|
-
--color-
|
|
48
|
-
--color-
|
|
44
|
+
--color-primary: #9ca3af;
|
|
45
|
+
--color-primary-dark: #6b7280;
|
|
46
|
+
--color-bg-primary: #0f0f0f;
|
|
47
|
+
--color-bg-secondary: #1a1a1a;
|
|
48
|
+
--color-text-primary: #e5e5e5;
|
|
49
|
+
--color-text-secondary: #a3a3a3;
|
|
50
|
+
--color-border: #2a2a2a;
|
|
49
51
|
}
|
|
50
52
|
|
|
51
53
|
html, body {
|
|
@@ -740,8 +740,7 @@ class StreamingRenderer {
|
|
|
740
740
|
const input = block.input || {};
|
|
741
741
|
|
|
742
742
|
const details = document.createElement('details');
|
|
743
|
-
details.className = 'block-tool-use folded-tool
|
|
744
|
-
details.setAttribute('open', '');
|
|
743
|
+
details.className = 'block-tool-use folded-tool';
|
|
745
744
|
if (block.id) details.dataset.toolUseId = block.id;
|
|
746
745
|
details.classList.add(this._getBlockTypeClass('tool_use'));
|
|
747
746
|
details.classList.add(this._getToolColorClass(toolName));
|
|
@@ -1297,8 +1296,7 @@ class StreamingRenderer {
|
|
|
1297
1296
|
*/
|
|
1298
1297
|
renderBlockSystem(block, context) {
|
|
1299
1298
|
const details = document.createElement('details');
|
|
1300
|
-
details.className = 'folded-tool folded-tool-info
|
|
1301
|
-
details.setAttribute('open', '');
|
|
1299
|
+
details.className = 'folded-tool folded-tool-info';
|
|
1302
1300
|
details.dataset.eventType = 'system';
|
|
1303
1301
|
details.classList.add(this._getBlockTypeClass('system'));
|
|
1304
1302
|
const desc = block.model ? this.escapeHtml(block.model) : 'Session';
|
|
@@ -1335,8 +1333,7 @@ class StreamingRenderer {
|
|
|
1335
1333
|
const statsDesc = [duration, cost, turns ? turns + ' turns' : ''].filter(Boolean).join(' / ');
|
|
1336
1334
|
|
|
1337
1335
|
const details = document.createElement('details');
|
|
1338
|
-
details.className = isError ? 'folded-tool folded-tool-error
|
|
1339
|
-
details.setAttribute('open', '');
|
|
1336
|
+
details.className = isError ? 'folded-tool folded-tool-error' : 'folded-tool';
|
|
1340
1337
|
details.dataset.eventType = 'result';
|
|
1341
1338
|
details.classList.add(this._getBlockTypeClass(isError ? 'error' : 'result'));
|
|
1342
1339
|
|