"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;