AG X v2.0.3 - Antigravity fork with multi-provider support
Features: - Welcome screen on first run (provider choice before LS starts) - 15+ AI providers (Google Gemini, OpenAI, Anthropic, DeepSeek, Ollama, etc.) - Provider config syncs to endpoints.json for translation proxy - Built-in Node.js translation proxy for non-native backends - Auto-update support, tray integration, URI scheme handler
This commit is contained in:
116
dist/services/apiProxy.js
vendored
Normal file
116
dist/services/apiProxy.js
vendored
Normal file
@@ -0,0 +1,116 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.ApiProxy = void 0;
|
||||
const http = require("http");
|
||||
const https = require("https");
|
||||
const child_process = require("child_process");
|
||||
const path = require("path");
|
||||
const os = require("os");
|
||||
const fs = require("fs");
|
||||
const translationProxy_1 = require("./translationProxy");
|
||||
|
||||
/**
|
||||
* API Proxy for AG X.
|
||||
*
|
||||
* All backends now use the built-in Node.js translation proxy.
|
||||
* No external Python or tools required.
|
||||
*/
|
||||
class ApiProxy {
|
||||
constructor(providerService) {
|
||||
this.providerService = providerService;
|
||||
this.server = null;
|
||||
this.proxyProcess = null;
|
||||
this.port = providerService.getProxyPort();
|
||||
}
|
||||
start() {
|
||||
if (this.server || this.proxyProcess) {
|
||||
return;
|
||||
}
|
||||
const backendType = this.providerService.getActiveBackendType();
|
||||
if (backendType === 'gemini-native' || backendType === 'native') {
|
||||
console.log('[ApiProxy] Native backend, no proxy needed');
|
||||
return;
|
||||
}
|
||||
this.startInternalProxy();
|
||||
}
|
||||
/**
|
||||
* Start the built-in Node.js translation proxy as a child process
|
||||
*/
|
||||
startInternalProxy() {
|
||||
const activeProvider = this.providerService.getActiveProvider();
|
||||
const config = this.providerService.getProviderConfig(activeProvider);
|
||||
if (!config) {
|
||||
console.error('[ApiProxy] No provider config found');
|
||||
return;
|
||||
}
|
||||
// Prepare the proxy config
|
||||
const configDir = path.join(os.homedir(), '.cache', 'ag-x-proxy');
|
||||
if (!fs.existsSync(configDir)) {
|
||||
fs.mkdirSync(configDir, { recursive: true });
|
||||
}
|
||||
const models = (config.models || []).map((m) => {
|
||||
if (typeof m === 'string') {
|
||||
return { id: m, object: "model", created: 1700000000, owned_by: activeProvider };
|
||||
}
|
||||
return m;
|
||||
});
|
||||
const proxyConfig = {
|
||||
port: this.port,
|
||||
backend_type: config.backendType || 'openai-compat',
|
||||
target_url: config.apiUrl || '',
|
||||
api_key: config.apiKey || '',
|
||||
cc_version: config.ccVersion || '0.26.8',
|
||||
oauth_provider: config.oauthProvider || '',
|
||||
reasoning_enabled: config.reasoningEnabled !== undefined ? config.reasoningEnabled : true,
|
||||
reasoning_effort: config.reasoningEffort || 'medium',
|
||||
models: models,
|
||||
};
|
||||
const configPath = path.join(configDir, `ag-x-proxy-${this.port}.json`);
|
||||
fs.writeFileSync(configPath, JSON.stringify(proxyConfig, null, 2), 'utf-8');
|
||||
console.log(`[ApiProxy] Starting built-in Node.js translation proxy on port ${this.port}`);
|
||||
// Use Electron's Node.js binary to run our translation proxy
|
||||
const proxyScript = path.join(__dirname, 'translationProxy.js');
|
||||
const nodeBin = process.execPath;
|
||||
this.proxyProcess = child_process.spawn(nodeBin, [proxyScript], {
|
||||
stdio: ['ignore', 'pipe', 'pipe'],
|
||||
detached: false,
|
||||
env: { ...process.env },
|
||||
});
|
||||
this.proxyProcess.stdout?.on('data', (data) => {
|
||||
const lines = data.toString().trim().split('\n');
|
||||
for (const line of lines) {
|
||||
console.log(`[Proxy] ${line}`);
|
||||
}
|
||||
});
|
||||
this.proxyProcess.stderr?.on('data', (data) => {
|
||||
const lines = data.toString().trim().split('\n');
|
||||
for (const line of lines) {
|
||||
console.log(`[Proxy] ${line}`);
|
||||
}
|
||||
});
|
||||
this.proxyProcess.on('error', (err) => {
|
||||
console.error('[ApiProxy] Proxy error:', err);
|
||||
});
|
||||
this.proxyProcess.on('exit', (code, signal) => {
|
||||
console.log(`[ApiProxy] Proxy exited with code ${code}, signal ${signal}`);
|
||||
this.proxyProcess = null;
|
||||
});
|
||||
this.proxyProcess.unref();
|
||||
console.log(`[ApiProxy] Built-in Node.js proxy spawned for ${config.backendType} on port ${this.port}`);
|
||||
}
|
||||
stop() {
|
||||
if (this.proxyProcess) {
|
||||
try {
|
||||
this.proxyProcess.kill();
|
||||
}
|
||||
catch (e) { /* ignore */ }
|
||||
this.proxyProcess = null;
|
||||
}
|
||||
if (this.server) {
|
||||
this.server.close();
|
||||
this.server = null;
|
||||
console.log('[ApiProxy] Stopped');
|
||||
}
|
||||
}
|
||||
}
|
||||
exports.ApiProxy = ApiProxy;
|
||||
Reference in New Issue
Block a user