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 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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "agentgui",
3
- "version": "1.0.271",
3
+ "version": "1.0.273",
4
4
  "description": "Multi-agent ACP client with real-time communication",
5
5
  "type": "module",
6
6
  "main": "server.js",
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
- `https://ipfs.io/ipfs/${ipfsCid.cid}`,
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
- `https://ipfs.io/ipfs/${ipfsCid.cid}`,
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
- debugLog(`[stream] Conversation ${conversationId} already has active execution, aborting duplicate`);
2895
- return;
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: #3b82f6;
27
- --color-primary-dark: #1e40af;
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: #0891b2;
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-bg-primary: #111827;
45
- --color-bg-secondary: #1f2937;
46
- --color-text-primary: #f9fafb;
47
- --color-text-secondary: #d1d5db;
48
- --color-border: #374151;
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 permanently-expanded';
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 permanently-expanded';
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 permanently-expanded' : 'folded-tool permanently-expanded';
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