From ceff3771ea2fc9b6914b09ddecb60fc22d3825b9 Mon Sep 17 00:00:00 2001 From: hex2077 Date: Sat, 4 Apr 2026 22:49:44 +0800 Subject: [PATCH 01/10] =?UTF-8?q?Revert=20"feat:=20=E6=9B=B4=E6=96=B0?= =?UTF-8?q?=E7=89=88=E6=9C=AC=E8=87=B32.12.3=E5=B9=B6=E4=BF=AE=E5=A4=8D?= =?UTF-8?q?=E5=A4=9A=E4=B8=AA=E9=97=AE=E9=A2=98"?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This reverts commit 1570fbb09638dc11d55346a9ca2371b37beeb5ab. --- README-JA.md | 10 --- README-ZH.md | 10 --- README.md | 10 --- VERSION | 2 +- install-and-run.ps1 | 42 ++++++------ src/providers/gemini/antigravity-core.js | 82 ++++++++--------------- src/providers/gemini/gemini-core.js | 41 +++++------- src/providers/openai/qwen-core.js | 34 +--------- static/lingtrueapi.png | Bin 201094 -> 0 bytes 9 files changed, 69 insertions(+), 162 deletions(-) delete mode 100644 static/lingtrueapi.png diff --git a/README-JA.md b/README-JA.md index 529829a..227c362 100644 --- a/README-JA.md +++ b/README-JA.md @@ -47,16 +47,6 @@ AICodeMirror の本プロジェクトへのスポンサーシップに感謝します!AICodeMirror は、Claude Code / Codex / Gemini CLI 向けに公式の高安定性リレーサービスを提供しており、企業レベルの同時実行性、迅速な請求書発行、24時間365日の専用技術サポートを備えています。Claude Code / Codex / Gemini の公式チャンネルを、元の価格の 38% / 2% / 9% で利用でき、チャージ時にはさらなる割引もあります!AICodeMirror は AIClient-2-API ユーザーに特別な特典を提供しています:このリンクから登録すると、初回チャージが 20% オフになり、法人のお客様は最大 25% オフになります! - - - - LingtrueAPI Sponsor - - - - LingtrueAPIによる本プロジェクトへのスポンサーに感謝します!LingtrueAPIは世界的な大規模言語モデルAPI中継プラットフォームであり、Claude opus 4.6、GPT 5.4、Gemini 3.1 proなど各種モデルのAPI呼び出しサービスを提供しています。低コスト、高安定性で世界中のAI機能に接続し、生産性を最大化することを目指しています。LingtrueAPIは本ソフトウェアユーザー向けに特別優遇を提供しています。このリンクから登録し、初回チャージ時に「LingtrueAPI」のクーポンコードを入力すると、10%オフで利用できます。 - - Sponsor Contact diff --git a/README-ZH.md b/README-ZH.md index 048bf2f..e7e2ddf 100644 --- a/README-ZH.md +++ b/README-ZH.md @@ -46,16 +46,6 @@ 感谢 AICodeMirror 赞助本项目!AICodeMirror 为 Claude Code / Codex / Gemini CLI 提供官方高稳定性中转服务,具备企业级并发能力、快速开票和 7/24 专属技术支持。Claude Code / Codex / Gemini 官方渠道价格仅为原价的 38% / 2% / 9%,充值还有额外优惠!AICodeMirror 为 AIClient-2-API 用户提供专属福利:通过此链接注册即可享受首充 8折(20% off) 优惠,企业客户最高可享 75折(25% off)! - - - - LingtrueAPI Sponsor - - - - 感谢 LingtrueAPI 对本项目的赞助!LingtrueAPI 是一家全球大模型API中转服务平台,提供Claude opus 4.6、GPT 5.4、Gemini 3.1 pro等多种模型API调用服务,致力于让用户以低成本、高稳定性链接全球AI能力,最大化生产效率。LingtrueAPI为本软件用户提供了特别优惠:通过此链接注册并在首次充值时输入 LingtrueAPI 优惠码即可享受 9折优惠。 - - Sponsor Contact diff --git a/README.md b/README.md index 3aef936..8c0895e 100644 --- a/README.md +++ b/README.md @@ -47,16 +47,6 @@ Thanks to AICodeMirror for sponsoring this project! AICodeMirror provides official high-stability relay services for Claude Code / Codex / Gemini CLI, with enterprise-grade concurrency, fast invoicing, and 24/7 dedicated technical support. Claude Code / Codex / Gemini official channels at 38% / 2% / 9% of original price, with extra discounts on top-ups! AICodeMirror offers special benefits for AIClient-2-API users: register via this link to enjoy 20% off your first top-up, and enterprise customers can get up to 25% off! - - - - LingtrueAPI Sponsor - - - - Thanks to LingtrueAPI for its sponsorship of this project! LingtrueAPI is a global large-model API intermediary service platform that offers API calling services for various models such as Claude opus 4.6, GPT 5.4, and Gemini 3.1 pro. It is committed to enabling users to connect to global AI capabilities at low cost and with high stability, maximizing production efficiency. LingtrueAPI provides special discounts for users of this software: register using this link and enter the LingtrueAPI promo code when making the first recharge to enjoy a 10% discount. - - Sponsor Contact diff --git a/VERSION b/VERSION index ccc99d0..d463c35 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -2.12.3 +2.12.2.2 diff --git a/install-and-run.ps1 b/install-and-run.ps1 index d72a7f7..11821a0 100644 --- a/install-and-run.ps1 +++ b/install-and-run.ps1 @@ -2,70 +2,70 @@ $OutputEncoding = [System.Text.Encoding]::UTF8 Write-Host "========================================" -ForegroundColor Cyan -Write-Host " AI Client 2 API Quick Setup Script" -ForegroundColor Cyan +Write-Host " AI Client 2 API 快速安装启动脚本" -ForegroundColor Cyan Write-Host "========================================" -ForegroundColor Cyan Write-Host "" -# Handle parameters +# 处理参数 $forcePull = $args -contains "--pull" -# Check Git and Pull +# 检查 Git 并拉取 if ($forcePull) { - Write-Host "[UPDATE] Pulling latest code from remote repository..." + Write-Host "[更新] 正在从远程仓库拉取最新代码..." if (Get-Command git -ErrorAction SilentlyContinue) { git pull if ($LASTEXITCODE -ne 0) { - Write-Warning "Git pull failed. Please check your network or handle conflicts manually." + Write-Warning "Git pull 失败,请检查网络或手动处理冲突。" } else { - Write-Host "[SUCCESS] Code updated." -ForegroundColor Green + Write-Host "[成功] 代码已更新。" -ForegroundColor Green } } else { - Write-Warning "Git not detected. Skipping code pull." + Write-Warning "未检测到 Git,跳过代码拉取。" } } -# Check Node.js -Write-Host "[CHECK] Checking if Node.js is installed..." +# 检查 Node.js +Write-Host "[检查] 正在检查Node.js是否已安装..." if (-not (Get-Command node -ErrorAction SilentlyContinue)) { - Write-Host "[ERROR] Node.js not detected. Please install Node.js (https://nodejs.org/)" -ForegroundColor Red + Write-Host "[错误] 未检测到Node.js,请先安装Node.js (https://nodejs.org/)" -ForegroundColor Red Pause exit 1 } $nodeVersion = node --version -Write-Host "[SUCCESS] Node.js installed, version: $nodeVersion" -ForegroundColor Green +Write-Host "[成功] Node.js已安装,版本: $nodeVersion" -ForegroundColor Green -# Check package.json +# 检查 package.json if (-not (Test-Path "package.json")) { - Write-Host "[ERROR] package.json not found. Please ensure you are running this script from the project root." -ForegroundColor Red + Write-Host "[错误] 未找到package.json文件,请确保在项目根目录下运行此脚本" -ForegroundColor Red Pause exit 1 } -# Determine package manager +# 确定包管理器 $pkgManager = if (Get-Command pnpm -ErrorAction SilentlyContinue) { "pnpm" } else { "npm" } -Write-Host "[INSTALL] Installing/updating dependencies using $pkgManager..." -ForegroundColor Cyan +Write-Host "[安装] 正在使用 $pkgManager 安装/更新依赖..." -ForegroundColor Cyan & $pkgManager install if ($LASTEXITCODE -ne 0) { - Write-Host "[ERROR] Dependency installation failed. Please check your network connection." -ForegroundColor Red + Write-Host "[错误] 依赖安装失败,请检查网络连接。" -ForegroundColor Red Pause exit 1 } -# Check master file +# 检查主文件 if (-not (Test-Path "src\core\master.js")) { - Write-Host "[ERROR] src\core\master.js not found." -ForegroundColor Red + Write-Host "[错误] 未找到 src\core\master.js 文件" -ForegroundColor Red Pause exit 1 } Write-Host "" Write-Host "========================================" -ForegroundColor Green -Write-Host " Starting AIClient2API Server..." -ForegroundColor Green +Write-Host " 启动 AIClient2API 服务器..." -ForegroundColor Green Write-Host "========================================" -ForegroundColor Green -Write-Host "Server will start at http://localhost:3000" -Write-Host "Press Ctrl+C to stop the server" +Write-Host "服务器将在 http://localhost:3000 启动" +Write-Host "按 Ctrl+C 停止服务器" Write-Host "" node src\core\master.js diff --git a/src/providers/gemini/antigravity-core.js b/src/providers/gemini/antigravity-core.js index e1da3dc..c66fd2e 100644 --- a/src/providers/gemini/antigravity-core.js +++ b/src/providers/gemini/antigravity-core.js @@ -40,7 +40,6 @@ const ANTIGRAVITY_SYSTEM_PROMPT = `You are Antigravity, a powerful agentic AI co // Thinking 配置相关常量 const DEFAULT_THINKING_MIN = 1024; const DEFAULT_THINKING_MAX = 100000; -const FALLBACK_THINKING_SIGNATURE = "skip_thought_signature_validator_fallback"; // 获取 Antigravity 模型列表 const ANTIGRAVITY_MODELS = getProviderModels(MODEL_PROVIDER.ANTIGRAVITY); @@ -200,16 +199,16 @@ function normalizeAntigravityThinking(modelName, payload, isClaudeModel) { let normalizedBudget = normalizeThinkingBudget(modelName, budget); - // 确保 thinking budget < max_tokens (对所有模型生效,不仅是 Claude) - const maxTokens = payload?.request?.generationConfig?.maxOutputTokens || payload?.request?.generationConfig?.max_output_tokens; - if (maxTokens && maxTokens > 0 && normalizedBudget >= maxTokens) { - normalizedBudget = Math.max(0, maxTokens - 1); - } - - // 如果是 Claude 模型,检查最小 budget + // 对于 Claude 模型,确保 thinking budget < max_tokens if (isClaudeModel) { + const maxTokens = payload?.request?.generationConfig?.maxOutputTokens; + if (maxTokens && maxTokens > 0 && normalizedBudget >= maxTokens) { + normalizedBudget = maxTokens - 1; + } + + // 检查最小 budget const minBudget = DEFAULT_THINKING_MIN; - if (normalizedBudget >= 0 && normalizedBudget < minBudget && normalizedBudget !== -1) { + if (normalizedBudget >= 0 && normalizedBudget < minBudget) { // Budget 低于最小值,移除 thinking 配置 delete payload.request.generationConfig.thinkingConfig; return payload; @@ -600,7 +599,7 @@ function toGeminiApiResponse(antigravityResponse) { } /** - * 确保请求体中的内容部分都有角色属性,并修复历史记录中的思考签名 + * 确保请求体中的内容部分都有角色属性 * @param {Object} requestBody - 请求体 * @returns {Object} 处理后的请求体 */ @@ -675,24 +674,6 @@ function ensureRolesInContents(requestBody, modelName) { if (!content.role) { content.role = 'user'; } - - // [FIX] 修复历史记录中的思考块,确保有签名 (messages.1.content.0.thinking.signature 报错修复) - if (content.parts && Array.isArray(content.parts)) { - content.parts.forEach(part => { - if (part && part.thought === true) { - if (!part.thoughtSignature && !part.thought_signature) { - part.thoughtSignature = FALLBACK_THINKING_SIGNATURE; - } - - // [FIX] 额外增加一个 'thinking' 对象以适配某些 Antigravity 内部验证逻辑 - if (!part.thinking) { - part.thinking = { - signature: part.thoughtSignature || part.thought_signature || FALLBACK_THINKING_SIGNATURE - }; - } - } - }); - } }); } @@ -715,6 +696,25 @@ export class AntigravityApiService { timeout: 120000, }); + // 检查是否需要使用代理 + const proxyConfig = getGoogleAuthProxyConfig(config, config.MODEL_PROVIDER || MODEL_PROVIDER.ANTIGRAVITY); + + // 配置 OAuth2Client 使用自定义的 HTTP agent + const oauth2Options = { + clientId: OAUTH_CLIENT_ID, + clientSecret: OAUTH_CLIENT_SECRET, + }; + + if (proxyConfig) { + oauth2Options.transporterOptions = proxyConfig; + logger.info('[Antigravity] Using proxy for OAuth2Client'); + } else { + oauth2Options.transporterOptions = { + agent: this.httpsAgent, + }; + } + + this.authClient = new OAuth2Client(oauth2Options); this.availableModels = []; this.isInitialized = false; @@ -730,32 +730,6 @@ export class AntigravityApiService { // 保存代理配置供后续使用 this.proxyConfig = getProxyConfigForProvider(config, config.MODEL_PROVIDER || MODEL_PROVIDER.ANTIGRAVITY); - - // 检查是否需要使用代理 - const proxyConfig = getGoogleAuthProxyConfig(config, config.MODEL_PROVIDER || MODEL_PROVIDER.ANTIGRAVITY); - - // 配置 OAuth2Client 使用自定义的 HTTP agent - const oauth2Options = { - clientId: OAUTH_CLIENT_ID, - clientSecret: OAUTH_CLIENT_SECRET, - }; - - if (proxyConfig) { - oauth2Options.transporterOptions = proxyConfig; - logger.info('[Antigravity] Using proxy for OAuth2Client'); - } else { - // 根据 base URL 判断使用 http 还是 https agent - const firstBaseURL = this.baseURLs && this.baseURLs.length > 0 ? this.baseURLs[0] : ''; - const useHttp = firstBaseURL.startsWith('http://'); - oauth2Options.transporterOptions = { - agent: useHttp ? this.httpAgent : this.httpsAgent, - }; - if (useHttp) { - logger.info('[Antigravity] Using HTTP agent for OAuth2Client'); - } - } - - this.authClient = new OAuth2Client(oauth2Options); } _applySidecar(requestOptions) { diff --git a/src/providers/gemini/gemini-core.js b/src/providers/gemini/gemini-core.js index 57abb77..b4f386c 100644 --- a/src/providers/gemini/gemini-core.js +++ b/src/providers/gemini/gemini-core.js @@ -287,6 +287,24 @@ export class GeminiApiService { maxFreeSockets: 5, timeout: 120000, }); + + // 检查是否需要使用代理 + const proxyConfig = getGoogleAuthProxyConfig(config, config.MODEL_PROVIDER || MODEL_PROVIDER.GEMINI_CLI); + + // 配置 OAuth2Client 使用自定义的 HTTP agent + const oauth2Options = { + clientId: OAUTH_CLIENT_ID, + clientSecret: OAUTH_CLIENT_SECRET, + }; + + if (proxyConfig) { + oauth2Options.transporterOptions = proxyConfig; + logger.info('[Gemini] Using proxy for OAuth2Client'); + } else { + oauth2Options.transporterOptions = { + agent: this.httpsAgent, + }; + } this.authClient = new OAuth2Client(oauth2Options); this.availableModels = []; @@ -304,29 +322,6 @@ export class GeminiApiService { // 保存代理配置供后续使用 this.proxyConfig = getProxyConfigForProvider(config, config.MODEL_PROVIDER || MODEL_PROVIDER.GEMINI_CLI); - - // 检查是否需要使用代理 - const proxyConfig = getGoogleAuthProxyConfig(config, config.MODEL_PROVIDER || MODEL_PROVIDER.GEMINI_CLI); - - // 配置 OAuth2Client 使用自定义的 HTTP agent - const oauth2Options = { - clientId: OAUTH_CLIENT_ID, - clientSecret: OAUTH_CLIENT_SECRET, - }; - - if (proxyConfig) { - oauth2Options.transporterOptions = proxyConfig; - logger.info('[Gemini] Using proxy for OAuth2Client'); - } else { - // 根据 base URL 判断使用 http 还是 https agent - const useHttp = this.codeAssistEndpoint && this.codeAssistEndpoint.startsWith('http://'); - oauth2Options.transporterOptions = { - agent: useHttp ? this.httpAgent : this.httpsAgent, - }; - if (useHttp) { - logger.info('[Gemini] Using HTTP agent for OAuth2Client'); - } - } } async initialize() { diff --git a/src/providers/openai/qwen-core.js b/src/providers/openai/qwen-core.js index f84a679..e2621ca 100644 --- a/src/providers/openai/qwen-core.js +++ b/src/providers/openai/qwen-core.js @@ -50,38 +50,6 @@ export const qwenOAuth2Events = new EventEmitter(); // --- Helper Functions --- -/** - * Qwen 默认系统提示词 - */ -const QWEN_DEFAULT_SYSTEM_PROMPT = "You are a helpful assistant. You are Qwen, a large language model trained by Alibaba."; - -/** - * 应用 Qwen 默认系统提示词逻辑 - * @param {Object} requestBody - OpenAI 格式的请求体 - * @returns {Object} 处理后的请求体 - */ -function applyQwenDefaultSystemPrompt(requestBody) { - if (!requestBody || !requestBody.messages || !Array.isArray(requestBody.messages)) { - return requestBody; - } - - // 检查是否已有系统提示词 (role 为 system 或 developer) - const hasSystemPrompt = requestBody.messages.some(msg => - msg.role === 'system' || msg.role === 'developer' - ); - - // 如果没有系统提示词,则在消息列表最前面插入默认提示词 - if (!hasSystemPrompt) { - requestBody.messages.unshift({ - role: 'system', - content: QWEN_DEFAULT_SYSTEM_PROMPT - }); - logger.info('[Qwen Auth] 已应用默认系统提示词'); - } - - return requestBody; -} - // 封装公共的 await fetch 方法 async function commonFetch(url, options = {}, useSystemProxy = false) { const defaultOptions = { @@ -612,7 +580,7 @@ export class QwenApiService { this.currentAxiosInstance = axios.create(axiosConfig); // Process message content before sending the request - const processedBody = applyQwenDefaultSystemPrompt(body); + const processedBody = body;//this.processMessageContent(body); // Check if model in body is in QWEN_MODEL_LIST, if not, use the first model's id if (processedBody.model && !QWEN_MODEL_LIST.some(model => model.id === processedBody.model)) { diff --git a/static/lingtrueapi.png b/static/lingtrueapi.png deleted file mode 100644 index 0829a7ca7db3f14684c7395cb5f687f05428a10c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 201094 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 z�~Hi*4$g-8;A7qKhxUamO5sp!OIG)qo^O)+*;Xc*b#B6CVQ7V{SgTen*R%CyIjb zdV5S8fomUgCMH?|TWafs&00rn(fCZMo}XI;|3j&*io=%88?i;tCZnf0=Bt1CRs8RN z`9JCTQ7G1rYv;%QUM zagIK8Tc!2f*zO$&T3Z#;7t&`06!M{M1GFS>Y0cZ&whhPZ+=;8(<9ODxqi|_w9LLIL zQm`FU-^Fx~c$^p{6EBmLl9?xI(Ew3p448&^NFxv)($bp39?}Q|hIHfURRUTKfUA$j zW3Ij$8;gKlkgiooA99^EQ<-8!S|mY-X>Tt01|>&tTB#q>GiYH#QuSpjm&~c_W&xRb zGN+aeptdDDr6iLNlA7c)UA57vfxcbTCst7}j{&k%Tr4mA%m*~7W{A`Tuh#-iVvd(0 z3V+MWa%jVdWFk#xVt7q;s#tG68R9KBM1t(+H**BSixgM8YL97yqq#51 ziQ{34q>}{F<-`GgY=ay|O>uzj|3S?h4g1;%-}NH5VBt~(nSoOd?PU$++P&OIAP ztyq~}1nb>djRB1qi6eT7!I@{AhR0uf4X(ZF3S4{5Re1c>SK#s2T$ym4(rd500@q%7 zS&GfoiqDl-T#Bo&x)P_Hv<974JH7O2xXIt})UX;dHOlv?5p^RknVQ69mt2gi?C;9U zaka|0`pQehXSgiuu5sU7b}_EJ>=M~rfhRuUIvlH)&Q>uT$5jy|K@P`sB|ngKS_|j& za-)qLZ_1ps<^;ugo#K3U8V^@qdJ!&D|9IS7mip~{jfZu(uwzp^~spx8qfvR-a;P&O|%Ofy?hzYI`dRK`AJW}o8ELIKK^Hag1`Bz zui>^^KaC%M!|T<)bFpmc6!dr(g32yZJ6o;1sZiBvr(QmG?%0`hmeqlI4$oz(e$tGM zjj1gm(ax8MgLEOQQjqEf9eyEi>m_{k(W~&vSH2v#-STOC?z6YzZEt-uuDbG4#cCWo z^g_Jhf$!mg`@V|@@4E-<@4FWp?z;~UK5!p4Ja8`_)aL2>`@bjoJ-Gkgd&GZFFWQ^1 zWPA)K>HZnlJWdYFRs1cRHq^Y ztXjD;jm0}YdmBFX(Lcp=pY;qZnHb2hSbzUL+Ed(xtFO8ofB50wQ$KzRuXy=O;f!zi6CR)LiK{g?`I&IF=Adh@x=i!WW$^rG*%g|TtiM`w*LBxjhvSbs4xuPien8b{ z*v})?Yfj!AOV`tgYNy*frVZ7LFTMcp{l%ZhSO5Hr_`m-65Ao8Mya*>8b2N4;2AkI3 z2Y-uiyEc3L&ETj_OLt45%nBje?SQt%d0XS7U5FN1iUndIN>{Pa)%6uzK2k_*|j2$&=KstM!b$O5^h? zjmsJupO2$ft%4xt@^V~z_2uxI z>AGvKNc7cuPNaFm{iSt+*9ey@z4Ee4arR>$hpEX4FaSaKqJ0~SX|{$0pnCY%eZ47o zqB1>xYAK$#<|I5}>2f?~=WZOU4{=v)*@Wf#fOz@NU09|MQCDd5a+yAuT&}tF_^n&< zIIV52Te1XCTX{6D&}QI?@-rpp-Y}$SpJb+7x4psk708^g;+yoLi-3mI+``;>mDIFR z@$;p7)6bV@Uu1{c|Gw1aaJD6fHB3@dNvzu_PJe!w+&Tc z(?-fK9?EZjhBMix^-(WEr4~d%{>)o90LuXh*TcU1^-r;_>-&~5=63bjy(W7zNL9}v z+necr=_~(LN{$vrwb^ZVe5m-Ne^jv|nZ}`C{Jk-#rHJoUle$hMM~tiT$t(}5 zzhyv#MTYZ51RxafqAluP@!#p_6~tEAmD;#E{pxGb){7yufFP;7Oy!VOiXFyZnB(wfb+1z=@?YQ%EpH29J z>_30|XYmEWvMM#5VB0>dGc5nY?YAlat=ho3O?47|N5);Bm)|ekF1gds;;uVyR~>Fo z{$1azv_S1>14>QRStj`2gXT0b@WM7|oc#DrZ@|r;_$Y4s%qMZn%^%0DpZ+9nz4;Tk zkW-1&vi;)`GS9KL+#7x0xYe-S_P(?6{jvsEeXQS;P+)Uc`_YKLWMPL$)GUivGQ zs-619bBd;o^zwh4HdMX&`?}Y@3h)1oU%_W@{S?0OmtV!-|MfTUfB(%lg}>6K;n&4~ z4gdGwek0L;@s%&8&BUMknRnvZ&wQ#jI8RBx7F+~(eVOL0cDvB>B#34z({*sYNTwKW z*}NIsc5c^Di2$LD07>YPFaq?Cm>LvOgn+53Nl>XXk?dO>+(fm~Op8>fw#HZC4ITi2 zDqk;u-VA!@PrVJd-}V`NTPevyMN(l@qyp`RebbMJ_64l-~7hcC4U=^UcDM+jHyf&GdQbySm19} z_If>>ub1yX(meGgji)bZ?EU#&cjC{#cqhJm*B9``yFQOEec_G-^I!SWozmSUd=a0y z`DR>p>18NdZHEp4wAx1eae&Z;otiZ z{_@Yij6YGEfA|$Yh_lz8iK+1xc5dB(4flT+>+k(e!u|LB2aE^4_aEZ##+D8D>BHPE z&Ny`qUi7?YqAj{^v9XtiMJ5@8`!Q`f$S=if$CC zhG72>rg+WvVcq~pq9_WqRQE!0Q!{j57i!zFcjngP@C8(W{%r^cPn<^!F~7r2ksUB;QD*8dE@=qE!!m%1=gK?7GCng z=V}c9n&z^*aJ%N?x4z{kaGo~e++Qu#p-`QI>P-P4e2@f5lM8|z)%!mG$v3@ObF1dh zJMX}sYb<~HiyGq^-*??{EAG_u`7S*J@6vPmOM3o&QFH7UrSm*{*By7@6CeE;o}dqn z#l z5P0DWUZAo6Nqp(fI~C{KwXXSGewJzN;<5Av#r_L-+@fdQXK<(b;`3T3-L7@hZMS>| zKmNv>u;zpl><0Ph-~3{#GDVJ@BnLb>qzA&oj35b;gIb+*;)(dVpM95}0iVQeng?#X z`IDkQj=YZg1iYrYP3x)KwVwH$=8ZcvXM9c{EZuSIt$JqszUJji)W;rgNPfwoZ`6+{ zMr#I5Q6hYn$-Wf|6xtY^6i!y&$A=bPv1}E7boDWK&e%AvnCaqi+qYxQ<_B@?h6ix` zrU!A>&aJp~W*45R52b!&^|5%#l9jluXyZ7!om2sBRiThClBo=dCDpahlUYuVrm{$< z``SoMbJ?#59B8I6p97KuG08#aT3BiTIW?-zBlVK4#ffD`B{w}AbzPmV+s&4ftg9P( zfe2J_BZ;b?NXIT@UW;TNb1cq!{B_tMdZ$#;i@lmZ>V<%0T4ZN&OiAT0F}je{_3%Ia z!cebesl}Yzk~Z!`WMUjs6Io`tWlopa#+Xt*rAw7sW}V@`vEuA zEL~Qo)6RXb{+yb0-;7~Wv0E}RuC|O}-0cxRnJ}g{bg)#LS!2o_wN3B|p1RC*gQ) z9sGMdc&?fayqIoR#WApFhtb`h}p=%aAnx^waUPq_gvd+Cee zZ%V%F9dE}k{`}A2z3+K9-uFxI#?Om>``h1wH{SGGyy{1P7|(n5GvRN=o_XdOShj2# zN{xrKdAo%a%;3pMrW? z&sUY>xT1E<=E>21shJ*Ba=vnl5Yl)JYHzz0(x&tCp8IV4+AseSzMxH@ul?np<1TH6 ze(Dn+#|MA={dnJde-ZC__s`5@HeDqKML>pFL#NTOS`>Wc7|IqLKHeT`a zmtpN=&%zSLfogxLIiuBTqth8zS*_HjQtRbJ=))4vhmPU+SR0;~j0xS-lZw6NWBs|x z{J3nKPHC=g6)lZfkK63&P+mPQ9Y2F)DvHdh1{Dg$?`VzBYp%WmH@@yQ+I;w3cvJ10 zfAw{3u-%1QZ~hei=np=G-~O%N#IOCz`|vC8eNT$zuf6Y=@S)%R06z8ck7`rs4*bnG zzJ|a3>#yTZZM=Q(gCD?;{O~Jq?m26*LLW|cIxTqJWfbbGkZxA3Iuv8q%SaVl#HDT< z7_egbG8}u%(K!03l~}&aV|Y??=meH1&Pyi8kz%gro#Q?w-dHjrAsE^&HUQS zPrn9HX|A7$!|5EU3)$~SNlkjZI`uPpsoFQC7)j)7xdhjsqO^2!w}uyVz6cYN7N@pmfy*7h&R*ld#3SCZ(2; zCKMT#^pFUe{3)(FWAcS4T_3*rjZ$VtWx3eYd5p!{FV@a=O3(rgEMYhvs2veKi6aUS zj6DR|Iu9w{kgXT*kgn2G6Q^yGt?m05=o3%n96eK>h>>p{T2|#7wLWmpF*Pbrrt7HW zPN{l1JrwZYax7w@2m5f$L{%hGBB4~&Bc<;bUX9ZbfgEcpW-DeZ-t(;>lrJsu8~BtRS=8 zG(b@Is-CYPi9&YJLpg1(NZ1Q4Jg86k;<3lzxGS$fOB*o}1e6C*pJ4PL2~v!-7tud;r|3TL z`1if!S`?~_`#A){&vY^XDy!?iALw~cdI@w|o?$zKBq)25KuHk8`xrW+#-EaOx=yxW zvM)f2Go&p-0ly3vMFIPjXwK>9Ql-ynOSXQYv@f9ufZG6~U_eziNsy8y-K=+BwV@T-@F(~NZOHkZo@A60uZw{KVHb^V-1%^e<3o}Wtv!g70aJ4mK-TW*Ky=+vm|iXzB{Ac>&1 zgMfXJlw9r7hZHTfq1Ec3t@yXw9kr>IV0#xIm4Rf+ZyC~&JLVt$@gJ~#=Ps0rN15aR zsX~C1x((1lW|>MyS1*=J^}@MKFSSJo(&n?W&D_Dcx>UoyUH3w9syv%+DRxGu)4`Zt z?Aq-@?PTijwsf6#3&vQdtqrF(oQ}zMTrbOQ*|ytlwA*dv!M|_L000mGNklN6GJYp=cv=bXJ3C!TOZ`gQK9Nyn}Y_e(3Z)K6`V-7&N@ClqWUpg?YW35pi)EBtBuFNE zlE_C?lH(8pVZX7zz6n7p2E~?8M%aJBfB^B%1|Z2)w#SIaUkC+AN`pa)Bk=I^z||%Q zKhFc9wnAJ0w01)OnMV>j(;AO4h&C+iLqTK_lsC)0yt7@Q{v<6EpmA;mazCItG{2x9 z=PV+$P*Pc?>IAe^skRgy*&VI)OjYD!;RgAAj_%PHw#M;1;Yqr8FOlpl=~l~bLTJlz zA$NsnIZanzNP-kVvmiNwBup3AIT5PTNF}qdf34!!XPe{@MIcmu9dMErJ8x>6*$T_Z zVLozxy2@w!`RGdKlpOjnU(aK{!Tb>z#7XfZiTa}6IkXLi7~0_K)j03TPsV0_`mjYW zl|4_snv88j(GtM`s7V8`A8&l1f3VKiNoy`M&fBavV zp6;eHtgFL$3^I>pk_bh>%*<}AS#vyAtXQ7rQ0IXTa#)twLw1rx(0xVb@;o<_9K_MO zN@kkOIbmEXbS5Yp2f(a@Ral%| zwl#{oyKCVN!QCaegaE;U6D&w@cZb5=-90#jAccEy2~xOA@W1kP_ujqFxvJZG-nG`0 zG3OY=y;9Y7OX6JwQv{9nJ?1u%?gc{n%whBNY*Q1X)T}h3;tc$Vhh%|cr!fudO3T%XXIgSG^}|;l0V-T>$M-- zBSAYG)~8q?;$B1*=b$KWBn}7pFH|51$56KCKUikAZiYj z_>i3Lsmk${Odf1c7`i_kAmzrKY_FU?9sR})adN1+fm_F67#n8t{c{dS!G`$0<#1^R zaXfSyIC&0I+RtVmmZ~#VA>EISf@rN@7c-meiBJ(PPMB>(-0{HlKOE(lt~5SKUm#m8;fSL;sRix(OX0K682_$OVz@L}f!Jm0x zI)G2B!I_BlovYGnxNy<$-f8{`x&c@)MZdl;<<~}Ib+Tsvs)%YG{`rYB3ozr>IQIrZ0DLoM!Q3RKSjg>HLpu-(hXSUMd4_N`gu8=5O8MYyAalJt)N_v~A|9 zY`Um{OQbjOH#X_mGq8_ls6tAjcIN4i;YTdA3KW*Nu(T#nXV5duRZz)wWPO{t?@9ZQ zKBgsEFY9nQAAKYm?HHbGm9sGKh*L5u(FiGk(4@5V4asneenT5z7BCm7XR-XuN4hiA zHWO|!<~q7{J!igs>5~0XF{e7zkY*h9*%rs^s*L8@NmV9F7umlPEi%md2OU6!jT zxl;Kaa&zP3<}N{7RP+Go9LUnUZAg42W>ZZO>k@+GQNGcHj|C#gjKs-TH1OxBP|lTo zF6+3h0b-pp5ZX&I}8&Ld~c86lnLp7Ug`G?Muhc=9rP`fXcq zAa#x>(;vV7eB(vb=h(Ox{mp&(U9SSc-9VeK<#)B1ah+ceM`{?WTi+9ZhrZp3ze2w~ z_rA%xu_Yeim^n-10B}#=-`V7NX>qWvAFd1B&TGxp4H1z1Dn2hM=)NYiODK8;Y51w_ zCEhS96Rq41*SOYKF>YW<>r+t-amvdk!hxdJ>yoo`HZ6$ta*Mi+Yrzxme&x|oh^rRd zNyx_%5=y*8l;`2$y3R16IE0nOQR(rvDk$Ze>cOuDcaSLg>^E50;x(Jr>U;6U*@D6Q zx3bF!{S`oI_YSOJs*EUVm(28)Q1b}{q)~beU?LtRjsm@2T;867i0hvZv3?1XX2N%{ zbPrqeLh$G)=GVrzxTzEe@6259kpe7aHl%Ftlkuo(&%k=tS^szs@+ZqJE08 zD}NY&k+LKf%>0ccH1g?w%`T`X@{>Odh9WRaErGM7q!vZy&35#K@tcQctK_sGUS?w- zmpk)@;zX^!JfH#P{r_l!E?3|KUc0Lrym_d44Y0khz#{JG!2< zCZ zTa8IICq1?ra4ur!H!fh`BwTs0KTjq*l^?5K6^FCnNxqqSxdr=#t-Ib*OTo=qu9k_p zkmlb1ApBjL=Yf0Hes5G&@>MF~-PdV}$y?o9;f$SqA>hx`yl(Piemf}*>lYjs{1LmP zb|1P5CUp)br59*TNK-0*o2JYr$t3jj%TOPkne3VN&R6%apTpEIo_(sk8A7Xxs?!`J zKm~I#KMC1qoO!K3m14j@l8ZUj%;K5lC~DTd&ruzH=}K@JrWe#rU7xBoPCYwRvNUcw z7S7sCiho&H82cEpVZ3?0M=O{vtPq#Jdli1kV>}#j2@`Y5f-iW~3)Hn~B~P_#w?MFr zH5t3|;j%p!K|~IpM%NnmjrTBgu19sYLwl+z!?$nOxcn>9p)FMAwlvwLHPCGOs1S5) z2iYynOBk@yEpZX@?$Rq=t{q)5-b7o1b`<6!`O)|dS~^LF&bQF#Fdn_8;ZyGQLpR|{ zYn4M_zRDQf!klrbHMaE^*y*gjY5IahKCF_q;f^;U`*pisZ)Fpc(iks^F2adqqa)OY56f9^qqT})IjUiHg@VMN<>88$@X5OFb&Y|Iu}11&_AkOxdM(PN zx(=LRbZR{(G=v*|gYEI~On6k42e*aRv`=ax=}@25)dOeKw;8s2j} zPk+-4d66ZBiulY-;wuhWTz`QD;O2MGQ&A>AF~9kIZ4i@uaEWWz1y*ckLw2{d*R|i6 z*P|Z_7uZ*gsTrP5iwhY)I%vnuw%q_OV9Pd)k7U)kN`w)W_q{@cy8to|yll9K>5rVp z3zQL~EP8Oy^)9PxzvS>&voS#~cX6JWU|wd6oLci}MZ>TL{?&Yvhg>a%S$gA?j!$Ok zdHH9G21m+C-m60g)Q%qvGeo?fepbT4$_sQ&NQK_zq~k#+-%a>NnILU+l<0$R zyqrjJt%HeJ5qz>|Zb8zPa}V97ob>efnM;cSf~gY1bwJec<5z=oxW zosRA>xcG{@!cdoc?!`Pmc$7;Q%IEVoP^>vG7{F#g}m2X$0*QjlTObew%&s*emC-8caAqB z-mW<|hm3u9vc6xV8vj_dU*)R7B<#xA7tvW}ah1Pzd(8L+^<=3XmsO-Rai8*7aZtZ|J(>>XP@yzdMbr7Vf0j<`W9Qx1 z^!adr#%Ziq2KBwT10*wX>m>@RD0i@46?&CrYutqa6X%o$go-pfM2esfUx3|GP8=n43vC7;6VTfWX_<%lh2hPY2#D*j)00sZGWD`SwXnY^r0YN*!b$0 z`)Ls9`vWB@?2zPB8H%lp3T(r*d0)Tih$->z^UX8e3ZKHBwxSybi59YDiT8BUokbpk z%TvX(R~R5=#8RN%g}lcbWy(E|!94;~KFdjd*x|5#AaWoqV4n_rh$XROC3_ zOm?(^MKOp*)PScgp)_m;~f$+#sb zH%3vG-Z}rd!xYqaYzVGQTFhWu;JXU&tL^STLm4BYrC>VR^rq}XhN1~icCZo?U@ht-1qoI_j`?)w2}E{s*f zmWO+8QEr#FNK1cu%QQy9Y1#ZN!jz$6b-uspp`+$7RKn8#`tVo`JeMTMkuf)F>G;6h zIl$}72&taTQNIv(tnY3- zw48`OCbH&Z8^Uc!d*4#fK-eT*`%RR9`Da6YZSLZ#y&?Q65x%&wl3Mc8wJGJ09Se~0 z9dwd17Xw(0Yl>@?669G;L4pnH4>2B`rAtyaD>KraYce$`l2N|o%mwIF`X_Ho?B|xC`s@_1JkQP`CB;jlS9Gt=2Hzr~~ec<9Fzs zop?moyr*Av#CUJJo2RNjg9w4NLTMJzOq5>i2}NGV6mIHdm3+ctZhhUz`4sfWAk(#R z(gRAj6`Jeaa#2BXM+0!h0Jn2(_gSU6r7t}9eHDJ{g4P@&;vrM>RBiLOY=|r6yM0Cs zbqS0eH>%o^g1m<#JyM}3opB#A!ehn>P^EFzdjHVG>IK9T&!OuN9mfFS*(1vIk%{f0 zGac@qK16@Qx6|G?%!xg$!u$*!eDQ?F`w#M(JL)ct8{)HTl<%xwAd2W>uRFr`)`qi6 zjk$bx&)l#ym$?%Ph1%(kDwj_*Mt7Q(9`G@UO!-q5G2Hrr1@Jk&A@fCoP1E zunDay-%Fjgnz`%mqKt*X24UXwE}?V2RU7@~!=HT`W?L1>+_^J zRM1REx$=mJWiD6Hj5Li1js1YhNO&m81bcC?An^3mOWB#GY*J=7ZTp^83O7U?8;Q!t z15JP~7^e_wjz6P*WPp@-XnIX6nJbwLN!GW+VjMiMH;JI_AMEwSncPR^;yokI$}^(j zxmV|ippILFjZbNoKN8YAXd<2w{1^lo{1}&P>`G=@^Tr-CZGR{AdP!7-qs2iGDUg;j ze!2rleh9EG?s3kU5m){-LrCcaJZ9#P3*DMvp)Ev=aL)w>QX!30^aF`{kEBL-0#oWfg$ZKjm^zHb7MP2TKA;_sL~*xSY2Vk^ zboHIz(tJC~?4QVcV9k9iOxp_Xy_a9=DT=P38`H3s<~({3Yd2@=ao>FT6KecS_dM47 z%<@fbs?Yz+bkD5F?t`?>G%j-uEo<8w3Iu>~7s{$Lm-eg}HX^*s=xHzad%K|Yg)@Gh zP18ZZYW_Xa8p8jkuo8-e6$EY@*LsMe>GPM{ejFC3fQ(#Ao=dPaLSSSiZ@=P|cilGO znK23~FbHbIqM=E9~ppZ&HY(jfNF?n2WQ%WK;=d?hB ziw2CmfLh$a=6AQv7>v2W4KH@uo@{k<`7L?l=nqJ0wnz_ z3YNSRfLV??D{$sG-(*V9b&dB`6iee0Bz!^ zA|EB=t`-xo#}q~#nfl^cPjYkRrV&ZoHor3XUGs0olMA~S9W>9?@t1Mm{s!)I?L}vf z2WdX>D+JMeJ6(xPVM*HoK?p!qA8Ozf@njP<=P{mm3`$B#-(g$ROv{*XU|Y{)YQZU# zdS+*f`=(dA$>6`|UPv>KD#0RBIY6$s2-A7u0pndeUpSl9mF8Glm`dR9zw(P9 zLxweW)9kM?d>Bh-RLv;%6v?Bgf$6>;*MnIAxe^}x`3IRN1D7zO2!<)iU?1+Y^+qmBwLsRG)Nv zlb08%loa3J0=66p5ui|NBm^e$8{--EAR8Pl-A_~qX@T;G+pVOKPk712Tw_!8n^36; zAESPDiPD7z5xn*q_z1Cy#f1GN2LogPK}D%@fY)(K5Pmv98E6zjmdCPReAW7wkQtz4 zQ32RNav_>Weu%f4bzSP>|5RzM5ES1ti4XFPoy=va-b8aXQ}~h(PL8B|{9o?;x2!f_ zD4w@i{P2ulR`}nE#+dr};LOYEwVlwUiZ=6F-FS(PyLunUnkIRIN za&iwp%ROp-K^SN)vExN9$XsRRSFuf<^|8{|k)Y$Z*BfOKH+-7Q-gOjm->WKe8=m0b z49fEw?yUD4u>6@XSQV4cO;E{#EfMw{D+`s%L-W88nYzfj+GanHRO?SOIqg-tZrdL| zraUwn4;KLNNl*<|kOpNpVgKv03YNs6`58>v0R=I+t$a33A4*&HKkW%+nsLBl@sGO6!N5bJHmJ_KaCfA&99pIxvleDO%C`!PNqbM<9^=95_lKU~g-Z?#!q`Ztw6&Cd9m zZ>0BYE*wVQJ1T!J^Zp=<)SDI^3B(mzmk4>0!%(u<8C%u8-xXWPK)bNqidm`mIm9!1 z{!O^Ov=bNFiXzD^IX-eI^ilnPUi7~XNgA%wDo<;`zE*P%|EN)@`(yX1f{=|9kvtU{ z#GRnBRUG?bRF5iypnum|zx_t#6yELP4KEG-MoPU}l=L|F63xz_0cW*YZwWQj2TsNp zsMZbTacQ{cel&qnM$FvYdKn;NklK=dJJCMVwLFv+gx|PZ&@P5oqJ8ST=HjW*pp#rE z_=7`UeSAWPYQcS0E5V|XpPZ`QO-e>W@0j$7p+uMBZM4mEgyNbEkTlPChDnP|F_>1F zSLynVk&M=?)rUHl3+fv^ERYI$cs0R#Qjr@XI;2uXJNJV4{haN7tY!E;YlLCra`o4y zN8nh)$>^9mURyLF4txDY$jq+(~wi#k1G{u!kNX4Z%0ZZ2vNO)_Pk**&`-r4D~ z$?+zXdwT-jxqrKecbd9COR6}LsAp!8O90+#J@HlwvdqluT&Lt2Xp074y} zb&;z14mDj~s%^l8AUErq)r(c;%34!%_PJ?CVNYTUGF9cL2`R~`K0ypw}LW>NnST|RlNPtZ4^wTnGCC>DWA?{^1T4kni zT`{x2)vAhm#-sU*rYMqkC0@v_UxQ~OXy+r%tj2YH$6_5=xlW%v?O>90jbm}^x=}D0 z2R@)j*Ycrwd+A+_Ne09QyuOC9Vw|j{#iqcr9Bxk;wxmF+3uegf%Ke}Ob>VMNLF~`# z++yROjg`4m&5684zm~6-pUd3_PQSp7tT{IAC^?&>&A%+#*t<*N5srGhNx72Dz*cVW^ps5+~?wuoi5uGPufpz~T zf{)Vx{WJLOZu4@r_la5r{J`-;tLMDpPv5x@)-k`s51<7L)~>X76r z9_Xg*X1`W%hRoCCuwq5=6%s6_e+uH|UkivF&W?;dh3UKr3MdR%8!2+9YsNa~D5g_j zP%OchDRtq?3qdss`b64<-u3Wt*zRR}QtPzx=-@7cpINV)qmgxZ!g}bj?sI`bKF*B-v%Ph#s`160|i6=+D0n#gD>EeGMjmF^ zD61-u$}P^et(sl%3<%C;!&+c@`3)iEB6jeI20)wPYU$Ik4hLto{!U#z>x<>@!Tu$> z?e)oTu*G9mD>sa=cX!X@^w{yo>gJ{D^AB%7 z;Xvtn<26^ywQ)1_%j|Szm?{edrOECJRFsBrBPL4z9y&eD-%Icg8>;=HDRGzLHX4}{ zG?>oIhp7Q~qyK=FGLPr-Q8r+lzp(cK49~A;BG*{U2km*%@bSKoQbOb_I$!1D92?t@ zRW=QU-c|*i+W`(Vx1Iud+O4!|4NwB=MhJOhu%q<6jEh1qT%vNT&IxFZq3H$stLp1A z3^zE3&G8RxbimWlQW7EeaPD};sn%QNs%6a${nq_vS&lEsUx$i5;G7_NzjObNVj z*98VlhP-BkbC1-OQxoXe&F&7h%x zh6ZG1HiI}&$r#r14_{1&KK}>Dw*Zc{2Rev&hcDXsTh8X7_vU?-$2rFfir+D8Z*;uh ziPoRrX>TxZf8JhsAPScS6TQf+dX>*w?`7g`NO7;ow;xFgkZjnaR_f6z<1N_p0OL=2 z8O>6GL6VfI$q=D^$*yM$j={OSOKsMSY~|DPeZhC~|9e1x?;<4f1Yskg+S*2SvsK@f z*0l>2?`~_xORtQ;x~evw7liamnh&Acogx-8Ml~nMRmD2(>j{AMrurv!SQ>co4)EF3 zy@mzul68eKP6mP_s-IVAuZB$Z2cJIY`=|5eUoF42;t}{JGndB6TKS}-6@7z^4UKXa zX`1BXddyy}_(kiuNTQcncUGq?$)QrB(5*12d5Nbd*G31V_p=K%I43`+`(6!c2Hq5-KYzSjE9yae@cchd7{`2N!Jhv?>y+@&&Q zJ?i>aQQXp-9uk_ZM;n;?_wt>oc|Ny%^t{zU@?w&ow#;2ioafEcfE|9|Modud8`<`P zODTG8WDqR0Pyc(7MRJ^)62sKaJ+WNILr=O`1OYC zV?*VSnU7!RXFk$D%94pG*Vw!B?XZX%6ZBKt^B3NBx8 z@^+qrTA@(+7OvH9BjnuwD#>Z*i&1P*oRE@Rtka~FUj#e`OAP#c?DzkEhyp&e)AJ`= za#XBCius|DAhrF=05-o2NMGAAu1bYQ~!xzmd ztu%3BTYxctJf zADSo@Y+OCH39eCgi2!22cT{VJ-W10N_?UaVXAjEk zJdqcZ@iscLL7evVdQ`{8Mhc|j5z&=Bq*e%eBnd9=l5UmsM60a*xsQ&yH9E%L@9nn@ z{yKD6Ceaz5d8~8@CpEN>Sv9#t0YQ20Z%dv_pcqr$($SQ<)n-DR$ZZ}Ax3>#(E6W1J^9bTSh+@WcCi4lI3g z&Sofr7mb3&N_J2lSwaXV5Q*Bvqg;w4R!{rLFAg^4Sj2>+@b49;rGYW;`Bm_gIq%ZV zA6$+u41_S2^ZrEg|DF(k^=`{UvyttGO~u1igu`%*1MbDoUsF5|TqYcFGFBD#o1^Nq z26!tq=bm7}3{7udes>4DhJUEQM{NArn@oy$Bn+I_;5Ib0?vfPkik^6Qc z;bT^l>LPE>C)(>JstL?kxFuw;slV<(Gj(jmh#`kgUAH4l99w< zOL6&f-n?KNn2D+nf4RfI9^wABHud>omTsxTEm{m~EmpNNWuM#;K~B^vMzi8tS}V{K zxDvxM=OSvGG{cP_JUaA_$qW}pF@g9qH8U6@e=w=W4VD*Epf8+8FlK~ND740BjDmSZ zR9Qb`xAVI26M2FdG(cn*9k;Vx7L^FMijV|j_2<$Z|IfMnZ9(e6NW}|UEsU#8hvkc& ztkf9<9;Jk^+#Gjy?=3s7ES5JU_C;E0c?|a$cpTS@C@?~~Sgg5bHY@l@P*7 ziz2@joPDSY?jv{(?O&q#?hLQ$)sI?#HOg`s@N7R<_Ry^wDD~|#G+WO)A^`UoeMqJ_ zx~o)bn*#w5X|H1b(Z<}N;g_Z?u|`G1k`HD|4!?A)q~}SmObH=%(5^aNhcXvg1VYFv zLCP)WJlluqZ+aDJi(Z|Dy>UST z=}iz-X>MxX53;9E*4m|dRtZUP3;i4oH~jGUf0)TLJME+@B}J=Q#wd1S8gxv;;V{29 zsfrPQ$-DQ75xr}Gh+AxB@pE=7%O5JzQ%Z6SQa8&GDk74bFD|Q|WGB_;nTUdl`Ew%n zXaANJ*aU(3j|f=MHPaC7JW-D3+rZoswh3(Uo5r-?wEh=Q-?zG&8qCJ%Pu3b#rd$i> z4g+KZdM7Z*Z7>$ru#&^)*S55n_HxWK-@lx8A6OA7u_1anQP7Sc0JBo75|hj`^F*em zF`4&d-|ELbPjK&`C&C^RoR9ZoB^>!T9^%?|e);XCeSJJEtDIz$@B$*SPTRzq+S#!_ z$hrJit4R+Nt^=1jO6G@+WaN>k%*&G#A^T}0d$<$=3-&V1kCj^ksoKlzyyp`I9rqmL zhvJu6gR_{w;>mQd0k>krW{|w5emm@s>Ebg&eu6iV!b7wlh z%xh>WrdJ}2Gq;v2LSgup-*7yC@trVAUEIv%~Rm9fgt_ z2H;k8=r>Dm2@2pWeRBLPm34vL`JrxTdCH4^Xi5*!|4W;EG40K&Zc0i>M|vFZyz#xvnUsg17w#qR%tfo$zLbF z0F_-ZDzyEoxKS1g)*U2k>&;d_RQqpjGId&bN!#4Ul$mz%~NH4QR;5RXi658)}o&^&GmOFUC>nhFQd7>Uc!IRgNBImp9U1p zsiHm}I2tP&ji&MAn9WG(Eoo4g0k)y767*E}@m>ZYL{#pQE}?VB+MK~6z{Y7pv~&SjoMhyHNs#zUEiwPULqMx)=_iA zFW<8V_7W3GCcwGYNy_tD%8ZgA1Cr1cqY>YM-XY{??s`)yB4!aojfe&A|I?c)#6an- z50spN(=#QwXL`AYVhZRQWMpoRafIlKo0gOfOp_YPtBH{QF#`>eZsud zCI_yJwfh#jSO|f~IHcvAP1`N5$$cV4$eCmh~4qusR zQ7Rp^{Tku>FTb7~xjNmStuOiA*k(U<5t{Yv9UM|*&6E~29_EhT&y7TPFq69l zL)1U*8eQ}Q&1qPCKV#g??mGTO80w?@M&^rFGVXl}n53?y;CS<7P7hiP*hF44t1b@J ze8~JChy5eI)P2VjZnOUphK^}+UrV0Z!|ZlSR2c>ojyWR;f3q75##{@JR1M_s*>3q0UFSpmm*@AFZugh~&-k(( z3B?aL5WJgUQ~o!!{H=ihrxxm#lNhVBlg1#_G@8~^veX+iSlk+klemG=Usr1ErQ*2x zEa6e0iW3knlfZsNmwzmZx`%|*hIKoe&kqx_6F;26;YFSL=^N9TPF(B?Ts8(<{+=U> zQvMtVvQj=>55a|oQN=t?V97zc`R{$vQRii?6?~@3;t)@c*h-30 z^Z*GMIgI0&j)dkKBhMQGLOjJ|ACA=D3pOBB#e{b(Et<^8$!M@6!8aB#t_kxxfm%~h zBffRyr7)=mR~P-pA|Q2x`8ee&_{i4rX44f;NaLswr@e7Wf_;;b&i6Jdh6pz}zcU5{ z=CYTu_Zst_IOlX|ZE>(R6W7x>q%F^*;*pdBdOf5lPewwjwnibjJy;V7J-nsLjy13| zWL@Fd=t3&S*aw-DH-!(DHej0BHL>O~z8K(KCj!tRnDv##0YGvuV1*FKJS+5z2_VGW z>-JBx;jt?dkg1hVY`R1fg?54X?QlTYzA{m!?ic(!uyTz1MRl1de%|9B`LEXuVqs}7 zeb)`n4}ew&F9}lDd$X}r6$qkXu`+kEW2J=YcScg9-p8n2`U@8#E(KLs<0g$QQ$Yr- zkK2$zg9Z;5XORFuOJs}xAgXo~^p zlV!-UQ3MYAdHF8-!pW@5s#6pq&5t!3Thn@7?RZ<={}JecEU<1wGW=d6?8Qn-Gpd~E zQ@nvv=U50esx2t0j2`Jf9;@MZ>vsI zp#w>!|0a+aPvJI;r9N1ZN})pym6 zb}SKfd_J_GsWyt$GPafhYF$B7HUQ$ zJ<1X;$eQB}TN=2)(eGtSWrj>Nf>^>sbILzvX>1Xs`M8{JZ`IStWq%UeHc=oegF>j( zZJiQj=wPK?5Qg)el3egjl<``gyO6|U+#z_?+Pr-T$~--RE-DIXEP3497AhbrB_$)w zV_+`@#hK}=j$9$H5eN$96~Pp`*zt`&@pP6qpylwL0y1Oo z`)I{FaUpqaT;L|F(Y!4bxgbKpOUJ#CM3w`dCj0+{d3u=WIEnfaV;oR$Q#sA;tTz-# z<}RnWU^T8_u^|`%5#nNFBWZa5`>XmT09SE;-rs5jrV*-TyDa`FkS0K$JhaK^&*x9i zKL|fxU+sNY%L+C497$ZWQlTfXOJF3j>#fpSQnnXY8nV*5 zfd;qE``f^TW3V&Y$uhbazo60hMw7QrWPZz!3iKMiP$~3>S$4 zO5@1+@o+rZKW6;+x$9i?e8|e-RiNkY-*P&a_x|@P5Y~HdT<`Ny8bn8DJ+jW{67|n$ z+W8ON-YYtvmoLWso6on#+m5{t=swqVJzRSz9P3h=lm_S=Rn}fc>P-R8J2#;$}&sI`>dd`RMUrhU&_Vq6U2t&bhCOR4s3(w zL*3SugBX?k3(K(HiFsHhXj!P{i?k7TT!kR&AEc~uIE(BhA#y6o3QwFkO?{!jF}IZn zY(ZyzewroJri8q1^HoRQjGc2np*!_)#X-ym1!rEGQH&R{(M;cNISbBYk?OKz6IN|x zUIOnQQV(Iyvk&1GSSzJ2!;8J1l`6kjqioi!|DX?9sz2bz>mk}~N@#zcUyu~KFPPD~ z)VP;#;|;sz?($!D&c13c+ip(l!aJQ)g>62hkcK`mLRHnVjC?Gx?|+q}fPf5c(NW(# z@lRd()MkJGD;)ozm5AFo-u>Z&BpIJf5LH;yEKvaVfHI|;5XF|Iq8B2s{?vfRkmDq> znCphXF62lKd0Q}_zAlG;e+EW>1%(ottS^80x^GkVdE#>T^Ft#Y(J_QYH))Km9Y#O* zZOkUXQWctUNeOAzKw>r$OM-xk#fT;c03HE2O#YuriZYPihNfN}?uS&=fZ`e9#~r82 zIocBT>%j%?0sHD%W$;AB4a)$I4BL1o)lDmuva;zQ@2{<^U)=~f!!?7V-8iJTv-Qyu z@vp=1k6pdLU=`VJuIsPcicgH6s1+(szD8g=UXlH#!N~L;E_VJ<#+DVI$JVs&Q@)x} z%b9mdt0Bi7%dZ)%h3@*4Qk-N?QWQzt?i5m$?zMrlvR8$t^ukS=a1Ak{yfl1-|K%U- z;*4S->+fwzGRKe`f@=H+hU_iID!*l4#>59^gEJX*N#2|j**ZxS_W@!(W?nmBxAcP> z@*8XuY;N0YQv~TI$Nm`9VR`VFh2Th>t%iwl|q0EC?^e zosMXkZ|(N0gM%Jr=AV}tlGg239+>t1*Xn9<> zd`yJ{&{m5vTBngluC0Fw(e^=F5kR53DhR@sL}*A+E>?9;PP4{lxOKMR0rM)0XFHL{ zRAQ9IMs23eKQQn5Xykm5;;3Qrn@-0WzwgC9crCMzKhG}m)2YVW`3M_i5n!Q{XFXEp zh%4o%o&B4XtA=Y+N3da`-?cLs(VORcuU5XxwovvBjA%?UXoxu z|GGk{ReK)zaJd+qbSU*D5CtDX(JdLXL8Zp4w9D9MQL%_@vriDGN+X;bGC`&+wkUm{ zP|C)8x~A?Yj?4Dt{}0G5A-!WMACx=7HYe;hn{mVhiM4=>M|TDvO=fDliurDnd0SyD zf6Ci`yZFf~a81WCI4FJrn=WXI-owKatU~3L!#9lsb>r0y*K4xmK0g%oQ|S7)(a!-t zTTDy!a3N7F3Ys66<)4Jbh63boS~XY98x0M0mrt1Jkb$5O^Fl@X*F-nH?WGcL@7{FI8+3bA&Vu@Eo4via(u3q_-JSEu+bV^`v#{qN3;{DwpqQUve8-3Du z57W$UUC0E4H|g{L(ydTY5EpvaV4V?)+lRrt) z#pb`O>3@!>7#k`2@+@@o^T`q4tqAIj+f$g)Cpe5Se2{D>brHb<*K#K%h`ElBYLpu! zZCzmP7DBKzTlTuq{IL;F>z8pns`0(Pvf)?avpLHx*maweR5pDxq~w}4;8hWNe7-%q zzc5PxRmQVd6W!Z-U%Gjv5-{GV@FOe;;mMg8JD zYs&&0sLs{9^*&_1XD;wUyM?#hTBt)DOf^l+ZWBYgsCs z_rw|4aVx`~xJ#4AZ=_DCT>SnsIlaSyc6RNd3Ks#r1D^~IN~kzX=w9RMDbTlrMd&`e zB2c4b3TshZf1a~hQHWtLMNgbq{!cZm0!LARZJoIwv!yOarH#r%s983lONGe7+b!Z< zkjm@!6nbDM_|}qZT!!i-=Ve_m)|BJ=CX{u=84Xt3+ z0XivZi@0oO4bt&|MZn8Tt&c=&MJh?L7C+e$>UrpYY1AjB^O-AP%%&c|Bx{yk9iZ&N zET<`MIj0misWSA75IP?Ui?!1M-vn_kdx zltG}KcaS`-zCNH#y#>kA6~i<#j)iYn8?XK*>EI1J)L?YFC~cZ67_ty3O_6!>G%0AP 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 J$s?0j{|~+io@@XB From b8a983a3cd9776d7a841577b1405367308130ada Mon Sep 17 00:00:00 2001 From: hex2077 Date: Sat, 4 Apr 2026 22:49:52 +0800 Subject: [PATCH 02/10] =?UTF-8?q?Revert=20"feat:=20=E6=94=AF=E6=8C=81?= =?UTF-8?q?=E5=8A=A8=E6=80=81=E6=8F=90=E4=BE=9B=E5=95=86=E9=85=8D=E7=BD=AE?= =?UTF-8?q?=E7=BB=84=E5=92=8C=E5=89=8D=E7=BC=80=E5=8C=B9=E9=85=8D=E6=9C=BA?= =?UTF-8?q?=E5=88=B6"?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This reverts commit 0c9d52f5379928b650e522a942eb7a95ce0497b3. --- package.json | 2 +- pnpm-lock.yaml | 22 +- src/core/config-manager.js | 15 - src/handlers/request-handler.js | 8 +- src/providers/adapter.js | 33 +- src/providers/claude/claude-core.js | 4 +- src/providers/claude/claude-kiro.js | 14 +- src/providers/forward/forward-core.js | 4 +- src/providers/gemini/antigravity-core.js | 28 +- src/providers/gemini/gemini-core.js | 19 +- src/providers/grok/grok-core.js | 26 +- src/providers/openai/codex-core.js | 12 +- src/providers/openai/openai-core.js | 4 +- src/providers/openai/openai-responses-core.js | 4 +- src/providers/openai/qwen-core.js | 14 +- src/providers/provider-models.js | 13 +- src/providers/provider-pool-manager.js | 32 +- src/services/service-manager.js | 16 +- src/services/ui-manager.js | 4 +- src/ui-modules/provider-api.js | 154 ++------- src/utils/common.js | 2 +- src/utils/proxy-utils.js | 20 +- static/app/app.js | 4 +- static/app/event-handlers.js | 12 - static/app/i18n.js | 13 - static/app/modal.js | 37 ++- static/app/models-manager.js | 38 +-- static/app/provider-manager.js | 307 ++---------------- static/app/routing-examples.js | 42 +-- static/app/utils.js | 94 ++---- static/components/section-providers.css | 22 -- static/components/section-providers.html | 3 - 32 files changed, 221 insertions(+), 801 deletions(-) diff --git a/package.json b/package.json index 5b1b23b..a967544 100644 --- a/package.json +++ b/package.json @@ -3,7 +3,7 @@ "dependencies": { "@anthropic-ai/tokenizer": "^0.0.4", "adm-zip": "^0.5.16", - "axios": "^1.14.0", + "axios": "^1.10.0", "deepmerge": "^4.3.1", "dotenv": "^16.4.5", "google-auth-library": "^10.1.0", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 3da5f07..8570703 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -15,8 +15,8 @@ importers: specifier: ^0.5.16 version: 0.5.16 axios: - specifier: ^1.14.0 - version: 1.14.0 + specifier: ^1.10.0 + version: 1.13.4 deepmerge: specifier: ^4.3.1 version: 4.3.1 @@ -883,8 +883,8 @@ packages: asynckit@0.4.0: resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==} - axios@1.14.0: - resolution: {integrity: sha512-3Y8yrqLSwjuzpXuZ0oIYZ/XGgLwUIBU3uLvbcpb0pidD9ctpShJd43KSlEEkVQg6DS0G9NKyzOvBfUtDKEyHvQ==} + axios@1.13.4: + resolution: {integrity: sha512-1wVkUaAO6WyaYtCkcYCOx12ZgpGf9Zif+qXa4n+oYzK558YryKqiL6UWwd5DqiH3VRW0GYhTZQ/vlgJrCoNQlg==} babel-jest@29.7.0: resolution: {integrity: sha512-BrvGY3xZSwEcCzKvKsCi2GgHqDqsYkOP4/by5xCgIwGXQxIEh+8ew3gmrE1y7XRR6LHZIj6yLYnUi/mm2KXKBg==} @@ -1308,12 +1308,11 @@ packages: glob@10.5.0: resolution: {integrity: sha512-DfXN8DfhJ7NH3Oe7cFmu3NCu1wKbkReJ8TorzSAFbSKrlNaQSKfIzqYqVY8zlbs2NLBbWpRiU52GX2PbaBVNkg==} - deprecated: Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me hasBin: true glob@7.2.3: resolution: {integrity: sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==} - deprecated: Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me + deprecated: Glob versions prior to v9 are no longer supported google-auth-library@10.5.0: resolution: {integrity: sha512-7ABviyMOlX5hIVD60YOfHw4/CxOfBhyduaYB+wbFWCWoni4N7SLcV46hrVRktuBbZjFC9ONyqamZITN7q3n32w==} @@ -1835,9 +1834,8 @@ packages: resolution: {integrity: sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==} engines: {node: '>= 6'} - proxy-from-env@2.1.0: - resolution: {integrity: sha512-cJ+oHTW1VAEa8cJslgmUZrc+sjRKgAKl3Zyse6+PV38hZe/V6Z14TbCuXcan9F9ghlz4QrFr2c92TNF82UkYHA==} - engines: {node: '>=10'} + proxy-from-env@1.1.0: + resolution: {integrity: sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==} pure-rand@6.1.0: resolution: {integrity: sha512-bVWawvoZoBYpp6yIoQtQXHZjmz35RSVHnUOTefl8Vcjr8snTPY1wnpSPMWekcFwbxI6gtmT7rSYPFvz71ldiOA==} @@ -3271,11 +3269,11 @@ snapshots: asynckit@0.4.0: {} - axios@1.14.0: + axios@1.13.4: dependencies: follow-redirects: 1.15.11 form-data: 4.0.5 - proxy-from-env: 2.1.0 + proxy-from-env: 1.1.0 transitivePeerDependencies: - debug @@ -4443,7 +4441,7 @@ snapshots: kleur: 3.0.3 sisteransi: 1.0.5 - proxy-from-env@2.1.0: {} + proxy-from-env@1.1.0: {} pure-rand@6.1.0: {} diff --git a/src/core/config-manager.js b/src/core/config-manager.js index 0af5b88..364dd99 100644 --- a/src/core/config-manager.js +++ b/src/core/config-manager.js @@ -76,11 +76,6 @@ export async function initializeConfig(args = process.argv.slice(2), configFileP LOGIN_MIN_INTERVAL: 5000, // 两次尝试之间的最小间隔(毫秒),默认1秒 PROVIDER_POOLS_FILE_PATH: null, // 新增号池配置文件路径 MAX_ERROR_COUNT: 10, // 提供商最大错误次数 - SCHEDULED_HEALTH_CHECK: { - enabled: false, - interval: 600000, - startupRun: false - }, providerFallbackChain: {}, // 跨类型 Fallback 链配置 LOG_ENABLED: true, LOG_OUTPUT_MODE: "all", @@ -131,8 +126,6 @@ export async function initializeConfig(args = process.argv.slice(2), configFileP { flag: '--login-max-attempts', configKey: 'LOGIN_MAX_ATTEMPTS', type: 'int' }, { flag: '--login-lockout-duration', configKey: 'LOGIN_LOCKOUT_DURATION', type: 'int' }, { flag: '--login-min-interval', configKey: 'LOGIN_MIN_INTERVAL', type: 'int' }, - { flag: '--scheduled-health-check-enabled', configKey: 'SCHEDULE_HEALTH_CHECK_ENABLED', type: 'bool' }, - { flag: '--scheduled-health-check-interval', configKey: 'SCHEDULE_HEALTH_CHECK_INTERVAL', type: 'int' }, ]; // Parse command-line arguments using definitions @@ -167,14 +160,6 @@ export async function initializeConfig(args = process.argv.slice(2), configFileP } } - // 合并定时健康检查的 CLI 配置 - if (currentConfig.SCHEDULE_HEALTH_CHECK_ENABLED !== undefined) { - currentConfig.SCHEDULED_HEALTH_CHECK.enabled = currentConfig.SCHEDULE_HEALTH_CHECK_ENABLED; - } - if (currentConfig.SCHEDULE_HEALTH_CHECK_INTERVAL !== undefined) { - currentConfig.SCHEDULED_HEALTH_CHECK.interval = currentConfig.SCHEDULE_HEALTH_CHECK_INTERVAL; - } - normalizeConfiguredProviders(currentConfig); if (!currentConfig.SYSTEM_PROMPT_FILE_PATH) { diff --git a/src/handlers/request-handler.js b/src/handlers/request-handler.js index 57e830b..ebc84da 100644 --- a/src/handlers/request-handler.js +++ b/src/handlers/request-handler.js @@ -6,7 +6,7 @@ import { handleAPIRequests } from '../services/api-manager.js'; import { getApiService, getProviderStatus } from '../services/service-manager.js'; import { getProviderPoolManager } from '../services/service-manager.js'; import { MODEL_PROVIDER } from '../utils/common.js'; -import { getRegisteredProviders, isRegisteredProvider } from '../providers/adapter.js'; +import { getRegisteredProviders } from '../providers/adapter.js'; import { countTokensAnthropic } from '../utils/token-utils.js'; import { PROMPT_LOG_FILENAME } from '../core/config-manager.js'; import { getPluginManager } from '../core/plugin-manager.js'; @@ -152,7 +152,8 @@ export function createRequestHandler(config, providerPoolManager) { // Allow overriding MODEL_PROVIDER via request header const modelProviderHeader = req.headers['model-provider']; if (modelProviderHeader) { - if (isRegisteredProvider(modelProviderHeader)) { + const registeredProviders = getRegisteredProviders(); + if (registeredProviders.includes(modelProviderHeader)) { currentConfig.MODEL_PROVIDER = modelProviderHeader; logger.info(`[Config] MODEL_PROVIDER overridden by header to: ${currentConfig.MODEL_PROVIDER}`); } else { @@ -168,7 +169,8 @@ export function createRequestHandler(config, providerPoolManager) { if (pathSegments.length > 0) { const firstSegment = pathSegments[0]; - const isValidProvider = isRegisteredProvider(firstSegment); + const registeredProviders = getRegisteredProviders(); + const isValidProvider = registeredProviders.includes(firstSegment); const isAutoMode = firstSegment === MODEL_PROVIDER.AUTO; if (firstSegment && (isValidProvider || isAutoMode)) { diff --git a/src/providers/adapter.js b/src/providers/adapter.js index 7f9436c..bfaceac 100644 --- a/src/providers/adapter.js +++ b/src/providers/adapter.js @@ -704,26 +704,6 @@ registerAdapter(MODEL_PROVIDER.GROK_CUSTOM, GrokApiServiceAdapter); // 用于存储服务适配器单例的映射 export const serviceInstances = {}; -/** - * 检查提供商是否已注册(支持前缀匹配) - * @param {string} provider - 提供商名称 - * @returns {boolean} - 是否有效 - */ -export function isRegisteredProvider(provider) { - if (adapterRegistry.has(provider)) { - return true; - } - - // 检查前缀 (例如 openai-custom-1 -> openai-custom) - for (const key of adapterRegistry.keys()) { - if (provider.startsWith(key + '-')) { - return true; - } - } - - return false; -} - // 服务适配器工厂 export function getServiceAdapter(config) { const customNameDisplay = config.customName ? ` (${config.customName})` : ''; @@ -732,18 +712,7 @@ export function getServiceAdapter(config) { const providerKey = config.uuid ? provider + config.uuid : provider; if (!serviceInstances[providerKey]) { - let AdapterClass = adapterRegistry.get(provider); - - // 如果没找到精确匹配,尝试通过前缀查找 (例如 openai-custom-1 -> openai-custom) - if (!AdapterClass) { - for (const [key, value] of adapterRegistry.entries()) { - if (provider === key || provider.startsWith(key + '-')) { - AdapterClass = value; - break; - } - } - } - + const AdapterClass = adapterRegistry.get(provider); if (AdapterClass) { serviceInstances[providerKey] = new AdapterClass(config); } else { diff --git a/src/providers/claude/claude-core.js b/src/providers/claude/claude-core.js index 89f5e22..e95e3b5 100644 --- a/src/providers/claude/claude-core.js +++ b/src/providers/claude/claude-core.js @@ -63,13 +63,13 @@ export class ClaudeApiService { } // 配置自定义代理 - configureAxiosProxy(axiosConfig, this.config, this.config.MODEL_PROVIDER || MODEL_PROVIDER.CLAUDE_CUSTOM); + configureAxiosProxy(axiosConfig, this.config, MODEL_PROVIDER.CLAUDE_CUSTOM); return axios.create(axiosConfig); } _applySidecar(axiosConfig) { - return configureTLSSidecar(axiosConfig, this.config, this.config.MODEL_PROVIDER || MODEL_PROVIDER.CLAUDE_CUSTOM, this.baseUrl); + return configureTLSSidecar(axiosConfig, this.config, MODEL_PROVIDER.CLAUDE_CUSTOM, this.baseUrl); } /** diff --git a/src/providers/claude/claude-kiro.js b/src/providers/claude/claude-kiro.js index cd7fa0d..7c185e3 100644 --- a/src/providers/claude/claude-kiro.js +++ b/src/providers/claude/claude-kiro.js @@ -494,7 +494,7 @@ export class KiroApiService { } // 配置自定义代理 - configureAxiosProxy(axiosConfig, this.config, this.config.MODEL_PROVIDER || MODEL_PROVIDER.KIRO_API); + configureAxiosProxy(axiosConfig, this.config, 'claude-kiro-oauth'); this.axiosInstance = axios.create(axiosConfig); @@ -505,7 +505,7 @@ export class KiroApiService { } _applySidecar(axiosConfig) { - return configureTLSSidecar(axiosConfig, this.config, this.config.MODEL_PROVIDER || MODEL_PROVIDER.KIRO_API); + return configureTLSSidecar(axiosConfig, this.config, MODEL_PROVIDER.KIRO_API); } /** @@ -744,7 +744,7 @@ async saveCredentialsToFile(filePath, newData) { // 刷新成功,重置 PoolManager 中的刷新状态并标记为健康 const poolManager = getProviderPoolManager(); if (poolManager && this.uuid) { - poolManager.resetProviderRefreshStatus(this.config.MODEL_PROVIDER || MODEL_PROVIDER.KIRO_API, this.uuid); + poolManager.resetProviderRefreshStatus(MODEL_PROVIDER.KIRO_API, this.uuid); } } else { throw new Error('Invalid refresh response: Missing accessToken'); @@ -1627,7 +1627,7 @@ async saveCredentialsToFile(filePath, newData) { _refreshUuid() { const poolManager = getProviderPoolManager(); if (poolManager && this.uuid) { - const newUuid = poolManager.refreshProviderUuid(this.config.MODEL_PROVIDER || MODEL_PROVIDER.KIRO_API, { + const newUuid = poolManager.refreshProviderUuid(MODEL_PROVIDER.KIRO_API, { uuid: this.uuid }); return newUuid; @@ -1649,7 +1649,7 @@ async saveCredentialsToFile(filePath, newData) { if (poolManager && this.uuid) { logger.info(`[Kiro] Marking credential ${this.uuid} as needs refresh. Reason: ${reason}`); // 使用新的 markProviderNeedRefresh 方法代替 markProviderUnhealthyImmediately - poolManager.markProviderNeedRefresh(this.config.MODEL_PROVIDER || MODEL_PROVIDER.KIRO_API, { + poolManager.markProviderNeedRefresh(MODEL_PROVIDER.KIRO_API, { uuid: this.uuid }); // Attach marker to error object to prevent duplicate marking in upper layers @@ -1674,7 +1674,7 @@ async saveCredentialsToFile(filePath, newData) { const poolManager = getProviderPoolManager(); if (poolManager && this.uuid) { logger.info(`[Kiro] Marking credential ${this.uuid} as unhealthy. Reason: ${reason}`); - poolManager.markProviderUnhealthyImmediately(this.config.MODEL_PROVIDER || MODEL_PROVIDER.KIRO_API, { + poolManager.markProviderUnhealthyImmediately(MODEL_PROVIDER.KIRO_API, { uuid: this.uuid }, reason); // Attach marker to error object to prevent duplicate marking in upper layers @@ -1701,7 +1701,7 @@ async saveCredentialsToFile(filePath, newData) { const poolManager = getProviderPoolManager(); if (poolManager && this.uuid) { logger.info(`[Kiro] Marking credential ${this.uuid} as unhealthy with recovery time. Reason: ${reason}, Recovery: ${recoveryTime?.toISOString()}`); - poolManager.markProviderUnhealthyWithRecoveryTime(this.config.MODEL_PROVIDER || MODEL_PROVIDER.KIRO_API, { + poolManager.markProviderUnhealthyWithRecoveryTime(MODEL_PROVIDER.KIRO_API, { uuid: this.uuid }, reason, recoveryTime); // Attach marker to error object to prevent duplicate marking in upper layers diff --git a/src/providers/forward/forward-core.js b/src/providers/forward/forward-core.js index 260dcd2..8730ac3 100644 --- a/src/providers/forward/forward-core.js +++ b/src/providers/forward/forward-core.js @@ -56,13 +56,13 @@ export class ForwardApiService { axiosConfig.proxy = false; } - configureAxiosProxy(axiosConfig, config, config.MODEL_PROVIDER || MODEL_PROVIDER.FORWARD_API); + configureAxiosProxy(axiosConfig, config, MODEL_PROVIDER.FORWARD_API); this.axiosInstance = axios.create(axiosConfig); } _applySidecar(axiosConfig) { - return configureTLSSidecar(axiosConfig, this.config, this.config.MODEL_PROVIDER || MODEL_PROVIDER.FORWARD_API, this.baseUrl); + return configureTLSSidecar(axiosConfig, this.config, MODEL_PROVIDER.FORWARD_API, this.baseUrl); } async callApi(endpoint, body, isRetry = false, retryCount = 0) { diff --git a/src/providers/gemini/antigravity-core.js b/src/providers/gemini/antigravity-core.js index c66fd2e..3b34ba0 100644 --- a/src/providers/gemini/antigravity-core.js +++ b/src/providers/gemini/antigravity-core.js @@ -697,7 +697,7 @@ export class AntigravityApiService { }); // 检查是否需要使用代理 - const proxyConfig = getGoogleAuthProxyConfig(config, config.MODEL_PROVIDER || MODEL_PROVIDER.ANTIGRAVITY); + const proxyConfig = getGoogleAuthProxyConfig(config, 'gemini-antigravity'); // 配置 OAuth2Client 使用自定义的 HTTP agent const oauth2Options = { @@ -729,11 +729,11 @@ export class AntigravityApiService { this.baseURLs = this.getBaseURLFallbackOrder(config); // 保存代理配置供后续使用 - this.proxyConfig = getProxyConfigForProvider(config, config.MODEL_PROVIDER || MODEL_PROVIDER.ANTIGRAVITY); + this.proxyConfig = getProxyConfigForProvider(config, 'gemini-antigravity'); } _applySidecar(requestOptions) { - return configureTLSSidecar(requestOptions, this.config, this.config.MODEL_PROVIDER || MODEL_PROVIDER.ANTIGRAVITY); + return configureTLSSidecar(requestOptions, this.config, MODEL_PROVIDER.ANTIGRAVITY); } /** @@ -821,7 +821,7 @@ export class AntigravityApiService { // 刷新成功,重置 PoolManager 中的刷新状态并标记为健康 const poolManager = getProviderPoolManager(); if (poolManager && this.uuid) { - poolManager.resetProviderRefreshStatus(this.config.MODEL_PROVIDER || MODEL_PROVIDER.ANTIGRAVITY, this.uuid); + poolManager.resetProviderRefreshStatus(MODEL_PROVIDER.ANTIGRAVITY, this.uuid); } } else { logger.info(`[Antigravity Auth] No access token or refresh token. Starting new authentication flow...`); @@ -832,7 +832,7 @@ export class AntigravityApiService { // 认证成功,重置状态 const poolManager = getProviderPoolManager(); if (poolManager && this.uuid) { - poolManager.resetProviderRefreshStatus(this.config.MODEL_PROVIDER || MODEL_PROVIDER.ANTIGRAVITY, this.uuid); + poolManager.resetProviderRefreshStatus(MODEL_PROVIDER.ANTIGRAVITY, this.uuid); } } } catch (error) { @@ -1109,7 +1109,7 @@ export class AntigravityApiService { const poolManager = getProviderPoolManager(); if (poolManager && this.uuid) { logger.info(`[Antigravity] Marking credential ${this.uuid} as needs refresh. Reason: 401/400 Unauthorized`); - poolManager.markProviderNeedRefresh(this.config.MODEL_PROVIDER || MODEL_PROVIDER.ANTIGRAVITY, { + poolManager.markProviderNeedRefresh(MODEL_PROVIDER.ANTIGRAVITY, { uuid: this.uuid }); error.credentialMarkedUnhealthy = true; @@ -1212,7 +1212,7 @@ export class AntigravityApiService { const poolManager = getProviderPoolManager(); if (poolManager && this.uuid) { logger.info(`[Antigravity] Marking credential ${this.uuid} as needs refresh. Reason: 401/400 Unauthorized in stream`); - poolManager.markProviderNeedRefresh(this.config.MODEL_PROVIDER || MODEL_PROVIDER.ANTIGRAVITY, { + poolManager.markProviderNeedRefresh(MODEL_PROVIDER.ANTIGRAVITY, { uuid: this.uuid }); error.credentialMarkedUnhealthy = true; @@ -1315,7 +1315,7 @@ export class AntigravityApiService { const poolManager = getProviderPoolManager(); if (poolManager && this.uuid) { logger.info(`[Antigravity] Token is near expiry, marking credential ${this.uuid} for refresh`); - poolManager.markProviderNeedRefresh(this.config.MODEL_PROVIDER || MODEL_PROVIDER.ANTIGRAVITY, { + poolManager.markProviderNeedRefresh(MODEL_PROVIDER.ANTIGRAVITY, { uuid: this.uuid }); } @@ -1393,7 +1393,7 @@ export class AntigravityApiService { const poolManager = getProviderPoolManager(); if (poolManager && this.uuid) { logger.info(`[Antigravity] Token is near expiry, marking credential ${this.uuid} for refresh`); - poolManager.markProviderNeedRefresh(this.config.MODEL_PROVIDER || MODEL_PROVIDER.ANTIGRAVITY, { + poolManager.markProviderNeedRefresh(MODEL_PROVIDER.ANTIGRAVITY, { uuid: this.uuid }); } @@ -1442,6 +1442,13 @@ export class AntigravityApiService { async getUsageLimits() { if (!this.isInitialized) await this.initialize(); + // 注意:V2 架构下不再在 getUsageLimits 中同步刷新 token + // 如果 token 过期,PoolManager 后台会自动处理 + // if (this.isExpiryDateNear()) { + // logger.info('[Antigravity] Token is near expiry, refreshing before getUsageLimits request...'); + // await this.initializeAuth(true); + // } + try { const modelsWithQuotas = await this.getModelsWithQuotas(); return modelsWithQuotas; @@ -1480,12 +1487,15 @@ export class AntigravityApiService { this._applySidecar(requestOptions); const res = await this.authClient.request(requestOptions); + // logger.info(`[Antigravity] fetchAvailableModels success: ${JSON.stringify(res.data)}`); if (res.data) { + if (res.data.models) { const modelsData = res.data.models; // 遍历模型数据,提取配额信息 for (const [modelId, modelData] of Object.entries(modelsData)) { + // 参考 fetchAvailableModels 的逻辑修复 modelName2Alias 不存在的问题 if (!modelId || (!ANTIGRAVITY_MODELS.includes(modelId) && !modelId.startsWith('claude-'))) { continue; } diff --git a/src/providers/gemini/gemini-core.js b/src/providers/gemini/gemini-core.js index b4f386c..0033cbf 100644 --- a/src/providers/gemini/gemini-core.js +++ b/src/providers/gemini/gemini-core.js @@ -289,7 +289,7 @@ export class GeminiApiService { }); // 检查是否需要使用代理 - const proxyConfig = getGoogleAuthProxyConfig(config, config.MODEL_PROVIDER || MODEL_PROVIDER.GEMINI_CLI); + const proxyConfig = getGoogleAuthProxyConfig(config, 'gemini-cli-oauth'); // 配置 OAuth2Client 使用自定义的 HTTP agent const oauth2Options = { @@ -312,7 +312,6 @@ export class GeminiApiService { this.config = config; this.host = config.HOST; - this.uuid = config.uuid; this.oauthCredsBase64 = config.GEMINI_OAUTH_CREDS_BASE64; this.oauthCredsFilePath = config.GEMINI_OAUTH_CREDS_FILE_PATH; this.projectId = config.PROJECT_ID; @@ -321,7 +320,7 @@ export class GeminiApiService { this.apiVersion = DEFAULT_CODE_ASSIST_API_VERSION; // 保存代理配置供后续使用 - this.proxyConfig = getProxyConfigForProvider(config, config.MODEL_PROVIDER || MODEL_PROVIDER.GEMINI_CLI); + this.proxyConfig = getProxyConfigForProvider(config, 'gemini-cli-oauth'); } async initialize() { @@ -346,7 +345,7 @@ export class GeminiApiService { } _applySidecar(requestOptions) { - return configureTLSSidecar(requestOptions, this.config, this.config.MODEL_PROVIDER || MODEL_PROVIDER.GEMINI_CLI); + return configureTLSSidecar(requestOptions, this.config, MODEL_PROVIDER.GEMINI_CLI); } /** @@ -413,7 +412,7 @@ export class GeminiApiService { // 刷新成功,重置 PoolManager 中的刷新状态并标记为健康 const poolManager = getProviderPoolManager(); if (poolManager && this.uuid) { - poolManager.resetProviderRefreshStatus(this.config.MODEL_PROVIDER || MODEL_PROVIDER.GEMINI_CLI, this.uuid); + poolManager.resetProviderRefreshStatus(MODEL_PROVIDER.GEMINI_CLI, this.uuid); } } else { logger.info(`[Gemini Auth] No access token or refresh token. Starting new authentication flow...`); @@ -424,7 +423,7 @@ export class GeminiApiService { // 认证成功,重置状态 const poolManager = getProviderPoolManager(); if (poolManager && this.uuid) { - poolManager.resetProviderRefreshStatus(this.config.MODEL_PROVIDER || MODEL_PROVIDER.GEMINI_CLI, this.uuid); + poolManager.resetProviderRefreshStatus(MODEL_PROVIDER.GEMINI_CLI, this.uuid); } } } catch (error) { @@ -599,7 +598,7 @@ export class GeminiApiService { const poolManager = getProviderPoolManager(); if (poolManager && this.uuid) { logger.info(`[Gemini] Marking credential ${this.uuid} as needs refresh. Reason: 401/400 Unauthorized`); - poolManager.markProviderNeedRefresh(this.config.MODEL_PROVIDER || MODEL_PROVIDER.GEMINI_CLI, { + poolManager.markProviderNeedRefresh(MODEL_PROVIDER.GEMINI_CLI, { uuid: this.uuid }); error.credentialMarkedUnhealthy = true; @@ -682,7 +681,7 @@ export class GeminiApiService { const poolManager = getProviderPoolManager(); if (poolManager && this.uuid) { logger.info(`[Gemini] Marking credential ${this.uuid} as needs refresh. Reason: 401/400 Unauthorized in stream`); - poolManager.markProviderNeedRefresh(this.config.MODEL_PROVIDER || MODEL_PROVIDER.GEMINI_CLI, { + poolManager.markProviderNeedRefresh(MODEL_PROVIDER.GEMINI_CLI, { uuid: this.uuid }); error.credentialMarkedUnhealthy = true; @@ -758,7 +757,7 @@ export class GeminiApiService { const poolManager = getProviderPoolManager(); if (poolManager && this.uuid) { logger.info(`[Gemini] Token is near expiry, marking credential ${this.uuid} for refresh`); - poolManager.markProviderNeedRefresh(this.config.MODEL_PROVIDER || MODEL_PROVIDER.GEMINI_CLI, { + poolManager.markProviderNeedRefresh(MODEL_PROVIDER.GEMINI_CLI, { uuid: this.uuid }); } @@ -797,7 +796,7 @@ export class GeminiApiService { const poolManager = getProviderPoolManager(); if (poolManager && this.uuid) { logger.info(`[Gemini] Token is near expiry, marking credential ${this.uuid} for refresh`); - poolManager.markProviderNeedRefresh(this.config.MODEL_PROVIDER || MODEL_PROVIDER.GEMINI_CLI, { + poolManager.markProviderNeedRefresh(MODEL_PROVIDER.GEMINI_CLI, { uuid: this.uuid }); } diff --git a/src/providers/grok/grok-core.js b/src/providers/grok/grok-core.js index 8e34b3d..7fb962d 100644 --- a/src/providers/grok/grok-core.js +++ b/src/providers/grok/grok-core.js @@ -129,14 +129,14 @@ export class GrokApiService { async acceptTos() { const axiosConfig = { method: 'post', url: `${this.baseUrl}/rest/app-chat/accept-tos`, headers: this.buildHeaders(), data: {}, httpAgent, httpsAgent, timeout: 15000 }; - configureAxiosProxy(axiosConfig, this.config, this.config.MODEL_PROVIDER || MODEL_PROVIDER.GROK_CUSTOM); + configureAxiosProxy(axiosConfig, this.config, MODEL_PROVIDER.GROK_CUSTOM); this._applySidecar(axiosConfig); try { await axios(axiosConfig); } catch (e) { logger.debug(`[Grok TOS] ${e.message}`); } } async setBirthDate() { const axiosConfig = { method: 'post', url: `${this.baseUrl}/rest/app-chat/set-birth-date`, headers: this.buildHeaders(), data: { "birthDate": "1990-01-01" }, httpAgent, httpsAgent, timeout: 15000 }; - configureAxiosProxy(axiosConfig, this.config, this.config.MODEL_PROVIDER || MODEL_PROVIDER.GROK_CUSTOM); + configureAxiosProxy(axiosConfig, this.config, MODEL_PROVIDER.GROK_CUSTOM); this._applySidecar(axiosConfig); try { await axios(axiosConfig); } catch (e) { logger.debug(`[Grok Birth] ${e.message}`); } } @@ -167,13 +167,13 @@ export class GrokApiService { timeout: 15000, responseType: 'arraybuffer' }; - configureAxiosProxy(axiosConfig, this.config, this.config.MODEL_PROVIDER || MODEL_PROVIDER.GROK_CUSTOM); + configureAxiosProxy(axiosConfig, this.config, MODEL_PROVIDER.GROK_CUSTOM); this._applySidecar(axiosConfig); try { await axios(axiosConfig); } catch (e) { throw e; } } _applySidecar(axiosConfig) { - return configureTLSSidecar(axiosConfig, this.config, this.config.MODEL_PROVIDER || MODEL_PROVIDER.GROK_CUSTOM); + return configureTLSSidecar(axiosConfig, this.config, MODEL_PROVIDER.GROK_CUSTOM); } async initialize() { @@ -190,7 +190,7 @@ export class GrokApiService { // await this.getUsageLimits(); return Promise.resolve(); const poolManager = getProviderPoolManager(); if (poolManager && this.uuid) { - poolManager.resetProviderRefreshStatus(this.config.MODEL_PROVIDER || MODEL_PROVIDER.GROK_CUSTOM, this.uuid); + poolManager.resetProviderRefreshStatus(MODEL_PROVIDER.GROK_CUSTOM, this.uuid); } } catch (error) { logger.error('[Grok] Failed to initialize authentication:', error); @@ -202,7 +202,7 @@ export class GrokApiService { const headers = this.buildHeaders(); const payload = { "requestKind": "DEFAULT", "modelName": "grok-3" }; const axiosConfig = { method: 'post', url: `${this.baseUrl}/rest/rate-limits`, headers, data: payload, httpAgent, httpsAgent, timeout: 30000 }; - configureAxiosProxy(axiosConfig, this.config, this.config.MODEL_PROVIDER || MODEL_PROVIDER.GROK_CUSTOM); + configureAxiosProxy(axiosConfig, this.config, MODEL_PROVIDER.GROK_CUSTOM); this._applySidecar(axiosConfig); try { const response = await axios(axiosConfig); @@ -282,7 +282,7 @@ export class GrokApiService { if (mediaUrl && mediaUrl.trim()) payload.mediaUrl = mediaUrl; const axiosConfig = { method: 'post', url: `${this.baseUrl}/rest/media/post/create`, headers, data: payload, httpAgent, httpsAgent, timeout: 30000 }; - configureAxiosProxy(axiosConfig, this.config, this.config.MODEL_PROVIDER || MODEL_PROVIDER.GROK_CUSTOM); + configureAxiosProxy(axiosConfig, this.config, MODEL_PROVIDER.GROK_CUSTOM); this._applySidecar(axiosConfig); try { const response = await axios(axiosConfig); @@ -302,7 +302,7 @@ export class GrokApiService { if (!idMatch) return videoUrl; const videoId = idMatch[1]; const axiosConfig = { method: 'post', url: `${this.baseUrl}/rest/media/video/upscale`, headers: this.buildHeaders(), data: { videoId }, httpAgent, httpsAgent, timeout: 30000 }; - configureAxiosProxy(axiosConfig, this.config, this.config.MODEL_PROVIDER || MODEL_PROVIDER.GROK_CUSTOM); + configureAxiosProxy(axiosConfig, this.config, MODEL_PROVIDER.GROK_CUSTOM); this._applySidecar(axiosConfig); try { const response = await axios(axiosConfig); @@ -329,7 +329,7 @@ export class GrokApiService { httpsAgent, timeout: 15000 }; - configureAxiosProxy(axiosConfig, this.config, this.config.MODEL_PROVIDER || MODEL_PROVIDER.GROK_CUSTOM); + configureAxiosProxy(axiosConfig, this.config, MODEL_PROVIDER.GROK_CUSTOM); this._applySidecar(axiosConfig); try { const response = await axios(axiosConfig); @@ -455,7 +455,7 @@ export class GrokApiService { rolloutId: "", modelResponse: null, cardAttachment: null, - cardAttachments: [], + cardAttachments: [], // 收集所有的卡片附件 streamingImageGenerationResponse: null, streamingVideoGenerationResponse: null, finalVideoUrl: null, @@ -743,7 +743,7 @@ export class GrokApiService { } if (!b64) return null; const axiosConfig = { method: 'post', url: `${this.baseUrl}/rest/app-chat/upload-file`, headers: this.buildHeaders(), data: { fileName: `file.${mime.split("/")[1] || "bin"}`, fileMimeType: mime, content: b64 }, httpAgent, httpsAgent, timeout: 30000 }; - configureAxiosProxy(axiosConfig, this.config, this.config.MODEL_PROVIDER || MODEL_PROVIDER.GROK_CUSTOM); + configureAxiosProxy(axiosConfig, this.config, MODEL_PROVIDER.GROK_CUSTOM); this._applySidecar(axiosConfig); try { return (await axios(axiosConfig)).data; } catch (error) { return null; } } @@ -763,7 +763,7 @@ export class GrokApiService { if (requestBody._requestBaseUrl) delete requestBody._requestBaseUrl; if (this.isExpiryDateNear() && getProviderPoolManager() && this.uuid) { - getProviderPoolManager().markProviderNeedRefresh(this.config.MODEL_PROVIDER || MODEL_PROVIDER.GROK_CUSTOM, { uuid: this.uuid }); + getProviderPoolManager().markProviderNeedRefresh(MODEL_PROVIDER.GROK_CUSTOM, { uuid: this.uuid }); } const rawModel = typeof model === 'string' ? model : ''; @@ -841,7 +841,7 @@ export class GrokApiService { const payload = this.buildPayload(model, requestBody); const axiosConfig = { method: 'post', url: this.chatApi, headers: this.buildHeaders(), data: payload, responseType: 'stream', httpAgent, httpsAgent, timeout: 60000, maxRedirects: 0 }; - configureAxiosProxy(axiosConfig, this.config, this.config.MODEL_PROVIDER || MODEL_PROVIDER.GROK_CUSTOM); + configureAxiosProxy(axiosConfig, this.config, MODEL_PROVIDER.GROK_CUSTOM); this._applySidecar(axiosConfig); try { diff --git a/src/providers/openai/codex-core.js b/src/providers/openai/codex-core.js index 909414f..3eceb68 100644 --- a/src/providers/openai/codex-core.js +++ b/src/providers/openai/codex-core.js @@ -40,7 +40,7 @@ export class CodexApiService { } _applySidecar(axiosConfig) { - return configureTLSSidecar(axiosConfig, this.config, this.config.MODEL_PROVIDER || MODEL_PROVIDER.CODEX_API, this.baseUrl); + return configureTLSSidecar(axiosConfig, this.config, MODEL_PROVIDER.CODEX_API, this.baseUrl); } /** @@ -148,7 +148,7 @@ export class CodexApiService { const poolManager = getProviderPoolManager(); if (poolManager && this.uuid) { logger.info(`[Codex] Token is near expiry, marking credential ${this.uuid} for background refresh`); - poolManager.markProviderNeedRefresh(this.config.MODEL_PROVIDER || MODEL_PROVIDER.CODEX_API, { + poolManager.markProviderNeedRefresh(MODEL_PROVIDER.CODEX_API, { uuid: this.uuid }); } @@ -195,7 +195,7 @@ export class CodexApiService { }; // 配置代理 - const proxyConfig = getProxyConfigForProvider(this.config, this.config.MODEL_PROVIDER || MODEL_PROVIDER.CODEX_API); + const proxyConfig = getProxyConfigForProvider(this.config, 'openai-codex-oauth'); if (proxyConfig) { config.httpAgent = proxyConfig.httpAgent; config.httpsAgent = proxyConfig.httpsAgent; @@ -272,7 +272,7 @@ export class CodexApiService { }; // 配置代理 - const proxyConfig = getProxyConfigForProvider(this.config, this.config.MODEL_PROVIDER || MODEL_PROVIDER.CODEX_API); + const proxyConfig = getProxyConfigForProvider(this.config, 'openai-codex-oauth'); if (proxyConfig) { config.httpAgent = proxyConfig.httpAgent; config.httpsAgent = proxyConfig.httpsAgent; @@ -454,7 +454,7 @@ export class CodexApiService { // 刷新成功,重置 PoolManager 中的刷新状态并标记为健康 const poolManager = getProviderPoolManager(); if (poolManager && this.uuid) { - poolManager.resetProviderRefreshStatus(this.config.MODEL_PROVIDER || MODEL_PROVIDER.CODEX_API, this.uuid); + poolManager.resetProviderRefreshStatus(MODEL_PROVIDER.CODEX_API, this.uuid); } logger.info('[Codex] Token refreshed successfully'); } catch (error) { @@ -688,7 +688,7 @@ export class CodexApiService { }; // 配置代理 - const proxyConfig = getProxyConfigForProvider(this.config, this.config.MODEL_PROVIDER || MODEL_PROVIDER.CODEX_API); + const proxyConfig = getProxyConfigForProvider(this.config, 'openai-codex-oauth'); if (proxyConfig) { config.httpAgent = proxyConfig.httpAgent; config.httpsAgent = proxyConfig.httpsAgent; diff --git a/src/providers/openai/openai-core.js b/src/providers/openai/openai-core.js index 0485fd6..6fe800a 100644 --- a/src/providers/openai/openai-core.js +++ b/src/providers/openai/openai-core.js @@ -47,13 +47,13 @@ export class OpenAIApiService { } // 配置自定义代理 - configureAxiosProxy(axiosConfig, config, config.MODEL_PROVIDER || MODEL_PROVIDER.OPENAI_CUSTOM); + configureAxiosProxy(axiosConfig, config, MODEL_PROVIDER.OPENAI_CUSTOM); this.axiosInstance = axios.create(axiosConfig); } _applySidecar(axiosConfig) { - return configureTLSSidecar(axiosConfig, this.config, this.config.MODEL_PROVIDER || MODEL_PROVIDER.OPENAI_CUSTOM, this.baseUrl); + return configureTLSSidecar(axiosConfig, this.config, MODEL_PROVIDER.OPENAI_CUSTOM, this.baseUrl); } async callApi(endpoint, body, isRetry = false, retryCount = 0) { diff --git a/src/providers/openai/openai-responses-core.js b/src/providers/openai/openai-responses-core.js index 853a3fd..d12cbad 100644 --- a/src/providers/openai/openai-responses-core.js +++ b/src/providers/openai/openai-responses-core.js @@ -47,13 +47,13 @@ export class OpenAIResponsesApiService { } // 配置自定义代理 (使用 openai-custom 的代理配置) - configureAxiosProxy(axiosConfig, config, config.MODEL_PROVIDER || MODEL_PROVIDER.OPENAI_CUSTOM_RESPONSES); + configureAxiosProxy(axiosConfig, config, MODEL_PROVIDER.OPENAI_CUSTOM_RESPONSES); this.axiosInstance = axios.create(axiosConfig); } _applySidecar(axiosConfig) { - return configureTLSSidecar(axiosConfig, this.config, this.config.MODEL_PROVIDER || MODEL_PROVIDER.OPENAI_CUSTOM_RESPONSES, this.baseUrl); + return configureTLSSidecar(axiosConfig, this.config, MODEL_PROVIDER.OPENAI_CUSTOM_RESPONSES, this.baseUrl); } async callApi(endpoint, body, isRetry = false, retryCount = 0) { diff --git a/src/providers/openai/qwen-core.js b/src/providers/openai/qwen-core.js index e2621ca..8d31638 100644 --- a/src/providers/openai/qwen-core.js +++ b/src/providers/openai/qwen-core.js @@ -230,7 +230,7 @@ export class QwenApiService { } // 配置自定义代理 - configureAxiosProxy(axiosConfig, this.config, this.config.MODEL_PROVIDER || MODEL_PROVIDER.QWEN_API); + configureAxiosProxy(axiosConfig, this.config, 'openai-qwen-oauth'); this.currentAxiosInstance = axios.create(axiosConfig); @@ -239,7 +239,7 @@ export class QwenApiService { } _applySidecar(axiosConfig) { - return configureTLSSidecar(axiosConfig, this.config, this.config.MODEL_PROVIDER || MODEL_PROVIDER.QWEN_API, this.baseUrl); + return configureTLSSidecar(axiosConfig, this.config, MODEL_PROVIDER.QWEN_API, this.baseUrl); } /** @@ -278,7 +278,7 @@ export class QwenApiService { if (forceRefresh || (credentials && credentials.access_token)) { const poolManager = getProviderPoolManager(); if (poolManager && this.uuid) { - poolManager.resetProviderRefreshStatus(this.config.MODEL_PROVIDER || MODEL_PROVIDER.QWEN_API, this.uuid); + poolManager.resetProviderRefreshStatus(MODEL_PROVIDER.QWEN_API, this.uuid); } } } catch (error) { @@ -331,7 +331,7 @@ export class QwenApiService { // 认证成功,重置状态 const poolManager = getProviderPoolManager(); if (poolManager && this.uuid) { - poolManager.resetProviderRefreshStatus(this.config.MODEL_PROVIDER || MODEL_PROVIDER.QWEN_API, this.uuid); + poolManager.resetProviderRefreshStatus(MODEL_PROVIDER.QWEN_API, this.uuid); } } } @@ -575,7 +575,7 @@ export class QwenApiService { } // 配置自定义代理 - configureAxiosProxy(axiosConfig, this.config, this.config.MODEL_PROVIDER || MODEL_PROVIDER.QWEN_API); + configureAxiosProxy(axiosConfig, this.config, 'openai-qwen-oauth'); this.currentAxiosInstance = axios.create(axiosConfig); @@ -629,7 +629,7 @@ export class QwenApiService { const poolManager = getProviderPoolManager(); if (poolManager && this.uuid) { logger.info(`[Qwen] Marking credential ${this.uuid} as needs refresh. Reason: Auth Error ${status}`); - poolManager.markProviderNeedRefresh(this.config.MODEL_PROVIDER || MODEL_PROVIDER.QWEN_API, { + poolManager.markProviderNeedRefresh(MODEL_PROVIDER.QWEN_API, { uuid: this.uuid }); error.credentialMarkedUnhealthy = true; @@ -677,7 +677,7 @@ export class QwenApiService { const poolManager = getProviderPoolManager(); if (poolManager && this.uuid) { logger.info(`[Qwen] Token is near expiry, marking credential ${this.uuid} for refresh`); - poolManager.markProviderNeedRefresh(this.config.MODEL_PROVIDER || MODEL_PROVIDER.QWEN_API, { + poolManager.markProviderNeedRefresh(MODEL_PROVIDER.QWEN_API, { uuid: this.uuid }); } diff --git a/src/providers/provider-models.js b/src/providers/provider-models.js index 8c815a0..faa044c 100644 --- a/src/providers/provider-models.js +++ b/src/providers/provider-models.js @@ -116,18 +116,7 @@ export const PROVIDER_MODELS = { * @returns {Array} 模型列表 */ export function getProviderModels(providerType) { - if (PROVIDER_MODELS[providerType]) { - return PROVIDER_MODELS[providerType]; - } - - // 尝试前缀匹配 (例如 openai-custom-1 -> openai-custom) - for (const key of Object.keys(PROVIDER_MODELS)) { - if (providerType.startsWith(key + '-')) { - return PROVIDER_MODELS[key]; - } - } - - return []; + return PROVIDER_MODELS[providerType] || []; } /** diff --git a/src/providers/provider-pool-manager.js b/src/providers/provider-pool-manager.js index 334c9d3..345badf 100644 --- a/src/providers/provider-pool-manager.js +++ b/src/providers/provider-pool-manager.js @@ -1841,11 +1841,7 @@ export class ProviderPoolManager { for (const { providerType, provider, uuid, customName } of providersToCheck) { const providerCheckStart = Date.now(); - const baseProviderType = this._getBaseProviderType(providerType); - const checkModelName = provider.config.checkModelName || - ProviderPoolManager.DEFAULT_HEALTH_CHECK_MODELS[providerType] || - ProviderPoolManager.DEFAULT_HEALTH_CHECK_MODELS[baseProviderType] || - 'unknown'; + const checkModelName = provider.config.checkModelName || ProviderPoolManager.DEFAULT_HEALTH_CHECK_MODELS[providerType] || 'unknown'; const displayName = customName || uuid.substring(0, 8); try { @@ -1907,7 +1903,7 @@ export class ProviderPoolManager { } // OpenAI Custom Responses 使用特殊格式 - if (this._getBaseProviderType(providerType) === MODEL_PROVIDER.OPENAI_CUSTOM_RESPONSES) { + if (providerType === MODEL_PROVIDER.OPENAI_CUSTOM_RESPONSES) { requests.push({ input: [baseMessage], model: modelName @@ -1924,26 +1920,6 @@ export class ProviderPoolManager { return requests; } - /** - * 根据提供商类型获取基准提供商类型(用于查找配置和模型) - * 例如:openai-custom-1 -> openai-custom - * @private - */ - _getBaseProviderType(providerType) { - if (ProviderPoolManager.DEFAULT_HEALTH_CHECK_MODELS[providerType]) { - return providerType; - } - - // 尝试前缀匹配 - for (const key of Object.keys(ProviderPoolManager.DEFAULT_HEALTH_CHECK_MODELS)) { - if (providerType === key || providerType.startsWith(key + '-')) { - return key; - } - } - - return providerType; - } - /** * Performs an actual health check for a specific provider. * @@ -1958,10 +1934,8 @@ export class ProviderPoolManager { */ async _checkProviderHealth(providerType, providerConfig) { // 确定健康检查使用的模型名称 - const baseProviderType = this._getBaseProviderType(providerType); const modelName = providerConfig.checkModelName || - ProviderPoolManager.DEFAULT_HEALTH_CHECK_MODELS[providerType] || - ProviderPoolManager.DEFAULT_HEALTH_CHECK_MODELS[baseProviderType]; + ProviderPoolManager.DEFAULT_HEALTH_CHECK_MODELS[providerType]; if (!modelName) { this._log('warn', `Unknown provider type for health check: ${providerType}. Please check DEFAULT_HEALTH_CHECK_MODELS.`); diff --git a/src/services/service-manager.js b/src/services/service-manager.js index 47f1673..747518f 100644 --- a/src/services/service-manager.js +++ b/src/services/service-manager.js @@ -563,8 +563,7 @@ export async function getProviderStatus(config, options = {}) { 'gemini-antigravity': 'ANTIGRAVITY_OAUTH_CREDS_FILE_PATH', 'openai-iflow': 'IFLOW_TOKEN_FILE_PATH', 'forward-api': 'FORWARD_BASE_URL', - 'grok-custom': 'GROK_COOKIE_TOKEN', - 'openai-codex-oauth': 'CODEX_OAUTH_CREDS_FILE_PATH' + 'grok-custom': 'GROK_COOKIE_TOKEN' }; let providerPoolsSlim = []; let unhealthyProvideIdentifyList = []; @@ -576,18 +575,7 @@ export async function getProviderStatus(config, options = {}) { for (const key of Object.keys(providerPools)) { if (!Array.isArray(providerPools[key])) continue; if (filterProvider && key !== filterProvider) continue; - - let identifyField = identifyFieldMap[key] || null; - if (!identifyField) { - // 尝试通过前缀查找 identifyField (例如 openai-custom-1 -> openai-custom) - for (const [prefix, field] of Object.entries(identifyFieldMap)) { - if (key.startsWith(prefix + '-')) { - identifyField = field; - break; - } - } - } - + const identifyField = identifyFieldMap[key] || null; const slimArr = providerPools[key] .filter(item => { if (item.isDisabled) return false; diff --git a/src/services/ui-manager.js b/src/services/ui-manager.js index cd71bb9..91db632 100644 --- a/src/services/ui-manager.js +++ b/src/services/ui-manager.js @@ -125,7 +125,7 @@ export async function handleUIApiRequests(method, pathParam, req, res, currentCo // Get supported provider types based on registered adapters if (method === 'GET' && pathParam === '/api/providers/supported') { - return await providerApi.handleGetSupportedProviders(req, res, currentConfig, providerPoolManager); + return await providerApi.handleGetSupportedProviders(req, res); } // Get specific provider type details @@ -137,7 +137,7 @@ export async function handleUIApiRequests(method, pathParam, req, res, currentCo // Get available models for all providers or specific provider type if (method === 'GET' && pathParam === '/api/provider-models') { - return await providerApi.handleGetProviderModels(req, res, currentConfig, providerPoolManager); + return await providerApi.handleGetProviderModels(req, res); } // Get available models for a specific provider type diff --git a/src/ui-modules/provider-api.js b/src/ui-modules/provider-api.js index 600f4d0..1d4cf3d 100644 --- a/src/ui-modules/provider-api.js +++ b/src/ui-modules/provider-api.js @@ -9,53 +9,38 @@ import { getRegisteredProviders } from '../providers/adapter.js'; // 文件级互斥锁:防止并发读写导致数据丢失 // 安全净化:移除用户输入字段中的危险内容(script、事件处理器、javascript:协议等), // 存储原始文本。HTML 转义统一由前端 escHtml() 负责,避免双编码问题。 -// 安全净化:移除用户输入字段中的危险内容,并可选地过滤敏感 API 密钥 -function sanitizeProviderData(provider, maskSensitive = false) { +function sanitizeProviderData(provider) { if (!provider || typeof provider !== 'object') return provider; const sanitized = { ...provider }; - - // 1. 过滤敏感字段(API Keys, Tokens 等) - if (maskSensitive) { - const sensitiveKeys = [ - 'OPENAI_API_KEY', 'CLAUDE_API_KEY', 'FORWARD_API_KEY', - 'GROK_COOKIE_TOKEN', 'GROK_CF_CLEARANCE', - 'refreshToken', 'accessToken', 'clientSecret' - ]; - - sensitiveKeys.forEach(key => { - if (sanitized[key]) { - // 对密钥进行脱敏显示(只保留前 4 位和后 4 位) - const val = sanitized[key]; - if (typeof val === 'string' && val.length > 10) { - sanitized[key] = val.substring(0, 4) + '****' + val.substring(val.length - 4); - } else { - sanitized[key] = '********'; - } - } - }); - } - - // 2. 净化 customName 中的 HTML/脚本 if (typeof sanitized.customName === 'string') { let name = sanitized.customName; + + // 拒绝包含危险协议 if (/(?:data|javascript|vbscript)\s*:/i.test(name)) { sanitized.customName = ''; return sanitized; } + + // 移除所有 HTML 标签(更安全的方式) name = name.replace(/<[^>]*>/g, ''); + + // 移除 HTML 事件处理器属性(onclick/onerror 等) name = name.replace(/\s+on\w+\s*=\s*(?:"[^"]*"|'[^']*'|[^\s>]*)/gi, ''); + + // 移除潜在的 HTML 实体编码攻击 name = name.replace(/&[#\w]+;/g, ''); + sanitized.customName = name.trim(); } return sanitized; } -function sanitizeProviderPools(pools, maskSensitive = false) { +function sanitizeProviderPools(pools) { if (!pools || typeof pools !== 'object') return pools; const sanitized = {}; for (const [type, providers] of Object.entries(pools)) { sanitized[type] = Array.isArray(providers) - ? providers.map(p => sanitizeProviderData(p, maskSensitive)) + ? providers.map(sanitizeProviderData) : providers; } return sanitized; @@ -85,53 +70,34 @@ function withFileLock(fn) { return next; } /** - * 获取所有提供商的状态(包括支持的类型和号池组) + * 获取提供商池摘要 */ export async function handleGetProviders(req, res, currentConfig, providerPoolManager) { - if (!providerPoolManager) { - res.writeHead(400, { 'Content-Type': 'application/json' }); - res.end(JSON.stringify({ error: { message: 'Provider pool manager not initialized' } })); - return true; - } - - // 1. 获取支持的基础提供商类型 - const registeredProviders = getRegisteredProviders(); - let poolTypes = []; - - // 2. 从管理器获取当前所有池的状态 - const providerStatus = {}; - for (const [type, providers] of Object.entries(providerPoolManager.providerStatus)) { - providerStatus[type] = providers.map(p => ({ - ...p.config, - activeRequests: p.state?.activeCount || 0, - waitingRequests: p.state?.waitingCount || 0 - })); - } - - // 3. 补全号池配置文件中的所有组 + let providerPools = {}; const filePath = currentConfig.PROVIDER_POOLS_FILE_PATH || 'configs/provider_pools.json'; try { - if (existsSync(filePath)) { + if (providerPoolManager && providerPoolManager.providerPools) { + providerPools = providerPoolManager.providerPools; + } else if (filePath && existsSync(filePath)) { const poolsData = JSON.parse(readFileSync(filePath, 'utf-8')); - poolTypes = Object.keys(poolsData); - poolTypes.forEach(type => { - if (!providerStatus[type]) { - providerStatus[type] = []; - } - }); + providerPools = poolsData; } } catch (error) { - logger.warn('[UI API] Failed to supplement provider status:', error.message); + logger.warn('[UI API] Failed to load provider pools:', error.message); } - // 合并生成支持的类型列表 - const supportedProviders = [...new Set([...registeredProviders, ...poolTypes])]; - res.writeHead(200, { 'Content-Type': 'application/json' }); - res.end(JSON.stringify({ - providers: sanitizeProviderPools(providerStatus, true), // 列表显示进行打码 - supportedProviders: supportedProviders - })); + res.end(JSON.stringify(sanitizeProviderPools(providerPools))); + return true; +} + +/** + * 获取支持的提供商类型(已注册适配器的) + */ +export async function handleGetSupportedProviders(req, res) { + const supportedProviders = getRegisteredProviders(); + res.writeHead(200, { 'Content-Type': 'application/json' }); + res.end(JSON.stringify(supportedProviders)); return true; } @@ -156,7 +122,7 @@ export async function handleGetProviderType(req, res, currentConfig, providerPoo res.writeHead(200, { 'Content-Type': 'application/json' }); res.end(JSON.stringify({ providerType, - providers: providers.map(p => sanitizeProviderData(p, false)), // 详情页(用于编辑)不打码 + providers: providers.map(sanitizeProviderData), totalCount: providers.length, healthyCount: providers.filter(p => p.isHealthy).length })); @@ -164,62 +130,10 @@ export async function handleGetProviderType(req, res, currentConfig, providerPoo } /** - * 获取支持的提供商类型(已注册适配器的,以及号池中已存在的自定义类型) + * 获取所有提供商的可用模型 */ -export async function handleGetSupportedProviders(req, res, currentConfig, providerPoolManager) { - const registeredProviders = getRegisteredProviders(); - let poolTypes = []; - - const filePath = currentConfig.PROVIDER_POOLS_FILE_PATH || 'configs/provider_pools.json'; - try { - if (providerPoolManager && providerPoolManager.providerPools) { - poolTypes = Object.keys(providerPoolManager.providerPools); - } else if (filePath && existsSync(filePath)) { - const poolsData = JSON.parse(readFileSync(filePath, 'utf-8')); - poolTypes = Object.keys(poolsData); - } - } catch (error) { - logger.warn('[UI API] Failed to load provider pools for supported types:', error.message); - } - - // 合并注册的提供商和号池中的类型 - const supportedProviders = [...new Set([...registeredProviders, ...poolTypes])]; - - res.writeHead(200, { 'Content-Type': 'application/json' }); - res.end(JSON.stringify(supportedProviders)); - return true; -} - -/** - * 获取所有提供商的可用模型(支持动态配置组) - */ -export async function handleGetProviderModels(req, res, currentConfig, providerPoolManager) { - const registeredProviders = getRegisteredProviders(); - let poolTypes = []; - - // 获取所有存在的类型(基础 + 动态) - const filePath = currentConfig.PROVIDER_POOLS_FILE_PATH || 'configs/provider_pools.json'; - try { - if (providerPoolManager && providerPoolManager.providerPools) { - poolTypes = Object.keys(providerPoolManager.providerPools); - } else if (existsSync(filePath)) { - const poolsData = JSON.parse(readFileSync(filePath, 'utf-8')); - poolTypes = Object.keys(poolsData); - } - } catch (error) { - logger.warn('[UI API] Failed to load provider pools for models:', error.message); - } - - const allTypes = [...new Set([...registeredProviders, ...poolTypes])]; - const allModels = {}; - - allTypes.forEach(type => { - const models = getProviderModels(type); - if (models && models.length > 0) { - allModels[type] = models; - } - }); - +export async function handleGetProviderModels(req, res) { + const allModels = getAllProviderModels(); res.writeHead(200, { 'Content-Type': 'application/json' }); res.end(JSON.stringify(allModels)); return true; diff --git a/src/utils/common.js b/src/utils/common.js index 3582277..c031ea4 100644 --- a/src/utils/common.js +++ b/src/utils/common.js @@ -961,7 +961,7 @@ export async function handleContentGenerationRequest(req, res, service, endpoint } // 为 forward provider 添加原始请求路径作为 endpoint - if (requestPath && getProtocolPrefix(toProvider) === MODEL_PROTOCOL_PREFIX.FORWARD) { + if (requestPath && toProvider === MODEL_PROVIDER.FORWARD_API) { logger.info(`[Forward API] Request path: ${requestPath}`); processedRequestBody.endpoint = requestPath; } diff --git a/src/utils/proxy-utils.js b/src/utils/proxy-utils.js index 8053c19..45bd9ec 100644 --- a/src/utils/proxy-utils.js +++ b/src/utils/proxy-utils.js @@ -54,7 +54,7 @@ export function parseProxyUrl(proxyUrl) { } /** - * 检查指定的提供商是否启用了代理(支持前缀匹配) + * 检查指定的提供商是否启用了代理 * @param {Object} config - 配置对象 * @param {string} providerType - 提供商类型 * @returns {boolean} 是否启用代理 @@ -69,13 +69,7 @@ export function isProxyEnabledForProvider(config, providerType) { return false; } - // 1. 尝试精确匹配 - if (enabledProviders.includes(providerType)) { - return true; - } - - // 2. 尝试前缀匹配 (例如 openai-custom-prod 继承 openai-custom 的配置) - return enabledProviders.some(p => providerType.startsWith(p + '-')); + return enabledProviders.includes(providerType); } /** @@ -118,7 +112,7 @@ export function configureAxiosProxy(axiosConfig, config, providerType) { } /** - * 检查指定的提供商是否启用了 TLS Sidecar(支持前缀匹配) + * 检查指定的提供商是否启用了 TLS Sidecar * @param {Object} config - 配置对象 * @param {string} providerType - 提供商类型 * @returns {boolean} 是否启用 TLS Sidecar @@ -133,13 +127,7 @@ export function isTLSSidecarEnabledForProvider(config, providerType) { return false; } - // 1. 尝试精确匹配 - if (enabledProviders.includes(providerType)) { - return true; - } - - // 2. 尝试前缀匹配 - return enabledProviders.some(p => providerType.startsWith(p + '-')); + return enabledProviders.includes(providerType); } /** diff --git a/static/app/app.js b/static/app/app.js index 4d38fb3..2704104 100644 --- a/static/app/app.js +++ b/static/app/app.js @@ -41,8 +41,7 @@ import { openProviderManager, showAuthModal, executeGenerateAuthUrl, - handleGenerateAuthUrl, - showAddProviderGroupModal + handleGenerateAuthUrl } from './provider-manager.js'; import { @@ -235,7 +234,6 @@ window.fileUploadHandler = fileUploadHandler; window.showAuthModal = showAuthModal; window.executeGenerateAuthUrl = executeGenerateAuthUrl; window.handleGenerateAuthUrl = handleGenerateAuthUrl; -window.showAddProviderGroupModal = showAddProviderGroupModal; // 配置管理相关全局函数 window.viewConfig = viewConfig; diff --git a/static/app/event-handlers.js b/static/app/event-handlers.js index 5377ecb..283bdcf 100644 --- a/static/app/event-handlers.js +++ b/static/app/event-handlers.js @@ -219,18 +219,6 @@ function initEventListeners() { performUpdateBtn.addEventListener('click', performUpdate); } - // 添加提供商组按钮 - const addProviderGroupBtn = document.getElementById('add-provider-group-btn'); - if (addProviderGroupBtn) { - addProviderGroupBtn.addEventListener('click', () => { - if (window.showAddProviderGroupModal) { - window.showAddProviderGroupModal(); - } else { - console.error('showAddProviderGroupModal function not found'); - } - }); - } - // 日志容器滚动 if (elements.logsContainer) { elements.logsContainer.addEventListener('scroll', () => { diff --git a/static/app/i18n.js b/static/app/i18n.js index f4ee713..13a06ee 100644 --- a/static/app/i18n.js +++ b/static/app/i18n.js @@ -452,12 +452,6 @@ const translations = { // Providers 'providers.title': '提供商池管理', - 'providers.addGroup': '新的分组', - 'providers.addGroup.title': '添加新分组', - 'providers.addGroup.success': '分组创建成功,请添加账号', - 'providers.addGroup.error': '创建失败', - 'providers.addGroup.suffix': '分组名称 (后缀)', - 'providers.addGroup.suffixPlaceholder': '例如: qwen, glm, minimax', 'providers.note': '如使用客户端默认授权配置需使用空节点', 'providers.activeConnections': '活动连接', 'providers.activeProviders': '活跃提供商', @@ -1310,13 +1304,6 @@ const translations = { // Providers 'providers.title': 'Provider Pool Management', - 'providers.addGroup': 'Add Group', - 'providers.addGroup.title': 'Add New Configuration Group', - 'providers.addGroup.baseType': 'Base Type', - 'providers.addGroup.suffix': 'Suffix Name', - 'providers.addGroup.suffixPlaceholder': 'e.g., qwen, glm, minimax', - 'providers.addGroup.success': 'Configuration group created, please add accounts', - 'providers.addGroup.error': 'Creation failed', 'providers.note': 'If using default client authorization config, use an empty node', 'providers.activeConnections': 'Active Connections', 'providers.activeProviders': 'Active Providers', diff --git a/static/app/modal.js b/static/app/modal.js index 60a1cd3..f906030 100644 --- a/static/app/modal.js +++ b/static/app/modal.js @@ -667,13 +667,8 @@ function renderProviderConfig(provider) { * @param {Object} provider - 提供商对象 * @returns {Array} 字段键数组 */ -/** - * 获取字段显示顺序 - * @param {Object} provider - 提供商对象 - * @returns {Array} 字段名数组 - */ function getFieldOrder(provider) { - const orderedFields = ['customName', 'checkModelName', 'checkHealth', 'concurrencyLimit', 'queueLimit']; + const orderedFields = ['customName', 'checkModelName', 'checkHealth']; // 需要排除的内部状态字段 const excludedFields = [ @@ -682,10 +677,23 @@ function getFieldOrder(provider) { 'notSupportedModels', 'refreshCount', 'needsRefresh', '_lastSelectionSeq' ]; - // 尝试从当前模态框上下文中获取提供商类型 - let providerType = currentProviderType; + // 从 getProviderTypeFields 获取字段顺序映射 + const fieldOrderMap = { + 'openai-custom': ['OPENAI_API_KEY', 'OPENAI_BASE_URL'], + 'openaiResponses-custom': ['OPENAI_API_KEY', 'OPENAI_BASE_URL'], + 'claude-custom': ['CLAUDE_API_KEY', 'CLAUDE_BASE_URL'], + 'gemini-cli-oauth': ['PROJECT_ID', 'GEMINI_OAUTH_CREDS_FILE_PATH', 'GEMINI_BASE_URL'], + 'claude-kiro-oauth': ['KIRO_OAUTH_CREDS_FILE_PATH', 'KIRO_BASE_URL', 'KIRO_REFRESH_URL', 'KIRO_REFRESH_IDC_URL'], + 'openai-qwen-oauth': ['QWEN_OAUTH_CREDS_FILE_PATH', 'QWEN_BASE_URL', 'QWEN_OAUTH_BASE_URL'], + 'gemini-antigravity': ['PROJECT_ID', 'ANTIGRAVITY_OAUTH_CREDS_FILE_PATH', 'ANTIGRAVITY_BASE_URL_DAILY', 'ANTIGRAVITY_BASE_URL_AUTOPUSH'], + 'openai-iflow': ['IFLOW_OAUTH_CREDS_FILE_PATH', 'IFLOW_BASE_URL'], + 'openai-codex-oauth': ['CODEX_OAUTH_CREDS_FILE_PATH', 'CODEX_EMAIL', 'CODEX_BASE_URL'], + 'grok-custom': ['GROK_COOKIE_TOKEN', 'GROK_CF_CLEARANCE', 'GROK_USER_AGENT', 'GROK_BASE_URL'], + 'forward-api': ['FORWARD_API_KEY', 'FORWARD_BASE_URL', 'FORWARD_HEADER_NAME', 'FORWARD_HEADER_VALUE_PREFIX'] + }; - // 如果没有上下文类型,尝试从对象字段推断(回退逻辑) + // 尝试从全局或当前模态框上下文中推断提供商类型 + let providerType = currentProviderType; if (!providerType) { if (provider.OPENAI_API_KEY && provider.OPENAI_BASE_URL) { providerType = 'openai-custom'; @@ -710,9 +718,8 @@ function getFieldOrder(provider) { } } - // 直接从 utils.js 获取该类型的预定义字段列表(支持前缀匹配) - const predefinedFields = providerType ? getProviderTypeFields(providerType) : []; - const predefinedOrder = predefinedFields.map(f => f.id); + // 获取该类型应该具有的所有字段(预定义顺序) + const predefinedOrder = providerType ? (fieldOrderMap[providerType] || []) : []; // 获取当前对象中存在且不在预定义列表中的其他字段 const otherFields = Object.keys(provider).filter(key => @@ -727,8 +734,12 @@ function getFieldOrder(provider) { // 只有在字段确实存在于 provider 中,或者它是该提供商类型的预定义字段时才显示 return allExpectedFields.filter(key => - Object.prototype.hasOwnProperty.call(provider, key) || predefinedOrder.includes(key) + provider.hasOwnProperty(key) || predefinedOrder.includes(key) ); + + // 如果无法识别提供商类型,按字母顺序排序 + otherFields.sort(); + return [...orderedFields, ...otherFields].filter(key => provider.hasOwnProperty(key)); } /** diff --git a/static/app/models-manager.js b/static/app/models-manager.js index b976b13..25a5099 100644 --- a/static/app/models-manager.js +++ b/static/app/models-manager.js @@ -199,23 +199,10 @@ function getProviderDisplayName(providerType) { 'openaiResponses-custom': 'OpenAI Responses Custom', 'openai-qwen-oauth': 'Qwen (OAuth)', 'openai-iflow': 'iFlow', - 'openai-codex-oauth': 'OpenAI Codex (OAuth)', - 'grok-custom': 'Grok Reverse' + 'openai-codex-oauth': 'OpenAI Codex (OAuth)' }; - if (displayNames[providerType]) { - return displayNames[providerType]; - } - - // 尝试前缀匹配 - for (const baseType in displayNames) { - if (providerType.startsWith(baseType + '-')) { - const suffix = providerType.substring(baseType.length + 1); - return `${displayNames[baseType]} (${suffix})`; - } - } - - return providerType; + return displayNames[providerType] || providerType; } /** @@ -233,22 +220,13 @@ function getProviderIcon(providerType) { } } - const iconMap = { - 'gemini': 'fas fa-gem', - 'claude': 'fas fa-robot', - 'openai': 'fas fa-brain', - 'qwen': 'fas fa-brain', - 'iflow': 'fas fa-brain', - 'forward': 'fas fa-share-square', - 'grok': 'fas fa-search' - }; - - for (const key in iconMap) { - if (providerType.includes(key)) { - return iconMap[key]; - } + if (providerType.includes('gemini')) { + return 'fas fa-gem'; + } else if (providerType.includes('claude')) { + return 'fas fa-robot'; + } else if (providerType.includes('openai') || providerType.includes('qwen') || providerType.includes('iflow')) { + return 'fas fa-brain'; } - return 'fas fa-server'; } diff --git a/static/app/provider-manager.js b/static/app/provider-manager.js index 6238720..1a9b12f 100644 --- a/static/app/provider-manager.js +++ b/static/app/provider-manager.js @@ -1,7 +1,7 @@ // 提供商管理功能模块 import { providerStats, updateProviderStats } from './constants.js'; -import { showToast, formatUptime, getProviderConfigs, getBaseProviderConfigs } from './utils.js'; +import { showToast, formatUptime, getProviderConfigs } from './utils.js'; import { fileUploadHandler } from './file-upload.js'; import { t, getCurrentLanguage } from './i18n.js'; import { renderRoutingExamples } from './routing-examples.js'; @@ -178,37 +178,35 @@ function updateTimeDisplay() { } /** - * 加载提供商数据 - * @param {boolean} forceRefreshSupported - 是否强制刷新支持的提供商列表 + * 加载提供商列表 */ -async function loadProviders(forceRefreshSupported = false) { +async function loadProviders() { try { - // 获取合并后的数据(包括 providers 和 supportedProviders) - const data = await window.apiClient.get('/providers'); - if (!data || !data.providers) return; + const providers = await window.apiClient.get('/providers'); - const { providers, supportedProviders } = data; - - // 检查支持列表是否发生了变化(或者是否尚未初始化) - const isChanged = !cachedSupportedProviders || - supportedProviders.length !== cachedSupportedProviders.length || - supportedProviders.some((p, i) => p !== cachedSupportedProviders[i]); - - // 如果强制刷新或是对象类型(可能是由事件触发),则也视为需要刷新 - const shouldForce = forceRefreshSupported === true || (typeof forceRefreshSupported === 'object'); - - if (isChanged || shouldForce) { - cachedSupportedProviders = supportedProviders; + // 动态更新其他模块的提供商信息,只需更新一次 + if (!isStaticProviderConfigsUpdated) { + cachedSupportedProviders = await window.apiClient.get('/providers/supported'); const providerConfigs = getProviderConfigs(cachedSupportedProviders); - // 动态更新各个页面的提供商信息 - updateModelsProviderConfigs(providerConfigs); - updateTutorialProviderConfigs(providerConfigs); - updateUsageProviderConfigs(providerConfigs); - updateConfigProviderConfigs(providerConfigs); + // 动态更新凭据文件管理的提供商类型筛选项 updateProviderFilterOptions(providerConfigs); + + // 动态更新仪表盘页面的路径路由调用示例 renderRoutingExamples(providerConfigs); + // 动态更新仪表盘页面的可用模型列表提供商信息 + updateModelsProviderConfigs(providerConfigs); + + // 动态更新配置教程页面的提供商信息 + updateTutorialProviderConfigs(providerConfigs); + + // 动态更新用量查询页面的提供商信息 + updateUsageProviderConfigs(providerConfigs); + + // 动态更新配置管理页面的提供商选择标签 + updateConfigProviderConfigs(providerConfigs); + isStaticProviderConfigsUpdated = true; } @@ -321,7 +319,6 @@ function renderProviders(providers, supportedProviders = []) { ${displayName}
- ${generateAddGroupButton(providerType)} ${generateAuthButton(providerType)}
@@ -362,60 +359,6 @@ function renderProviders(providers, supportedProviders = []) { container.appendChild(providerDiv); - // 为添加分组按钮添加事件监听 - const addGroupBtn = providerDiv.querySelector('.add-group-btn'); - if (addGroupBtn) { - addGroupBtn.addEventListener('click', (e) => { - e.stopPropagation(); - - // 使用自定义的主题风格 Prompt - showSimplePrompt( - t('providers.addGroup.title'), - t('providers.addGroup.suffixPlaceholder'), - async (suffix) => { - const cleanSuffix = suffix.toLowerCase().replace(/[^a-z0-9]/g, ''); - if (!cleanSuffix) { - showToast(t('common.warning'), '请输入有效的后缀(仅限字母和数字)', 'warning'); - return; - } - - const newProviderType = `${providerType}-${cleanSuffix}`; - - // 显示加载状态 - addGroupBtn.disabled = true; - const originalHtml = addGroupBtn.innerHTML; - addGroupBtn.innerHTML = ''; - - try { - const response = await window.apiClient.post('/providers', { - providerType: newProviderType, - providerConfig: { - customName: cleanSuffix.toUpperCase(), - isHealthy: true, - isDisabled: false, - usageCount: 0, - errorCount: 0 - } - }); - - if (response.success) { - showToast(t('common.success'), t('providers.addGroup.success'), 'success'); - await loadProviders(true); - setTimeout(() => openProviderManager(newProviderType), 500); - } else { - throw new Error(response.error?.message || 'Unknown error'); - } - } catch (error) { - console.error('Failed to add provider group:', error); - showToast(t('common.error'), t('providers.addGroup.error') + ': ' + error.message, 'error'); - addGroupBtn.disabled = false; - addGroupBtn.innerHTML = originalHtml; - } - } - ); - }); - } - // 为授权按钮添加事件监听 const authBtn = providerDiv.querySelector('.generate-auth-btn'); if (authBtn) { @@ -543,74 +486,6 @@ function generateAuthButton(providerType) { `; } -/** - * 显示一个极简的主题风格输入框 - * @param {string} title - 标题 - * @param {string} placeholder - 占位符 - * @param {function} callback - 确认回调 - */ -function showSimplePrompt(title, placeholder, callback) { - const overlay = document.createElement('div'); - overlay.className = 'modal-overlay'; - overlay.style.display = 'flex'; - overlay.style.zIndex = '3000'; - overlay.style.background = 'rgba(0, 0, 0, 0.2)'; - overlay.style.backdropFilter = 'blur(2px)'; - - overlay.innerHTML = ` - - `; - - document.body.appendChild(overlay); - - const input = overlay.querySelector('#simple-prompt-input'); - const submitBtn = overlay.querySelector('#simple-prompt-submit'); - - input.focus(); - - const finish = () => { - const val = input.value.trim(); - if (val) { - overlay.remove(); - callback(val); - } - }; - - submitBtn.onclick = finish; - input.onkeydown = (e) => { - if (e.key === 'Enter') finish(); - if (e.key === 'Escape') overlay.remove(); - }; - overlay.onclick = (e) => { - if (e.target === overlay) overlay.remove(); - }; -} - -/** - * 生成添加分组按钮HTML - * @param {string} providerType - 提供商类型 - * @returns {string} 按钮HTML - */ -function generateAddGroupButton(providerType) { - const allowedTypes = ['claude-custom', 'openai-custom', 'openaiResponses-custom']; - if (!allowedTypes.includes(providerType)) { - return ''; - } - - return ` - - `; -} - /** * 处理生成授权链接 * @param {string} providerType - 提供商类型 @@ -3246,148 +3121,16 @@ async function restartServiceAfterUpdate() { } } -/** - * 显示添加提供商组模态框 - * @param {string} defaultBaseType - 默认的基础类型 - */ -function showAddProviderGroupModal(defaultBaseType = null) { - const modal = document.createElement('div'); - modal.className = 'modal-overlay'; - modal.style.display = 'flex'; - modal.style.zIndex = '2000'; - - // 获取所有基础母版配置,并过滤掉当前已经存在的“自定义组” - // 确保下拉菜单只显示纯净的基础类型(如 openai-custom),而不显示已有的带后缀组 - const allBaseConfigs = getBaseProviderConfigs(); - const baseTypes = allBaseConfigs.filter(config => { - // 1. 必须在后端支持的列表中 - const isSupported = cachedSupportedProviders.includes(config.id); - - // 2. 限制只能添加特定类型的配置组 (Claude Custom, OpenAI Custom, OpenAI Responses) - const allowedTypes = ['claude-custom', 'openai-custom', 'openaiResponses-custom']; - const isAllowed = allowedTypes.includes(config.id); - - return isSupported && isAllowed; - }); - - let optionsHtml = baseTypes.map(type => { - const selected = (defaultBaseType && type.id === defaultBaseType) ? 'selected' : ''; - return ``; - }).join(''); - - const selectedConfig = allBaseConfigs.find(c => c.id === defaultBaseType); - const baseTypeSectionHtml = defaultBaseType ? ` -
- -
- - ${selectedConfig?.name || defaultBaseType} -
- -
- ` : ` -
- - -
- `; - - modal.innerHTML = ` - - `; - - document.body.appendChild(modal); - - const closeBtn = modal.querySelector('.modal-close'); - const cancelBtn = modal.querySelector('.modal-cancel'); - const submitBtn = modal.querySelector('.modal-submit'); - const suffixInput = modal.querySelector('#groupSuffix'); - const baseTypeSelect = modal.querySelector('#groupBaseType'); - - const closeModal = () => modal.remove(); - - [closeBtn, cancelBtn].forEach(btn => btn.addEventListener('click', closeModal)); - - submitBtn.addEventListener('click', async () => { - const baseType = baseTypeSelect.value; - const suffix = suffixInput.value.trim().toLowerCase().replace(/[^a-z0-9]/g, ''); - - if (!suffix) { - showToast(t('common.warning'), '请输入有效的后缀(仅限字母和数字)', 'warning'); - return; - } - - const newProviderType = `${baseType}-${suffix}`; - - submitBtn.disabled = true; - submitBtn.innerHTML = ''; - - try { - // 创建一个带后缀的新提供商组,并添加一个初始的空配置(或者让用户在随后的模态框中添加) - // 这里我们先创建一个临时的空配置,这样组就会在 dashboard 中显示出来 - const response = await window.apiClient.post('/providers', { - providerType: newProviderType, - providerConfig: { - customName: suffix.toUpperCase(), - isHealthy: true, - isDisabled: false, - usageCount: 0, - errorCount: 0 - } - }); - - if (response.success) { - showToast(t('common.success'), t('providers.addGroup.success'), 'success'); - closeModal(); - // 重新加载提供商列表,强制刷新支持的类型 - await loadProviders(true); - // 自动打开新创建的组的管理界面 - setTimeout(() => openProviderManager(newProviderType), 500); - } else { - throw new Error(response.error?.message || 'Unknown error'); - } - } catch (error) { - console.error('Failed to add provider group:', error); - showToast(t('common.error'), t('providers.addGroup.error') + ': ' + error.message, 'error'); - submitBtn.disabled = false; - submitBtn.innerHTML = ` ${t('common.confirm')}`; - } - }); -} - export { loadSystemInfo, updateTimeDisplay, loadProviders, + renderProviders, + updateProviderStatsDisplay, openProviderManager, showAuthModal, executeGenerateAuthUrl, handleGenerateAuthUrl, checkUpdate, - performUpdate, - showAddProviderGroupModal + performUpdate }; diff --git a/static/app/routing-examples.js b/static/app/routing-examples.js index 4caf762..ed71b3b 100644 --- a/static/app/routing-examples.js +++ b/static/app/routing-examples.js @@ -453,17 +453,8 @@ function renderRoutingExamples(providerConfigs) { let routeInfo = routes.find(r => r.provider === config.id); - // 如果没找到,则创建一个默认的,并尝试继承基础类型的徽章 + // 如果没找到,则创建一个默认的 if (!routeInfo) { - // 尝试查找基础类型的路由信息以获取徽章 - let baseRouteInfo = null; - for (const r of routes) { - if (config.id.startsWith(r.provider + '-')) { - baseRouteInfo = r; - break; - } - } - routeInfo = { provider: config.id, name: config.name, @@ -471,35 +462,14 @@ function renderRoutingExamples(providerConfigs) { openai: `/${config.id}/v1/chat/completions`, claude: `/${config.id}/v1/messages` }, - description: baseRouteInfo ? baseRouteInfo.description : t('dashboard.routing.oauth'), - badge: baseRouteInfo ? baseRouteInfo.badge : t('dashboard.routing.oauth'), - badgeClass: baseRouteInfo ? baseRouteInfo.badgeClass : 'oauth' + description: t('dashboard.routing.oauth'), + badge: t('dashboard.routing.oauth'), + badgeClass: 'oauth' }; } - // 确定图标:尝试精确匹配,然后尝试前缀匹配 - let icon = iconMap[config.id]; - if (!icon) { - for (const baseId in iconMap) { - if (config.id.startsWith(baseId + '-')) { - icon = iconMap[baseId]; - break; - } - } - } - icon = icon || 'fa-route'; - - // 确定默认模型:尝试精确匹配,然后尝试前缀匹配 - let defaultModel = modelMap[config.id]; - if (!defaultModel) { - for (const baseId in modelMap) { - if (config.id.startsWith(baseId + '-')) { - defaultModel = modelMap[baseId]; - break; - } - } - } - defaultModel = defaultModel || 'default-model'; + const icon = iconMap[config.id] || 'fa-route'; + const defaultModel = modelMap[config.id] || 'default-model'; const hostname = window.location.hostname === 'localhost' || window.location.hostname === '127.0.0.1' ? `http://${window.location.host}` : `${window.location.protocol}//${window.location.host}`; diff --git a/static/app/utils.js b/static/app/utils.js index d43e29e..f796c45 100644 --- a/static/app/utils.js +++ b/static/app/utils.js @@ -7,115 +7,83 @@ import { apiClient } from './auth.js'; * @param {string[]} supportedProviders - 已注册的提供商类型列表 * @returns {Object[]} 提供商配置对象数组 */ -/** - * 获取所有基础提供商配置(母版) - * @returns {Object[]} 基础提供商配置数组 - */ -function getBaseProviderConfigs() { +function getProviderConfigs(supportedProviders = []) { return [ { id: 'forward-api', name: 'NewAPI', - icon: 'fa-share-square' + icon: 'fa-share-square', + visible: supportedProviders.includes('forward-api') }, { id: 'gemini-cli-oauth', name: t('dashboard.routing.nodeName.gemini'), icon: 'fa-robot', - defaultPath: 'configs/gemini/' + defaultPath: 'configs/gemini/', + visible: supportedProviders.includes('gemini-cli-oauth') }, { id: 'gemini-antigravity', name: t('dashboard.routing.nodeName.antigravity'), icon: 'fa-rocket', - defaultPath: 'configs/antigravity/' + defaultPath: 'configs/antigravity/', + visible: supportedProviders.includes('gemini-antigravity') }, { id: 'claude-kiro-oauth', name: t('dashboard.routing.nodeName.kiro'), icon: 'fa-key', - defaultPath: 'configs/kiro/' + defaultPath: 'configs/kiro/', + visible: supportedProviders.includes('claude-kiro-oauth') }, { id: 'openai-codex-oauth', name: t('dashboard.routing.nodeName.codex'), icon: 'fa-code', - defaultPath: 'configs/codex/' + defaultPath: 'configs/codex/', + visible: supportedProviders.includes('openai-codex-oauth') }, { id: 'openai-qwen-oauth', name: t('dashboard.routing.nodeName.qwen'), icon: 'fa-cloud', - defaultPath: 'configs/qwen/' + defaultPath: 'configs/qwen/', + visible: supportedProviders.includes('openai-qwen-oauth') }, { id: 'openai-iflow', name: t('dashboard.routing.nodeName.iflow'), icon: 'fa-stream', - defaultPath: 'configs/iflow/' + defaultPath: 'configs/iflow/', + visible: supportedProviders.includes('openai-iflow') }, { id: 'grok-custom', name: t('dashboard.routing.nodeName.grok'), - icon: 'fa-user-secret' + icon: 'fa-user-secret', + visible: supportedProviders.includes('grok-custom') }, { id: 'openai-custom', name: t('dashboard.routing.nodeName.openai'), - icon: 'fa-microchip' + icon: 'fa-microchip', + visible: supportedProviders.includes('openai-custom') }, { id: 'claude-custom', name: t('dashboard.routing.nodeName.claude'), - icon: 'fa-brain' + icon: 'fa-brain', + visible: supportedProviders.includes('claude-custom') }, { id: 'openaiResponses-custom', name: 'OpenAI Responses', - icon: 'fa-reply-all' + icon: 'fa-reply-all', + visible: supportedProviders.includes('openaiResponses-custom') }, ]; } -/** - * 获取所有支持的提供商配置列表 - * @param {string[]} supportedProviders - 已注册的提供商类型列表 - * @returns {Object[]} 提供商配置对象数组 - */ -function getProviderConfigs(supportedProviders = []) { - const baseConfigs = getBaseProviderConfigs(); - - const result = []; - const usedIds = new Set(); - - // 1. 处理 supportedProviders 中匹配基础配置的类型 - baseConfigs.forEach(config => { - const isSupported = supportedProviders.includes(config.id); - result.push({ ...config, visible: isSupported }); - usedIds.add(config.id); - }); - - // 2. 处理带有后缀的自定义类型 (例如 openai-custom-test) - supportedProviders.forEach(providerId => { - if (usedIds.has(providerId)) return; - - // 查找匹配的前缀 - const baseConfig = baseConfigs.find(bc => providerId.startsWith(bc.id + '-')); - if (baseConfig) { - const suffix = providerId.substring(baseConfig.id.length + 1); - result.push({ - ...baseConfig, - id: providerId, - name: `${baseConfig.name} (${suffix})`, - visible: true - }); - usedIds.add(providerId); - } - }); - - return result; -} - /** * 格式化运行时间 * @param {number} seconds - 秒数 @@ -229,7 +197,6 @@ function getFieldLabel(key) { * @returns {Array} 字段配置数组 */ function getProviderTypeFields(providerType) { - // 基础配置字段定义 const fieldConfigs = { 'openai-custom': [ { @@ -453,19 +420,7 @@ function getProviderTypeFields(providerType) { ] }; - // 1. 尝试精确匹配 - if (fieldConfigs[providerType]) { - return fieldConfigs[providerType]; - } - - // 2. 尝试匹配前缀 (例如 openai-custom-test -> openai-custom) - for (const baseType in fieldConfigs) { - if (providerType.startsWith(baseType + '-')) { - return fieldConfigs[baseType]; - } - } - - return []; + return fieldConfigs[providerType] || []; } /** @@ -506,7 +461,6 @@ export { getFieldLabel, getProviderTypeFields, getProviderConfigs, - getBaseProviderConfigs, getProviderStats, apiRequest }; \ No newline at end of file diff --git a/static/components/section-providers.css b/static/components/section-providers.css index f8304de..c14907d 100644 --- a/static/components/section-providers.css +++ b/static/components/section-providers.css @@ -1138,28 +1138,6 @@ transform: translateY(-1px); } -/* 添加分组按钮样式 */ -.add-group-btn { - display: inline-flex; - align-items: center; - gap: 0.5rem; - padding: 0.25rem 0.75rem; - background: #ecfdf5; /* 绿色系背景 */ - color: #065f46; /* 绿色系文字 */ - border: none; - border-radius: 9999px; - font-size: 0.75rem; - font-weight: 500; - cursor: pointer; - transition: var(--transition); -} - -.add-group-btn:hover { - background: #10b981; - color: white; - transform: translateY(-1px); -} - /* 授权模态框样式 */ .modal-overlay { position: fixed; diff --git a/static/components/section-providers.html b/static/components/section-providers.html index 69b520a..93b481a 100644 --- a/static/components/section-providers.html +++ b/static/components/section-providers.html @@ -38,9 +38,6 @@
-
- -
+
+ +
From 8531343c2b70bee36682f03337ebd7ace88721cd Mon Sep 17 00:00:00 2001 From: hex2077 Date: Sun, 5 Apr 2026 15:23:09 +0800 Subject: [PATCH 07/10] =?UTF-8?q?Reapply=20"feat:=20=E6=9B=B4=E6=96=B0?= =?UTF-8?q?=E7=89=88=E6=9C=AC=E8=87=B32.12.3=E5=B9=B6=E4=BF=AE=E5=A4=8D?= =?UTF-8?q?=E5=A4=9A=E4=B8=AA=E9=97=AE=E9=A2=98"?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This reverts commit ceff3771ea2fc9b6914b09ddecb60fc22d3825b9. --- install-and-run.ps1 | 42 ++++++------ src/providers/gemini/antigravity-core.js | 82 ++++++++++++++++-------- src/providers/gemini/gemini-core.js | 41 ++++++------ src/providers/openai/qwen-core.js | 34 +++++++++- 4 files changed, 131 insertions(+), 68 deletions(-) diff --git a/install-and-run.ps1 b/install-and-run.ps1 index 11821a0..d72a7f7 100644 --- a/install-and-run.ps1 +++ b/install-and-run.ps1 @@ -2,70 +2,70 @@ $OutputEncoding = [System.Text.Encoding]::UTF8 Write-Host "========================================" -ForegroundColor Cyan -Write-Host " AI Client 2 API 快速安装启动脚本" -ForegroundColor Cyan +Write-Host " AI Client 2 API Quick Setup Script" -ForegroundColor Cyan Write-Host "========================================" -ForegroundColor Cyan Write-Host "" -# 处理参数 +# Handle parameters $forcePull = $args -contains "--pull" -# 检查 Git 并拉取 +# Check Git and Pull if ($forcePull) { - Write-Host "[更新] 正在从远程仓库拉取最新代码..." + Write-Host "[UPDATE] Pulling latest code from remote repository..." if (Get-Command git -ErrorAction SilentlyContinue) { git pull if ($LASTEXITCODE -ne 0) { - Write-Warning "Git pull 失败,请检查网络或手动处理冲突。" + Write-Warning "Git pull failed. Please check your network or handle conflicts manually." } else { - Write-Host "[成功] 代码已更新。" -ForegroundColor Green + Write-Host "[SUCCESS] Code updated." -ForegroundColor Green } } else { - Write-Warning "未检测到 Git,跳过代码拉取。" + Write-Warning "Git not detected. Skipping code pull." } } -# 检查 Node.js -Write-Host "[检查] 正在检查Node.js是否已安装..." +# Check Node.js +Write-Host "[CHECK] Checking if Node.js is installed..." if (-not (Get-Command node -ErrorAction SilentlyContinue)) { - Write-Host "[错误] 未检测到Node.js,请先安装Node.js (https://nodejs.org/)" -ForegroundColor Red + Write-Host "[ERROR] Node.js not detected. Please install Node.js (https://nodejs.org/)" -ForegroundColor Red Pause exit 1 } $nodeVersion = node --version -Write-Host "[成功] Node.js已安装,版本: $nodeVersion" -ForegroundColor Green +Write-Host "[SUCCESS] Node.js installed, version: $nodeVersion" -ForegroundColor Green -# 检查 package.json +# Check package.json if (-not (Test-Path "package.json")) { - Write-Host "[错误] 未找到package.json文件,请确保在项目根目录下运行此脚本" -ForegroundColor Red + Write-Host "[ERROR] package.json not found. Please ensure you are running this script from the project root." -ForegroundColor Red Pause exit 1 } -# 确定包管理器 +# Determine package manager $pkgManager = if (Get-Command pnpm -ErrorAction SilentlyContinue) { "pnpm" } else { "npm" } -Write-Host "[安装] 正在使用 $pkgManager 安装/更新依赖..." -ForegroundColor Cyan +Write-Host "[INSTALL] Installing/updating dependencies using $pkgManager..." -ForegroundColor Cyan & $pkgManager install if ($LASTEXITCODE -ne 0) { - Write-Host "[错误] 依赖安装失败,请检查网络连接。" -ForegroundColor Red + Write-Host "[ERROR] Dependency installation failed. Please check your network connection." -ForegroundColor Red Pause exit 1 } -# 检查主文件 +# Check master file if (-not (Test-Path "src\core\master.js")) { - Write-Host "[错误] 未找到 src\core\master.js 文件" -ForegroundColor Red + Write-Host "[ERROR] src\core\master.js not found." -ForegroundColor Red Pause exit 1 } Write-Host "" Write-Host "========================================" -ForegroundColor Green -Write-Host " 启动 AIClient2API 服务器..." -ForegroundColor Green +Write-Host " Starting AIClient2API Server..." -ForegroundColor Green Write-Host "========================================" -ForegroundColor Green -Write-Host "服务器将在 http://localhost:3000 启动" -Write-Host "按 Ctrl+C 停止服务器" +Write-Host "Server will start at http://localhost:3000" +Write-Host "Press Ctrl+C to stop the server" Write-Host "" node src\core\master.js diff --git a/src/providers/gemini/antigravity-core.js b/src/providers/gemini/antigravity-core.js index c66fd2e..e1da3dc 100644 --- a/src/providers/gemini/antigravity-core.js +++ b/src/providers/gemini/antigravity-core.js @@ -40,6 +40,7 @@ const ANTIGRAVITY_SYSTEM_PROMPT = `You are Antigravity, a powerful agentic AI co // Thinking 配置相关常量 const DEFAULT_THINKING_MIN = 1024; const DEFAULT_THINKING_MAX = 100000; +const FALLBACK_THINKING_SIGNATURE = "skip_thought_signature_validator_fallback"; // 获取 Antigravity 模型列表 const ANTIGRAVITY_MODELS = getProviderModels(MODEL_PROVIDER.ANTIGRAVITY); @@ -199,16 +200,16 @@ function normalizeAntigravityThinking(modelName, payload, isClaudeModel) { let normalizedBudget = normalizeThinkingBudget(modelName, budget); - // 对于 Claude 模型,确保 thinking budget < max_tokens + // 确保 thinking budget < max_tokens (对所有模型生效,不仅是 Claude) + const maxTokens = payload?.request?.generationConfig?.maxOutputTokens || payload?.request?.generationConfig?.max_output_tokens; + if (maxTokens && maxTokens > 0 && normalizedBudget >= maxTokens) { + normalizedBudget = Math.max(0, maxTokens - 1); + } + + // 如果是 Claude 模型,检查最小 budget if (isClaudeModel) { - const maxTokens = payload?.request?.generationConfig?.maxOutputTokens; - if (maxTokens && maxTokens > 0 && normalizedBudget >= maxTokens) { - normalizedBudget = maxTokens - 1; - } - - // 检查最小 budget const minBudget = DEFAULT_THINKING_MIN; - if (normalizedBudget >= 0 && normalizedBudget < minBudget) { + if (normalizedBudget >= 0 && normalizedBudget < minBudget && normalizedBudget !== -1) { // Budget 低于最小值,移除 thinking 配置 delete payload.request.generationConfig.thinkingConfig; return payload; @@ -599,7 +600,7 @@ function toGeminiApiResponse(antigravityResponse) { } /** - * 确保请求体中的内容部分都有角色属性 + * 确保请求体中的内容部分都有角色属性,并修复历史记录中的思考签名 * @param {Object} requestBody - 请求体 * @returns {Object} 处理后的请求体 */ @@ -674,6 +675,24 @@ function ensureRolesInContents(requestBody, modelName) { if (!content.role) { content.role = 'user'; } + + // [FIX] 修复历史记录中的思考块,确保有签名 (messages.1.content.0.thinking.signature 报错修复) + if (content.parts && Array.isArray(content.parts)) { + content.parts.forEach(part => { + if (part && part.thought === true) { + if (!part.thoughtSignature && !part.thought_signature) { + part.thoughtSignature = FALLBACK_THINKING_SIGNATURE; + } + + // [FIX] 额外增加一个 'thinking' 对象以适配某些 Antigravity 内部验证逻辑 + if (!part.thinking) { + part.thinking = { + signature: part.thoughtSignature || part.thought_signature || FALLBACK_THINKING_SIGNATURE + }; + } + } + }); + } }); } @@ -696,25 +715,6 @@ export class AntigravityApiService { timeout: 120000, }); - // 检查是否需要使用代理 - const proxyConfig = getGoogleAuthProxyConfig(config, config.MODEL_PROVIDER || MODEL_PROVIDER.ANTIGRAVITY); - - // 配置 OAuth2Client 使用自定义的 HTTP agent - const oauth2Options = { - clientId: OAUTH_CLIENT_ID, - clientSecret: OAUTH_CLIENT_SECRET, - }; - - if (proxyConfig) { - oauth2Options.transporterOptions = proxyConfig; - logger.info('[Antigravity] Using proxy for OAuth2Client'); - } else { - oauth2Options.transporterOptions = { - agent: this.httpsAgent, - }; - } - - this.authClient = new OAuth2Client(oauth2Options); this.availableModels = []; this.isInitialized = false; @@ -730,6 +730,32 @@ export class AntigravityApiService { // 保存代理配置供后续使用 this.proxyConfig = getProxyConfigForProvider(config, config.MODEL_PROVIDER || MODEL_PROVIDER.ANTIGRAVITY); + + // 检查是否需要使用代理 + const proxyConfig = getGoogleAuthProxyConfig(config, config.MODEL_PROVIDER || MODEL_PROVIDER.ANTIGRAVITY); + + // 配置 OAuth2Client 使用自定义的 HTTP agent + const oauth2Options = { + clientId: OAUTH_CLIENT_ID, + clientSecret: OAUTH_CLIENT_SECRET, + }; + + if (proxyConfig) { + oauth2Options.transporterOptions = proxyConfig; + logger.info('[Antigravity] Using proxy for OAuth2Client'); + } else { + // 根据 base URL 判断使用 http 还是 https agent + const firstBaseURL = this.baseURLs && this.baseURLs.length > 0 ? this.baseURLs[0] : ''; + const useHttp = firstBaseURL.startsWith('http://'); + oauth2Options.transporterOptions = { + agent: useHttp ? this.httpAgent : this.httpsAgent, + }; + if (useHttp) { + logger.info('[Antigravity] Using HTTP agent for OAuth2Client'); + } + } + + this.authClient = new OAuth2Client(oauth2Options); } _applySidecar(requestOptions) { diff --git a/src/providers/gemini/gemini-core.js b/src/providers/gemini/gemini-core.js index b4f386c..57abb77 100644 --- a/src/providers/gemini/gemini-core.js +++ b/src/providers/gemini/gemini-core.js @@ -287,24 +287,6 @@ export class GeminiApiService { maxFreeSockets: 5, timeout: 120000, }); - - // 检查是否需要使用代理 - const proxyConfig = getGoogleAuthProxyConfig(config, config.MODEL_PROVIDER || MODEL_PROVIDER.GEMINI_CLI); - - // 配置 OAuth2Client 使用自定义的 HTTP agent - const oauth2Options = { - clientId: OAUTH_CLIENT_ID, - clientSecret: OAUTH_CLIENT_SECRET, - }; - - if (proxyConfig) { - oauth2Options.transporterOptions = proxyConfig; - logger.info('[Gemini] Using proxy for OAuth2Client'); - } else { - oauth2Options.transporterOptions = { - agent: this.httpsAgent, - }; - } this.authClient = new OAuth2Client(oauth2Options); this.availableModels = []; @@ -322,6 +304,29 @@ export class GeminiApiService { // 保存代理配置供后续使用 this.proxyConfig = getProxyConfigForProvider(config, config.MODEL_PROVIDER || MODEL_PROVIDER.GEMINI_CLI); + + // 检查是否需要使用代理 + const proxyConfig = getGoogleAuthProxyConfig(config, config.MODEL_PROVIDER || MODEL_PROVIDER.GEMINI_CLI); + + // 配置 OAuth2Client 使用自定义的 HTTP agent + const oauth2Options = { + clientId: OAUTH_CLIENT_ID, + clientSecret: OAUTH_CLIENT_SECRET, + }; + + if (proxyConfig) { + oauth2Options.transporterOptions = proxyConfig; + logger.info('[Gemini] Using proxy for OAuth2Client'); + } else { + // 根据 base URL 判断使用 http 还是 https agent + const useHttp = this.codeAssistEndpoint && this.codeAssistEndpoint.startsWith('http://'); + oauth2Options.transporterOptions = { + agent: useHttp ? this.httpAgent : this.httpsAgent, + }; + if (useHttp) { + logger.info('[Gemini] Using HTTP agent for OAuth2Client'); + } + } } async initialize() { diff --git a/src/providers/openai/qwen-core.js b/src/providers/openai/qwen-core.js index e2621ca..f84a679 100644 --- a/src/providers/openai/qwen-core.js +++ b/src/providers/openai/qwen-core.js @@ -50,6 +50,38 @@ export const qwenOAuth2Events = new EventEmitter(); // --- Helper Functions --- +/** + * Qwen 默认系统提示词 + */ +const QWEN_DEFAULT_SYSTEM_PROMPT = "You are a helpful assistant. You are Qwen, a large language model trained by Alibaba."; + +/** + * 应用 Qwen 默认系统提示词逻辑 + * @param {Object} requestBody - OpenAI 格式的请求体 + * @returns {Object} 处理后的请求体 + */ +function applyQwenDefaultSystemPrompt(requestBody) { + if (!requestBody || !requestBody.messages || !Array.isArray(requestBody.messages)) { + return requestBody; + } + + // 检查是否已有系统提示词 (role 为 system 或 developer) + const hasSystemPrompt = requestBody.messages.some(msg => + msg.role === 'system' || msg.role === 'developer' + ); + + // 如果没有系统提示词,则在消息列表最前面插入默认提示词 + if (!hasSystemPrompt) { + requestBody.messages.unshift({ + role: 'system', + content: QWEN_DEFAULT_SYSTEM_PROMPT + }); + logger.info('[Qwen Auth] 已应用默认系统提示词'); + } + + return requestBody; +} + // 封装公共的 await fetch 方法 async function commonFetch(url, options = {}, useSystemProxy = false) { const defaultOptions = { @@ -580,7 +612,7 @@ export class QwenApiService { this.currentAxiosInstance = axios.create(axiosConfig); // Process message content before sending the request - const processedBody = body;//this.processMessageContent(body); + const processedBody = applyQwenDefaultSystemPrompt(body); // Check if model in body is in QWEN_MODEL_LIST, if not, use the first model's id if (processedBody.model && !QWEN_MODEL_LIST.some(model => model.id === processedBody.model)) { From 85d7b50cb1f63a38e7446addc36f1b25b8d90a89 Mon Sep 17 00:00:00 2001 From: hex2077 Date: Sun, 5 Apr 2026 17:50:11 +0800 Subject: [PATCH 08/10] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8DQwen=20API?= =?UTF-8?q?=E9=85=8D=E9=A2=9D=E9=94=99=E8=AF=AF=E5=A4=84=E7=90=86=E5=92=8C?= =?UTF-8?q?Gemini=E5=88=9D=E5=A7=8B=E5=8C=96=E9=A1=BA=E5=BA=8F=E9=97=AE?= =?UTF-8?q?=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 修复Qwen API的配额错误识别和速率限制,避免因配额耗尽导致服务中断 - 修正Gemini API服务初始化顺序,确保OAuth2客户端在HTTP代理配置后创建 - 优化提供商数据脱敏逻辑,防止保存时覆盖真实的敏感信息 - 增强前端错误处理,支持国际化错误消息的翻译和显示 - 移除Antigravity中冗余的思考签名修复代码,简化历史记录处理 - 修复服务管理器初始化逻辑,确保提供商池状态正确更新 - 统一日志下载文件名格式,改进文件下载错误处理 - 更新翻译文件,添加缺失的通用错误消息国际化支持 --- VERSION | 2 +- src/providers/gemini/antigravity-core.js | 18 -- src/providers/gemini/gemini-core.js | 5 +- src/providers/openai/qwen-core.js | 283 +++++++++++++++-------- src/providers/provider-pool-manager.js | 79 ++++--- src/services/service-manager.js | 33 ++- src/ui-modules/config-api.js | 21 +- src/ui-modules/provider-api.js | 86 ++++--- static/app/auth.js | 56 ++++- static/app/event-handlers.js | 33 +-- static/app/i18n.js | 18 ++ static/app/provider-manager.js | 4 +- 12 files changed, 415 insertions(+), 223 deletions(-) diff --git a/VERSION b/VERSION index 56beced..dcb27a7 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -2.12.4 +2.12.5 diff --git a/src/providers/gemini/antigravity-core.js b/src/providers/gemini/antigravity-core.js index e1da3dc..905a344 100644 --- a/src/providers/gemini/antigravity-core.js +++ b/src/providers/gemini/antigravity-core.js @@ -40,7 +40,6 @@ const ANTIGRAVITY_SYSTEM_PROMPT = `You are Antigravity, a powerful agentic AI co // Thinking 配置相关常量 const DEFAULT_THINKING_MIN = 1024; const DEFAULT_THINKING_MAX = 100000; -const FALLBACK_THINKING_SIGNATURE = "skip_thought_signature_validator_fallback"; // 获取 Antigravity 模型列表 const ANTIGRAVITY_MODELS = getProviderModels(MODEL_PROVIDER.ANTIGRAVITY); @@ -676,23 +675,6 @@ function ensureRolesInContents(requestBody, modelName) { content.role = 'user'; } - // [FIX] 修复历史记录中的思考块,确保有签名 (messages.1.content.0.thinking.signature 报错修复) - if (content.parts && Array.isArray(content.parts)) { - content.parts.forEach(part => { - if (part && part.thought === true) { - if (!part.thoughtSignature && !part.thought_signature) { - part.thoughtSignature = FALLBACK_THINKING_SIGNATURE; - } - - // [FIX] 额外增加一个 'thinking' 对象以适配某些 Antigravity 内部验证逻辑 - if (!part.thinking) { - part.thinking = { - signature: part.thoughtSignature || part.thought_signature || FALLBACK_THINKING_SIGNATURE - }; - } - } - }); - } }); } diff --git a/src/providers/gemini/gemini-core.js b/src/providers/gemini/gemini-core.js index 57abb77..c57fd49 100644 --- a/src/providers/gemini/gemini-core.js +++ b/src/providers/gemini/gemini-core.js @@ -287,8 +287,7 @@ export class GeminiApiService { maxFreeSockets: 5, timeout: 120000, }); - - this.authClient = new OAuth2Client(oauth2Options); + this.availableModels = []; this.isInitialized = false; @@ -327,6 +326,8 @@ export class GeminiApiService { logger.info('[Gemini] Using HTTP agent for OAuth2Client'); } } + + this.authClient = new OAuth2Client(oauth2Options); } async initialize() { diff --git a/src/providers/openai/qwen-core.js b/src/providers/openai/qwen-core.js index f84a679..919a42e 100644 --- a/src/providers/openai/qwen-core.js +++ b/src/providers/openai/qwen-core.js @@ -50,36 +50,131 @@ export const qwenOAuth2Events = new EventEmitter(); // --- Helper Functions --- -/** - * Qwen 默认系统提示词 - */ -const QWEN_DEFAULT_SYSTEM_PROMPT = "You are a helpful assistant. You are Qwen, a large language model trained by Alibaba."; +// --- Rate Limiting & Quota --- +const qwenRateLimiter = { + requests: new Map(), // authID -> timestamps[] +}; +const QWEN_RATE_LIMIT_PER_MIN = 60; +const QWEN_RATE_LIMIT_WINDOW_MS = 60 * 1000; +const QWEN_QUOTA_CODES = new Set(['insufficient_quota', 'quota_exceeded']); /** - * 应用 Qwen 默认系统提示词逻辑 + * 检查 Qwen 速率限制 (60 requests/min) + * @param {string} authID + * @returns {Error|null} + */ +function checkQwenRateLimit(authID) { + if (!authID) return null; + const now = Date.now(); + const windowStart = now - QWEN_RATE_LIMIT_WINDOW_MS; + + let timestamps = qwenRateLimiter.requests.get(authID) || []; + timestamps = timestamps.filter(ts => ts > windowStart); + + if (timestamps.length >= QWEN_RATE_LIMIT_PER_MIN) { + const oldestInWindow = timestamps[0]; + const retryAfterMs = oldestInWindow + QWEN_RATE_LIMIT_WINDOW_MS - now; + const retryAfterSec = Math.max(1, Math.ceil(retryAfterMs / 1000)); + const error = new Error(`Qwen rate limit exceeded for ${authID.substring(0, 8)}, retry after ${retryAfterSec}s`); + error.status = 429; + error.data = { error: { code: "rate_limit_exceeded", message: error.message } }; + error.retryAfter = retryAfterMs; + return error; + } + + timestamps.push(now); + qwenRateLimiter.requests.set(authID, timestamps); + return null; +} + +/** + * 检查是否为配额错误 + */ +function isQwenQuotaError(body) { + if (!body || typeof body !== 'object') return false; + const error = body.error || {}; + const code = (error.code || '').toLowerCase(); + const type = (error.type || '').toLowerCase(); + const message = (error.message || '').toLowerCase(); + return QWEN_QUOTA_CODES.has(code) || QWEN_QUOTA_CODES.has(type) || + /insufficient_quota|quota exceeded|free allocated quota exceeded/i.test(message); +} + +/** + * 计算到北京时间次日凌晨的毫秒数 + */ +function timeUntilNextDayBeijing() { + const now = new Date(); + // UTC to Beijing (UTC+8) + const utcTime = now.getTime() + (now.getTimezoneOffset() * 60000); + const beijingNow = new Date(utcTime + (3600000 * 8)); + const tomorrow = new Date(beijingNow); + tomorrow.setDate(tomorrow.getDate() + 1); + tomorrow.setHours(0, 0, 0, 0); + return tomorrow.getTime() - beijingNow.getTime(); +} + +/** + * 确保 Qwen 系统消息在开头且唯一,合并多条系统消息并支持缓存控制 * @param {Object} requestBody - OpenAI 格式的请求体 * @returns {Object} 处理后的请求体 */ -function applyQwenDefaultSystemPrompt(requestBody) { +function ensureQwenSystemMessage(requestBody) { if (!requestBody || !requestBody.messages || !Array.isArray(requestBody.messages)) { return requestBody; } - // 检查是否已有系统提示词 (role 为 system 或 developer) - const hasSystemPrompt = requestBody.messages.some(msg => - msg.role === 'system' || msg.role === 'developer' - ); + const isInjectedSystemPart = (part) => { + if (!part || typeof part !== 'object') return false; + if (part.type !== 'text') return false; + if (part.cache_control?.type !== 'ephemeral') return false; + return part.text === "" || part.text === "You are Qwen Code."; + }; - // 如果没有系统提示词,则在消息列表最前面插入默认提示词 - if (!hasSystemPrompt) { - requestBody.messages.unshift({ - role: 'system', - content: QWEN_DEFAULT_SYSTEM_PROMPT - }); - logger.info('[Qwen Auth] 已应用默认系统提示词'); + let systemParts = []; + // 注入默认系统提示词部分 (带缓存控制) + systemParts.push({ + type: "text", + text: "You are Qwen Code.", + cache_control: { type: "ephemeral" } + }); + + const appendSystemContent = (content) => { + if (content === undefined || content === null) return; + + if (Array.isArray(content)) { + for (const part of content) { + if (typeof part === 'string') { + systemParts.push({ type: 'text', text: part }); + } else if (!isInjectedSystemPart(part)) { + systemParts.push(part); + } + } + } else if (typeof content === 'string') { + systemParts.push({ type: 'text', text: content }); + } else if (typeof content === 'object') { + if (!isInjectedSystemPart(content)) { + systemParts.push(content); + } + } + }; + + const nonSystemMessages = []; + for (const msg of requestBody.messages) { + if (msg.role === 'system' || msg.role === 'developer') { + appendSystemContent(msg.content); + } else { + nonSystemMessages.push(msg); + } } - return requestBody; + return { + ...requestBody, + messages: [ + { role: 'system', content: systemParts }, + ...nonSystemMessages + ] + }; } // 封装公共的 await fetch 方法 @@ -564,85 +659,87 @@ export class QwenApiService { } async callApiWithAuthAndRetry(endpoint, body, isStream = false, retryCount = 0) { + // 速率限制检查 + if (this.uuid) { + const limitErr = checkQwenRateLimit(this.uuid); + if (limitErr) throw limitErr; + } + const maxRetries = (this.config && this.config.REQUEST_MAX_RETRIES) || 3; const baseDelay = (this.config && this.config.REQUEST_BASE_DELAY) || 1000; - const version = "0.10.1"; + const version = "0.13.2"; const userAgent = `QwenCode/${version} (${process.platform}; ${process.arch})`; - logger.info(`[QwenApiService] User-Agent: ${userAgent}`); try { const { token, endpoint: qwenBaseUrl } = await this.getValidToken(); - // 配置 HTTP/HTTPS agent 限制连接池大小,避免资源泄漏 - const httpAgent = new http.Agent({ - keepAlive: true, - maxSockets: 100, - maxFreeSockets: 5, - timeout: 120000, - }); - const httpsAgent = new https.Agent({ - keepAlive: true, - maxSockets: 100, - maxFreeSockets: 5, - timeout: 120000, - }); + const headers = { + 'Content-Type': 'application/json', + 'Authorization': `Bearer ${token}`, + 'User-Agent': userAgent, + 'X-DashScope-UserAgent': userAgent, + 'X-Stainless-Runtime-Version': 'v22.17.0', + 'X-Stainless-Lang': 'js', + 'X-Stainless-Arch': process.arch === 'x64' ? 'x86_64' : process.arch, + 'X-Stainless-Package-Version': '5.11.0', + 'X-DashScope-CacheControl': 'enable', + 'X-DashScope-AuthType': 'qwen-oauth', + 'X-Stainless-Runtime': 'node', + 'Accept': isStream ? 'text/event-stream' : 'application/json', + }; const axiosConfig = { baseURL: qwenBaseUrl, - httpAgent, - httpsAgent, - headers: { - 'Content-Type': 'application/json', - 'Authorization': `Bearer ${token}`, - 'X-DashScope-CacheControl': 'enable', - 'X-DashScope-UserAgent': userAgent, - 'X-DashScope-AuthType': 'qwen-oauth', - }, + headers, + // axios 默认不传 proxy 配置时会遵循环境变量,这里明确控制 + proxy: this.useSystemProxy ? undefined : false, }; - // 禁用系统代理 - if (!this.useSystemProxy) { - axiosConfig.proxy = false; - } - - // 配置自定义代理 + // 配置自定义代理 (如果 config.json 中有定义) configureAxiosProxy(axiosConfig, this.config, this.config.MODEL_PROVIDER || MODEL_PROVIDER.QWEN_API); - this.currentAxiosInstance = axios.create(axiosConfig); + const instance = axios.create(axiosConfig); - // Process message content before sending the request - const processedBody = applyQwenDefaultSystemPrompt(body); + // 处理消息和模型 + let processedBody = ensureQwenSystemMessage(body); - // Check if model in body is in QWEN_MODEL_LIST, if not, use the first model's id - if (processedBody.model && !QWEN_MODEL_LIST.some(model => model.id === processedBody.model)) { - logger.warn(`[QwenApiService] Model '${processedBody.model}' not found. Using default model: '${QWEN_MODEL_LIST[0].id}'`); - processedBody.model = QWEN_MODEL_LIST[0].id; + // 检查模型是否存在于列表中 + if (processedBody.model && !QWEN_MODELS.includes(processedBody.model)) { + logger.warn(`[QwenApiService] Model '${processedBody.model}' not found in supported list. Using default: '${QWEN_MODELS[0]}'`); + processedBody.model = QWEN_MODELS[0]; } - const defaultTools = [ - { - "type": "function", - "function": { - "name": "ext" - } - } - ]; + // Qwen3 兼容性补丁:针对 Qwen3 "Poisoning" 问题优化工具注入 + // 如果请求本身没有 tools,注入一个虚拟工具防止模型在流式响应中随机吐出 Token + const dummyTool = { + type: "function", + function: { + name: "ext", + description: "Internal extension tool" + } + }; - // Merge tools if requestBody already has tools defined - const mergedTools = processedBody.tools ? [...defaultTools, ...processedBody.tools] : defaultTools; + if (processedBody.tools) { + processedBody.tools = [dummyTool, ...processedBody.tools]; + } else { + processedBody.tools = [dummyTool]; + } - const requestBody = isStream ? { ...processedBody, stream: true, tools: mergedTools } : { ...processedBody, tools: mergedTools }; - - const axiosRequestConfig = { + if (isStream) { + processedBody.stream = true; + processedBody.stream_options = { include_usage: true }; + } + + const requestConfig = { method: 'post', url: endpoint, - data: requestBody, + data: processedBody, ...(isStream ? { responseType: 'stream' } : {}) }; - this._applySidecar(axiosRequestConfig); + this._applySidecar(requestConfig); - const response = await this.currentAxiosInstance.request(axiosRequestConfig); + const response = await instance.request(requestConfig); return response.data; } catch (error) { @@ -651,40 +748,38 @@ export class QwenApiService { const errorCode = error.code; const errorMessage = error.message || ''; - // 检查是否为可重试的网络错误 - const isNetworkError = isRetryableNetworkError(error); - - if (this.isAuthError(error) && retryCount === 0) { - logger.warn(`[QwenApiService] Auth error (${status}). Triggering background refresh via PoolManager...`); + // 检查配额错误 -> 映射为 429 并设置冷却时间 + if ((status === 403 || status === 429) && isQwenQuotaError(error.response?.data)) { + const cooldown = timeUntilNextDayBeijing(); + logger.warn(`[QwenApiService] Daily quota exceeded (http ${status} -> 429), cooling down until tomorrow (~${Math.round(cooldown / 3600000)} hours)`); + error.status = 429; + error.retryAfter = cooldown; - // 标记当前凭证为不健康(会自动进入刷新队列) + // 标记 unhealthy const poolManager = getProviderPoolManager(); if (poolManager && this.uuid) { - logger.info(`[Qwen] Marking credential ${this.uuid} as needs refresh. Reason: Auth Error ${status}`); - poolManager.markProviderNeedRefresh(this.config.MODEL_PROVIDER || MODEL_PROVIDER.QWEN_API, { - uuid: this.uuid - }); + poolManager.markProviderNeedRefresh(this.config.MODEL_PROVIDER || MODEL_PROVIDER.QWEN_API, { uuid: this.uuid }); + } + throw error; + } + + if (this.isAuthError(error) && retryCount === 0) { + logger.warn(`[QwenApiService] Auth error (${status}). Triggering background refresh...`); + + const poolManager = getProviderPoolManager(); + if (poolManager && this.uuid) { + poolManager.markProviderNeedRefresh(this.config.MODEL_PROVIDER || MODEL_PROVIDER.QWEN_API, { uuid: this.uuid }); error.credentialMarkedUnhealthy = true; } - // Mark error for credential switch without recording error count error.shouldSwitchCredential = true; error.skipErrorCount = true; throw error; } - if ((status === 429 || (status >= 500 && status < 600)) && retryCount < maxRetries) { + if ((status === 429 || (status >= 500 && status < 600) || isRetryableNetworkError(error)) && retryCount < maxRetries) { const delay = baseDelay * Math.pow(2, retryCount); - logger.info(`[QwenApiService] Status ${status}. Retrying in ${delay}ms...`); - await new Promise(resolve => setTimeout(resolve, delay)); - return this.callApiWithAuthAndRetry(endpoint, body, isStream, retryCount + 1); - } - - // Handle network errors (ECONNRESET, ETIMEDOUT, etc.) with exponential backoff - if (isNetworkError && retryCount < maxRetries) { - const delay = baseDelay * Math.pow(2, retryCount); - const errorIdentifier = errorCode || errorMessage.substring(0, 50); - logger.info(`[QwenApiService] Network error (${errorIdentifier}). Retrying in ${delay}ms... (attempt ${retryCount + 1}/${maxRetries})`); + logger.info(`[QwenApiService] Request failed (${status || errorCode}). Retrying in ${delay}ms... (${retryCount + 1}/${maxRetries})`); await new Promise(resolve => setTimeout(resolve, delay)); return this.callApiWithAuthAndRetry(endpoint, body, isStream, retryCount + 1); } @@ -733,7 +828,7 @@ export class QwenApiService { const poolManager = getProviderPoolManager(); if (poolManager && this.uuid) { logger.info(`[Qwen] Token is near expiry, marking credential ${this.uuid} for refresh`); - poolManager.markProviderNeedRefresh(MODEL_PROVIDER.QWEN_API, { + poolManager.markProviderNeedRefresh(this.config.MODEL_PROVIDER || MODEL_PROVIDER.QWEN_API, { uuid: this.uuid }); } diff --git a/src/providers/provider-pool-manager.js b/src/providers/provider-pool-manager.js index 334c9d3..99d2512 100644 --- a/src/providers/provider-pool-manager.js +++ b/src/providers/provider-pool-manager.js @@ -626,50 +626,59 @@ export class ProviderPoolManager { * Initially, all providers are considered healthy and have zero usage. */ initializeProviderStatus() { + const oldFullStatus = this.providerStatus || {}; + this.providerStatus = {}; // Tracks health and usage for each provider instance for (const providerType in this.providerPools) { - const oldStatus = this.providerStatus[providerType] || []; + const oldStatus = oldFullStatus[providerType] || []; this.providerStatus[providerType] = []; this.roundRobinIndex[providerType] = 0; // Initialize round-robin index for each type // 只有在锁不存在时才初始化,避免在运行中被重置导致并发问题 if (!this._selectionLocks[providerType]) { this._selectionLocks[providerType] = Promise.resolve(); } - this.providerPools[providerType].forEach((providerConfig) => { - // 尝试从旧状态中恢复活跃请求计数和队列,避免重载配置时重置并发限制 - const existing = oldStatus.find(p => p.uuid === providerConfig.uuid); + + const pool = this.providerPools[providerType]; + + pool.forEach((providerConfig) => { + try { + // 尝试从旧状态中恢复活跃请求计数和队列,避免重载配置时重置并发限制 + const existing = oldStatus.find(p => p.uuid === providerConfig.uuid); - // Ensure initial health and usage stats are present in the config - providerConfig.isHealthy = providerConfig.isHealthy !== undefined ? providerConfig.isHealthy : true; - providerConfig.isDisabled = providerConfig.isDisabled !== undefined ? providerConfig.isDisabled : false; - providerConfig.lastUsed = providerConfig.lastUsed !== undefined ? providerConfig.lastUsed : null; - providerConfig.usageCount = providerConfig.usageCount !== undefined ? providerConfig.usageCount : 0; - providerConfig.errorCount = providerConfig.errorCount !== undefined ? providerConfig.errorCount : 0; - - // --- V2: 刷新监控字段 --- - providerConfig.needsRefresh = providerConfig.needsRefresh !== undefined ? providerConfig.needsRefresh : false; - providerConfig.refreshCount = providerConfig.refreshCount !== undefined ? providerConfig.refreshCount : 0; - - // 优化2: 简化 lastErrorTime 处理逻辑 - providerConfig.lastErrorTime = providerConfig.lastErrorTime instanceof Date - ? providerConfig.lastErrorTime.toISOString() - : (providerConfig.lastErrorTime || null); - - // 健康检测相关字段 - providerConfig.lastHealthCheckTime = providerConfig.lastHealthCheckTime || null; - providerConfig.lastHealthCheckModel = providerConfig.lastHealthCheckModel || null; - providerConfig.lastErrorMessage = providerConfig.lastErrorMessage || null; - providerConfig.customName = providerConfig.customName || null; + // Ensure initial health and usage stats are present in the config + providerConfig.isHealthy = providerConfig.isHealthy !== undefined ? providerConfig.isHealthy : true; + providerConfig.isDisabled = providerConfig.isDisabled !== undefined ? providerConfig.isDisabled : false; + providerConfig.lastUsed = providerConfig.lastUsed !== undefined ? providerConfig.lastUsed : null; + providerConfig.usageCount = providerConfig.usageCount !== undefined ? providerConfig.usageCount : 0; + providerConfig.errorCount = providerConfig.errorCount !== undefined ? providerConfig.errorCount : 0; + + // --- V2: 刷新监控字段 --- + providerConfig.needsRefresh = providerConfig.needsRefresh !== undefined ? providerConfig.needsRefresh : false; + providerConfig.refreshCount = providerConfig.refreshCount !== undefined ? providerConfig.refreshCount : 0; + + // 优化2: 简化 lastErrorTime 处理逻辑 + providerConfig.lastErrorTime = providerConfig.lastErrorTime instanceof Date + ? providerConfig.lastErrorTime.toISOString() + : (providerConfig.lastErrorTime || null); + + // 健康检测相关字段 + providerConfig.lastHealthCheckTime = providerConfig.lastHealthCheckTime || null; + providerConfig.lastHealthCheckModel = providerConfig.lastHealthCheckModel || null; + providerConfig.lastErrorMessage = providerConfig.lastErrorMessage || null; + providerConfig.customName = providerConfig.customName || null; - this.providerStatus[providerType].push({ - config: providerConfig, - uuid: providerConfig.uuid, // Still keep uuid at the top level for easy access - type: providerType, // 保存 providerType 引用 - state: existing ? existing.state : { - activeCount: 0, - waitingCount: 0, - queue: [] - } - }); + this.providerStatus[providerType].push({ + config: providerConfig, + uuid: providerConfig.uuid, // Still keep uuid at the top level for easy access + type: providerType, // 保存 providerType 引用 + state: existing ? existing.state : { + activeCount: 0, + waitingCount: 0, + queue: [] + } + }); + } catch (nodeError) { + logger.error(`[ProviderPoolManager] Error initializing node for ${providerType}: ${nodeError.message}`); + } }); } this._log('info', `Initialized provider statuses: ok (maxErrorCount: ${this.maxErrorCount})`); diff --git a/src/services/service-manager.js b/src/services/service-manager.js index 47f1673..ac25461 100644 --- a/src/services/service-manager.js +++ b/src/services/service-manager.js @@ -269,14 +269,21 @@ async function scanProviderDirectory(dirPath, linkedPaths, newProviders, options */ export async function initApiService(config, isReady = false) { - if (config.providerPools && Object.keys(config.providerPools).length > 0) { - providerPoolManager = new ProviderPoolManager(config.providerPools, { + // Initialize or update ProviderPoolManager + if (providerPoolManager) { + providerPoolManager.providerPools = config.providerPools || {}; + providerPoolManager.initializeProviderStatus(); + logger.info('[Initialization] ProviderPoolManager existing instance updated.'); + } else { + providerPoolManager = new ProviderPoolManager(config.providerPools || {}, { globalConfig: config, - maxErrorCount: config.MAX_ERROR_COUNT ?? 3, + maxErrorCount: config.MAX_ERROR_COUNT ?? 10, providerFallbackChain: config.providerFallbackChain || {}, }); - logger.info('[Initialization] ProviderPoolManager initialized with configured pools.'); + logger.info('[Initialization] ProviderPoolManager initialized.'); + } + if (config.providerPools && Object.keys(config.providerPools).length > 0) { if(isReady){ // --- V2: 触发系统预热 --- // 预热逻辑是异步的,不会阻塞服务器启动 @@ -289,10 +296,8 @@ export async function initApiService(config, isReady = false) { logger.error(`[Initialization] Check and refresh expiring nodes failed: ${err.message}`); }); } - - // 健康检查将在服务器完全启动后执行 } else { - logger.info('[Initialization] No provider pools configured. Using single provider mode.'); + logger.info('[Initialization] Provider pools are currently empty.'); } // Initialize all provider pool nodes at startup @@ -302,9 +307,17 @@ export async function initApiService(config, isReady = false) { let totalFailed = 0; for (const [providerType, providerConfigs] of Object.entries(config.providerPools)) { - // 验证提供商类型是否在 DEFAULT_MODEL_PROVIDERS 中 - if (config.DEFAULT_MODEL_PROVIDERS && Array.isArray(config.DEFAULT_MODEL_PROVIDERS)) { - if (!config.DEFAULT_MODEL_PROVIDERS.includes(providerType)) { + // 验证提供商类型是否有效且被包含在 DEFAULT_MODEL_PROVIDERS 中 + // 如果没设置 DEFAULT_MODEL_PROVIDERS,则允许所有已注册的类型 + const isDefaultProvider = !config.DEFAULT_MODEL_PROVIDERS || + (Array.isArray(config.DEFAULT_MODEL_PROVIDERS) && config.DEFAULT_MODEL_PROVIDERS.includes(providerType)); + + if (!isDefaultProvider) { + // 进一步检查是否是注册提供商的变体(带后缀) + const isVariantOfDefault = Array.isArray(config.DEFAULT_MODEL_PROVIDERS) && + config.DEFAULT_MODEL_PROVIDERS.some(p => providerType.startsWith(p + '-')); + + if (!isVariantOfDefault) { logger.info(`[Initialization] Skipping provider type '${providerType}' (not in DEFAULT_MODEL_PROVIDERS).`); continue; } diff --git a/src/ui-modules/config-api.js b/src/ui-modules/config-api.js index d39b028..be4c9c6 100644 --- a/src/ui-modules/config-api.js +++ b/src/ui-modules/config-api.js @@ -114,7 +114,12 @@ export async function handleUpdateConfig(req, res, currentConfig) { // Update config values in memory(含类型校验) if (newConfig.REQUIRED_API_KEY !== undefined) { - if (typeof newConfig.REQUIRED_API_KEY === 'string') currentConfig.REQUIRED_API_KEY = newConfig.REQUIRED_API_KEY; + if (typeof newConfig.REQUIRED_API_KEY === 'string') { + // 如果是脱敏后的字符串,则忽略更新,保留原值 + if (newConfig.REQUIRED_API_KEY !== '******') { + currentConfig.REQUIRED_API_KEY = newConfig.REQUIRED_API_KEY; + } + } } if (newConfig.HOST !== undefined) { if (typeof newConfig.HOST === 'string' && newConfig.HOST.length > 0) currentConfig.HOST = newConfig.HOST; @@ -401,13 +406,23 @@ export async function handleUpdateAdminPassword(req, res) { if (!password || password.trim() === '') { res.writeHead(400, { 'Content-Type': 'application/json' }); - res.end(JSON.stringify({ error: { message: 'Password cannot be empty' } })); + res.end(JSON.stringify({ + error: { + message: 'Password cannot be empty', + messageCode: 'common.passwordEmpty' + } + })); return true; } if (password.trim().length < PASSWORD.MIN_LENGTH) { res.writeHead(400, { 'Content-Type': 'application/json' }); - res.end(JSON.stringify({ error: { message: `Password must be at least ${PASSWORD.MIN_LENGTH} characters` } })); + res.end(JSON.stringify({ + error: { + message: `Password must be at least ${PASSWORD.MIN_LENGTH} characters`, + messageCode: 'common.passwordTooShort' + } + })); return true; } diff --git a/src/ui-modules/provider-api.js b/src/ui-modules/provider-api.js index 600f4d0..8a986d2 100644 --- a/src/ui-modules/provider-api.js +++ b/src/ui-modules/provider-api.js @@ -16,23 +16,27 @@ function sanitizeProviderData(provider, maskSensitive = false) { // 1. 过滤敏感字段(API Keys, Tokens 等) if (maskSensitive) { - const sensitiveKeys = [ - 'OPENAI_API_KEY', 'CLAUDE_API_KEY', 'FORWARD_API_KEY', - 'GROK_COOKIE_TOKEN', 'GROK_CF_CLEARANCE', - 'refreshToken', 'accessToken', 'clientSecret' - ]; - - sensitiveKeys.forEach(key => { - if (sanitized[key]) { + for (const key in sanitized) { + // 排除已知非敏感字段 + if (key === 'uuid' || key === 'customName' || key === 'isHealthy' || key === 'isDisabled') continue; + + const val = sanitized[key]; + if (typeof val !== 'string' || !val) continue; + + // 识别敏感字段:包含 KEY, TOKEN, SECRET, PASSWORD, CLEARANCE 等关键词 + // 同时排除包含 PATH, URL, DIR, ENDPOINT 等关键词的路径/地址字段 + const isSensitive = /API_KEY|TOKEN|SECRET|PASSWORD|CLEARANCE|ACCESS_KEY|credentials/i.test(key); + const isPath = /PATH|URL|DIR|ENDPOINT|REGION/i.test(key); + + if (isSensitive && !isPath) { // 对密钥进行脱敏显示(只保留前 4 位和后 4 位) - const val = sanitized[key]; - if (typeof val === 'string' && val.length > 10) { + if (val.length > 10) { sanitized[key] = val.substring(0, 4) + '****' + val.substring(val.length - 4); } else { sanitized[key] = '********'; } } - }); + } } // 2. 净化 customName 中的 HTML/脚本 @@ -60,6 +64,29 @@ function sanitizeProviderPools(pools, maskSensitive = false) { } return sanitized; } + +/** + * 过滤掉数据中的脱敏占位符,避免在保存时覆盖真实数据 + */ +function filterMaskedData(data) { + if (!data || typeof data !== 'object') return data; + const result = { ...data }; + + for (const key in result) { + const val = result[key]; + if (typeof val === 'string') { + // 匹配 ******** 或 XXXX****XXXX 格式 + // 如果值包含 **** 且长度符合脱敏特征,则认为它是脱敏后的回传值,应该忽略 + // 不再仅限于特定的 sensitiveKeys,而是检查所有字符串字段 + if (val === '********' || (val.includes('****') && val.length >= 10)) { + delete result[key]; + } + } + } + + return result; +} + // 使用 Promise 链式队列,确保文件操作顺序执行 let _fileLockChain = Promise.resolve(); @@ -88,24 +115,20 @@ function withFileLock(fn) { * 获取所有提供商的状态(包括支持的类型和号池组) */ export async function handleGetProviders(req, res, currentConfig, providerPoolManager) { - if (!providerPoolManager) { - res.writeHead(400, { 'Content-Type': 'application/json' }); - res.end(JSON.stringify({ error: { message: 'Provider pool manager not initialized' } })); - return true; - } - // 1. 获取支持的基础提供商类型 const registeredProviders = getRegisteredProviders(); let poolTypes = []; // 2. 从管理器获取当前所有池的状态 const providerStatus = {}; - for (const [type, providers] of Object.entries(providerPoolManager.providerStatus)) { - providerStatus[type] = providers.map(p => ({ - ...p.config, - activeRequests: p.state?.activeCount || 0, - waitingRequests: p.state?.waitingCount || 0 - })); + if (providerPoolManager) { + for (const [type, providers] of Object.entries(providerPoolManager.providerStatus)) { + providerStatus[type] = providers.map(p => ({ + ...p.config, + activeRequests: p.state?.activeCount || 0, + waitingRequests: p.state?.waitingCount || 0 + })); + } } // 3. 补全号池配置文件中的所有组 @@ -156,7 +179,7 @@ export async function handleGetProviderType(req, res, currentConfig, providerPoo res.writeHead(200, { 'Content-Type': 'application/json' }); res.end(JSON.stringify({ providerType, - providers: providers.map(p => sanitizeProviderData(p, false)), // 详情页(用于编辑)不打码 + providers: providers.map(p => sanitizeProviderData(p, true)), // 详情页也进行打码,确保即便点击显示也是脱敏数据 totalCount: providers.length, healthyCount: providers.filter(p => p.isHealthy).length })); @@ -288,7 +311,10 @@ async function _handleAddProvider(req, res, currentConfig, providerPoolManager) if (!providerPools[providerType]) { providerPools[providerType] = []; } - providerPools[providerType].push(providerConfig); + + // 过滤掉脱敏字段 + const filteredConfig = filterMaskedData(providerConfig); + providerPools[providerType].push(filteredConfig); // Save to file writeFileSync(filePath, JSON.stringify(providerPools, null, 2), 'utf-8'); @@ -321,7 +347,7 @@ async function _handleAddProvider(req, res, currentConfig, providerPoolManager) res.end(JSON.stringify({ success: true, message: 'Provider added successfully', - provider: sanitizeProviderData(providerConfig), + provider: sanitizeProviderData(providerConfig, true), providerType })); return true; @@ -380,9 +406,13 @@ async function _handleUpdateProvider(req, res, currentConfig, providerPoolManage // Update provider while preserving certain fields const existingProvider = providers[providerIndex]; + + // 过滤掉传入配置中的脱敏占位符,避免覆盖真实数据 + const filteredConfig = filterMaskedData(providerConfig); + const updatedProvider = { ...existingProvider, - ...providerConfig, + ...filteredConfig, uuid: providerUuid, // Ensure UUID doesn't change lastUsed: existingProvider.lastUsed, // Preserve usage stats usageCount: existingProvider.usageCount, @@ -415,7 +445,7 @@ async function _handleUpdateProvider(req, res, currentConfig, providerPoolManage res.end(JSON.stringify({ success: true, message: 'Provider updated successfully', - provider: sanitizeProviderData(updatedProvider) + provider: sanitizeProviderData(updatedProvider, true) })); return true; } catch (error) { diff --git a/static/app/auth.js b/static/app/auth.js index c6a5083..a9fc412 100644 --- a/static/app/auth.js +++ b/static/app/auth.js @@ -1,4 +1,5 @@ // 认证模块 - 处理token管理和API调用封装 +import { t } from './i18n.js'; /** * 认证管理类 */ @@ -122,17 +123,45 @@ class ApiClient { // 如果是401错误,重定向到登录页 if (response.status === 401) { this.handleUnauthorized(); - throw new Error('未授权访问'); + throw new Error(t('common.unauthorized')); } const contentType = response.headers.get('content-type'); + let data; if (contentType && contentType.includes('application/json')) { - return await response.json(); + data = await response.json(); } else { - return await response.text(); + data = await response.text(); } + + // 如果响应状态码不是 2xx,抛出错误 + if (!response.ok) { + let errorMessage; + if (data && typeof data === 'object') { + // 优先使用错误代码进行翻译 + const code = (data.error && data.error.messageCode) || data.messageCode; + if (code) { + const translated = t(code); + if (translated !== code) { + errorMessage = translated; + } + } + + // 如果没有翻译,使用原始错误消息 + if (!errorMessage) { + errorMessage = (data.error && data.error.message) || data.message; + } + } + + if (!errorMessage) { + errorMessage = `${t('common.requestFailed')} (${t('common.status')}: ${response.status})`; + } + throw new Error(errorMessage); + } + + return data; } catch (error) { - if (error.message === '未授权访问') { + if (error.message === t('common.unauthorized')) { // 已经在handleUnauthorized中处理了重定向 throw error; } @@ -205,17 +234,28 @@ class ApiClient { // 如果是401错误,重定向到登录页 if (response.status === 401) { this.handleUnauthorized(); - throw new Error('未授权访问'); + throw new Error(t('common.unauthorized')); } const contentType = response.headers.get('content-type'); + let data; if (contentType && contentType.includes('application/json')) { - return await response.json(); + data = await response.json(); } else { - return await response.text(); + data = await response.text(); } + + // 如果响应状态码不是 2xx,抛出错误 + if (!response.ok) { + const errorMessage = (data && typeof data === 'object' && data.error && data.error.message) + || (data && typeof data === 'object' && data.message) + || `${t('common.uploadFailed')} (${t('common.status')}: ${response.status})`; + throw new Error(errorMessage); + } + + return data; } catch (error) { - if (error.message === '未授权访问') { + if (error.message === t('common.unauthorized')) { // 已经在handleUnauthorized中处理了重定向 throw error; } diff --git a/static/app/event-handlers.js b/static/app/event-handlers.js index 5377ecb..a8f2629 100644 --- a/static/app/event-handlers.js +++ b/static/app/event-handlers.js @@ -27,7 +27,7 @@ function initEventListeners() { try { const token = window.authManager.getToken(); if (!token) { - showToast(t('common.error'), '请先登录', 'error'); + showToast(t('common.error'), t('common.loginRequired'), 'error'); return; } @@ -41,7 +41,7 @@ function initEventListeners() { }); if (response.status === 401) { - showToast(t('common.error'), '认证失败,请重新登录', 'error'); + showToast(t('common.error'), t('common.unauthorized'), 'error'); window.authManager.clearToken(); window.location.href = '/login.html'; return; @@ -79,7 +79,7 @@ function initEventListeners() { try { const token = window.authManager.getToken(); if (!token) { - showToast(t('common.error'), '请先登录', 'error'); + showToast(t('common.error'), t('common.loginRequired'), 'error'); return; } @@ -93,43 +93,32 @@ function initEventListeners() { }); if (response.status === 401) { - showToast(t('common.error'), '认证失败,请重新登录', 'error'); + showToast(t('common.error'), t('common.unauthorized'), 'error'); window.authManager.clearToken(); window.location.href = '/login.html'; return; } if (!response.ok) { - const errorData = await response.json(); - showToast(t('common.error'), errorData.error?.message || '下载失败', 'error'); + const errorData = await response.json().catch(() => ({})); + showToast(t('common.error'), errorData.error?.message || t('common.downloadFailed'), 'error'); return; } - - // 获取文件名 - const contentDisposition = response.headers.get('Content-Disposition'); - let filename = 'app.log'; - if (contentDisposition) { - const matches = /filename="?([^"]+)"?/.exec(contentDisposition); - if (matches && matches[1]) { - filename = matches[1]; - } - } - - // 下载文件 + const blob = await response.blob(); const downloadUrl = window.URL.createObjectURL(blob); const a = document.createElement('a'); a.href = downloadUrl; - a.download = filename; + a.download = `app-${new Date().toISOString().split('T')[0]}.log`; document.body.appendChild(a); a.click(); + window.URL.revokeObjectURL(downloadUrl); document.body.removeChild(a); - window.URL.revokeObjectURL(downloadUrl); - showToast(t('common.success'), '日志下载成功', 'success'); + showToast(t('common.success'), t('common.downloadSuccess'), 'success'); } catch (error) { console.error('下载日志失败:', error); - showToast(t('common.error'), '下载失败: ' + error.message, 'error'); + showToast(t('common.error'), t('common.downloadFailed') + ': ' + error.message, 'error'); } }); } diff --git a/static/app/i18n.js b/static/app/i18n.js index f4ee713..ced6336 100644 --- a/static/app/i18n.js +++ b/static/app/i18n.js @@ -832,6 +832,15 @@ const translations = { 'common.fileSize': '文件大小不能超过 5MB', 'common.uploadSuccess': '文件上传成功', 'common.uploadFailed': '文件上传失败', + 'common.requestFailed': '请求失败', + 'common.status': '状态码', + 'common.unauthorized': '未授权访问,请重新登录', + 'common.loginRequired': '请先登录以继续', + 'common.invalidSuffix': '请输入有效的后缀(仅限字母和数字)', + 'common.downloadSuccess': '下载成功', + 'common.downloadFailed': '下载失败', + 'common.passwordEmpty': '密码不能为空', + 'common.passwordTooShort': '密码长度不足', 'common.passwordUpdated': '后台密码已更新,下次登录生效', 'common.configSaved': '配置已保存', 'common.providerPoolRefreshed': '提供商池数据已刷新', @@ -1692,6 +1701,15 @@ const translations = { 'common.fileSize': 'File size cannot exceed 5MB.', 'common.uploadSuccess': 'File uploaded successfully', 'common.uploadFailed': 'File upload failed', + 'common.requestFailed': 'Request failed', + 'common.status': 'Status code', + 'common.unauthorized': 'Unauthorized access, please login again', + 'common.loginRequired': 'Please login first to continue', + 'common.invalidSuffix': 'Please enter a valid suffix (letters and numbers only)', + 'common.downloadSuccess': 'Download successful', + 'common.downloadFailed': 'Download failed', + 'common.passwordEmpty': 'Password cannot be empty', + 'common.passwordTooShort': 'Password too short', 'common.passwordUpdated': 'Admin password updated, takes effect next login', 'common.configSaved': 'Configuration saved', 'common.providerPoolRefreshed': 'Provider pool data refreshed', diff --git a/static/app/provider-manager.js b/static/app/provider-manager.js index 6238720..50ab6d5 100644 --- a/static/app/provider-manager.js +++ b/static/app/provider-manager.js @@ -375,7 +375,7 @@ function renderProviders(providers, supportedProviders = []) { async (suffix) => { const cleanSuffix = suffix.toLowerCase().replace(/[^a-z0-9]/g, ''); if (!cleanSuffix) { - showToast(t('common.warning'), '请输入有效的后缀(仅限字母和数字)', 'warning'); + showToast(t('common.warning'), t('common.invalidSuffix'), 'warning'); return; } @@ -3337,7 +3337,7 @@ function showAddProviderGroupModal(defaultBaseType = null) { const suffix = suffixInput.value.trim().toLowerCase().replace(/[^a-z0-9]/g, ''); if (!suffix) { - showToast(t('common.warning'), '请输入有效的后缀(仅限字母和数字)', 'warning'); + showToast(t('common.warning'), t('common.invalidSuffix'), 'warning'); return; } From 1ee4ca37d146dd3e8f0425bbb99dc4c09ee72ea5 Mon Sep 17 00:00:00 2001 From: hex2077 Date: Sun, 5 Apr 2026 21:46:05 +0800 Subject: [PATCH 09/10] =?UTF-8?q?feat(ui):=20=E5=A2=9E=E5=BC=BA=E6=8F=90?= =?UTF-8?q?=E4=BE=9B=E5=95=86=E5=88=B7=E6=96=B0=E7=8A=B6=E6=80=81=E6=98=BE?= =?UTF-8?q?=E7=A4=BA=E5=92=8C=E7=89=88=E6=9C=AC=E9=80=89=E6=8B=A9=E5=8A=9F?= =?UTF-8?q?=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 在提供商管理界面添加刷新状态徽章,显示“刷新中”状态 - 为更新功能添加版本选择下拉框,支持选择特定版本进行更新 - 在提供商状态中新增 needsRefresh 字段用于跟踪刷新状态 - 修复冷启动时刷新状态重置逻辑,避免持久化状态影响新会话 - 为刷新操作添加超时保护机制,防止适配器调用无限挂起 - 完善国际化翻译,添加相关状态和版本标签 --- src/providers/provider-pool-manager.js | 55 +++++++++- src/services/service-manager.js | 3 +- src/ui-modules/provider-api.js | 16 ++- src/ui-modules/update-api.js | 125 +++++++++++++---------- static/app/i18n.js | 6 ++ static/app/modal.js | 6 +- static/app/provider-manager.js | 48 +++++++-- static/components/section-dashboard.html | 5 + static/components/section-providers.css | 11 +- 9 files changed, 201 insertions(+), 74 deletions(-) diff --git a/src/providers/provider-pool-manager.js b/src/providers/provider-pool-manager.js index 99d2512..ab87f0a 100644 --- a/src/providers/provider-pool-manager.js +++ b/src/providers/provider-pool-manager.js @@ -72,6 +72,7 @@ export class ProviderPoolManager { this.refreshBufferQueues = {}; // 按 providerType 分组的缓冲队列 this.refreshBufferTimers = {}; // 按 providerType 分组的定时器 this.bufferDelay = options.globalConfig?.REFRESH_BUFFER_DELAY ?? 5000; // 默认5秒缓冲延迟 + this.refreshTaskTimeoutMs = options.globalConfig?.REFRESH_TASK_TIMEOUT_MS ?? 60000; // 默认60秒刷新超时 // 用于并发选点时的原子排序辅助(自增序列) this._selectionSequence = 0; @@ -184,6 +185,12 @@ export class ProviderPoolManager { _enqueueRefresh(providerType, providerStatus, force = false) { const uuid = providerStatus.uuid; + // 如果节点被禁用,不进行刷新 + if (providerStatus.config.isDisabled) { + this._log('debug', `Skipping refresh for disabled node ${uuid}`); + return; + } + // 如果已经在刷新中,直接返回 if (this.refreshingUuids.has(uuid)) { this._log('debug', `Node ${uuid} is already in refresh queue.`); @@ -405,16 +412,18 @@ export class ProviderPoolManager { // 调用适配器的 refreshToken 方法(内部封装了具体的刷新逻辑) if (typeof serviceAdapter.refreshToken === 'function') { const startTime = Date.now(); + let refreshOperation; if (force) { if (typeof serviceAdapter.forceRefreshToken === 'function') { - await serviceAdapter.forceRefreshToken(); + refreshOperation = serviceAdapter.forceRefreshToken(); } else { this._log('warn', `forceRefreshToken not implemented for ${providerType}, falling back to refreshToken`); - await serviceAdapter.refreshToken(); + refreshOperation = serviceAdapter.refreshToken(); } } else { - await serviceAdapter.refreshToken(); + refreshOperation = serviceAdapter.refreshToken(); } + await this._awaitRefreshWithTimeout(refreshOperation, providerType, providerStatus.uuid); const duration = Date.now() - startTime; this._log('info', `Token refresh successful for node ${providerStatus.uuid} (Duration: ${duration}ms)`); @@ -422,6 +431,8 @@ export class ProviderPoolManager { config.needsRefresh = false; config.refreshCount = 0; config.lastRefreshTime = Date.now(); // 记录最后刷新成功时间 + + this._debouncedSave(providerType); } else { throw new Error(`refreshToken method not implemented for ${providerType}`); } @@ -433,6 +444,31 @@ export class ProviderPoolManager { } } + /** + * 为刷新任务附加超时保护,避免单个适配器调用无限挂起。 + * @private + */ + async _awaitRefreshWithTimeout(refreshOperation, providerType, uuid) { + if (this.refreshTaskTimeoutMs <= 0) { + return await refreshOperation; + } + + let timeoutId = null; + const timeoutPromise = new Promise((_, reject) => { + timeoutId = setTimeout(() => { + reject(new Error(`Refresh timeout after ${this.refreshTaskTimeoutMs}ms for node ${uuid} (${providerType})`)); + }, this.refreshTaskTimeoutMs); + }); + + try { + return await Promise.race([Promise.resolve(refreshOperation), timeoutPromise]); + } finally { + if (timeoutId) { + clearTimeout(timeoutId); + } + } + } + /** * 计算节点的权重/评分,用于排序 * 分数越低,优先级越高 @@ -627,6 +663,7 @@ export class ProviderPoolManager { */ initializeProviderStatus() { const oldFullStatus = this.providerStatus || {}; + const isColdStart = Object.keys(oldFullStatus).length === 0; this.providerStatus = {}; // Tracks health and usage for each provider instance for (const providerType in this.providerPools) { const oldStatus = oldFullStatus[providerType] || []; @@ -652,8 +689,13 @@ export class ProviderPoolManager { providerConfig.errorCount = providerConfig.errorCount !== undefined ? providerConfig.errorCount : 0; // --- V2: 刷新监控字段 --- - providerConfig.needsRefresh = providerConfig.needsRefresh !== undefined ? providerConfig.needsRefresh : false; - providerConfig.refreshCount = providerConfig.refreshCount !== undefined ? providerConfig.refreshCount : 0; + const persistedNeedsRefresh = providerConfig.needsRefresh !== undefined ? providerConfig.needsRefresh : false; + const persistedRefreshCount = providerConfig.refreshCount !== undefined ? providerConfig.refreshCount : 0; + if (isColdStart && (persistedNeedsRefresh || persistedRefreshCount > 0)) { + this._log('info', `Resetting stale refresh state for provider ${providerConfig.uuid} (${providerType}) on startup.`); + } + providerConfig.needsRefresh = isColdStart ? false : persistedNeedsRefresh; + providerConfig.refreshCount = isColdStart ? 0 : persistedRefreshCount; // 优化2: 简化 lastErrorTime 处理逻辑 providerConfig.lastErrorTime = providerConfig.lastErrorTime instanceof Date @@ -680,6 +722,9 @@ export class ProviderPoolManager { logger.error(`[ProviderPoolManager] Error initializing node for ${providerType}: ${nodeError.message}`); } }); + + // 确保初始化时的默认值补全也能写盘 + this._debouncedSave(providerType); } this._log('info', `Initialized provider statuses: ok (maxErrorCount: ${this.maxErrorCount})`); } diff --git a/src/services/service-manager.js b/src/services/service-manager.js index ac25461..e574b54 100644 --- a/src/services/service-manager.js +++ b/src/services/service-manager.js @@ -563,7 +563,8 @@ export async function getProviderStatus(config, options = {}) { 'customName', 'isHealthy', 'lastErrorTime', - 'lastErrorMessage' + 'lastErrorMessage', + 'needsRefresh' ]; // identify 字段映射表 const identifyFieldMap = { diff --git a/src/ui-modules/provider-api.js b/src/ui-modules/provider-api.js index 8a986d2..d6692ad 100644 --- a/src/ui-modules/provider-api.js +++ b/src/ui-modules/provider-api.js @@ -18,7 +18,7 @@ function sanitizeProviderData(provider, maskSensitive = false) { if (maskSensitive) { for (const key in sanitized) { // 排除已知非敏感字段 - if (key === 'uuid' || key === 'customName' || key === 'isHealthy' || key === 'isDisabled') continue; + if (key === 'uuid' || key === 'customName' || key === 'isHealthy' || key === 'isDisabled' || key === 'needsRefresh') continue; const val = sanitized[key]; if (typeof val !== 'string' || !val) continue; @@ -138,8 +138,18 @@ export async function handleGetProviders(req, res, currentConfig, providerPoolMa const poolsData = JSON.parse(readFileSync(filePath, 'utf-8')); poolTypes = Object.keys(poolsData); poolTypes.forEach(type => { - if (!providerStatus[type]) { - providerStatus[type] = []; + // 如果管理器中没有该组,或者该组是空的,则从文件中补全 + if (!providerStatus[type] || providerStatus[type].length === 0) { + const fileProviders = poolsData[type] || []; + if (fileProviders.length > 0) { + providerStatus[type] = fileProviders.map(p => ({ + ...p, + activeRequests: 0, + waitingRequests: 0 + })); + } else if (!providerStatus[type]) { + providerStatus[type] = []; + } } }); } diff --git a/src/ui-modules/update-api.js b/src/ui-modules/update-api.js index ac8976d..b112dc1 100644 --- a/src/ui-modules/update-api.js +++ b/src/ui-modules/update-api.js @@ -6,6 +6,7 @@ import { exec } from 'child_process'; import { promisify } from 'util'; import { CONFIG } from '../core/config-manager.js'; import { parseProxyUrl } from '../utils/proxy-utils.js'; +import { getRequestBody } from '../utils/common.js'; const execAsync = promisify(exec); const GITHUB_REPO = 'justlovemaki/AIClient-2-API'; @@ -149,16 +150,16 @@ function compareVersions(v1, v2) { } /** - * 通过 GitHub API 获取最新版本 - * @returns {Promise} 最新版本号或 null + * 通过 GitHub API 获取最近的版本列表 + * @param {number} limit - 限制返回的版本数量 + * @returns {Promise} 版本列表 */ -async function getLatestVersionFromGitHub() { +async function getVersionsFromGitHub(limit = 10) { const candidates = buildGitHubApiCandidates(GITHUB_REPO); for (const candidate of candidates) { try { - logger.info(`[Update] Fetching latest version from GitHub API via ${candidate.name}...`); - logger.info(`[Update] Request URL: ${candidate.url}`); + logger.info(`[Update] Fetching versions from GitHub API via ${candidate.name}...`); const response = await fetchWithProxy(candidate.url, { headers: { 'Accept': 'application/vnd.github.v3+json', @@ -189,15 +190,23 @@ async function getLatestVersionFromGitHub() { } versions.sort((a, b) => compareVersions(b, a)); - logger.info(`[Update] Latest version fetched successfully via ${candidate.name}: ${versions[0]}`); - return versions[0]; + return versions.slice(0, limit); } catch (error) { - logger.warn(`[Update] Failed to fetch latest version via ${candidate.name}: ${error.message}`); + logger.warn(`[Update] Failed to fetch versions via ${candidate.name}: ${error.message}`); } } logger.warn('[Update] All GitHub API proxy attempts failed'); - return null; + return []; +} + +/** + * 通过 GitHub API 获取最新版本 + * @returns {Promise} 最新版本号或 null + */ +async function getLatestVersionFromGitHub() { + const versions = await getVersionsFromGitHub(1); + return versions.length > 0 ? versions[0] : null; } /** @@ -231,10 +240,11 @@ export async function checkForUpdates() { } let latestTag = null; + let availableVersions = []; let updateMethod = 'unknown'; if (isGitRepo) { - // Git 仓库模式:使用 git 命令 + // Git 仓库模式:使用 git命令 updateMethod = 'git'; // 获取远程 tags @@ -244,45 +254,33 @@ export async function checkForUpdates() { } catch (error) { logger.warn('[Update] Failed to fetch tags via git, falling back to GitHub API:', error.message); // 如果 git fetch 失败,回退到 GitHub API - latestTag = await getLatestVersionFromGitHub(); + availableVersions = await getVersionsFromGitHub(10); + latestTag = availableVersions.length > 0 ? availableVersions[0] : null; updateMethod = 'github_api'; } - // 如果 git fetch 成功,获取最新的 tag + // 如果 git fetch 成功,获取最新的 tag 和可用的 tags if (!latestTag && updateMethod === 'git') { - const isWindows = process.platform === 'win32'; - try { - if (isWindows) { - // Windows: 使用 git for-each-ref,这是跨平台兼容的方式 - const { stdout } = await execAsync('git for-each-ref --sort=-v:refname --format="%(refname:short)" refs/tags --count=1'); - latestTag = stdout.trim(); - } else { - // Linux/macOS: 使用 head 命令,更高效 - const { stdout } = await execAsync('git tag --sort=-v:refname | head -n 1'); - latestTag = stdout.trim(); + // 获取最近的 10 个 tag + const { stdout } = await execAsync('git tag --sort=-v:refname'); + const tags = stdout.trim().split('\n').filter(t => t); + if (tags.length > 0) { + availableVersions = tags.slice(0, 10); + latestTag = availableVersions[0]; } } catch (error) { - // 备用方案:获取所有 tags 并在 JavaScript 中排序 - try { - const { stdout } = await execAsync('git tag'); - const tags = stdout.trim().split('\n').filter(t => t); - if (tags.length > 0) { - // 按版本号排序(降序) - tags.sort((a, b) => compareVersions(b, a)); - latestTag = tags[0]; - } - } catch (e) { - logger.warn('[Update] Failed to get latest tag via git, falling back to GitHub API:', e.message); - latestTag = await getLatestVersionFromGitHub(); - updateMethod = 'github_api'; - } + logger.warn('[Update] Failed to get tags via git, falling back to GitHub API:', error.message); + availableVersions = await getVersionsFromGitHub(10); + latestTag = availableVersions.length > 0 ? availableVersions[0] : null; + updateMethod = 'github_api'; } } } else { // 非 Git 仓库模式(如 Docker 容器):使用 GitHub API updateMethod = 'github_api'; - latestTag = await getLatestVersionFromGitHub(); + availableVersions = await getVersionsFromGitHub(10); + latestTag = availableVersions.length > 0 ? availableVersions[0] : null; } if (!latestTag) { @@ -290,6 +288,7 @@ export async function checkForUpdates() { hasUpdate: false, localVersion, latestVersion: null, + availableVersions: [], updateMethod, error: 'Unable to get latest version information' }; @@ -305,6 +304,7 @@ export async function checkForUpdates() { hasUpdate, localVersion, latestVersion: latestTag, + availableVersions, updateMethod, error: null }; @@ -312,9 +312,10 @@ export async function checkForUpdates() { /** * 执行更新操作 + * @param {string} targetTag - 目标版本 tag,如果未提供则更新到最新版本 * @returns {Promise} 更新结果 */ -export async function performUpdate() { +export async function performUpdate(targetTag = null) { // 首先检查是否有更新 const updateInfo = await checkForUpdates(); @@ -322,7 +323,12 @@ export async function performUpdate() { throw new Error(updateInfo.error); } - if (!updateInfo.hasUpdate) { + // 如果未提供 targetTag,使用最新版本 + const latestTag = updateInfo.latestVersion; + const finalTag = targetTag || latestTag; + + // 如果是更新到最新版本,且当前已是最新版本 + if (!targetTag && !updateInfo.hasUpdate) { return { success: true, message: 'Already at the latest version', @@ -332,16 +338,25 @@ export async function performUpdate() { }; } - const latestTag = updateInfo.latestVersion; + // 如果指定了 tag,但与本地版本相同 + if (targetTag && (targetTag === updateInfo.localVersion || targetTag === `v${updateInfo.localVersion}`)) { + return { + success: true, + message: `Already at version ${targetTag}`, + localVersion: updateInfo.localVersion, + latestVersion: updateInfo.latestVersion, + updated: false + }; + } // 检查更新方式 - 如果是通过 GitHub API 获取的版本信息,说明不在 Git 仓库中 if (updateInfo.updateMethod === 'github_api') { // Docker/非 Git 环境,通过下载 tarball 更新 - logger.info('[Update] Running in Docker/non-Git environment, will download and extract tarball'); - return await performTarballUpdate(updateInfo.localVersion, latestTag); + logger.info(`[Update] Running in Docker/non-Git environment, will download and extract tarball for ${finalTag}`); + return await performTarballUpdate(updateInfo.localVersion, finalTag); } - logger.info(`[Update] Starting update to ${latestTag}...`); + logger.info(`[Update] Starting update to ${finalTag}...`); // 检查是否有未提交的更改 try { @@ -355,19 +370,19 @@ export async function performUpdate() { logger.warn('[Update] Failed to check git status:', error.message); } - // 执行 checkout 到最新 tag + // 执行 checkout 到目标 tag try { - logger.info(`[Update] Checking out to ${latestTag}...`); - await execAsync(`git checkout ${latestTag}`); + logger.info(`[Update] Checking out to ${finalTag}...`); + await execAsync(`git checkout ${finalTag}`); } catch (error) { logger.error('[Update] Failed to checkout:', error.message); - throw new Error('Failed to switch to new version: ' + error.message); + throw new Error(`Failed to switch to version ${finalTag}: ` + error.message); } // 更新 VERSION 文件(如果 tag 和 VERSION 文件不同步) const versionFilePath = path.join(process.cwd(), 'VERSION'); try { - const newVersion = latestTag.replace(/^v/, ''); + const newVersion = finalTag.replace(/^v/, ''); writeFileSync(versionFilePath, newVersion, 'utf-8'); logger.info(`[Update] VERSION file updated to ${newVersion}`); } catch (error) { @@ -379,7 +394,7 @@ export async function performUpdate() { try { // 确保本地版本号有 v 前缀,以匹配 git tag 格式 const localVersionTag = updateInfo.localVersion.startsWith('v') ? updateInfo.localVersion : `v${updateInfo.localVersion}`; - const { stdout: diffOutput } = await execAsync(`git diff ${localVersionTag}..${latestTag} --name-only`); + const { stdout: diffOutput } = await execAsync(`git diff ${localVersionTag}..${finalTag} --name-only`); if (diffOutput.includes('package.json') || diffOutput.includes('package-lock.json')) { logger.info('[Update] package.json changed, running npm install...'); await execAsync('npm install'); @@ -389,13 +404,14 @@ export async function performUpdate() { logger.warn('[Update] Failed to check package changes:', error.message); } - logger.info(`[Update] Update completed successfully to ${latestTag}`); + logger.info(`[Update] Update completed successfully to ${finalTag}`); return { success: true, - message: `Successfully updated to version ${latestTag}`, + message: `Successfully updated to version ${finalTag}`, localVersion: updateInfo.localVersion, latestVersion: latestTag, + targetVersion: finalTag, updated: true, updateMethod: 'git', needsRestart: needsRestart, @@ -626,7 +642,10 @@ export async function handleCheckUpdate(req, res) { */ export async function handlePerformUpdate(req, res) { try { - const updateResult = await performUpdate(); + const body = await getRequestBody(req); + const version = body?.version || null; + + const updateResult = await performUpdate(version); res.writeHead(200, { 'Content-Type': 'application/json' }); res.end(JSON.stringify(updateResult)); return true; @@ -640,4 +659,4 @@ export async function handlePerformUpdate(req, res) { })); return true; } -} \ No newline at end of file +} diff --git a/static/app/i18n.js b/static/app/i18n.js index ced6336..e51e1ad 100644 --- a/static/app/i18n.js +++ b/static/app/i18n.js @@ -47,6 +47,8 @@ const translations = { 'dashboard.update.performTitle': '更新到最新版本', 'dashboard.update.checking': '正在检查...', 'dashboard.update.upToDate': '已是最新', + 'dashboard.update.latest': '最新', + 'dashboard.update.current': '当前', 'dashboard.update.hasUpdate': '发现新版本: {version}', 'dashboard.update.updating': '正在更新...', 'dashboard.update.success': '更新成功', @@ -464,6 +466,7 @@ const translations = { 'providers.healthyProviders': '健康提供商', 'providers.status.healthy': '{healthy}/{total} 可用', 'providers.status.empty': '0/0 节点', + 'providers.status.needsRefresh': '刷新中', 'providers.stat.totalAccounts': '总账户', 'providers.stat.healthyAccounts': '健康账户', 'providers.stat.usageCount': '使用次数', @@ -914,6 +917,8 @@ const translations = { 'dashboard.update.performTitle': 'Update to latest version', 'dashboard.update.checking': 'Checking...', 'dashboard.update.upToDate': 'Up to date', + 'dashboard.update.latest': 'Latest', + 'dashboard.update.current': 'Current', 'dashboard.update.hasUpdate': 'New version available: {version}', 'dashboard.update.updating': 'Updating...', 'dashboard.update.success': 'Update successful', @@ -1332,6 +1337,7 @@ const translations = { 'providers.healthyProviders': 'Healthy Providers', 'providers.status.healthy': '{healthy}/{total} Available', 'providers.status.empty': '0/0 Nodes', + 'providers.status.needsRefresh': 'Refreshing', 'providers.stat.totalAccounts': 'Total Accounts', 'providers.stat.healthyAccounts': 'Healthy Accounts', 'providers.stat.usageCount': 'Usage Count', diff --git a/static/app/modal.js b/static/app/modal.js index 60a1cd3..16132eb 100644 --- a/static/app/modal.js +++ b/static/app/modal.js @@ -370,6 +370,7 @@ function renderProviderList(providers) { const toggleButtonText = isDisabled ? t('modal.provider.enabled') : t('modal.provider.disabled'); const toggleButtonIcon = isDisabled ? 'fas fa-play' : 'fas fa-ban'; const toggleButtonClass = isDisabled ? 'btn-success' : 'btn-warning'; + const needsRefresh = !!provider.needsRefresh; // 构建错误信息显示 let errorInfoHtml = ''; @@ -388,7 +389,10 @@ function renderProviderList(providers) {
-
${provider.customName || provider.uuid}
+
+ ${provider.customName || provider.uuid} + ${needsRefresh ? ` ${t('providers.status.needsRefresh')}` : ''} +
diff --git a/static/app/provider-manager.js b/static/app/provider-manager.js index 50ab6d5..02087ac 100644 --- a/static/app/provider-manager.js +++ b/static/app/provider-manager.js @@ -3108,6 +3108,8 @@ async function checkUpdate(silent = false) { const updateBtn = document.getElementById('performUpdateBtn'); const updateBadge = document.getElementById('updateBadge'); const latestVersionText = document.getElementById('latestVersionText'); + const versionSelectWrapper = document.getElementById('versionSelectWrapper'); + const versionSelect = document.getElementById('versionSelect'); const checkBtnIcon = checkBtn?.querySelector('i'); const checkBtnText = checkBtn?.querySelector('span'); @@ -3120,16 +3122,46 @@ async function checkUpdate(silent = false) { const data = await window.apiClient.get('/check-update'); + // 处理版本列表 + if (versionSelect && data.availableVersions && data.availableVersions.length > 0) { + versionSelect.innerHTML = ''; + data.availableVersions.forEach(version => { + const option = document.createElement('option'); + option.value = version; + option.textContent = version; + // 如果是最新版本,增加标识 + if (version === data.latestVersion) { + option.textContent += ` (${t('dashboard.update.latest') || 'Latest'})`; + } + // 如果是当前版本,增加标识 + if (version === data.localVersion || version === `v${data.localVersion}`) { + option.textContent += ` (${t('dashboard.update.current') || 'Current'})`; + option.selected = true; + } + versionSelect.appendChild(option); + }); + + if (versionSelectWrapper) versionSelectWrapper.style.display = 'block'; + if (updateBtn) { + updateBtn.style.display = 'inline-flex'; + // 如果是回退,修改按钮文字 + updateBtn.querySelector('span').textContent = t('dashboard.update.perform'); + } + } + if (data.hasUpdate) { - if (updateBtn) updateBtn.style.display = 'inline-flex'; if (updateBadge) updateBadge.style.display = 'inline-flex'; if (latestVersionText) latestVersionText.textContent = data.latestVersion; + // 如果有新版本且未选择特定版本,默认选中最新 + if (versionSelect && data.latestVersion) { + versionSelect.value = data.latestVersion; + } + if (!silent) { showToast(t('common.info'), t('dashboard.update.hasUpdate', { version: data.latestVersion }), 'info'); } } else { - if (updateBtn) updateBtn.style.display = 'none'; if (updateBadge) updateBadge.style.display = 'none'; if (!silent) { showToast(t('common.info'), t('dashboard.update.upToDate'), 'success'); @@ -3154,10 +3186,10 @@ async function checkUpdate(silent = false) { */ async function performUpdate() { const updateBtn = document.getElementById('performUpdateBtn'); - const latestVersionText = document.getElementById('latestVersionText'); - const version = latestVersionText?.textContent || ''; + const versionSelect = document.getElementById('versionSelect'); + const selectedVersion = versionSelect?.value || ''; - if (!confirm(t('dashboard.update.confirmMsg', { version }))) { + if (!confirm(t('dashboard.update.confirmMsg', { version: selectedVersion }))) { return; } @@ -3173,7 +3205,7 @@ async function performUpdate() { showToast(t('common.info'), t('dashboard.update.updating'), 'info'); - const data = await window.apiClient.post('/update'); + const data = await window.apiClient.post('/update', { version: selectedVersion }); if (data.success) { if (data.updated) { @@ -3183,8 +3215,8 @@ async function performUpdate() { // 自动重启服务 await restartServiceAfterUpdate(); } else { - // 已是最新版本 - showToast(t('common.info'), t('dashboard.update.upToDate'), 'info'); + // 已是目标版本 + showToast(t('common.info'), data.message || t('dashboard.update.upToDate'), 'info'); } } } catch (error) { diff --git a/static/components/section-dashboard.html b/static/components/section-dashboard.html index 83a1b93..67c2253 100644 --- a/static/components/section-dashboard.html +++ b/static/components/section-dashboard.html @@ -41,6 +41,11 @@

系统信息

+ diff --git a/static/components/section-providers.css b/static/components/section-providers.css index f8304de..f30523b 100644 --- a/static/components/section-providers.css +++ b/static/components/section-providers.css @@ -198,9 +198,14 @@ letter-spacing: 0.05em; } -.provider-badge.official { background: var(--info-bg); color: var(--info-text); } -.provider-badge.oauth { background: var(--success-bg); color: var(--success-text); } -.provider-badge.responses { background: var(--warning-bg); color: var(--warning-text); } +.badge-warning { + background: var(--warning-bg); + color: var(--warning-text); + padding: 0.25rem 0.5rem; + border-radius: 4px; + font-size: 0.75rem; + font-weight: 600; +} .routing-card-content { padding: 1.5rem; From 1d4710f92d0158850469be84f0de2433333e0574 Mon Sep 17 00:00:00 2001 From: hex2077 Date: Sun, 5 Apr 2026 21:46:32 +0800 Subject: [PATCH 10/10] =?UTF-8?q?chore:=20=E6=9B=B4=E6=96=B0=E7=89=88?= =?UTF-8?q?=E6=9C=AC=E5=8F=B7=E8=87=B32.12.6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION b/VERSION index dcb27a7..e464374 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -2.12.5 +2.12.6
From 8f4de503c600956edf6de55726f9e91d4e4f7057 Mon Sep 17 00:00:00 2001 From: hex2077 Date: Sat, 4 Apr 2026 22:50:11 +0800 Subject: [PATCH 03/10] =?UTF-8?q?=E5=85=88=E5=9B=9E=E6=BB=9A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION b/VERSION index d463c35..56beced 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -2.12.2.2 +2.12.4 From 7c0f26fca4f61bccba9cc4b04efd28256b870f3b Mon Sep 17 00:00:00 2001 From: hex2077 Date: Sun, 5 Apr 2026 08:12:02 +0800 Subject: [PATCH 04/10] =?UTF-8?q?docs:=20=E5=9C=A8README=E4=B8=AD=E6=B7=BB?= =?UTF-8?q?=E5=8A=A0LingtrueAPI=E8=B5=9E=E5=8A=A9=E5=95=86=E4=BF=A1?= =?UTF-8?q?=E6=81=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 在README.md、README-ZH.md、README-JA.md的赞助商部分添加LingtrueAPI条目 - 添加赞助商Logo图片 static/lingtrueapi.png - 描述LingtrueAPI服务内容及为用户提供的专属优惠 --- README-JA.md | 10 ++++++++++ README-ZH.md | 10 ++++++++++ README.md | 10 ++++++++++ static/lingtrueapi.png | Bin 0 -> 201094 bytes 4 files changed, 30 insertions(+) create mode 100644 static/lingtrueapi.png diff --git a/README-JA.md b/README-JA.md index 227c362..529829a 100644 --- a/README-JA.md +++ b/README-JA.md @@ -47,6 +47,16 @@ AICodeMirror の本プロジェクトへのスポンサーシップに感謝します!AICodeMirror は、Claude Code / Codex / Gemini CLI 向けに公式の高安定性リレーサービスを提供しており、企業レベルの同時実行性、迅速な請求書発行、24時間365日の専用技術サポートを備えています。Claude Code / Codex / Gemini の公式チャンネルを、元の価格の 38% / 2% / 9% で利用でき、チャージ時にはさらなる割引もあります!AICodeMirror は AIClient-2-API ユーザーに特別な特典を提供しています:このリンクから登録すると、初回チャージが 20% オフになり、法人のお客様は最大 25% オフになります! + + + + LingtrueAPI Sponsor + + + + LingtrueAPIによる本プロジェクトへのスポンサーに感謝します!LingtrueAPIは世界的な大規模言語モデルAPI中継プラットフォームであり、Claude opus 4.6、GPT 5.4、Gemini 3.1 proなど各種モデルのAPI呼び出しサービスを提供しています。低コスト、高安定性で世界中のAI機能に接続し、生産性を最大化することを目指しています。LingtrueAPIは本ソフトウェアユーザー向けに特別優遇を提供しています。このリンクから登録し、初回チャージ時に「LingtrueAPI」のクーポンコードを入力すると、10%オフで利用できます。 + + Sponsor Contact diff --git a/README-ZH.md b/README-ZH.md index e7e2ddf..048bf2f 100644 --- a/README-ZH.md +++ b/README-ZH.md @@ -46,6 +46,16 @@ 感谢 AICodeMirror 赞助本项目!AICodeMirror 为 Claude Code / Codex / Gemini CLI 提供官方高稳定性中转服务,具备企业级并发能力、快速开票和 7/24 专属技术支持。Claude Code / Codex / Gemini 官方渠道价格仅为原价的 38% / 2% / 9%,充值还有额外优惠!AICodeMirror 为 AIClient-2-API 用户提供专属福利:通过此链接注册即可享受首充 8折(20% off) 优惠,企业客户最高可享 75折(25% off)! + + + + LingtrueAPI Sponsor + + + + 感谢 LingtrueAPI 对本项目的赞助!LingtrueAPI 是一家全球大模型API中转服务平台,提供Claude opus 4.6、GPT 5.4、Gemini 3.1 pro等多种模型API调用服务,致力于让用户以低成本、高稳定性链接全球AI能力,最大化生产效率。LingtrueAPI为本软件用户提供了特别优惠:通过此链接注册并在首次充值时输入 LingtrueAPI 优惠码即可享受 9折优惠。 + + Sponsor Contact diff --git a/README.md b/README.md index 8c0895e..3aef936 100644 --- a/README.md +++ b/README.md @@ -47,6 +47,16 @@ Thanks to AICodeMirror for sponsoring this project! AICodeMirror provides official high-stability relay services for Claude Code / Codex / Gemini CLI, with enterprise-grade concurrency, fast invoicing, and 24/7 dedicated technical support. Claude Code / Codex / Gemini official channels at 38% / 2% / 9% of original price, with extra discounts on top-ups! AICodeMirror offers special benefits for AIClient-2-API users: register via this link to enjoy 20% off your first top-up, and enterprise customers can get up to 25% off! + + + + LingtrueAPI Sponsor + + + + Thanks to LingtrueAPI for its sponsorship of this project! LingtrueAPI is a global large-model API intermediary service platform that offers API calling services for various models such as Claude opus 4.6, GPT 5.4, and Gemini 3.1 pro. It is committed to enabling users to connect to global AI capabilities at low cost and with high stability, maximizing production efficiency. LingtrueAPI provides special discounts for users of this software: register using this link and enter the LingtrueAPI promo code when making the first recharge to enjoy a 10% discount. + + Sponsor Contact diff --git a/static/lingtrueapi.png b/static/lingtrueapi.png new file mode 100644 index 0000000000000000000000000000000000000000..0829a7ca7db3f14684c7395cb5f687f05428a10c GIT binary patch literal 201094 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 z�~Hi*4$g-8;A7qKhxUamO5sp!OIG)qo^O)+*;Xc*b#B6CVQ7V{SgTen*R%CyIjb zdV5S8fomUgCMH?|TWafs&00rn(fCZMo}XI;|3j&*io=%88?i;tCZnf0=Bt1CRs8RN z`9JCTQ7G1rYv;%QUM zagIK8Tc!2f*zO$&T3Z#;7t&`06!M{M1GFS>Y0cZ&whhPZ+=;8(<9ODxqi|_w9LLIL zQm`FU-^Fx~c$^p{6EBmLl9?xI(Ew3p448&^NFxv)($bp39?}Q|hIHfURRUTKfUA$j zW3Ij$8;gKlkgiooA99^EQ<-8!S|mY-X>Tt01|>&tTB#q>GiYH#QuSpjm&~c_W&xRb zGN+aeptdDDr6iLNlA7c)UA57vfxcbTCst7}j{&k%Tr4mA%m*~7W{A`Tuh#-iVvd(0 z3V+MWa%jVdWFk#xVt7q;s#tG68R9KBM1t(+H**BSixgM8YL97yqq#51 ziQ{34q>}{F<-`GgY=ay|O>uzj|3S?h4g1;%-}NH5VBt~(nSoOd?PU$++P&OIAP ztyq~}1nb>djRB1qi6eT7!I@{AhR0uf4X(ZF3S4{5Re1c>SK#s2T$ym4(rd500@q%7 zS&GfoiqDl-T#Bo&x)P_Hv<974JH7O2xXIt})UX;dHOlv?5p^RknVQ69mt2gi?C;9U zaka|0`pQehXSgiuu5sU7b}_EJ>=M~rfhRuUIvlH)&Q>uT$5jy|K@P`sB|ngKS_|j& za-)qLZ_1ps<^;ugo#K3U8V^@qdJ!&D|9IS7mip~{jfZu(uwzp^~spx8qfvR-a;P&O|%Ofy?hzYI`dRK`AJW}o8ELIKK^Hag1`Bz zui>^^KaC%M!|T<)bFpmc6!dr(g32yZJ6o;1sZiBvr(QmG?%0`hmeqlI4$oz(e$tGM zjj1gm(ax8MgLEOQQjqEf9eyEi>m_{k(W~&vSH2v#-STOC?z6YzZEt-uuDbG4#cCWo z^g_Jhf$!mg`@V|@@4E-<@4FWp?z;~UK5!p4Ja8`_)aL2>`@bjoJ-Gkgd&GZFFWQ^1 zWPA)K>HZnlJWdYFRs1cRHq^Y ztXjD;jm0}YdmBFX(Lcp=pY;qZnHb2hSbzUL+Ed(xtFO8ofB50wQ$KzRuXy=O;f!zi6CR)LiK{g?`I&IF=Adh@x=i!WW$^rG*%g|TtiM`w*LBxjhvSbs4xuPien8b{ z*v})?Yfj!AOV`tgYNy*frVZ7LFTMcp{l%ZhSO5Hr_`m-65Ao8Mya*>8b2N4;2AkI3 z2Y-uiyEc3L&ETj_OLt45%nBje?SQt%d0XS7U5FN1iUndIN>{Pa)%6uzK2k_*|j2$&=KstM!b$O5^h? zjmsJupO2$ft%4xt@^V~z_2uxI z>AGvKNc7cuPNaFm{iSt+*9ey@z4Ee4arR>$hpEX4FaSaKqJ0~SX|{$0pnCY%eZ47o zqB1>xYAK$#<|I5}>2f?~=WZOU4{=v)*@Wf#fOz@NU09|MQCDd5a+yAuT&}tF_^n&< zIIV52Te1XCTX{6D&}QI?@-rpp-Y}$SpJb+7x4psk708^g;+yoLi-3mI+``;>mDIFR z@$;p7)6bV@Uu1{c|Gw1aaJD6fHB3@dNvzu_PJe!w+&Tc z(?-fK9?EZjhBMix^-(WEr4~d%{>)o90LuXh*TcU1^-r;_>-&~5=63bjy(W7zNL9}v z+necr=_~(LN{$vrwb^ZVe5m-Ne^jv|nZ}`C{Jk-#rHJoUle$hMM~tiT$t(}5 zzhyv#MTYZ51RxafqAluP@!#p_6~tEAmD;#E{pxGb){7yufFP;7Oy!VOiXFyZnB(wfb+1z=@?YQ%EpH29J z>_30|XYmEWvMM#5VB0>dGc5nY?YAlat=ho3O?47|N5);Bm)|ekF1gds;;uVyR~>Fo z{$1azv_S1>14>QRStj`2gXT0b@WM7|oc#DrZ@|r;_$Y4s%qMZn%^%0DpZ+9nz4;Tk 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%0AP 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 J$s?0j{|~+io@@XB literal 0 HcmV?d00001 From 47d92a41cb35792533e437301b59344a2ee3badb Mon Sep 17 00:00:00 2001 From: hex2077 Date: Sun, 5 Apr 2026 15:20:24 +0800 Subject: [PATCH 05/10] =?UTF-8?q?docs:=20=E6=B7=BB=E5=8A=A0=20Poixe=20AI?= =?UTF-8?q?=20=E8=B5=9E=E5=8A=A9=E5=95=86=E4=BF=A1=E6=81=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 在 README 及其翻译版本中新增 Poixe AI 作为赞助商,并添加其徽标图片。此举旨在感谢赞助商支持并为用户提供更多 API 服务选择。 --- README-JA.md | 10 ++++++++++ README-ZH.md | 10 ++++++++++ README.md | 10 ++++++++++ static/poixeai.png | Bin 0 -> 39559 bytes 4 files changed, 30 insertions(+) create mode 100644 static/poixeai.png diff --git a/README-JA.md b/README-JA.md index 529829a..d251d06 100644 --- a/README-JA.md +++ b/README-JA.md @@ -57,6 +57,16 @@ LingtrueAPIによる本プロジェクトへのスポンサーに感謝します!LingtrueAPIは世界的な大規模言語モデルAPI中継プラットフォームであり、Claude opus 4.6、GPT 5.4、Gemini 3.1 proなど各種モデルのAPI呼び出しサービスを提供しています。低コスト、高安定性で世界中のAI機能に接続し、生産性を最大化することを目指しています。LingtrueAPIは本ソフトウェアユーザー向けに特別優遇を提供しています。このリンクから登録し、初回チャージ時に「LingtrueAPI」のクーポンコードを入力すると、10%オフで利用できます。 + + + + Poixe AI Sponsor + + + + Poixe AI は信頼性の高い LLM API サービスを提供しています。プラットフォームが提供する API エンドポイントを活用して、AI 製品をシームレスに構築できます。また、AI API リソースをプラットフォームに提供するベンダーになり、収益を得ることも可能です。AIClient-2-API 専用リンクから登録すると、初回チャージ時に $5 USD のボーナスを受け取れます。 + + Sponsor Contact diff --git a/README-ZH.md b/README-ZH.md index 048bf2f..d4be818 100644 --- a/README-ZH.md +++ b/README-ZH.md @@ -56,6 +56,16 @@ 感谢 LingtrueAPI 对本项目的赞助!LingtrueAPI 是一家全球大模型API中转服务平台,提供Claude opus 4.6、GPT 5.4、Gemini 3.1 pro等多种模型API调用服务,致力于让用户以低成本、高稳定性链接全球AI能力,最大化生产效率。LingtrueAPI为本软件用户提供了特别优惠:通过此链接注册并在首次充值时输入 LingtrueAPI 优惠码即可享受 9折优惠。 + + + + Poixe AI Sponsor + + + + Poixe AI 提供可靠的 AI 模型接口服务,您可以使用平台提供的 LLM API 接口轻松构建 AI 产品,同时也可以成为供应商,为平台提供大模型资源以赚取收益。通过 AIClient-2-API 专属链接注册,充值额外赠送 $5 美金。 + + Sponsor Contact diff --git a/README.md b/README.md index 3aef936..8629d9c 100644 --- a/README.md +++ b/README.md @@ -57,6 +57,16 @@ Thanks to LingtrueAPI for its sponsorship of this project! LingtrueAPI is a global large-model API intermediary service platform that offers API calling services for various models such as Claude opus 4.6, GPT 5.4, and Gemini 3.1 pro. It is committed to enabling users to connect to global AI capabilities at low cost and with high stability, maximizing production efficiency. LingtrueAPI provides special discounts for users of this software: register using this link and enter the LingtrueAPI promo code when making the first recharge to enjoy a 10% discount. + + + + Poixe AI Sponsor + + + + Poixe AI provides reliable LLM API services. You can leverage the platform's API endpoints to seamlessly build AI-powered products. Additionally, you can become a vendor by providing AI API resources to the platform and earn revenue. Register through the exclusive AIClient-2-API referral link and receive a bonus of $5 USD on your first top-up. + + Sponsor Contact diff --git a/static/poixeai.png b/static/poixeai.png new file mode 100644 index 0000000000000000000000000000000000000000..aa89cb06c92bd6ad9d038d674b3df5b28fedaba0 GIT binary patch literal 39559 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 literal 0 HcmV?d00001 From 02fdc39571deb520c3fcceebf1acc0a18f50ace3 Mon Sep 17 00:00:00 2001 From: hex2077 Date: Sun, 5 Apr 2026 15:20:48 +0800 Subject: [PATCH 06/10] =?UTF-8?q?Reapply=20"feat:=20=E6=94=AF=E6=8C=81?= =?UTF-8?q?=E5=8A=A8=E6=80=81=E6=8F=90=E4=BE=9B=E5=95=86=E9=85=8D=E7=BD=AE?= =?UTF-8?q?=E7=BB=84=E5=92=8C=E5=89=8D=E7=BC=80=E5=8C=B9=E9=85=8D=E6=9C=BA?= =?UTF-8?q?=E5=88=B6"?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This reverts commit b8a983a3cd9776d7a841577b1405367308130ada. --- package.json | 2 +- pnpm-lock.yaml | 22 +- src/core/config-manager.js | 15 + src/handlers/request-handler.js | 8 +- src/providers/adapter.js | 33 +- src/providers/claude/claude-core.js | 4 +- src/providers/claude/claude-kiro.js | 14 +- src/providers/forward/forward-core.js | 4 +- src/providers/gemini/antigravity-core.js | 28 +- src/providers/gemini/gemini-core.js | 19 +- src/providers/grok/grok-core.js | 26 +- src/providers/openai/codex-core.js | 12 +- src/providers/openai/openai-core.js | 4 +- src/providers/openai/openai-responses-core.js | 4 +- src/providers/openai/qwen-core.js | 14 +- src/providers/provider-models.js | 13 +- src/providers/provider-pool-manager.js | 32 +- src/services/service-manager.js | 16 +- src/services/ui-manager.js | 4 +- src/ui-modules/provider-api.js | 162 +++++++--- src/utils/common.js | 2 +- src/utils/proxy-utils.js | 20 +- static/app/app.js | 4 +- static/app/event-handlers.js | 12 + static/app/i18n.js | 13 + static/app/modal.js | 37 +-- static/app/models-manager.js | 38 ++- static/app/provider-manager.js | 303 ++++++++++++++++-- static/app/routing-examples.js | 42 ++- static/app/utils.js | 94 ++++-- static/components/section-providers.css | 22 ++ static/components/section-providers.html | 3 + 32 files changed, 803 insertions(+), 223 deletions(-) diff --git a/package.json b/package.json index a967544..5b1b23b 100644 --- a/package.json +++ b/package.json @@ -3,7 +3,7 @@ "dependencies": { "@anthropic-ai/tokenizer": "^0.0.4", "adm-zip": "^0.5.16", - "axios": "^1.10.0", + "axios": "^1.14.0", "deepmerge": "^4.3.1", "dotenv": "^16.4.5", "google-auth-library": "^10.1.0", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 8570703..3da5f07 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -15,8 +15,8 @@ importers: specifier: ^0.5.16 version: 0.5.16 axios: - specifier: ^1.10.0 - version: 1.13.4 + specifier: ^1.14.0 + version: 1.14.0 deepmerge: specifier: ^4.3.1 version: 4.3.1 @@ -883,8 +883,8 @@ packages: asynckit@0.4.0: resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==} - axios@1.13.4: - resolution: {integrity: sha512-1wVkUaAO6WyaYtCkcYCOx12ZgpGf9Zif+qXa4n+oYzK558YryKqiL6UWwd5DqiH3VRW0GYhTZQ/vlgJrCoNQlg==} + axios@1.14.0: + resolution: {integrity: sha512-3Y8yrqLSwjuzpXuZ0oIYZ/XGgLwUIBU3uLvbcpb0pidD9ctpShJd43KSlEEkVQg6DS0G9NKyzOvBfUtDKEyHvQ==} babel-jest@29.7.0: resolution: {integrity: sha512-BrvGY3xZSwEcCzKvKsCi2GgHqDqsYkOP4/by5xCgIwGXQxIEh+8ew3gmrE1y7XRR6LHZIj6yLYnUi/mm2KXKBg==} @@ -1308,11 +1308,12 @@ packages: glob@10.5.0: resolution: {integrity: sha512-DfXN8DfhJ7NH3Oe7cFmu3NCu1wKbkReJ8TorzSAFbSKrlNaQSKfIzqYqVY8zlbs2NLBbWpRiU52GX2PbaBVNkg==} + deprecated: Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me hasBin: true glob@7.2.3: resolution: {integrity: sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==} - deprecated: Glob versions prior to v9 are no longer supported + deprecated: Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me google-auth-library@10.5.0: resolution: {integrity: sha512-7ABviyMOlX5hIVD60YOfHw4/CxOfBhyduaYB+wbFWCWoni4N7SLcV46hrVRktuBbZjFC9ONyqamZITN7q3n32w==} @@ -1834,8 +1835,9 @@ packages: resolution: {integrity: sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==} engines: {node: '>= 6'} - proxy-from-env@1.1.0: - resolution: {integrity: sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==} + proxy-from-env@2.1.0: + resolution: {integrity: sha512-cJ+oHTW1VAEa8cJslgmUZrc+sjRKgAKl3Zyse6+PV38hZe/V6Z14TbCuXcan9F9ghlz4QrFr2c92TNF82UkYHA==} + engines: {node: '>=10'} pure-rand@6.1.0: resolution: {integrity: sha512-bVWawvoZoBYpp6yIoQtQXHZjmz35RSVHnUOTefl8Vcjr8snTPY1wnpSPMWekcFwbxI6gtmT7rSYPFvz71ldiOA==} @@ -3269,11 +3271,11 @@ snapshots: asynckit@0.4.0: {} - axios@1.13.4: + axios@1.14.0: dependencies: follow-redirects: 1.15.11 form-data: 4.0.5 - proxy-from-env: 1.1.0 + proxy-from-env: 2.1.0 transitivePeerDependencies: - debug @@ -4441,7 +4443,7 @@ snapshots: kleur: 3.0.3 sisteransi: 1.0.5 - proxy-from-env@1.1.0: {} + proxy-from-env@2.1.0: {} pure-rand@6.1.0: {} diff --git a/src/core/config-manager.js b/src/core/config-manager.js index 364dd99..0af5b88 100644 --- a/src/core/config-manager.js +++ b/src/core/config-manager.js @@ -76,6 +76,11 @@ export async function initializeConfig(args = process.argv.slice(2), configFileP LOGIN_MIN_INTERVAL: 5000, // 两次尝试之间的最小间隔(毫秒),默认1秒 PROVIDER_POOLS_FILE_PATH: null, // 新增号池配置文件路径 MAX_ERROR_COUNT: 10, // 提供商最大错误次数 + SCHEDULED_HEALTH_CHECK: { + enabled: false, + interval: 600000, + startupRun: false + }, providerFallbackChain: {}, // 跨类型 Fallback 链配置 LOG_ENABLED: true, LOG_OUTPUT_MODE: "all", @@ -126,6 +131,8 @@ export async function initializeConfig(args = process.argv.slice(2), configFileP { flag: '--login-max-attempts', configKey: 'LOGIN_MAX_ATTEMPTS', type: 'int' }, { flag: '--login-lockout-duration', configKey: 'LOGIN_LOCKOUT_DURATION', type: 'int' }, { flag: '--login-min-interval', configKey: 'LOGIN_MIN_INTERVAL', type: 'int' }, + { flag: '--scheduled-health-check-enabled', configKey: 'SCHEDULE_HEALTH_CHECK_ENABLED', type: 'bool' }, + { flag: '--scheduled-health-check-interval', configKey: 'SCHEDULE_HEALTH_CHECK_INTERVAL', type: 'int' }, ]; // Parse command-line arguments using definitions @@ -160,6 +167,14 @@ export async function initializeConfig(args = process.argv.slice(2), configFileP } } + // 合并定时健康检查的 CLI 配置 + if (currentConfig.SCHEDULE_HEALTH_CHECK_ENABLED !== undefined) { + currentConfig.SCHEDULED_HEALTH_CHECK.enabled = currentConfig.SCHEDULE_HEALTH_CHECK_ENABLED; + } + if (currentConfig.SCHEDULE_HEALTH_CHECK_INTERVAL !== undefined) { + currentConfig.SCHEDULED_HEALTH_CHECK.interval = currentConfig.SCHEDULE_HEALTH_CHECK_INTERVAL; + } + normalizeConfiguredProviders(currentConfig); if (!currentConfig.SYSTEM_PROMPT_FILE_PATH) { diff --git a/src/handlers/request-handler.js b/src/handlers/request-handler.js index ebc84da..57e830b 100644 --- a/src/handlers/request-handler.js +++ b/src/handlers/request-handler.js @@ -6,7 +6,7 @@ import { handleAPIRequests } from '../services/api-manager.js'; import { getApiService, getProviderStatus } from '../services/service-manager.js'; import { getProviderPoolManager } from '../services/service-manager.js'; import { MODEL_PROVIDER } from '../utils/common.js'; -import { getRegisteredProviders } from '../providers/adapter.js'; +import { getRegisteredProviders, isRegisteredProvider } from '../providers/adapter.js'; import { countTokensAnthropic } from '../utils/token-utils.js'; import { PROMPT_LOG_FILENAME } from '../core/config-manager.js'; import { getPluginManager } from '../core/plugin-manager.js'; @@ -152,8 +152,7 @@ export function createRequestHandler(config, providerPoolManager) { // Allow overriding MODEL_PROVIDER via request header const modelProviderHeader = req.headers['model-provider']; if (modelProviderHeader) { - const registeredProviders = getRegisteredProviders(); - if (registeredProviders.includes(modelProviderHeader)) { + if (isRegisteredProvider(modelProviderHeader)) { currentConfig.MODEL_PROVIDER = modelProviderHeader; logger.info(`[Config] MODEL_PROVIDER overridden by header to: ${currentConfig.MODEL_PROVIDER}`); } else { @@ -169,8 +168,7 @@ export function createRequestHandler(config, providerPoolManager) { if (pathSegments.length > 0) { const firstSegment = pathSegments[0]; - const registeredProviders = getRegisteredProviders(); - const isValidProvider = registeredProviders.includes(firstSegment); + const isValidProvider = isRegisteredProvider(firstSegment); const isAutoMode = firstSegment === MODEL_PROVIDER.AUTO; if (firstSegment && (isValidProvider || isAutoMode)) { diff --git a/src/providers/adapter.js b/src/providers/adapter.js index bfaceac..7f9436c 100644 --- a/src/providers/adapter.js +++ b/src/providers/adapter.js @@ -704,6 +704,26 @@ registerAdapter(MODEL_PROVIDER.GROK_CUSTOM, GrokApiServiceAdapter); // 用于存储服务适配器单例的映射 export const serviceInstances = {}; +/** + * 检查提供商是否已注册(支持前缀匹配) + * @param {string} provider - 提供商名称 + * @returns {boolean} - 是否有效 + */ +export function isRegisteredProvider(provider) { + if (adapterRegistry.has(provider)) { + return true; + } + + // 检查前缀 (例如 openai-custom-1 -> openai-custom) + for (const key of adapterRegistry.keys()) { + if (provider.startsWith(key + '-')) { + return true; + } + } + + return false; +} + // 服务适配器工厂 export function getServiceAdapter(config) { const customNameDisplay = config.customName ? ` (${config.customName})` : ''; @@ -712,7 +732,18 @@ export function getServiceAdapter(config) { const providerKey = config.uuid ? provider + config.uuid : provider; if (!serviceInstances[providerKey]) { - const AdapterClass = adapterRegistry.get(provider); + let AdapterClass = adapterRegistry.get(provider); + + // 如果没找到精确匹配,尝试通过前缀查找 (例如 openai-custom-1 -> openai-custom) + if (!AdapterClass) { + for (const [key, value] of adapterRegistry.entries()) { + if (provider === key || provider.startsWith(key + '-')) { + AdapterClass = value; + break; + } + } + } + if (AdapterClass) { serviceInstances[providerKey] = new AdapterClass(config); } else { diff --git a/src/providers/claude/claude-core.js b/src/providers/claude/claude-core.js index e95e3b5..89f5e22 100644 --- a/src/providers/claude/claude-core.js +++ b/src/providers/claude/claude-core.js @@ -63,13 +63,13 @@ export class ClaudeApiService { } // 配置自定义代理 - configureAxiosProxy(axiosConfig, this.config, MODEL_PROVIDER.CLAUDE_CUSTOM); + configureAxiosProxy(axiosConfig, this.config, this.config.MODEL_PROVIDER || MODEL_PROVIDER.CLAUDE_CUSTOM); return axios.create(axiosConfig); } _applySidecar(axiosConfig) { - return configureTLSSidecar(axiosConfig, this.config, MODEL_PROVIDER.CLAUDE_CUSTOM, this.baseUrl); + return configureTLSSidecar(axiosConfig, this.config, this.config.MODEL_PROVIDER || MODEL_PROVIDER.CLAUDE_CUSTOM, this.baseUrl); } /** diff --git a/src/providers/claude/claude-kiro.js b/src/providers/claude/claude-kiro.js index 7c185e3..cd7fa0d 100644 --- a/src/providers/claude/claude-kiro.js +++ b/src/providers/claude/claude-kiro.js @@ -494,7 +494,7 @@ export class KiroApiService { } // 配置自定义代理 - configureAxiosProxy(axiosConfig, this.config, 'claude-kiro-oauth'); + configureAxiosProxy(axiosConfig, this.config, this.config.MODEL_PROVIDER || MODEL_PROVIDER.KIRO_API); this.axiosInstance = axios.create(axiosConfig); @@ -505,7 +505,7 @@ export class KiroApiService { } _applySidecar(axiosConfig) { - return configureTLSSidecar(axiosConfig, this.config, MODEL_PROVIDER.KIRO_API); + return configureTLSSidecar(axiosConfig, this.config, this.config.MODEL_PROVIDER || MODEL_PROVIDER.KIRO_API); } /** @@ -744,7 +744,7 @@ async saveCredentialsToFile(filePath, newData) { // 刷新成功,重置 PoolManager 中的刷新状态并标记为健康 const poolManager = getProviderPoolManager(); if (poolManager && this.uuid) { - poolManager.resetProviderRefreshStatus(MODEL_PROVIDER.KIRO_API, this.uuid); + poolManager.resetProviderRefreshStatus(this.config.MODEL_PROVIDER || MODEL_PROVIDER.KIRO_API, this.uuid); } } else { throw new Error('Invalid refresh response: Missing accessToken'); @@ -1627,7 +1627,7 @@ async saveCredentialsToFile(filePath, newData) { _refreshUuid() { const poolManager = getProviderPoolManager(); if (poolManager && this.uuid) { - const newUuid = poolManager.refreshProviderUuid(MODEL_PROVIDER.KIRO_API, { + const newUuid = poolManager.refreshProviderUuid(this.config.MODEL_PROVIDER || MODEL_PROVIDER.KIRO_API, { uuid: this.uuid }); return newUuid; @@ -1649,7 +1649,7 @@ async saveCredentialsToFile(filePath, newData) { if (poolManager && this.uuid) { logger.info(`[Kiro] Marking credential ${this.uuid} as needs refresh. Reason: ${reason}`); // 使用新的 markProviderNeedRefresh 方法代替 markProviderUnhealthyImmediately - poolManager.markProviderNeedRefresh(MODEL_PROVIDER.KIRO_API, { + poolManager.markProviderNeedRefresh(this.config.MODEL_PROVIDER || MODEL_PROVIDER.KIRO_API, { uuid: this.uuid }); // Attach marker to error object to prevent duplicate marking in upper layers @@ -1674,7 +1674,7 @@ async saveCredentialsToFile(filePath, newData) { const poolManager = getProviderPoolManager(); if (poolManager && this.uuid) { logger.info(`[Kiro] Marking credential ${this.uuid} as unhealthy. Reason: ${reason}`); - poolManager.markProviderUnhealthyImmediately(MODEL_PROVIDER.KIRO_API, { + poolManager.markProviderUnhealthyImmediately(this.config.MODEL_PROVIDER || MODEL_PROVIDER.KIRO_API, { uuid: this.uuid }, reason); // Attach marker to error object to prevent duplicate marking in upper layers @@ -1701,7 +1701,7 @@ async saveCredentialsToFile(filePath, newData) { const poolManager = getProviderPoolManager(); if (poolManager && this.uuid) { logger.info(`[Kiro] Marking credential ${this.uuid} as unhealthy with recovery time. Reason: ${reason}, Recovery: ${recoveryTime?.toISOString()}`); - poolManager.markProviderUnhealthyWithRecoveryTime(MODEL_PROVIDER.KIRO_API, { + poolManager.markProviderUnhealthyWithRecoveryTime(this.config.MODEL_PROVIDER || MODEL_PROVIDER.KIRO_API, { uuid: this.uuid }, reason, recoveryTime); // Attach marker to error object to prevent duplicate marking in upper layers diff --git a/src/providers/forward/forward-core.js b/src/providers/forward/forward-core.js index 8730ac3..260dcd2 100644 --- a/src/providers/forward/forward-core.js +++ b/src/providers/forward/forward-core.js @@ -56,13 +56,13 @@ export class ForwardApiService { axiosConfig.proxy = false; } - configureAxiosProxy(axiosConfig, config, MODEL_PROVIDER.FORWARD_API); + configureAxiosProxy(axiosConfig, config, config.MODEL_PROVIDER || MODEL_PROVIDER.FORWARD_API); this.axiosInstance = axios.create(axiosConfig); } _applySidecar(axiosConfig) { - return configureTLSSidecar(axiosConfig, this.config, MODEL_PROVIDER.FORWARD_API, this.baseUrl); + return configureTLSSidecar(axiosConfig, this.config, this.config.MODEL_PROVIDER || MODEL_PROVIDER.FORWARD_API, this.baseUrl); } async callApi(endpoint, body, isRetry = false, retryCount = 0) { diff --git a/src/providers/gemini/antigravity-core.js b/src/providers/gemini/antigravity-core.js index 3b34ba0..c66fd2e 100644 --- a/src/providers/gemini/antigravity-core.js +++ b/src/providers/gemini/antigravity-core.js @@ -697,7 +697,7 @@ export class AntigravityApiService { }); // 检查是否需要使用代理 - const proxyConfig = getGoogleAuthProxyConfig(config, 'gemini-antigravity'); + const proxyConfig = getGoogleAuthProxyConfig(config, config.MODEL_PROVIDER || MODEL_PROVIDER.ANTIGRAVITY); // 配置 OAuth2Client 使用自定义的 HTTP agent const oauth2Options = { @@ -729,11 +729,11 @@ export class AntigravityApiService { this.baseURLs = this.getBaseURLFallbackOrder(config); // 保存代理配置供后续使用 - this.proxyConfig = getProxyConfigForProvider(config, 'gemini-antigravity'); + this.proxyConfig = getProxyConfigForProvider(config, config.MODEL_PROVIDER || MODEL_PROVIDER.ANTIGRAVITY); } _applySidecar(requestOptions) { - return configureTLSSidecar(requestOptions, this.config, MODEL_PROVIDER.ANTIGRAVITY); + return configureTLSSidecar(requestOptions, this.config, this.config.MODEL_PROVIDER || MODEL_PROVIDER.ANTIGRAVITY); } /** @@ -821,7 +821,7 @@ export class AntigravityApiService { // 刷新成功,重置 PoolManager 中的刷新状态并标记为健康 const poolManager = getProviderPoolManager(); if (poolManager && this.uuid) { - poolManager.resetProviderRefreshStatus(MODEL_PROVIDER.ANTIGRAVITY, this.uuid); + poolManager.resetProviderRefreshStatus(this.config.MODEL_PROVIDER || MODEL_PROVIDER.ANTIGRAVITY, this.uuid); } } else { logger.info(`[Antigravity Auth] No access token or refresh token. Starting new authentication flow...`); @@ -832,7 +832,7 @@ export class AntigravityApiService { // 认证成功,重置状态 const poolManager = getProviderPoolManager(); if (poolManager && this.uuid) { - poolManager.resetProviderRefreshStatus(MODEL_PROVIDER.ANTIGRAVITY, this.uuid); + poolManager.resetProviderRefreshStatus(this.config.MODEL_PROVIDER || MODEL_PROVIDER.ANTIGRAVITY, this.uuid); } } } catch (error) { @@ -1109,7 +1109,7 @@ export class AntigravityApiService { const poolManager = getProviderPoolManager(); if (poolManager && this.uuid) { logger.info(`[Antigravity] Marking credential ${this.uuid} as needs refresh. Reason: 401/400 Unauthorized`); - poolManager.markProviderNeedRefresh(MODEL_PROVIDER.ANTIGRAVITY, { + poolManager.markProviderNeedRefresh(this.config.MODEL_PROVIDER || MODEL_PROVIDER.ANTIGRAVITY, { uuid: this.uuid }); error.credentialMarkedUnhealthy = true; @@ -1212,7 +1212,7 @@ export class AntigravityApiService { const poolManager = getProviderPoolManager(); if (poolManager && this.uuid) { logger.info(`[Antigravity] Marking credential ${this.uuid} as needs refresh. Reason: 401/400 Unauthorized in stream`); - poolManager.markProviderNeedRefresh(MODEL_PROVIDER.ANTIGRAVITY, { + poolManager.markProviderNeedRefresh(this.config.MODEL_PROVIDER || MODEL_PROVIDER.ANTIGRAVITY, { uuid: this.uuid }); error.credentialMarkedUnhealthy = true; @@ -1315,7 +1315,7 @@ export class AntigravityApiService { const poolManager = getProviderPoolManager(); if (poolManager && this.uuid) { logger.info(`[Antigravity] Token is near expiry, marking credential ${this.uuid} for refresh`); - poolManager.markProviderNeedRefresh(MODEL_PROVIDER.ANTIGRAVITY, { + poolManager.markProviderNeedRefresh(this.config.MODEL_PROVIDER || MODEL_PROVIDER.ANTIGRAVITY, { uuid: this.uuid }); } @@ -1393,7 +1393,7 @@ export class AntigravityApiService { const poolManager = getProviderPoolManager(); if (poolManager && this.uuid) { logger.info(`[Antigravity] Token is near expiry, marking credential ${this.uuid} for refresh`); - poolManager.markProviderNeedRefresh(MODEL_PROVIDER.ANTIGRAVITY, { + poolManager.markProviderNeedRefresh(this.config.MODEL_PROVIDER || MODEL_PROVIDER.ANTIGRAVITY, { uuid: this.uuid }); } @@ -1442,13 +1442,6 @@ export class AntigravityApiService { async getUsageLimits() { if (!this.isInitialized) await this.initialize(); - // 注意:V2 架构下不再在 getUsageLimits 中同步刷新 token - // 如果 token 过期,PoolManager 后台会自动处理 - // if (this.isExpiryDateNear()) { - // logger.info('[Antigravity] Token is near expiry, refreshing before getUsageLimits request...'); - // await this.initializeAuth(true); - // } - try { const modelsWithQuotas = await this.getModelsWithQuotas(); return modelsWithQuotas; @@ -1487,15 +1480,12 @@ export class AntigravityApiService { this._applySidecar(requestOptions); const res = await this.authClient.request(requestOptions); - // logger.info(`[Antigravity] fetchAvailableModels success: ${JSON.stringify(res.data)}`); if (res.data) { - if (res.data.models) { const modelsData = res.data.models; // 遍历模型数据,提取配额信息 for (const [modelId, modelData] of Object.entries(modelsData)) { - // 参考 fetchAvailableModels 的逻辑修复 modelName2Alias 不存在的问题 if (!modelId || (!ANTIGRAVITY_MODELS.includes(modelId) && !modelId.startsWith('claude-'))) { continue; } diff --git a/src/providers/gemini/gemini-core.js b/src/providers/gemini/gemini-core.js index 0033cbf..b4f386c 100644 --- a/src/providers/gemini/gemini-core.js +++ b/src/providers/gemini/gemini-core.js @@ -289,7 +289,7 @@ export class GeminiApiService { }); // 检查是否需要使用代理 - const proxyConfig = getGoogleAuthProxyConfig(config, 'gemini-cli-oauth'); + const proxyConfig = getGoogleAuthProxyConfig(config, config.MODEL_PROVIDER || MODEL_PROVIDER.GEMINI_CLI); // 配置 OAuth2Client 使用自定义的 HTTP agent const oauth2Options = { @@ -312,6 +312,7 @@ export class GeminiApiService { this.config = config; this.host = config.HOST; + this.uuid = config.uuid; this.oauthCredsBase64 = config.GEMINI_OAUTH_CREDS_BASE64; this.oauthCredsFilePath = config.GEMINI_OAUTH_CREDS_FILE_PATH; this.projectId = config.PROJECT_ID; @@ -320,7 +321,7 @@ export class GeminiApiService { this.apiVersion = DEFAULT_CODE_ASSIST_API_VERSION; // 保存代理配置供后续使用 - this.proxyConfig = getProxyConfigForProvider(config, 'gemini-cli-oauth'); + this.proxyConfig = getProxyConfigForProvider(config, config.MODEL_PROVIDER || MODEL_PROVIDER.GEMINI_CLI); } async initialize() { @@ -345,7 +346,7 @@ export class GeminiApiService { } _applySidecar(requestOptions) { - return configureTLSSidecar(requestOptions, this.config, MODEL_PROVIDER.GEMINI_CLI); + return configureTLSSidecar(requestOptions, this.config, this.config.MODEL_PROVIDER || MODEL_PROVIDER.GEMINI_CLI); } /** @@ -412,7 +413,7 @@ export class GeminiApiService { // 刷新成功,重置 PoolManager 中的刷新状态并标记为健康 const poolManager = getProviderPoolManager(); if (poolManager && this.uuid) { - poolManager.resetProviderRefreshStatus(MODEL_PROVIDER.GEMINI_CLI, this.uuid); + poolManager.resetProviderRefreshStatus(this.config.MODEL_PROVIDER || MODEL_PROVIDER.GEMINI_CLI, this.uuid); } } else { logger.info(`[Gemini Auth] No access token or refresh token. Starting new authentication flow...`); @@ -423,7 +424,7 @@ export class GeminiApiService { // 认证成功,重置状态 const poolManager = getProviderPoolManager(); if (poolManager && this.uuid) { - poolManager.resetProviderRefreshStatus(MODEL_PROVIDER.GEMINI_CLI, this.uuid); + poolManager.resetProviderRefreshStatus(this.config.MODEL_PROVIDER || MODEL_PROVIDER.GEMINI_CLI, this.uuid); } } } catch (error) { @@ -598,7 +599,7 @@ export class GeminiApiService { const poolManager = getProviderPoolManager(); if (poolManager && this.uuid) { logger.info(`[Gemini] Marking credential ${this.uuid} as needs refresh. Reason: 401/400 Unauthorized`); - poolManager.markProviderNeedRefresh(MODEL_PROVIDER.GEMINI_CLI, { + poolManager.markProviderNeedRefresh(this.config.MODEL_PROVIDER || MODEL_PROVIDER.GEMINI_CLI, { uuid: this.uuid }); error.credentialMarkedUnhealthy = true; @@ -681,7 +682,7 @@ export class GeminiApiService { const poolManager = getProviderPoolManager(); if (poolManager && this.uuid) { logger.info(`[Gemini] Marking credential ${this.uuid} as needs refresh. Reason: 401/400 Unauthorized in stream`); - poolManager.markProviderNeedRefresh(MODEL_PROVIDER.GEMINI_CLI, { + poolManager.markProviderNeedRefresh(this.config.MODEL_PROVIDER || MODEL_PROVIDER.GEMINI_CLI, { uuid: this.uuid }); error.credentialMarkedUnhealthy = true; @@ -757,7 +758,7 @@ export class GeminiApiService { const poolManager = getProviderPoolManager(); if (poolManager && this.uuid) { logger.info(`[Gemini] Token is near expiry, marking credential ${this.uuid} for refresh`); - poolManager.markProviderNeedRefresh(MODEL_PROVIDER.GEMINI_CLI, { + poolManager.markProviderNeedRefresh(this.config.MODEL_PROVIDER || MODEL_PROVIDER.GEMINI_CLI, { uuid: this.uuid }); } @@ -796,7 +797,7 @@ export class GeminiApiService { const poolManager = getProviderPoolManager(); if (poolManager && this.uuid) { logger.info(`[Gemini] Token is near expiry, marking credential ${this.uuid} for refresh`); - poolManager.markProviderNeedRefresh(MODEL_PROVIDER.GEMINI_CLI, { + poolManager.markProviderNeedRefresh(this.config.MODEL_PROVIDER || MODEL_PROVIDER.GEMINI_CLI, { uuid: this.uuid }); } diff --git a/src/providers/grok/grok-core.js b/src/providers/grok/grok-core.js index 7fb962d..8e34b3d 100644 --- a/src/providers/grok/grok-core.js +++ b/src/providers/grok/grok-core.js @@ -129,14 +129,14 @@ export class GrokApiService { async acceptTos() { const axiosConfig = { method: 'post', url: `${this.baseUrl}/rest/app-chat/accept-tos`, headers: this.buildHeaders(), data: {}, httpAgent, httpsAgent, timeout: 15000 }; - configureAxiosProxy(axiosConfig, this.config, MODEL_PROVIDER.GROK_CUSTOM); + configureAxiosProxy(axiosConfig, this.config, this.config.MODEL_PROVIDER || MODEL_PROVIDER.GROK_CUSTOM); this._applySidecar(axiosConfig); try { await axios(axiosConfig); } catch (e) { logger.debug(`[Grok TOS] ${e.message}`); } } async setBirthDate() { const axiosConfig = { method: 'post', url: `${this.baseUrl}/rest/app-chat/set-birth-date`, headers: this.buildHeaders(), data: { "birthDate": "1990-01-01" }, httpAgent, httpsAgent, timeout: 15000 }; - configureAxiosProxy(axiosConfig, this.config, MODEL_PROVIDER.GROK_CUSTOM); + configureAxiosProxy(axiosConfig, this.config, this.config.MODEL_PROVIDER || MODEL_PROVIDER.GROK_CUSTOM); this._applySidecar(axiosConfig); try { await axios(axiosConfig); } catch (e) { logger.debug(`[Grok Birth] ${e.message}`); } } @@ -167,13 +167,13 @@ export class GrokApiService { timeout: 15000, responseType: 'arraybuffer' }; - configureAxiosProxy(axiosConfig, this.config, MODEL_PROVIDER.GROK_CUSTOM); + configureAxiosProxy(axiosConfig, this.config, this.config.MODEL_PROVIDER || MODEL_PROVIDER.GROK_CUSTOM); this._applySidecar(axiosConfig); try { await axios(axiosConfig); } catch (e) { throw e; } } _applySidecar(axiosConfig) { - return configureTLSSidecar(axiosConfig, this.config, MODEL_PROVIDER.GROK_CUSTOM); + return configureTLSSidecar(axiosConfig, this.config, this.config.MODEL_PROVIDER || MODEL_PROVIDER.GROK_CUSTOM); } async initialize() { @@ -190,7 +190,7 @@ export class GrokApiService { // await this.getUsageLimits(); return Promise.resolve(); const poolManager = getProviderPoolManager(); if (poolManager && this.uuid) { - poolManager.resetProviderRefreshStatus(MODEL_PROVIDER.GROK_CUSTOM, this.uuid); + poolManager.resetProviderRefreshStatus(this.config.MODEL_PROVIDER || MODEL_PROVIDER.GROK_CUSTOM, this.uuid); } } catch (error) { logger.error('[Grok] Failed to initialize authentication:', error); @@ -202,7 +202,7 @@ export class GrokApiService { const headers = this.buildHeaders(); const payload = { "requestKind": "DEFAULT", "modelName": "grok-3" }; const axiosConfig = { method: 'post', url: `${this.baseUrl}/rest/rate-limits`, headers, data: payload, httpAgent, httpsAgent, timeout: 30000 }; - configureAxiosProxy(axiosConfig, this.config, MODEL_PROVIDER.GROK_CUSTOM); + configureAxiosProxy(axiosConfig, this.config, this.config.MODEL_PROVIDER || MODEL_PROVIDER.GROK_CUSTOM); this._applySidecar(axiosConfig); try { const response = await axios(axiosConfig); @@ -282,7 +282,7 @@ export class GrokApiService { if (mediaUrl && mediaUrl.trim()) payload.mediaUrl = mediaUrl; const axiosConfig = { method: 'post', url: `${this.baseUrl}/rest/media/post/create`, headers, data: payload, httpAgent, httpsAgent, timeout: 30000 }; - configureAxiosProxy(axiosConfig, this.config, MODEL_PROVIDER.GROK_CUSTOM); + configureAxiosProxy(axiosConfig, this.config, this.config.MODEL_PROVIDER || MODEL_PROVIDER.GROK_CUSTOM); this._applySidecar(axiosConfig); try { const response = await axios(axiosConfig); @@ -302,7 +302,7 @@ export class GrokApiService { if (!idMatch) return videoUrl; const videoId = idMatch[1]; const axiosConfig = { method: 'post', url: `${this.baseUrl}/rest/media/video/upscale`, headers: this.buildHeaders(), data: { videoId }, httpAgent, httpsAgent, timeout: 30000 }; - configureAxiosProxy(axiosConfig, this.config, MODEL_PROVIDER.GROK_CUSTOM); + configureAxiosProxy(axiosConfig, this.config, this.config.MODEL_PROVIDER || MODEL_PROVIDER.GROK_CUSTOM); this._applySidecar(axiosConfig); try { const response = await axios(axiosConfig); @@ -329,7 +329,7 @@ export class GrokApiService { httpsAgent, timeout: 15000 }; - configureAxiosProxy(axiosConfig, this.config, MODEL_PROVIDER.GROK_CUSTOM); + configureAxiosProxy(axiosConfig, this.config, this.config.MODEL_PROVIDER || MODEL_PROVIDER.GROK_CUSTOM); this._applySidecar(axiosConfig); try { const response = await axios(axiosConfig); @@ -455,7 +455,7 @@ export class GrokApiService { rolloutId: "", modelResponse: null, cardAttachment: null, - cardAttachments: [], // 收集所有的卡片附件 + cardAttachments: [], streamingImageGenerationResponse: null, streamingVideoGenerationResponse: null, finalVideoUrl: null, @@ -743,7 +743,7 @@ export class GrokApiService { } if (!b64) return null; const axiosConfig = { method: 'post', url: `${this.baseUrl}/rest/app-chat/upload-file`, headers: this.buildHeaders(), data: { fileName: `file.${mime.split("/")[1] || "bin"}`, fileMimeType: mime, content: b64 }, httpAgent, httpsAgent, timeout: 30000 }; - configureAxiosProxy(axiosConfig, this.config, MODEL_PROVIDER.GROK_CUSTOM); + configureAxiosProxy(axiosConfig, this.config, this.config.MODEL_PROVIDER || MODEL_PROVIDER.GROK_CUSTOM); this._applySidecar(axiosConfig); try { return (await axios(axiosConfig)).data; } catch (error) { return null; } } @@ -763,7 +763,7 @@ export class GrokApiService { if (requestBody._requestBaseUrl) delete requestBody._requestBaseUrl; if (this.isExpiryDateNear() && getProviderPoolManager() && this.uuid) { - getProviderPoolManager().markProviderNeedRefresh(MODEL_PROVIDER.GROK_CUSTOM, { uuid: this.uuid }); + getProviderPoolManager().markProviderNeedRefresh(this.config.MODEL_PROVIDER || MODEL_PROVIDER.GROK_CUSTOM, { uuid: this.uuid }); } const rawModel = typeof model === 'string' ? model : ''; @@ -841,7 +841,7 @@ export class GrokApiService { const payload = this.buildPayload(model, requestBody); const axiosConfig = { method: 'post', url: this.chatApi, headers: this.buildHeaders(), data: payload, responseType: 'stream', httpAgent, httpsAgent, timeout: 60000, maxRedirects: 0 }; - configureAxiosProxy(axiosConfig, this.config, MODEL_PROVIDER.GROK_CUSTOM); + configureAxiosProxy(axiosConfig, this.config, this.config.MODEL_PROVIDER || MODEL_PROVIDER.GROK_CUSTOM); this._applySidecar(axiosConfig); try { diff --git a/src/providers/openai/codex-core.js b/src/providers/openai/codex-core.js index 3eceb68..909414f 100644 --- a/src/providers/openai/codex-core.js +++ b/src/providers/openai/codex-core.js @@ -40,7 +40,7 @@ export class CodexApiService { } _applySidecar(axiosConfig) { - return configureTLSSidecar(axiosConfig, this.config, MODEL_PROVIDER.CODEX_API, this.baseUrl); + return configureTLSSidecar(axiosConfig, this.config, this.config.MODEL_PROVIDER || MODEL_PROVIDER.CODEX_API, this.baseUrl); } /** @@ -148,7 +148,7 @@ export class CodexApiService { const poolManager = getProviderPoolManager(); if (poolManager && this.uuid) { logger.info(`[Codex] Token is near expiry, marking credential ${this.uuid} for background refresh`); - poolManager.markProviderNeedRefresh(MODEL_PROVIDER.CODEX_API, { + poolManager.markProviderNeedRefresh(this.config.MODEL_PROVIDER || MODEL_PROVIDER.CODEX_API, { uuid: this.uuid }); } @@ -195,7 +195,7 @@ export class CodexApiService { }; // 配置代理 - const proxyConfig = getProxyConfigForProvider(this.config, 'openai-codex-oauth'); + const proxyConfig = getProxyConfigForProvider(this.config, this.config.MODEL_PROVIDER || MODEL_PROVIDER.CODEX_API); if (proxyConfig) { config.httpAgent = proxyConfig.httpAgent; config.httpsAgent = proxyConfig.httpsAgent; @@ -272,7 +272,7 @@ export class CodexApiService { }; // 配置代理 - const proxyConfig = getProxyConfigForProvider(this.config, 'openai-codex-oauth'); + const proxyConfig = getProxyConfigForProvider(this.config, this.config.MODEL_PROVIDER || MODEL_PROVIDER.CODEX_API); if (proxyConfig) { config.httpAgent = proxyConfig.httpAgent; config.httpsAgent = proxyConfig.httpsAgent; @@ -454,7 +454,7 @@ export class CodexApiService { // 刷新成功,重置 PoolManager 中的刷新状态并标记为健康 const poolManager = getProviderPoolManager(); if (poolManager && this.uuid) { - poolManager.resetProviderRefreshStatus(MODEL_PROVIDER.CODEX_API, this.uuid); + poolManager.resetProviderRefreshStatus(this.config.MODEL_PROVIDER || MODEL_PROVIDER.CODEX_API, this.uuid); } logger.info('[Codex] Token refreshed successfully'); } catch (error) { @@ -688,7 +688,7 @@ export class CodexApiService { }; // 配置代理 - const proxyConfig = getProxyConfigForProvider(this.config, 'openai-codex-oauth'); + const proxyConfig = getProxyConfigForProvider(this.config, this.config.MODEL_PROVIDER || MODEL_PROVIDER.CODEX_API); if (proxyConfig) { config.httpAgent = proxyConfig.httpAgent; config.httpsAgent = proxyConfig.httpsAgent; diff --git a/src/providers/openai/openai-core.js b/src/providers/openai/openai-core.js index 6fe800a..0485fd6 100644 --- a/src/providers/openai/openai-core.js +++ b/src/providers/openai/openai-core.js @@ -47,13 +47,13 @@ export class OpenAIApiService { } // 配置自定义代理 - configureAxiosProxy(axiosConfig, config, MODEL_PROVIDER.OPENAI_CUSTOM); + configureAxiosProxy(axiosConfig, config, config.MODEL_PROVIDER || MODEL_PROVIDER.OPENAI_CUSTOM); this.axiosInstance = axios.create(axiosConfig); } _applySidecar(axiosConfig) { - return configureTLSSidecar(axiosConfig, this.config, MODEL_PROVIDER.OPENAI_CUSTOM, this.baseUrl); + return configureTLSSidecar(axiosConfig, this.config, this.config.MODEL_PROVIDER || MODEL_PROVIDER.OPENAI_CUSTOM, this.baseUrl); } async callApi(endpoint, body, isRetry = false, retryCount = 0) { diff --git a/src/providers/openai/openai-responses-core.js b/src/providers/openai/openai-responses-core.js index d12cbad..853a3fd 100644 --- a/src/providers/openai/openai-responses-core.js +++ b/src/providers/openai/openai-responses-core.js @@ -47,13 +47,13 @@ export class OpenAIResponsesApiService { } // 配置自定义代理 (使用 openai-custom 的代理配置) - configureAxiosProxy(axiosConfig, config, MODEL_PROVIDER.OPENAI_CUSTOM_RESPONSES); + configureAxiosProxy(axiosConfig, config, config.MODEL_PROVIDER || MODEL_PROVIDER.OPENAI_CUSTOM_RESPONSES); this.axiosInstance = axios.create(axiosConfig); } _applySidecar(axiosConfig) { - return configureTLSSidecar(axiosConfig, this.config, MODEL_PROVIDER.OPENAI_CUSTOM_RESPONSES, this.baseUrl); + return configureTLSSidecar(axiosConfig, this.config, this.config.MODEL_PROVIDER || MODEL_PROVIDER.OPENAI_CUSTOM_RESPONSES, this.baseUrl); } async callApi(endpoint, body, isRetry = false, retryCount = 0) { diff --git a/src/providers/openai/qwen-core.js b/src/providers/openai/qwen-core.js index 8d31638..e2621ca 100644 --- a/src/providers/openai/qwen-core.js +++ b/src/providers/openai/qwen-core.js @@ -230,7 +230,7 @@ export class QwenApiService { } // 配置自定义代理 - configureAxiosProxy(axiosConfig, this.config, 'openai-qwen-oauth'); + configureAxiosProxy(axiosConfig, this.config, this.config.MODEL_PROVIDER || MODEL_PROVIDER.QWEN_API); this.currentAxiosInstance = axios.create(axiosConfig); @@ -239,7 +239,7 @@ export class QwenApiService { } _applySidecar(axiosConfig) { - return configureTLSSidecar(axiosConfig, this.config, MODEL_PROVIDER.QWEN_API, this.baseUrl); + return configureTLSSidecar(axiosConfig, this.config, this.config.MODEL_PROVIDER || MODEL_PROVIDER.QWEN_API, this.baseUrl); } /** @@ -278,7 +278,7 @@ export class QwenApiService { if (forceRefresh || (credentials && credentials.access_token)) { const poolManager = getProviderPoolManager(); if (poolManager && this.uuid) { - poolManager.resetProviderRefreshStatus(MODEL_PROVIDER.QWEN_API, this.uuid); + poolManager.resetProviderRefreshStatus(this.config.MODEL_PROVIDER || MODEL_PROVIDER.QWEN_API, this.uuid); } } } catch (error) { @@ -331,7 +331,7 @@ export class QwenApiService { // 认证成功,重置状态 const poolManager = getProviderPoolManager(); if (poolManager && this.uuid) { - poolManager.resetProviderRefreshStatus(MODEL_PROVIDER.QWEN_API, this.uuid); + poolManager.resetProviderRefreshStatus(this.config.MODEL_PROVIDER || MODEL_PROVIDER.QWEN_API, this.uuid); } } } @@ -575,7 +575,7 @@ export class QwenApiService { } // 配置自定义代理 - configureAxiosProxy(axiosConfig, this.config, 'openai-qwen-oauth'); + configureAxiosProxy(axiosConfig, this.config, this.config.MODEL_PROVIDER || MODEL_PROVIDER.QWEN_API); this.currentAxiosInstance = axios.create(axiosConfig); @@ -629,7 +629,7 @@ export class QwenApiService { const poolManager = getProviderPoolManager(); if (poolManager && this.uuid) { logger.info(`[Qwen] Marking credential ${this.uuid} as needs refresh. Reason: Auth Error ${status}`); - poolManager.markProviderNeedRefresh(MODEL_PROVIDER.QWEN_API, { + poolManager.markProviderNeedRefresh(this.config.MODEL_PROVIDER || MODEL_PROVIDER.QWEN_API, { uuid: this.uuid }); error.credentialMarkedUnhealthy = true; @@ -677,7 +677,7 @@ export class QwenApiService { const poolManager = getProviderPoolManager(); if (poolManager && this.uuid) { logger.info(`[Qwen] Token is near expiry, marking credential ${this.uuid} for refresh`); - poolManager.markProviderNeedRefresh(MODEL_PROVIDER.QWEN_API, { + poolManager.markProviderNeedRefresh(this.config.MODEL_PROVIDER || MODEL_PROVIDER.QWEN_API, { uuid: this.uuid }); } diff --git a/src/providers/provider-models.js b/src/providers/provider-models.js index faa044c..8c815a0 100644 --- a/src/providers/provider-models.js +++ b/src/providers/provider-models.js @@ -116,7 +116,18 @@ export const PROVIDER_MODELS = { * @returns {Array} 模型列表 */ export function getProviderModels(providerType) { - return PROVIDER_MODELS[providerType] || []; + if (PROVIDER_MODELS[providerType]) { + return PROVIDER_MODELS[providerType]; + } + + // 尝试前缀匹配 (例如 openai-custom-1 -> openai-custom) + for (const key of Object.keys(PROVIDER_MODELS)) { + if (providerType.startsWith(key + '-')) { + return PROVIDER_MODELS[key]; + } + } + + return []; } /** diff --git a/src/providers/provider-pool-manager.js b/src/providers/provider-pool-manager.js index 345badf..334c9d3 100644 --- a/src/providers/provider-pool-manager.js +++ b/src/providers/provider-pool-manager.js @@ -1841,7 +1841,11 @@ export class ProviderPoolManager { for (const { providerType, provider, uuid, customName } of providersToCheck) { const providerCheckStart = Date.now(); - const checkModelName = provider.config.checkModelName || ProviderPoolManager.DEFAULT_HEALTH_CHECK_MODELS[providerType] || 'unknown'; + const baseProviderType = this._getBaseProviderType(providerType); + const checkModelName = provider.config.checkModelName || + ProviderPoolManager.DEFAULT_HEALTH_CHECK_MODELS[providerType] || + ProviderPoolManager.DEFAULT_HEALTH_CHECK_MODELS[baseProviderType] || + 'unknown'; const displayName = customName || uuid.substring(0, 8); try { @@ -1903,7 +1907,7 @@ export class ProviderPoolManager { } // OpenAI Custom Responses 使用特殊格式 - if (providerType === MODEL_PROVIDER.OPENAI_CUSTOM_RESPONSES) { + if (this._getBaseProviderType(providerType) === MODEL_PROVIDER.OPENAI_CUSTOM_RESPONSES) { requests.push({ input: [baseMessage], model: modelName @@ -1920,6 +1924,26 @@ export class ProviderPoolManager { return requests; } + /** + * 根据提供商类型获取基准提供商类型(用于查找配置和模型) + * 例如:openai-custom-1 -> openai-custom + * @private + */ + _getBaseProviderType(providerType) { + if (ProviderPoolManager.DEFAULT_HEALTH_CHECK_MODELS[providerType]) { + return providerType; + } + + // 尝试前缀匹配 + for (const key of Object.keys(ProviderPoolManager.DEFAULT_HEALTH_CHECK_MODELS)) { + if (providerType === key || providerType.startsWith(key + '-')) { + return key; + } + } + + return providerType; + } + /** * Performs an actual health check for a specific provider. * @@ -1934,8 +1958,10 @@ export class ProviderPoolManager { */ async _checkProviderHealth(providerType, providerConfig) { // 确定健康检查使用的模型名称 + const baseProviderType = this._getBaseProviderType(providerType); const modelName = providerConfig.checkModelName || - ProviderPoolManager.DEFAULT_HEALTH_CHECK_MODELS[providerType]; + ProviderPoolManager.DEFAULT_HEALTH_CHECK_MODELS[providerType] || + ProviderPoolManager.DEFAULT_HEALTH_CHECK_MODELS[baseProviderType]; if (!modelName) { this._log('warn', `Unknown provider type for health check: ${providerType}. Please check DEFAULT_HEALTH_CHECK_MODELS.`); diff --git a/src/services/service-manager.js b/src/services/service-manager.js index 747518f..47f1673 100644 --- a/src/services/service-manager.js +++ b/src/services/service-manager.js @@ -563,7 +563,8 @@ export async function getProviderStatus(config, options = {}) { 'gemini-antigravity': 'ANTIGRAVITY_OAUTH_CREDS_FILE_PATH', 'openai-iflow': 'IFLOW_TOKEN_FILE_PATH', 'forward-api': 'FORWARD_BASE_URL', - 'grok-custom': 'GROK_COOKIE_TOKEN' + 'grok-custom': 'GROK_COOKIE_TOKEN', + 'openai-codex-oauth': 'CODEX_OAUTH_CREDS_FILE_PATH' }; let providerPoolsSlim = []; let unhealthyProvideIdentifyList = []; @@ -575,7 +576,18 @@ export async function getProviderStatus(config, options = {}) { for (const key of Object.keys(providerPools)) { if (!Array.isArray(providerPools[key])) continue; if (filterProvider && key !== filterProvider) continue; - const identifyField = identifyFieldMap[key] || null; + + let identifyField = identifyFieldMap[key] || null; + if (!identifyField) { + // 尝试通过前缀查找 identifyField (例如 openai-custom-1 -> openai-custom) + for (const [prefix, field] of Object.entries(identifyFieldMap)) { + if (key.startsWith(prefix + '-')) { + identifyField = field; + break; + } + } + } + const slimArr = providerPools[key] .filter(item => { if (item.isDisabled) return false; diff --git a/src/services/ui-manager.js b/src/services/ui-manager.js index 91db632..cd71bb9 100644 --- a/src/services/ui-manager.js +++ b/src/services/ui-manager.js @@ -125,7 +125,7 @@ export async function handleUIApiRequests(method, pathParam, req, res, currentCo // Get supported provider types based on registered adapters if (method === 'GET' && pathParam === '/api/providers/supported') { - return await providerApi.handleGetSupportedProviders(req, res); + return await providerApi.handleGetSupportedProviders(req, res, currentConfig, providerPoolManager); } // Get specific provider type details @@ -137,7 +137,7 @@ export async function handleUIApiRequests(method, pathParam, req, res, currentCo // Get available models for all providers or specific provider type if (method === 'GET' && pathParam === '/api/provider-models') { - return await providerApi.handleGetProviderModels(req, res); + return await providerApi.handleGetProviderModels(req, res, currentConfig, providerPoolManager); } // Get available models for a specific provider type diff --git a/src/ui-modules/provider-api.js b/src/ui-modules/provider-api.js index 1d4cf3d..600f4d0 100644 --- a/src/ui-modules/provider-api.js +++ b/src/ui-modules/provider-api.js @@ -9,38 +9,53 @@ import { getRegisteredProviders } from '../providers/adapter.js'; // 文件级互斥锁:防止并发读写导致数据丢失 // 安全净化:移除用户输入字段中的危险内容(script、事件处理器、javascript:协议等), // 存储原始文本。HTML 转义统一由前端 escHtml() 负责,避免双编码问题。 -function sanitizeProviderData(provider) { +// 安全净化:移除用户输入字段中的危险内容,并可选地过滤敏感 API 密钥 +function sanitizeProviderData(provider, maskSensitive = false) { if (!provider || typeof provider !== 'object') return provider; const sanitized = { ...provider }; + + // 1. 过滤敏感字段(API Keys, Tokens 等) + if (maskSensitive) { + const sensitiveKeys = [ + 'OPENAI_API_KEY', 'CLAUDE_API_KEY', 'FORWARD_API_KEY', + 'GROK_COOKIE_TOKEN', 'GROK_CF_CLEARANCE', + 'refreshToken', 'accessToken', 'clientSecret' + ]; + + sensitiveKeys.forEach(key => { + if (sanitized[key]) { + // 对密钥进行脱敏显示(只保留前 4 位和后 4 位) + const val = sanitized[key]; + if (typeof val === 'string' && val.length > 10) { + sanitized[key] = val.substring(0, 4) + '****' + val.substring(val.length - 4); + } else { + sanitized[key] = '********'; + } + } + }); + } + + // 2. 净化 customName 中的 HTML/脚本 if (typeof sanitized.customName === 'string') { let name = sanitized.customName; - - // 拒绝包含危险协议 if (/(?:data|javascript|vbscript)\s*:/i.test(name)) { sanitized.customName = ''; return sanitized; } - - // 移除所有 HTML 标签(更安全的方式) name = name.replace(/<[^>]*>/g, ''); - - // 移除 HTML 事件处理器属性(onclick/onerror 等) name = name.replace(/\s+on\w+\s*=\s*(?:"[^"]*"|'[^']*'|[^\s>]*)/gi, ''); - - // 移除潜在的 HTML 实体编码攻击 name = name.replace(/&[#\w]+;/g, ''); - sanitized.customName = name.trim(); } return sanitized; } -function sanitizeProviderPools(pools) { +function sanitizeProviderPools(pools, maskSensitive = false) { if (!pools || typeof pools !== 'object') return pools; const sanitized = {}; for (const [type, providers] of Object.entries(pools)) { sanitized[type] = Array.isArray(providers) - ? providers.map(sanitizeProviderData) + ? providers.map(p => sanitizeProviderData(p, maskSensitive)) : providers; } return sanitized; @@ -70,34 +85,53 @@ function withFileLock(fn) { return next; } /** - * 获取提供商池摘要 + * 获取所有提供商的状态(包括支持的类型和号池组) */ export async function handleGetProviders(req, res, currentConfig, providerPoolManager) { - let providerPools = {}; - const filePath = currentConfig.PROVIDER_POOLS_FILE_PATH || 'configs/provider_pools.json'; - try { - if (providerPoolManager && providerPoolManager.providerPools) { - providerPools = providerPoolManager.providerPools; - } else if (filePath && existsSync(filePath)) { - const poolsData = JSON.parse(readFileSync(filePath, 'utf-8')); - providerPools = poolsData; - } - } catch (error) { - logger.warn('[UI API] Failed to load provider pools:', error.message); + if (!providerPoolManager) { + res.writeHead(400, { 'Content-Type': 'application/json' }); + res.end(JSON.stringify({ error: { message: 'Provider pool manager not initialized' } })); + return true; } - res.writeHead(200, { 'Content-Type': 'application/json' }); - res.end(JSON.stringify(sanitizeProviderPools(providerPools))); - return true; -} + // 1. 获取支持的基础提供商类型 + const registeredProviders = getRegisteredProviders(); + let poolTypes = []; + + // 2. 从管理器获取当前所有池的状态 + const providerStatus = {}; + for (const [type, providers] of Object.entries(providerPoolManager.providerStatus)) { + providerStatus[type] = providers.map(p => ({ + ...p.config, + activeRequests: p.state?.activeCount || 0, + waitingRequests: p.state?.waitingCount || 0 + })); + } + + // 3. 补全号池配置文件中的所有组 + const filePath = currentConfig.PROVIDER_POOLS_FILE_PATH || 'configs/provider_pools.json'; + try { + if (existsSync(filePath)) { + const poolsData = JSON.parse(readFileSync(filePath, 'utf-8')); + poolTypes = Object.keys(poolsData); + poolTypes.forEach(type => { + if (!providerStatus[type]) { + providerStatus[type] = []; + } + }); + } + } catch (error) { + logger.warn('[UI API] Failed to supplement provider status:', error.message); + } + + // 合并生成支持的类型列表 + const supportedProviders = [...new Set([...registeredProviders, ...poolTypes])]; -/** - * 获取支持的提供商类型(已注册适配器的) - */ -export async function handleGetSupportedProviders(req, res) { - const supportedProviders = getRegisteredProviders(); res.writeHead(200, { 'Content-Type': 'application/json' }); - res.end(JSON.stringify(supportedProviders)); + res.end(JSON.stringify({ + providers: sanitizeProviderPools(providerStatus, true), // 列表显示进行打码 + supportedProviders: supportedProviders + })); return true; } @@ -122,7 +156,7 @@ export async function handleGetProviderType(req, res, currentConfig, providerPoo res.writeHead(200, { 'Content-Type': 'application/json' }); res.end(JSON.stringify({ providerType, - providers: providers.map(sanitizeProviderData), + providers: providers.map(p => sanitizeProviderData(p, false)), // 详情页(用于编辑)不打码 totalCount: providers.length, healthyCount: providers.filter(p => p.isHealthy).length })); @@ -130,10 +164,62 @@ export async function handleGetProviderType(req, res, currentConfig, providerPoo } /** - * 获取所有提供商的可用模型 + * 获取支持的提供商类型(已注册适配器的,以及号池中已存在的自定义类型) */ -export async function handleGetProviderModels(req, res) { - const allModels = getAllProviderModels(); +export async function handleGetSupportedProviders(req, res, currentConfig, providerPoolManager) { + const registeredProviders = getRegisteredProviders(); + let poolTypes = []; + + const filePath = currentConfig.PROVIDER_POOLS_FILE_PATH || 'configs/provider_pools.json'; + try { + if (providerPoolManager && providerPoolManager.providerPools) { + poolTypes = Object.keys(providerPoolManager.providerPools); + } else if (filePath && existsSync(filePath)) { + const poolsData = JSON.parse(readFileSync(filePath, 'utf-8')); + poolTypes = Object.keys(poolsData); + } + } catch (error) { + logger.warn('[UI API] Failed to load provider pools for supported types:', error.message); + } + + // 合并注册的提供商和号池中的类型 + const supportedProviders = [...new Set([...registeredProviders, ...poolTypes])]; + + res.writeHead(200, { 'Content-Type': 'application/json' }); + res.end(JSON.stringify(supportedProviders)); + return true; +} + +/** + * 获取所有提供商的可用模型(支持动态配置组) + */ +export async function handleGetProviderModels(req, res, currentConfig, providerPoolManager) { + const registeredProviders = getRegisteredProviders(); + let poolTypes = []; + + // 获取所有存在的类型(基础 + 动态) + const filePath = currentConfig.PROVIDER_POOLS_FILE_PATH || 'configs/provider_pools.json'; + try { + if (providerPoolManager && providerPoolManager.providerPools) { + poolTypes = Object.keys(providerPoolManager.providerPools); + } else if (existsSync(filePath)) { + const poolsData = JSON.parse(readFileSync(filePath, 'utf-8')); + poolTypes = Object.keys(poolsData); + } + } catch (error) { + logger.warn('[UI API] Failed to load provider pools for models:', error.message); + } + + const allTypes = [...new Set([...registeredProviders, ...poolTypes])]; + const allModels = {}; + + allTypes.forEach(type => { + const models = getProviderModels(type); + if (models && models.length > 0) { + allModels[type] = models; + } + }); + res.writeHead(200, { 'Content-Type': 'application/json' }); res.end(JSON.stringify(allModels)); return true; diff --git a/src/utils/common.js b/src/utils/common.js index c031ea4..3582277 100644 --- a/src/utils/common.js +++ b/src/utils/common.js @@ -961,7 +961,7 @@ export async function handleContentGenerationRequest(req, res, service, endpoint } // 为 forward provider 添加原始请求路径作为 endpoint - if (requestPath && toProvider === MODEL_PROVIDER.FORWARD_API) { + if (requestPath && getProtocolPrefix(toProvider) === MODEL_PROTOCOL_PREFIX.FORWARD) { logger.info(`[Forward API] Request path: ${requestPath}`); processedRequestBody.endpoint = requestPath; } diff --git a/src/utils/proxy-utils.js b/src/utils/proxy-utils.js index 45bd9ec..8053c19 100644 --- a/src/utils/proxy-utils.js +++ b/src/utils/proxy-utils.js @@ -54,7 +54,7 @@ export function parseProxyUrl(proxyUrl) { } /** - * 检查指定的提供商是否启用了代理 + * 检查指定的提供商是否启用了代理(支持前缀匹配) * @param {Object} config - 配置对象 * @param {string} providerType - 提供商类型 * @returns {boolean} 是否启用代理 @@ -69,7 +69,13 @@ export function isProxyEnabledForProvider(config, providerType) { return false; } - return enabledProviders.includes(providerType); + // 1. 尝试精确匹配 + if (enabledProviders.includes(providerType)) { + return true; + } + + // 2. 尝试前缀匹配 (例如 openai-custom-prod 继承 openai-custom 的配置) + return enabledProviders.some(p => providerType.startsWith(p + '-')); } /** @@ -112,7 +118,7 @@ export function configureAxiosProxy(axiosConfig, config, providerType) { } /** - * 检查指定的提供商是否启用了 TLS Sidecar + * 检查指定的提供商是否启用了 TLS Sidecar(支持前缀匹配) * @param {Object} config - 配置对象 * @param {string} providerType - 提供商类型 * @returns {boolean} 是否启用 TLS Sidecar @@ -127,7 +133,13 @@ export function isTLSSidecarEnabledForProvider(config, providerType) { return false; } - return enabledProviders.includes(providerType); + // 1. 尝试精确匹配 + if (enabledProviders.includes(providerType)) { + return true; + } + + // 2. 尝试前缀匹配 + return enabledProviders.some(p => providerType.startsWith(p + '-')); } /** diff --git a/static/app/app.js b/static/app/app.js index 2704104..4d38fb3 100644 --- a/static/app/app.js +++ b/static/app/app.js @@ -41,7 +41,8 @@ import { openProviderManager, showAuthModal, executeGenerateAuthUrl, - handleGenerateAuthUrl + handleGenerateAuthUrl, + showAddProviderGroupModal } from './provider-manager.js'; import { @@ -234,6 +235,7 @@ window.fileUploadHandler = fileUploadHandler; window.showAuthModal = showAuthModal; window.executeGenerateAuthUrl = executeGenerateAuthUrl; window.handleGenerateAuthUrl = handleGenerateAuthUrl; +window.showAddProviderGroupModal = showAddProviderGroupModal; // 配置管理相关全局函数 window.viewConfig = viewConfig; diff --git a/static/app/event-handlers.js b/static/app/event-handlers.js index 283bdcf..5377ecb 100644 --- a/static/app/event-handlers.js +++ b/static/app/event-handlers.js @@ -219,6 +219,18 @@ function initEventListeners() { performUpdateBtn.addEventListener('click', performUpdate); } + // 添加提供商组按钮 + const addProviderGroupBtn = document.getElementById('add-provider-group-btn'); + if (addProviderGroupBtn) { + addProviderGroupBtn.addEventListener('click', () => { + if (window.showAddProviderGroupModal) { + window.showAddProviderGroupModal(); + } else { + console.error('showAddProviderGroupModal function not found'); + } + }); + } + // 日志容器滚动 if (elements.logsContainer) { elements.logsContainer.addEventListener('scroll', () => { diff --git a/static/app/i18n.js b/static/app/i18n.js index 13a06ee..f4ee713 100644 --- a/static/app/i18n.js +++ b/static/app/i18n.js @@ -452,6 +452,12 @@ const translations = { // Providers 'providers.title': '提供商池管理', + 'providers.addGroup': '新的分组', + 'providers.addGroup.title': '添加新分组', + 'providers.addGroup.success': '分组创建成功,请添加账号', + 'providers.addGroup.error': '创建失败', + 'providers.addGroup.suffix': '分组名称 (后缀)', + 'providers.addGroup.suffixPlaceholder': '例如: qwen, glm, minimax', 'providers.note': '如使用客户端默认授权配置需使用空节点', 'providers.activeConnections': '活动连接', 'providers.activeProviders': '活跃提供商', @@ -1304,6 +1310,13 @@ const translations = { // Providers 'providers.title': 'Provider Pool Management', + 'providers.addGroup': 'Add Group', + 'providers.addGroup.title': 'Add New Configuration Group', + 'providers.addGroup.baseType': 'Base Type', + 'providers.addGroup.suffix': 'Suffix Name', + 'providers.addGroup.suffixPlaceholder': 'e.g., qwen, glm, minimax', + 'providers.addGroup.success': 'Configuration group created, please add accounts', + 'providers.addGroup.error': 'Creation failed', 'providers.note': 'If using default client authorization config, use an empty node', 'providers.activeConnections': 'Active Connections', 'providers.activeProviders': 'Active Providers', diff --git a/static/app/modal.js b/static/app/modal.js index f906030..60a1cd3 100644 --- a/static/app/modal.js +++ b/static/app/modal.js @@ -667,8 +667,13 @@ function renderProviderConfig(provider) { * @param {Object} provider - 提供商对象 * @returns {Array} 字段键数组 */ +/** + * 获取字段显示顺序 + * @param {Object} provider - 提供商对象 + * @returns {Array} 字段名数组 + */ function getFieldOrder(provider) { - const orderedFields = ['customName', 'checkModelName', 'checkHealth']; + const orderedFields = ['customName', 'checkModelName', 'checkHealth', 'concurrencyLimit', 'queueLimit']; // 需要排除的内部状态字段 const excludedFields = [ @@ -677,23 +682,10 @@ function getFieldOrder(provider) { 'notSupportedModels', 'refreshCount', 'needsRefresh', '_lastSelectionSeq' ]; - // 从 getProviderTypeFields 获取字段顺序映射 - const fieldOrderMap = { - 'openai-custom': ['OPENAI_API_KEY', 'OPENAI_BASE_URL'], - 'openaiResponses-custom': ['OPENAI_API_KEY', 'OPENAI_BASE_URL'], - 'claude-custom': ['CLAUDE_API_KEY', 'CLAUDE_BASE_URL'], - 'gemini-cli-oauth': ['PROJECT_ID', 'GEMINI_OAUTH_CREDS_FILE_PATH', 'GEMINI_BASE_URL'], - 'claude-kiro-oauth': ['KIRO_OAUTH_CREDS_FILE_PATH', 'KIRO_BASE_URL', 'KIRO_REFRESH_URL', 'KIRO_REFRESH_IDC_URL'], - 'openai-qwen-oauth': ['QWEN_OAUTH_CREDS_FILE_PATH', 'QWEN_BASE_URL', 'QWEN_OAUTH_BASE_URL'], - 'gemini-antigravity': ['PROJECT_ID', 'ANTIGRAVITY_OAUTH_CREDS_FILE_PATH', 'ANTIGRAVITY_BASE_URL_DAILY', 'ANTIGRAVITY_BASE_URL_AUTOPUSH'], - 'openai-iflow': ['IFLOW_OAUTH_CREDS_FILE_PATH', 'IFLOW_BASE_URL'], - 'openai-codex-oauth': ['CODEX_OAUTH_CREDS_FILE_PATH', 'CODEX_EMAIL', 'CODEX_BASE_URL'], - 'grok-custom': ['GROK_COOKIE_TOKEN', 'GROK_CF_CLEARANCE', 'GROK_USER_AGENT', 'GROK_BASE_URL'], - 'forward-api': ['FORWARD_API_KEY', 'FORWARD_BASE_URL', 'FORWARD_HEADER_NAME', 'FORWARD_HEADER_VALUE_PREFIX'] - }; - - // 尝试从全局或当前模态框上下文中推断提供商类型 + // 尝试从当前模态框上下文中获取提供商类型 let providerType = currentProviderType; + + // 如果没有上下文类型,尝试从对象字段推断(回退逻辑) if (!providerType) { if (provider.OPENAI_API_KEY && provider.OPENAI_BASE_URL) { providerType = 'openai-custom'; @@ -718,8 +710,9 @@ function getFieldOrder(provider) { } } - // 获取该类型应该具有的所有字段(预定义顺序) - const predefinedOrder = providerType ? (fieldOrderMap[providerType] || []) : []; + // 直接从 utils.js 获取该类型的预定义字段列表(支持前缀匹配) + const predefinedFields = providerType ? getProviderTypeFields(providerType) : []; + const predefinedOrder = predefinedFields.map(f => f.id); // 获取当前对象中存在且不在预定义列表中的其他字段 const otherFields = Object.keys(provider).filter(key => @@ -734,12 +727,8 @@ function getFieldOrder(provider) { // 只有在字段确实存在于 provider 中,或者它是该提供商类型的预定义字段时才显示 return allExpectedFields.filter(key => - provider.hasOwnProperty(key) || predefinedOrder.includes(key) + Object.prototype.hasOwnProperty.call(provider, key) || predefinedOrder.includes(key) ); - - // 如果无法识别提供商类型,按字母顺序排序 - otherFields.sort(); - return [...orderedFields, ...otherFields].filter(key => provider.hasOwnProperty(key)); } /** diff --git a/static/app/models-manager.js b/static/app/models-manager.js index 25a5099..b976b13 100644 --- a/static/app/models-manager.js +++ b/static/app/models-manager.js @@ -199,10 +199,23 @@ function getProviderDisplayName(providerType) { 'openaiResponses-custom': 'OpenAI Responses Custom', 'openai-qwen-oauth': 'Qwen (OAuth)', 'openai-iflow': 'iFlow', - 'openai-codex-oauth': 'OpenAI Codex (OAuth)' + 'openai-codex-oauth': 'OpenAI Codex (OAuth)', + 'grok-custom': 'Grok Reverse' }; - return displayNames[providerType] || providerType; + if (displayNames[providerType]) { + return displayNames[providerType]; + } + + // 尝试前缀匹配 + for (const baseType in displayNames) { + if (providerType.startsWith(baseType + '-')) { + const suffix = providerType.substring(baseType.length + 1); + return `${displayNames[baseType]} (${suffix})`; + } + } + + return providerType; } /** @@ -220,13 +233,22 @@ function getProviderIcon(providerType) { } } - if (providerType.includes('gemini')) { - return 'fas fa-gem'; - } else if (providerType.includes('claude')) { - return 'fas fa-robot'; - } else if (providerType.includes('openai') || providerType.includes('qwen') || providerType.includes('iflow')) { - return 'fas fa-brain'; + const iconMap = { + 'gemini': 'fas fa-gem', + 'claude': 'fas fa-robot', + 'openai': 'fas fa-brain', + 'qwen': 'fas fa-brain', + 'iflow': 'fas fa-brain', + 'forward': 'fas fa-share-square', + 'grok': 'fas fa-search' + }; + + for (const key in iconMap) { + if (providerType.includes(key)) { + return iconMap[key]; + } } + return 'fas fa-server'; } diff --git a/static/app/provider-manager.js b/static/app/provider-manager.js index 1a9b12f..6238720 100644 --- a/static/app/provider-manager.js +++ b/static/app/provider-manager.js @@ -1,7 +1,7 @@ // 提供商管理功能模块 import { providerStats, updateProviderStats } from './constants.js'; -import { showToast, formatUptime, getProviderConfigs } from './utils.js'; +import { showToast, formatUptime, getProviderConfigs, getBaseProviderConfigs } from './utils.js'; import { fileUploadHandler } from './file-upload.js'; import { t, getCurrentLanguage } from './i18n.js'; import { renderRoutingExamples } from './routing-examples.js'; @@ -178,34 +178,36 @@ function updateTimeDisplay() { } /** - * 加载提供商列表 + * 加载提供商数据 + * @param {boolean} forceRefreshSupported - 是否强制刷新支持的提供商列表 */ -async function loadProviders() { +async function loadProviders(forceRefreshSupported = false) { try { - const providers = await window.apiClient.get('/providers'); + // 获取合并后的数据(包括 providers 和 supportedProviders) + const data = await window.apiClient.get('/providers'); + if (!data || !data.providers) return; - // 动态更新其他模块的提供商信息,只需更新一次 - if (!isStaticProviderConfigsUpdated) { - cachedSupportedProviders = await window.apiClient.get('/providers/supported'); + const { providers, supportedProviders } = data; + + // 检查支持列表是否发生了变化(或者是否尚未初始化) + const isChanged = !cachedSupportedProviders || + supportedProviders.length !== cachedSupportedProviders.length || + supportedProviders.some((p, i) => p !== cachedSupportedProviders[i]); + + // 如果强制刷新或是对象类型(可能是由事件触发),则也视为需要刷新 + const shouldForce = forceRefreshSupported === true || (typeof forceRefreshSupported === 'object'); + + if (isChanged || shouldForce) { + cachedSupportedProviders = supportedProviders; const providerConfigs = getProviderConfigs(cachedSupportedProviders); - // 动态更新凭据文件管理的提供商类型筛选项 - updateProviderFilterOptions(providerConfigs); - - // 动态更新仪表盘页面的路径路由调用示例 - renderRoutingExamples(providerConfigs); - - // 动态更新仪表盘页面的可用模型列表提供商信息 + // 动态更新各个页面的提供商信息 updateModelsProviderConfigs(providerConfigs); - - // 动态更新配置教程页面的提供商信息 updateTutorialProviderConfigs(providerConfigs); - - // 动态更新用量查询页面的提供商信息 updateUsageProviderConfigs(providerConfigs); - - // 动态更新配置管理页面的提供商选择标签 updateConfigProviderConfigs(providerConfigs); + updateProviderFilterOptions(providerConfigs); + renderRoutingExamples(providerConfigs); isStaticProviderConfigsUpdated = true; } @@ -319,6 +321,7 @@ function renderProviders(providers, supportedProviders = []) { ${displayName}
+ ${generateAddGroupButton(providerType)} ${generateAuthButton(providerType)}
@@ -359,6 +362,60 @@ function renderProviders(providers, supportedProviders = []) { container.appendChild(providerDiv); + // 为添加分组按钮添加事件监听 + const addGroupBtn = providerDiv.querySelector('.add-group-btn'); + if (addGroupBtn) { + addGroupBtn.addEventListener('click', (e) => { + e.stopPropagation(); + + // 使用自定义的主题风格 Prompt + showSimplePrompt( + t('providers.addGroup.title'), + t('providers.addGroup.suffixPlaceholder'), + async (suffix) => { + const cleanSuffix = suffix.toLowerCase().replace(/[^a-z0-9]/g, ''); + if (!cleanSuffix) { + showToast(t('common.warning'), '请输入有效的后缀(仅限字母和数字)', 'warning'); + return; + } + + const newProviderType = `${providerType}-${cleanSuffix}`; + + // 显示加载状态 + addGroupBtn.disabled = true; + const originalHtml = addGroupBtn.innerHTML; + addGroupBtn.innerHTML = ''; + + try { + const response = await window.apiClient.post('/providers', { + providerType: newProviderType, + providerConfig: { + customName: cleanSuffix.toUpperCase(), + isHealthy: true, + isDisabled: false, + usageCount: 0, + errorCount: 0 + } + }); + + if (response.success) { + showToast(t('common.success'), t('providers.addGroup.success'), 'success'); + await loadProviders(true); + setTimeout(() => openProviderManager(newProviderType), 500); + } else { + throw new Error(response.error?.message || 'Unknown error'); + } + } catch (error) { + console.error('Failed to add provider group:', error); + showToast(t('common.error'), t('providers.addGroup.error') + ': ' + error.message, 'error'); + addGroupBtn.disabled = false; + addGroupBtn.innerHTML = originalHtml; + } + } + ); + }); + } + // 为授权按钮添加事件监听 const authBtn = providerDiv.querySelector('.generate-auth-btn'); if (authBtn) { @@ -486,6 +543,74 @@ function generateAuthButton(providerType) { `; } +/** + * 显示一个极简的主题风格输入框 + * @param {string} title - 标题 + * @param {string} placeholder - 占位符 + * @param {function} callback - 确认回调 + */ +function showSimplePrompt(title, placeholder, callback) { + const overlay = document.createElement('div'); + overlay.className = 'modal-overlay'; + overlay.style.display = 'flex'; + overlay.style.zIndex = '3000'; + overlay.style.background = 'rgba(0, 0, 0, 0.2)'; + overlay.style.backdropFilter = 'blur(2px)'; + + overlay.innerHTML = ` + + `; + + document.body.appendChild(overlay); + + const input = overlay.querySelector('#simple-prompt-input'); + const submitBtn = overlay.querySelector('#simple-prompt-submit'); + + input.focus(); + + const finish = () => { + const val = input.value.trim(); + if (val) { + overlay.remove(); + callback(val); + } + }; + + submitBtn.onclick = finish; + input.onkeydown = (e) => { + if (e.key === 'Enter') finish(); + if (e.key === 'Escape') overlay.remove(); + }; + overlay.onclick = (e) => { + if (e.target === overlay) overlay.remove(); + }; +} + +/** + * 生成添加分组按钮HTML + * @param {string} providerType - 提供商类型 + * @returns {string} 按钮HTML + */ +function generateAddGroupButton(providerType) { + const allowedTypes = ['claude-custom', 'openai-custom', 'openaiResponses-custom']; + if (!allowedTypes.includes(providerType)) { + return ''; + } + + return ` + + `; +} + /** * 处理生成授权链接 * @param {string} providerType - 提供商类型 @@ -3121,16 +3246,148 @@ async function restartServiceAfterUpdate() { } } +/** + * 显示添加提供商组模态框 + * @param {string} defaultBaseType - 默认的基础类型 + */ +function showAddProviderGroupModal(defaultBaseType = null) { + const modal = document.createElement('div'); + modal.className = 'modal-overlay'; + modal.style.display = 'flex'; + modal.style.zIndex = '2000'; + + // 获取所有基础母版配置,并过滤掉当前已经存在的“自定义组” + // 确保下拉菜单只显示纯净的基础类型(如 openai-custom),而不显示已有的带后缀组 + const allBaseConfigs = getBaseProviderConfigs(); + const baseTypes = allBaseConfigs.filter(config => { + // 1. 必须在后端支持的列表中 + const isSupported = cachedSupportedProviders.includes(config.id); + + // 2. 限制只能添加特定类型的配置组 (Claude Custom, OpenAI Custom, OpenAI Responses) + const allowedTypes = ['claude-custom', 'openai-custom', 'openaiResponses-custom']; + const isAllowed = allowedTypes.includes(config.id); + + return isSupported && isAllowed; + }); + + let optionsHtml = baseTypes.map(type => { + const selected = (defaultBaseType && type.id === defaultBaseType) ? 'selected' : ''; + return ``; + }).join(''); + + const selectedConfig = allBaseConfigs.find(c => c.id === defaultBaseType); + const baseTypeSectionHtml = defaultBaseType ? ` +
+ +
+ + ${selectedConfig?.name || defaultBaseType} +
+ +
+ ` : ` +
+ + +
+ `; + + modal.innerHTML = ` + + `; + + document.body.appendChild(modal); + + const closeBtn = modal.querySelector('.modal-close'); + const cancelBtn = modal.querySelector('.modal-cancel'); + const submitBtn = modal.querySelector('.modal-submit'); + const suffixInput = modal.querySelector('#groupSuffix'); + const baseTypeSelect = modal.querySelector('#groupBaseType'); + + const closeModal = () => modal.remove(); + + [closeBtn, cancelBtn].forEach(btn => btn.addEventListener('click', closeModal)); + + submitBtn.addEventListener('click', async () => { + const baseType = baseTypeSelect.value; + const suffix = suffixInput.value.trim().toLowerCase().replace(/[^a-z0-9]/g, ''); + + if (!suffix) { + showToast(t('common.warning'), '请输入有效的后缀(仅限字母和数字)', 'warning'); + return; + } + + const newProviderType = `${baseType}-${suffix}`; + + submitBtn.disabled = true; + submitBtn.innerHTML = ''; + + try { + // 创建一个带后缀的新提供商组,并添加一个初始的空配置(或者让用户在随后的模态框中添加) + // 这里我们先创建一个临时的空配置,这样组就会在 dashboard 中显示出来 + const response = await window.apiClient.post('/providers', { + providerType: newProviderType, + providerConfig: { + customName: suffix.toUpperCase(), + isHealthy: true, + isDisabled: false, + usageCount: 0, + errorCount: 0 + } + }); + + if (response.success) { + showToast(t('common.success'), t('providers.addGroup.success'), 'success'); + closeModal(); + // 重新加载提供商列表,强制刷新支持的类型 + await loadProviders(true); + // 自动打开新创建的组的管理界面 + setTimeout(() => openProviderManager(newProviderType), 500); + } else { + throw new Error(response.error?.message || 'Unknown error'); + } + } catch (error) { + console.error('Failed to add provider group:', error); + showToast(t('common.error'), t('providers.addGroup.error') + ': ' + error.message, 'error'); + submitBtn.disabled = false; + submitBtn.innerHTML = ` ${t('common.confirm')}`; + } + }); +} + export { loadSystemInfo, updateTimeDisplay, loadProviders, - renderProviders, - updateProviderStatsDisplay, openProviderManager, showAuthModal, executeGenerateAuthUrl, handleGenerateAuthUrl, checkUpdate, - performUpdate + performUpdate, + showAddProviderGroupModal }; diff --git a/static/app/routing-examples.js b/static/app/routing-examples.js index ed71b3b..4caf762 100644 --- a/static/app/routing-examples.js +++ b/static/app/routing-examples.js @@ -453,8 +453,17 @@ function renderRoutingExamples(providerConfigs) { let routeInfo = routes.find(r => r.provider === config.id); - // 如果没找到,则创建一个默认的 + // 如果没找到,则创建一个默认的,并尝试继承基础类型的徽章 if (!routeInfo) { + // 尝试查找基础类型的路由信息以获取徽章 + let baseRouteInfo = null; + for (const r of routes) { + if (config.id.startsWith(r.provider + '-')) { + baseRouteInfo = r; + break; + } + } + routeInfo = { provider: config.id, name: config.name, @@ -462,14 +471,35 @@ function renderRoutingExamples(providerConfigs) { openai: `/${config.id}/v1/chat/completions`, claude: `/${config.id}/v1/messages` }, - description: t('dashboard.routing.oauth'), - badge: t('dashboard.routing.oauth'), - badgeClass: 'oauth' + description: baseRouteInfo ? baseRouteInfo.description : t('dashboard.routing.oauth'), + badge: baseRouteInfo ? baseRouteInfo.badge : t('dashboard.routing.oauth'), + badgeClass: baseRouteInfo ? baseRouteInfo.badgeClass : 'oauth' }; } - const icon = iconMap[config.id] || 'fa-route'; - const defaultModel = modelMap[config.id] || 'default-model'; + // 确定图标:尝试精确匹配,然后尝试前缀匹配 + let icon = iconMap[config.id]; + if (!icon) { + for (const baseId in iconMap) { + if (config.id.startsWith(baseId + '-')) { + icon = iconMap[baseId]; + break; + } + } + } + icon = icon || 'fa-route'; + + // 确定默认模型:尝试精确匹配,然后尝试前缀匹配 + let defaultModel = modelMap[config.id]; + if (!defaultModel) { + for (const baseId in modelMap) { + if (config.id.startsWith(baseId + '-')) { + defaultModel = modelMap[baseId]; + break; + } + } + } + defaultModel = defaultModel || 'default-model'; const hostname = window.location.hostname === 'localhost' || window.location.hostname === '127.0.0.1' ? `http://${window.location.host}` : `${window.location.protocol}//${window.location.host}`; diff --git a/static/app/utils.js b/static/app/utils.js index f796c45..d43e29e 100644 --- a/static/app/utils.js +++ b/static/app/utils.js @@ -7,83 +7,115 @@ import { apiClient } from './auth.js'; * @param {string[]} supportedProviders - 已注册的提供商类型列表 * @returns {Object[]} 提供商配置对象数组 */ -function getProviderConfigs(supportedProviders = []) { +/** + * 获取所有基础提供商配置(母版) + * @returns {Object[]} 基础提供商配置数组 + */ +function getBaseProviderConfigs() { return [ { id: 'forward-api', name: 'NewAPI', - icon: 'fa-share-square', - visible: supportedProviders.includes('forward-api') + icon: 'fa-share-square' }, { id: 'gemini-cli-oauth', name: t('dashboard.routing.nodeName.gemini'), icon: 'fa-robot', - defaultPath: 'configs/gemini/', - visible: supportedProviders.includes('gemini-cli-oauth') + defaultPath: 'configs/gemini/' }, { id: 'gemini-antigravity', name: t('dashboard.routing.nodeName.antigravity'), icon: 'fa-rocket', - defaultPath: 'configs/antigravity/', - visible: supportedProviders.includes('gemini-antigravity') + defaultPath: 'configs/antigravity/' }, { id: 'claude-kiro-oauth', name: t('dashboard.routing.nodeName.kiro'), icon: 'fa-key', - defaultPath: 'configs/kiro/', - visible: supportedProviders.includes('claude-kiro-oauth') + defaultPath: 'configs/kiro/' }, { id: 'openai-codex-oauth', name: t('dashboard.routing.nodeName.codex'), icon: 'fa-code', - defaultPath: 'configs/codex/', - visible: supportedProviders.includes('openai-codex-oauth') + defaultPath: 'configs/codex/' }, { id: 'openai-qwen-oauth', name: t('dashboard.routing.nodeName.qwen'), icon: 'fa-cloud', - defaultPath: 'configs/qwen/', - visible: supportedProviders.includes('openai-qwen-oauth') + defaultPath: 'configs/qwen/' }, { id: 'openai-iflow', name: t('dashboard.routing.nodeName.iflow'), icon: 'fa-stream', - defaultPath: 'configs/iflow/', - visible: supportedProviders.includes('openai-iflow') + defaultPath: 'configs/iflow/' }, { id: 'grok-custom', name: t('dashboard.routing.nodeName.grok'), - icon: 'fa-user-secret', - visible: supportedProviders.includes('grok-custom') + icon: 'fa-user-secret' }, { id: 'openai-custom', name: t('dashboard.routing.nodeName.openai'), - icon: 'fa-microchip', - visible: supportedProviders.includes('openai-custom') + icon: 'fa-microchip' }, { id: 'claude-custom', name: t('dashboard.routing.nodeName.claude'), - icon: 'fa-brain', - visible: supportedProviders.includes('claude-custom') + icon: 'fa-brain' }, { id: 'openaiResponses-custom', name: 'OpenAI Responses', - icon: 'fa-reply-all', - visible: supportedProviders.includes('openaiResponses-custom') + icon: 'fa-reply-all' }, ]; } +/** + * 获取所有支持的提供商配置列表 + * @param {string[]} supportedProviders - 已注册的提供商类型列表 + * @returns {Object[]} 提供商配置对象数组 + */ +function getProviderConfigs(supportedProviders = []) { + const baseConfigs = getBaseProviderConfigs(); + + const result = []; + const usedIds = new Set(); + + // 1. 处理 supportedProviders 中匹配基础配置的类型 + baseConfigs.forEach(config => { + const isSupported = supportedProviders.includes(config.id); + result.push({ ...config, visible: isSupported }); + usedIds.add(config.id); + }); + + // 2. 处理带有后缀的自定义类型 (例如 openai-custom-test) + supportedProviders.forEach(providerId => { + if (usedIds.has(providerId)) return; + + // 查找匹配的前缀 + const baseConfig = baseConfigs.find(bc => providerId.startsWith(bc.id + '-')); + if (baseConfig) { + const suffix = providerId.substring(baseConfig.id.length + 1); + result.push({ + ...baseConfig, + id: providerId, + name: `${baseConfig.name} (${suffix})`, + visible: true + }); + usedIds.add(providerId); + } + }); + + return result; +} + /** * 格式化运行时间 * @param {number} seconds - 秒数 @@ -197,6 +229,7 @@ function getFieldLabel(key) { * @returns {Array} 字段配置数组 */ function getProviderTypeFields(providerType) { + // 基础配置字段定义 const fieldConfigs = { 'openai-custom': [ { @@ -420,7 +453,19 @@ function getProviderTypeFields(providerType) { ] }; - return fieldConfigs[providerType] || []; + // 1. 尝试精确匹配 + if (fieldConfigs[providerType]) { + return fieldConfigs[providerType]; + } + + // 2. 尝试匹配前缀 (例如 openai-custom-test -> openai-custom) + for (const baseType in fieldConfigs) { + if (providerType.startsWith(baseType + '-')) { + return fieldConfigs[baseType]; + } + } + + return []; } /** @@ -461,6 +506,7 @@ export { getFieldLabel, getProviderTypeFields, getProviderConfigs, + getBaseProviderConfigs, getProviderStats, apiRequest }; \ No newline at end of file diff --git a/static/components/section-providers.css b/static/components/section-providers.css index c14907d..f8304de 100644 --- a/static/components/section-providers.css +++ b/static/components/section-providers.css @@ -1138,6 +1138,28 @@ transform: translateY(-1px); } +/* 添加分组按钮样式 */ +.add-group-btn { + display: inline-flex; + align-items: center; + gap: 0.5rem; + padding: 0.25rem 0.75rem; + background: #ecfdf5; /* 绿色系背景 */ + color: #065f46; /* 绿色系文字 */ + border: none; + border-radius: 9999px; + font-size: 0.75rem; + font-weight: 500; + cursor: pointer; + transition: var(--transition); +} + +.add-group-btn:hover { + background: #10b981; + color: white; + transform: translateY(-1px); +} + /* 授权模态框样式 */ .modal-overlay { position: fixed; diff --git a/static/components/section-providers.html b/static/components/section-providers.html index 93b481a..69b520a 100644 --- a/static/components/section-providers.html +++ b/static/components/section-providers.html @@ -38,6 +38,9 @@