()
| 2780 | } |
| 2781 | |
| 2782 | async function saveConfig() { |
| 2783 | try { |
| 2784 | const getValue = (id, def = '') => document.getElementById(id)?.value.trim() || def; |
| 2785 | const getInt = (id, def = 0) => parseInt(document.getElementById(id)?.value) || def; |
| 2786 | const getFloat = (id, def = 0.0) => parseFloat(document.getElementById(id)?.value) || def; |
| 2787 | const getChecked = (id, def = false) => document.getElementById(id)?.checked || def; |
| 2788 | |
| 2789 | const config = { |
| 2790 | host: getValue('host', '0.0.0.0'), |
| 2791 | port: getInt('port', 7861), |
| 2792 | api_password: getValue('configApiPassword'), |
| 2793 | panel_password: getValue('configPanelPassword'), |
| 2794 | password: getValue('configPassword', 'pwd'), |
| 2795 | code_assist_endpoint: getValue('codeAssistEndpoint'), |
| 2796 | credentials_dir: getValue('credentialsDir'), |
| 2797 | proxy: getValue('proxy'), |
| 2798 | oauth_proxy_url: getValue('oauthProxyUrl'), |
| 2799 | googleapis_proxy_url: getValue('googleapisProxyUrl'), |
| 2800 | resource_manager_api_url: getValue('resourceManagerApiUrl'), |
| 2801 | service_usage_api_url: getValue('serviceUsageApiUrl'), |
| 2802 | antigravity_api_url: getValue('antigravityApiUrl'), |
| 2803 | auto_ban_enabled: getChecked('autoBanEnabled'), |
| 2804 | auto_ban_error_codes: getValue('autoBanErrorCodes').split(',') |
| 2805 | .map(c => parseInt(c.trim())).filter(c => !isNaN(c)), |
| 2806 | calls_per_rotation: getInt('callsPerRotation', 10), |
| 2807 | retry_429_enabled: getChecked('retry429Enabled'), |
| 2808 | retry_429_max_retries: getInt('retry429MaxRetries', 20), |
| 2809 | retry_429_interval: getFloat('retry429Interval', 0.1), |
| 2810 | compatibility_mode_enabled: getChecked('compatibilityModeEnabled'), |
| 2811 | return_thoughts_to_frontend: getChecked('returnThoughtsToFrontend'), |
| 2812 | antigravity_stream2nostream: getChecked('antigravityStream2nostream'), |
| 2813 | antigravity_switch_credential_enabled: getChecked('antigravitySwitchCredentialEnabled'), |
| 2814 | anti_truncation_max_attempts: getInt('antiTruncationMaxAttempts', 3), |
| 2815 | keepalive_url: getValue('keepaliveUrl'), |
| 2816 | keepalive_interval: getInt('keepaliveInterval', 60) |
| 2817 | }; |
| 2818 | |
| 2819 | const response = await fetch('./config/save', { |
| 2820 | method: 'POST', |
| 2821 | headers: getAuthHeaders(), |
| 2822 | body: JSON.stringify({ config }) |
| 2823 | }); |
| 2824 | |
| 2825 | const data = await response.json(); |
| 2826 | |
| 2827 | if (response.ok) { |
| 2828 | let message = '配置保存成功'; |
| 2829 | |
| 2830 | if (data.hot_updated && data.hot_updated.length > 0) { |
| 2831 | message += `,以下配置已立即生效: ${data.hot_updated.join(', ')}`; |
| 2832 | } |
| 2833 | |
| 2834 | if (data.restart_required && data.restart_required.length > 0) { |
| 2835 | message += `\n⚠️ 重启提醒: ${data.restart_notice}`; |
| 2836 | showStatus(message, 'info'); |
| 2837 | } else { |
| 2838 | showStatus(message, 'success'); |
| 2839 | } |
nothing calls this directly
no test coverage detected