agentgui 1.0.775 → 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 -4
- 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
|
@@ -86,7 +86,6 @@ function buildSystemPrompt(agentId, model, subAgent) {
|
|
|
86
86
|
}
|
|
87
87
|
if (model) parts.push(`Model: ${model}.`);
|
|
88
88
|
if (subAgent) parts.push(`Subagent: ${subAgent}.`);
|
|
89
|
-
parts.push('Be concise. Minimize unnecessary tool calls. Read files before editing. Prefer targeted searches over broad exploration.');
|
|
90
89
|
return parts.join(' ');
|
|
91
90
|
}
|
|
92
91
|
|
|
@@ -144,10 +143,13 @@ function cleanupExecution(conversationId, broadcastCompletion = false) {
|
|
|
144
143
|
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
145
144
|
const rootDir = process.env.PORTABLE_EXE_DIR || __dirname;
|
|
146
145
|
const PORT = process.env.PORT || 3000;
|
|
147
|
-
const BASE_URL = (process.env.BASE_URL || '/gm').replace(/\/+$/, '');
|
|
146
|
+
const BASE_URL = (process.env.BASE_URL || '/gm').replace(/\/+/g, '/').replace(/\/+$/, '');
|
|
148
147
|
const watch = process.argv.includes('--no-watch') ? false : (process.argv.includes('--watch') || process.env.HOT_RELOAD !== 'false');
|
|
149
148
|
|
|
150
|
-
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
|
+
})();
|
|
151
153
|
const staticDir = path.join(rootDir, 'static');
|
|
152
154
|
if (!fs.existsSync(staticDir)) fs.mkdirSync(staticDir, { recursive: true });
|
|
153
155
|
|
|
@@ -655,7 +657,7 @@ const server = http.createServer(async (req, res) => {
|
|
|
655
657
|
sendJSON(req, res, 200, { message: userMessage, session, streamId: session.id });
|
|
656
658
|
|
|
657
659
|
processMessageWithStreaming(conversationId, userMessage.id, session.id, prompt, agentId, model, subAgent)
|
|
658
|
-
.catch(err => debugLog(`[stream] Uncaught error: ${err.message}`));
|
|
660
|
+
.catch(err => debugLog(`[stream] Uncaught error: ${err.stack || err.message}`));
|
|
659
661
|
return;
|
|
660
662
|
}
|
|
661
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);
|