agentgui 1.0.275 → 1.0.277
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/agentgui.ico +0 -0
- package/build-portable.js +11 -1
- package/lib/ipfs-downloader.js +1 -1
- package/lib/speech.js +9 -2
- package/package.json +1 -1
- package/server.js +20 -24
package/agentgui.ico
ADDED
|
Binary file
|
package/build-portable.js
CHANGED
|
@@ -50,8 +50,18 @@ rmrf(out);
|
|
|
50
50
|
fs.mkdirSync(out, { recursive: true });
|
|
51
51
|
|
|
52
52
|
log('Compiling Windows executable...');
|
|
53
|
+
const onWindows = process.platform === 'win32';
|
|
54
|
+
const icoPath = path.join(src, 'agentgui.ico');
|
|
55
|
+
const winFlags = onWindows ? [
|
|
56
|
+
'--windows-hide-console',
|
|
57
|
+
'--windows-title=AgentGUI',
|
|
58
|
+
'--windows-description=Multi-agent GUI client for AI coding agents',
|
|
59
|
+
'--windows-version=1.0.0.0',
|
|
60
|
+
...(fs.existsSync(icoPath) ? [`--windows-icon=${icoPath}`] : []),
|
|
61
|
+
] : [];
|
|
53
62
|
execSync(
|
|
54
|
-
`~/.bun/bin/bun build --compile --target=bun-windows-x64
|
|
63
|
+
[`~/.bun/bin/bun build --compile --target=bun-windows-x64`, ...winFlags,
|
|
64
|
+
`--outfile=${path.join(out, 'agentgui.exe')}`, path.join(src, 'portable-entry.js')].join(' '),
|
|
55
65
|
{ stdio: 'inherit', cwd: src }
|
|
56
66
|
);
|
|
57
67
|
|
package/lib/ipfs-downloader.js
CHANGED
|
@@ -19,7 +19,7 @@ const CONFIG = {
|
|
|
19
19
|
TIMEOUT_MS: 30000,
|
|
20
20
|
INITIAL_BACKOFF_MS: 1000,
|
|
21
21
|
BACKOFF_MULTIPLIER: 2,
|
|
22
|
-
DOWNLOADS_DIR
|
|
22
|
+
get DOWNLOADS_DIR() { return path.join(process.env.PORTABLE_DATA_DIR || path.join(os.homedir(), '.gmgui'), 'downloads'); },
|
|
23
23
|
RESUME_THRESHOLD: 0.5
|
|
24
24
|
};
|
|
25
25
|
|
package/lib/speech.js
CHANGED
|
@@ -78,12 +78,19 @@ function synthesizeDirect(text, voiceId) {
|
|
|
78
78
|
});
|
|
79
79
|
}
|
|
80
80
|
|
|
81
|
+
function getSttOptions() {
|
|
82
|
+
if (process.env.PORTABLE_DATA_DIR) {
|
|
83
|
+
return { cacheDir: path.join(process.env.PORTABLE_DATA_DIR, 'models') };
|
|
84
|
+
}
|
|
85
|
+
return {};
|
|
86
|
+
}
|
|
87
|
+
|
|
81
88
|
function transcribe(audioBuffer) {
|
|
82
|
-
return serverSTT.transcribe(audioBuffer);
|
|
89
|
+
return serverSTT.transcribe(audioBuffer, getSttOptions());
|
|
83
90
|
}
|
|
84
91
|
|
|
85
92
|
function getSTT() {
|
|
86
|
-
return serverSTT.getSTT();
|
|
93
|
+
return serverSTT.getSTT(getSttOptions());
|
|
87
94
|
}
|
|
88
95
|
|
|
89
96
|
function synthesize(text, voiceId) {
|
package/package.json
CHANGED
package/server.js
CHANGED
|
@@ -8,6 +8,9 @@ import { fileURLToPath } from 'url';
|
|
|
8
8
|
import { WebSocketServer } from 'ws';
|
|
9
9
|
import { execSync, spawn } from 'child_process';
|
|
10
10
|
import { createRequire } from 'module';
|
|
11
|
+
import express from 'express';
|
|
12
|
+
import Busboy from 'busboy';
|
|
13
|
+
import fsbrowse from 'fsbrowse';
|
|
11
14
|
import { OAuth2Client } from 'google-auth-library';
|
|
12
15
|
import { queries, dataDir } from './database.js';
|
|
13
16
|
import { runClaudeWithStreaming } from './lib/claude-runner.js';
|
|
@@ -69,12 +72,9 @@ async function ensureModelsDownloaded() {
|
|
|
69
72
|
}
|
|
70
73
|
|
|
71
74
|
try {
|
|
72
|
-
const
|
|
73
|
-
const
|
|
74
|
-
|
|
75
|
-
const gmguiModels = path.join(dataDir, 'models');
|
|
76
|
-
const sttDir = path.join(gmguiModels, 'onnx-community', 'whisper-base');
|
|
77
|
-
const ttsDir = path.join(gmguiModels, 'tts');
|
|
75
|
+
const gmguiModels = path.join(dataDir, 'models');
|
|
76
|
+
const sttDir = path.join(gmguiModels, 'onnx-community', 'whisper-base');
|
|
77
|
+
const ttsDir = path.join(gmguiModels, 'tts');
|
|
78
78
|
|
|
79
79
|
const sttOk = fs.existsSync(sttDir) && fs.readdirSync(sttDir).length > 0;
|
|
80
80
|
const ttsOk = fs.existsSync(ttsDir) && fs.readdirSync(ttsDir).length > 0;
|
|
@@ -276,10 +276,6 @@ function pushTTSAudio(cacheKey, wav, conversationId, sessionId, voiceId) {
|
|
|
276
276
|
});
|
|
277
277
|
}
|
|
278
278
|
|
|
279
|
-
const require = createRequire(import.meta.url);
|
|
280
|
-
const express = require('express');
|
|
281
|
-
const Busboy = require('busboy');
|
|
282
|
-
const fsbrowse = require('fsbrowse');
|
|
283
279
|
|
|
284
280
|
const SYSTEM_PROMPT = `Your output will be spoken aloud by a text-to-speech system. Write ONLY plain conversational sentences that sound natural when read aloud. Never use markdown, bold, italics, headers, bullet points, numbered lists, tables, or any formatting. Never use colons to introduce lists or options. Never use labels like "Option A" or "1." followed by a title. Instead of listing options, describe them conversationally in flowing sentences. For example, instead of "**Option 1**: Do X" say "One approach would be to do X." Keep sentences short and simple. Use transition words like "also", "another option", "or alternatively" to connect ideas. When mentioning file names, spell out the dot between the name and extension as the word "dot" so it is spoken clearly. For example, say "server dot js" instead of "server.js", "index dot html" instead of "index.html", and "package dot json" instead of "package.json". Write as if you are speaking to someone in a casual conversation.`;
|
|
285
281
|
|
|
@@ -296,16 +292,16 @@ const debugLog = (msg) => {
|
|
|
296
292
|
console.error(`[${timestamp}] ${msg}`);
|
|
297
293
|
};
|
|
298
294
|
|
|
299
|
-
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
300
|
-
const PORT = process.env.PORT || 3000;
|
|
301
|
-
const BASE_URL = (process.env.BASE_URL || '/gm').replace(/\/+$/, '');
|
|
302
|
-
const watch = process.argv.includes('--no-watch') ? false : (process.argv.includes('--watch') || process.env.HOT_RELOAD !== 'false');
|
|
303
|
-
|
|
304
|
-
const STARTUP_CWD = process.env.STARTUP_CWD || process.cwd();
|
|
305
|
-
const staticDir = process.env.PORTABLE_EXE_DIR
|
|
306
|
-
? path.join(process.env.PORTABLE_EXE_DIR, 'static')
|
|
307
|
-
: path.join(__dirname, 'static');
|
|
308
|
-
if (!fs.existsSync(staticDir)) fs.mkdirSync(staticDir, { recursive: true });
|
|
295
|
+
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
296
|
+
const PORT = process.env.PORT || 3000;
|
|
297
|
+
const BASE_URL = (process.env.BASE_URL || '/gm').replace(/\/+$/, '');
|
|
298
|
+
const watch = process.argv.includes('--no-watch') ? false : (process.argv.includes('--watch') || process.env.HOT_RELOAD !== 'false');
|
|
299
|
+
|
|
300
|
+
const STARTUP_CWD = process.env.STARTUP_CWD || process.cwd();
|
|
301
|
+
const staticDir = process.env.PORTABLE_EXE_DIR
|
|
302
|
+
? path.join(process.env.PORTABLE_EXE_DIR, 'static')
|
|
303
|
+
: path.join(__dirname, 'static');
|
|
304
|
+
if (!fs.existsSync(staticDir)) fs.mkdirSync(staticDir, { recursive: true });
|
|
309
305
|
|
|
310
306
|
// Express sub-app for fsbrowse file browser and file upload
|
|
311
307
|
const expressApp = express();
|
|
@@ -3697,21 +3693,21 @@ function onServerReady() {
|
|
|
3697
3693
|
|
|
3698
3694
|
resumeInterruptedStreams().catch(err => console.error('[RESUME] Startup error:', err.message));
|
|
3699
3695
|
|
|
3700
|
-
ensureModelsDownloaded().then(ok => {
|
|
3696
|
+
ensureModelsDownloaded().then(async ok => {
|
|
3701
3697
|
if (ok) console.log('[MODELS] Speech models ready');
|
|
3702
3698
|
else console.log('[MODELS] Speech model download failed');
|
|
3703
3699
|
try {
|
|
3704
|
-
const { getVoices } =
|
|
3700
|
+
const { getVoices } = await getSpeech();
|
|
3705
3701
|
const voices = getVoices();
|
|
3706
3702
|
broadcastSync({ type: 'voice_list', voices });
|
|
3707
3703
|
} catch (err) {
|
|
3708
3704
|
debugLog('[VOICE] Failed to broadcast voices: ' + err.message);
|
|
3709
3705
|
broadcastSync({ type: 'voice_list', voices: [] });
|
|
3710
3706
|
}
|
|
3711
|
-
}).catch(err => {
|
|
3707
|
+
}).catch(async err => {
|
|
3712
3708
|
console.error('[MODELS] Download error:', err.message);
|
|
3713
3709
|
try {
|
|
3714
|
-
const { getVoices } =
|
|
3710
|
+
const { getVoices } = await getSpeech();
|
|
3715
3711
|
const voices = getVoices();
|
|
3716
3712
|
broadcastSync({ type: 'voice_list', voices });
|
|
3717
3713
|
} catch (err2) {
|