agentgui 1.0.776 → 1.0.777
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/lib/speech-manager.js +6 -3
- package/lib/tool-spawner.js +4 -0
- package/package.json +1 -1
- package/server.js +6 -3
- package/static/js/client.js +1 -1
- package/static/js/voice.js +4 -2
package/lib/speech-manager.js
CHANGED
|
@@ -65,7 +65,8 @@ export const modelDownloadState = {
|
|
|
65
65
|
error: null,
|
|
66
66
|
complete: false,
|
|
67
67
|
startTime: null,
|
|
68
|
-
downloadMetrics: new Map()
|
|
68
|
+
downloadMetrics: new Map(),
|
|
69
|
+
waiters: []
|
|
69
70
|
};
|
|
70
71
|
|
|
71
72
|
export function broadcastModelProgress(progress) {
|
|
@@ -116,8 +117,7 @@ async function validateAndCleanupModels(modelsDir) {
|
|
|
116
117
|
|
|
117
118
|
export async function ensureModelsDownloaded() {
|
|
118
119
|
if (modelDownloadState.downloading) {
|
|
119
|
-
|
|
120
|
-
return modelDownloadState.complete;
|
|
120
|
+
return new Promise(resolve => { modelDownloadState.waiters.push(resolve); });
|
|
121
121
|
}
|
|
122
122
|
modelDownloadState.downloading = true;
|
|
123
123
|
modelDownloadState.error = null;
|
|
@@ -147,6 +147,9 @@ export async function ensureModelsDownloaded() {
|
|
|
147
147
|
return false;
|
|
148
148
|
} finally {
|
|
149
149
|
modelDownloadState.downloading = false;
|
|
150
|
+
const result = modelDownloadState.complete;
|
|
151
|
+
for (const resolve of modelDownloadState.waiters) resolve(result);
|
|
152
|
+
modelDownloadState.waiters = [];
|
|
150
153
|
}
|
|
151
154
|
}
|
|
152
155
|
|
package/lib/tool-spawner.js
CHANGED
|
@@ -100,9 +100,11 @@ export function createInstaller(getTool, statusCache, checkToolStatusAsync) {
|
|
|
100
100
|
toolInstallMachine.send(toolId, { type: 'INSTALL_COMPLETE', version: fresh.version });
|
|
101
101
|
return fresh;
|
|
102
102
|
}
|
|
103
|
+
clearVersionCache();
|
|
103
104
|
toolInstallMachine.send(toolId, { type: 'FAILED', error: result.error });
|
|
104
105
|
return result;
|
|
105
106
|
} catch (err) {
|
|
107
|
+
clearVersionCache();
|
|
106
108
|
toolInstallMachine.send(toolId, { type: 'FAILED', error: err.message });
|
|
107
109
|
return { success: false, error: err.message };
|
|
108
110
|
}
|
|
@@ -122,9 +124,11 @@ export function createInstaller(getTool, statusCache, checkToolStatusAsync) {
|
|
|
122
124
|
toolInstallMachine.send(toolId, { type: 'UPDATE_COMPLETE', version: fresh.version });
|
|
123
125
|
return fresh;
|
|
124
126
|
}
|
|
127
|
+
clearVersionCache();
|
|
125
128
|
toolInstallMachine.send(toolId, { type: 'FAILED', error: result.error });
|
|
126
129
|
return result;
|
|
127
130
|
} catch (err) {
|
|
131
|
+
clearVersionCache();
|
|
128
132
|
toolInstallMachine.send(toolId, { type: 'FAILED', error: err.message });
|
|
129
133
|
return { success: false, error: err.message };
|
|
130
134
|
}
|
package/package.json
CHANGED
package/server.js
CHANGED
|
@@ -143,10 +143,13 @@ function cleanupExecution(conversationId, broadcastCompletion = false) {
|
|
|
143
143
|
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
144
144
|
const rootDir = process.env.PORTABLE_EXE_DIR || __dirname;
|
|
145
145
|
const PORT = process.env.PORT || 3000;
|
|
146
|
-
const BASE_URL = (process.env.BASE_URL || '/gm').replace(/\/+$/, '');
|
|
146
|
+
const BASE_URL = (process.env.BASE_URL || '/gm').replace(/\/+/g, '/').replace(/\/+$/, '');
|
|
147
147
|
const watch = process.argv.includes('--no-watch') ? false : (process.argv.includes('--watch') || process.env.HOT_RELOAD !== 'false');
|
|
148
148
|
|
|
149
|
-
const STARTUP_CWD =
|
|
149
|
+
const STARTUP_CWD = (() => {
|
|
150
|
+
const cwd = process.env.STARTUP_CWD || process.cwd();
|
|
151
|
+
try { fs.accessSync(cwd, fs.constants.R_OK); return cwd; } catch { console.warn(`[server] STARTUP_CWD "${cwd}" not accessible, falling back to ${process.cwd()}`); return process.cwd(); }
|
|
152
|
+
})();
|
|
150
153
|
const staticDir = path.join(rootDir, 'static');
|
|
151
154
|
if (!fs.existsSync(staticDir)) fs.mkdirSync(staticDir, { recursive: true });
|
|
152
155
|
|
|
@@ -654,7 +657,7 @@ const server = http.createServer(async (req, res) => {
|
|
|
654
657
|
sendJSON(req, res, 200, { message: userMessage, session, streamId: session.id });
|
|
655
658
|
|
|
656
659
|
processMessageWithStreaming(conversationId, userMessage.id, session.id, prompt, agentId, model, subAgent)
|
|
657
|
-
.catch(err => debugLog(`[stream] Uncaught error: ${err.message}`));
|
|
660
|
+
.catch(err => debugLog(`[stream] Uncaught error: ${err.stack || err.message}`));
|
|
658
661
|
return;
|
|
659
662
|
}
|
|
660
663
|
|
package/static/js/client.js
CHANGED
|
@@ -94,7 +94,7 @@ class AgentGUIClient {
|
|
|
94
94
|
this._debug = typeof localStorage !== 'undefined' && localStorage.getItem('debug') === '1';
|
|
95
95
|
}
|
|
96
96
|
|
|
97
|
-
_dbg(...args) { if (this._debug)
|
|
97
|
+
_dbg(...args) { if (this._debug) console.log('[AgentGUI]', ...args); }
|
|
98
98
|
|
|
99
99
|
/**
|
|
100
100
|
* Initialize the client
|
package/static/js/voice.js
CHANGED
|
@@ -57,8 +57,9 @@
|
|
|
57
57
|
|
|
58
58
|
function _doSpeak(text) {
|
|
59
59
|
audioChunkQueue = [];
|
|
60
|
-
var
|
|
61
|
-
|
|
60
|
+
var cacheKey = selectedVoiceId + ':' + text;
|
|
61
|
+
var cached = ttsAudioCache.get(cacheKey);
|
|
62
|
+
if (cached) { ttsAudioCache.delete(cacheKey); ttsAudioCache.set(cacheKey, cached); audioChunkQueue.push(cached); playNextChunk(); return; }
|
|
62
63
|
function stream() {
|
|
63
64
|
if (!streamingSupported) { nonStream(text); return; }
|
|
64
65
|
fetch(BASE + '/api/tts-stream', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ text: text, voiceId: selectedVoiceId }) })
|
|
@@ -71,6 +72,7 @@
|
|
|
71
72
|
buf = cat(buf, res.value);
|
|
72
73
|
while (buf.length >= 4) {
|
|
73
74
|
var len = new DataView(buf.buffer, buf.byteOffset, 4).getUint32(0, false);
|
|
75
|
+
if (len > 10 * 1024 * 1024) { buf = new Uint8Array(0); if (api()) api().send({ type: 'PLAYBACK_ERROR' }); return; }
|
|
74
76
|
if (buf.length < 4 + len) break;
|
|
75
77
|
audioChunkQueue.push(new Blob([buf.slice(4, 4 + len)], { type: 'audio/wav' }));
|
|
76
78
|
buf = buf.slice(4 + len);
|