"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.openProviderSettings = openProviderSettings; exports.closeProviderSettings = closeProviderSettings; const electron_1 = require("electron"); const path_1 = require("path"); let settingsWindow = null; function openProviderSettings(providerService) { if (settingsWindow) { settingsWindow.show(); settingsWindow.focus(); return; } settingsWindow = new electron_1.BrowserWindow({ width: 820, height: 720, title: 'AI Provider Settings', resizable: true, minimizable: true, maximizable: true, backgroundColor: '#1a1a2e', titleBarStyle: 'hidden', titleBarOverlay: { color: '#16213e', symbolColor: '#e0e0e0', height: 36, }, webPreferences: { nodeIntegration: true, contextIsolation: false, enableRemoteModule: false, }, }); settingsWindow.loadFile(path_1.join(__dirname, 'provider', 'settings.html')); settingsWindow.on('closed', () => { settingsWindow = null; }); // Register IPC handlers for provider settings electron_1.ipcMain.handle('provider:get-config', async () => { return { activeProvider: providerService.getActiveProvider(), providers: providerService.getAllProviders(), }; }); electron_1.ipcMain.handle('provider:save', async (_event, settings) => { providerService.setActiveProvider(settings.activeProvider); providerService.updateProviderConfig(settings.activeProvider, settings.providerConfig); // Sync to endpoints.json so the LS proxy uses this provider on next restart try { const os = require('os'); const fs = require('fs'); const pathMod = require('path'); const home = os.homedir(); const endpointsPath = pathMod.join(home, '.codex', 'endpoints.json'); const activePath = pathMod.join(home, '.codex', '.active-endpoint.json'); const activeProvider = providerService.getActiveProvider(); const providerConfig = providerService.getProviderConfig(activeProvider); if (providerConfig) { let endpointsData = { default: '', endpoints: [] }; if (fs.existsSync(endpointsPath)) { try { endpointsData = JSON.parse(fs.readFileSync(endpointsPath, 'utf8')); } catch(e) {} } const endpointName = 'AG X: ' + (providerConfig.name || activeProvider); const existingIdx = endpointsData.endpoints.findIndex(e => e.name === endpointName); const endpoint = { name: endpointName, backend_type: providerConfig.backendType || 'openai-compat', base_url: providerConfig.apiUrl || '', api_key: providerConfig.apiKey || '', default_model: providerConfig.model || providerConfig.defaultModel || '', models: providerConfig.models || [], provider_preset: 'AG X', }; if (existingIdx >= 0) { endpointsData.endpoints[existingIdx] = endpoint; } else { endpointsData.endpoints.push(endpoint); } endpointsData.default = endpointName; fs.writeFileSync(endpointsPath, JSON.stringify(endpointsData, null, 2), 'utf-8'); fs.writeFileSync(activePath, JSON.stringify({ active: endpointName }, null, 2), 'utf-8'); console.log('[Settings] Provider synced to endpoints.json:', endpointName); } } catch(e) { console.error('[Settings] Failed to sync:', e); } // Notify welcome screen (if waiting) that settings are saved electron_1.ipcMain.emit('provider:settings-saved'); return { success: true, needsRestart: true }; }); electron_1.ipcMain.handle('provider:reset', async () => { const fs = require("fs"); const configPath = providerService.configPath; if (fs.existsSync(configPath)) { fs.unlinkSync(configPath); } // Reload defaults providerService.config = providerService.loadConfig(); return { success: true }; }); electron_1.ipcMain.handle('provider:save-advanced', async (_event, settings) => { // Store advanced settings const fs = require("fs"); const advancedPath = providerService.configPath.replace('.json', '_advanced.json'); fs.writeFileSync(advancedPath, JSON.stringify(settings, null, 2), 'utf-8'); return { success: true }; }); electron_1.ipcMain.on('provider:close-settings', () => { closeProviderSettings(); }); electron_1.ipcMain.handle('provider:test-connection', async (_event, testConfig) => { return testProviderConnection(testConfig); }); } function closeProviderSettings() { if (settingsWindow) { settingsWindow.close(); settingsWindow = null; } } async function testProviderConnection(testConfig) { const http = require("http"); const https = require("https"); const url = new URL(testConfig.apiUrl || 'https://api.openai.com'); const isHttps = url.protocol === 'https:'; const httpModule = isHttps ? https : http; return new Promise((resolve) => { const options = { hostname: url.hostname, port: url.port || (isHttps ? 443 : 80), path: testConfig.provider === 'ollama' ? '/api/tags' : '/', method: 'GET', timeout: 10000, headers: {}, }; if (testConfig.apiKey) { if (testConfig.provider === 'anthropic') { options.headers['x-api-key'] = testConfig.apiKey; options.headers['anthropic-version'] = '2023-06-01'; } else { options.headers['Authorization'] = `Bearer ${testConfig.apiKey}`; } } const req = httpModule.request(options, (res) => { let body = ''; res.on('data', (chunk) => (body += chunk)); res.on('end', () => { if (res.statusCode && res.statusCode < 500) { resolve({ success: true, message: `HTTP ${res.statusCode} — Server reachable. Model: ${testConfig.model || 'default'}`, }); } else { resolve({ success: false, error: `HTTP ${res.statusCode}: ${body.substring(0, 200)}`, }); } }); }); req.on('error', (err) => { resolve({ success: false, error: err.message }); }); req.on('timeout', () => { req.destroy(); resolve({ success: false, error: 'Connection timed out after 10s' }); }); req.end(); }); }