v2.0.5: Fix E2E flow - proxy, welcome screen, provider sync

Critical fixes:
- Translation proxy now uses system Node.js (not Electron binary)
- Removed duplicate proxy start causing port conflicts
- Added port availability check before spawning proxy
- Fixed welcome:choice double resolve()
- Fixed settings.html close using deprecated remote
- Fixed translationProxy /v1 for openai-compat backends
- Proxy no longer detached/unref - properly tracked as child
- SingletonLock cleanup on startup

Verified E2E:
- Welcome screen on first run ✓
- Provider selection works ✓
- Settings save + sync ✓
- Translation proxy starts correctly ✓
- LS connects to proxy ✓
- --ag-reset works ✓
This commit is contained in:
admin
2026-05-23 12:14:04 +04:00
Unverified
parent 0c4b0b9338
commit f7378eceb0
7 changed files with 80 additions and 68 deletions

View File

@@ -187,7 +187,7 @@ function setupNodeModules(env, modules) {
*/
const os = require('os');
function ensureProxyStarted() {
return new Promise((resolve) => {
return new Promise(async (resolve) => {
if (_proxyProcess) {
resolve();
return;
@@ -234,16 +234,45 @@ function ensureProxyStarted() {
models: modelList.map(m => ({ id: m, object: "model", created: 1700000000, owned_by: endpoint.name }))
};
fs.writeFileSync(activeConfigPath, JSON.stringify(pcfg, null, 2), 'utf8');
// Check if proxy is already running on port 48080
const net = require('net');
const proxyPortTest = await new Promise((resolve) => {
const tester = net.createConnection(48080, '127.0.0.1');
tester.on('connect', () => { tester.destroy(); resolve(true); });
tester.on('error', () => { tester.destroy(); resolve(false); });
setTimeout(() => { tester.destroy(); resolve(false); }, 1000);
});
if (proxyPortTest) {
console.log('[AG X] Translation proxy already running on port 48080, skipping spawn');
resolve();
return;
}
console.log('[AG X] Starting built-in Node.js translation proxy for:', endpoint.name);
// Use Electron's built-in Node.js to run our translation proxy
const proxyScript = path_1.default.join(__dirname, 'services', 'translationProxy.js');
const nodeBin = process.execPath;
_proxyProcess = (0, child_process_1.spawn)(nodeBin, ['--no-sandbox', proxyScript], {
stdio: 'ignore',
detached: true,
// Use system node (not Electron's process.execPath which starts a GUI)
const nodeBin = process.execPath.includes('electron') || process.execPath.includes('AG-X')
? (require('child_process').execSync('which node 2>/dev/null || echo /usr/bin/node').toString().trim())
: process.execPath;
_proxyProcess = (0, child_process_1.spawn)(nodeBin, [proxyScript], {
stdio: ['ignore', 'pipe', 'pipe'],
detached: false,
env: { ...process.env }
});
_proxyProcess.unref();
_proxyProcess.stdout?.on('data', (d) => {
for (const line of d.toString().split('\n')) {
if (line.trim()) console.log('[Proxy]', line.trim());
}
});
_proxyProcess.stderr?.on('data', (d) => {
for (const line of d.toString().split('\n')) {
if (line.trim()) console.log('[Proxy:err]', line.trim());
}
});
_proxyProcess.on('exit', (code) => {
console.log('[AG X] Translation proxy exited with code:', code);
_proxyProcess = null;
});
setTimeout(() => {
resolve();
}, 500);