diff --git a/src/handlers/request-handler.js b/src/handlers/request-handler.js index ec3cd41..e90a452 100644 --- a/src/handlers/request-handler.js +++ b/src/handlers/request-handler.js @@ -44,8 +44,9 @@ export function createRequestHandler(config, providerPoolManager) { // Set CORS headers for all requests res.setHeader('Access-Control-Allow-Origin', '*'); - res.setHeader('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS'); - res.setHeader('Access-Control-Allow-Headers', 'Content-Type, Authorization, x-goog-api-key, Model-Provider'); + res.setHeader('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS, PATCH'); + res.setHeader('Access-Control-Allow-Headers', 'Content-Type, Authorization, x-goog-api-key, Model-Provider, X-Requested-With, Accept, Origin'); + res.setHeader('Access-Control-Max-Age', '86400'); // 24 hours cache for preflight // Handle CORS preflight requests if (method === 'OPTIONS') { diff --git a/src/providers/claude/claude-kiro.js b/src/providers/claude/claude-kiro.js index a85a144..2a06752 100644 --- a/src/providers/claude/claude-kiro.js +++ b/src/providers/claude/claude-kiro.js @@ -27,7 +27,7 @@ const KIRO_CONSTANTS = { AMAZON_Q_URL: 'https://codewhisperer.{{region}}.amazonaws.com/SendMessageStreaming', USAGE_LIMITS_URL: 'https://q.{{region}}.amazonaws.com/getUsageLimits', DEFAULT_MODEL_NAME: 'claude-opus-4-5', - AXIOS_TIMEOUT: 300000, // 5 minutes timeout (increased from 2 minutes) + AXIOS_TIMEOUT: 120000, // 2 minutes timeout (increased from 2 minutes) USER_AGENT: 'KiroIDE', KIRO_VERSION: '0.7.5', CONTENT_TYPE_JSON: 'application/json', diff --git a/src/services/api-server.js b/src/services/api-server.js index dabd95e..d357987 100644 --- a/src/services/api-server.js +++ b/src/services/api-server.js @@ -222,8 +222,8 @@ async function startServer() { await initializeConfig(process.argv.slice(2), 'configs/config.json'); // 自动关联 configs 目录中的配置文件到对应的提供商 - console.log('[Initialization] Checking for unlinked provider configs...'); - await autoLinkProviderConfigs(CONFIG); + // console.log('[Initialization] Checking for unlinked provider configs...'); + // await autoLinkProviderConfigs(CONFIG); // Initialize plugin system console.log('[Initialization] Discovering and initializing plugins...'); @@ -253,7 +253,15 @@ async function startServer() { // Create request handler const requestHandlerInstance = createRequestHandler(CONFIG, getProviderPoolManager()); - serverInstance = http.createServer(requestHandlerInstance); + serverInstance = http.createServer({ + // 设置服务器级别的超时 + requestTimeout: 0, // 禁用请求超时(流式响应需要) + headersTimeout: 60000, // 头部超时 60 秒 + keepAliveTimeout: 65000 // Keep-alive 超时 + }, requestHandlerInstance); + + // 设置服务器的最大连接数 + serverInstance.maxConnections = 1000; serverInstance.listen(CONFIG.SERVER_PORT, CONFIG.HOST, async () => { console.log(`--- Unified API Server Configuration ---`); const configuredProviders = Array.isArray(CONFIG.DEFAULT_MODEL_PROVIDERS) && CONFIG.DEFAULT_MODEL_PROVIDERS.length > 0 diff --git a/src/ui-modules/update-api.js b/src/ui-modules/update-api.js index 2b1d6e7..f4753ae 100644 --- a/src/ui-modules/update-api.js +++ b/src/ui-modules/update-api.js @@ -3,9 +3,70 @@ import { promises as fs } from 'fs'; import path from 'path'; import { exec } from 'child_process'; import { promisify } from 'util'; +import { CONFIG } from '../core/config-manager.js'; +import { parseProxyUrl } from '../utils/proxy-utils.js'; const execAsync = promisify(exec); +/** + * 获取更新检查使用的代理配置 + * @returns {Object|null} 代理配置对象或 null + */ +function getUpdateProxyConfig() { + if (!CONFIG || !CONFIG.PROXY_URL) { + return null; + } + + const proxyConfig = parseProxyUrl(CONFIG.PROXY_URL); + if (proxyConfig) { + console.log(`[Update] Using ${proxyConfig.proxyType} proxy for update check: ${CONFIG.PROXY_URL}`); + } + return proxyConfig; +} + +/** + * 带代理支持的 fetch 封装 + * @param {string} url - 请求 URL + * @param {Object} options - fetch 选项 + * @returns {Promise} + */ +async function fetchWithProxy(url, options = {}) { + const proxyConfig = getUpdateProxyConfig(); + + if (proxyConfig) { + // 使用 undici 的 fetch 支持代理 + const fetchOptions = { + ...options, + dispatcher: undefined + }; + + // 根据 URL 协议选择合适的 agent + const urlObj = new URL(url); + if (urlObj.protocol === 'https:') { + fetchOptions.agent = proxyConfig.httpsAgent; + } else { + fetchOptions.agent = proxyConfig.httpAgent; + } + + // Node.js 原生 fetch 不直接支持 agent,需要使用 undici 或 node-fetch + // 这里使用动态导入 undici 来支持代理 + try { + const { fetch: undiciFetch, ProxyAgent } = await import('undici'); + const proxyAgent = new ProxyAgent(CONFIG.PROXY_URL); + return await undiciFetch(url, { + ...options, + dispatcher: proxyAgent + }); + } catch (importError) { + // 如果 undici 不可用,回退到原生 fetch(不使用代理) + console.warn('[Update] undici not available, falling back to native fetch without proxy'); + return await fetch(url, options); + } + } + + return await fetch(url, options); +} + /** * 比较版本号 * @param {string} v1 - 版本号1 @@ -43,7 +104,7 @@ async function getLatestVersionFromGitHub() { try { console.log('[Update] Fetching latest version from GitHub API...'); - const response = await fetch(apiUrl, { + const response = await fetchWithProxy(apiUrl, { headers: { 'Accept': 'application/vnd.github.v3+json', 'User-Agent': 'AIClient2API-UpdateChecker' @@ -306,7 +367,7 @@ async function performTarballUpdate(localVersion, latestTag) { // 2. 下载 tarball console.log('[Update] Downloading tarball...'); - const response = await fetch(tarballUrl, { + const response = await fetchWithProxy(tarballUrl, { headers: { 'User-Agent': 'AIClient2API-Updater' },