[PR #52] [MERGED] feat(server): 多提供商数组配置与启动初始化; fix(qwen-auth): 复用缓存凭据与账号级刷新清理 (src-only) #250

Closed
opened 2026-02-27 07:18:41 +03:00 by kerem · 0 comments
Owner

📋 Pull Request Information

Original PR: https://github.com/justlovemaki/AIClient-2-API/pull/52
Author: @d7185540
Created: 9/18/2025
Status: Merged
Merged: 9/18/2025
Merged by: @justlovemaki

Base: mainHead: feature/qwen-auth-and-providers


📝 Commits (1)

  • e7d8b23 feat(server): 多提供商数组配置与启动初始化; fix(qwen-auth): 复用缓存凭据与账号级刷新清理 (src-only)

📊 Changes

2 files changed (+272 additions, -113 deletions)

View changed files

📝 src/api-server.js (+117 -28)
📝 src/openai/qwen-core.js (+155 -85)

📄 Description

概述

  • 修复 Qwen OAuth 在号池多账号场景下的两处关键问题(缓存凭据不生效、刷新清理路径错配),显著降低频繁设备
    授权与刷新失败。
  • 增强多提供商同时启用的配置与启动体验(数组/逗号分隔配置、启动期预初始化与更清晰的日志)。
  • 提交仅包含 src/* 目录变更,便于审阅与合入。

历史问题与现象

  • 频繁设备授权:即使本地已保存有效凭据,服务仍反复触发设备授权,影响稳定性。
  • 刷新失败持续:refresh_token 失效(HTTP 400)后仍然不断失败、难以自愈,号池中的 Qwen 账号易被标记为不
    健康。
  • 多账号轮询存在但不稳定:ProviderPoolManager 可轮询到多个 Qwen 代理,但由于上面两个问题,Qwen 账号经常
    失败。

根因分析(对照历史代码)

  • 缓存可用性判断恒为失败
    • 旧版 _loadCachedQwenCredentials 设置完凭据后调用了不存在的 client.getAccessToken(),异常被吞、结果
      恒为 false,后续总进入设备授权流。
    • 参考旧实现: fe42aed 的 src/openai/qwen-core.js:297, 302-304(逻辑分布,调用 getAccessToken 的位置)
  • 刷新失败时清理了“错误路径”
    • 旧版在 HTTP 400 时删除固定路径 ~/.qwen/oauth_creds.json,与号池中“每个账号自定义的凭据路径”不一致,
      导致对应账号坏凭据未被清理,持续失败。
    • 参考旧实现: fe42aed 的 src/openai/qwen-core.js:663
  • 管理器未按账号路径隔离
    • 旧版 SharedTokenManager 内部用默认路径方法(如 getCredentialFilePath),与服务层基于账号路径写入的
      缓存错位,导致“服务读写 A 文件,管理器刷新 B 文件”。

本次修复(核心改动)

  • 按账号路径做缓存/刷新/清理(路径对齐、账号隔离)
    • 服务层显式传入账号的凭据路径,管理器基于该路径维护独立的缓存/锁/读写。
    • src/openai/qwen-core.js:11(构造时注入 tokenManagerOptions),31–37(getValidCredentials(...,
      this.tokenManagerOptions)),552–606(getContext/resolveCredentialFilePath/resolveLockFilePath)
  • 缓存凭据正确复用(避免无谓设备授权)
    • 使用 access_token 存在且 expiry_date 未临近过期判断缓存可用;可用则直接返回,不再跑设备授权。
    • src/openai/qwen-core.js:59–66(可用即返回)、322–333(移除 getAccessToken 调用,改为 access_token +
      expiry_date 判定)
  • 刷新 400 时按账号路径清理(避免误删)
    • 刷新 400 不再直接删除默认路径文件,而是抛 status=400;共享管理器捕获后删除“当前上下文账号”的凭据文
      件 context.credentialFilePath。
    • src/openai/qwen-core.js:796(抛出 err.status=400)、721(按 context.credentialFilePath 删除)

多提供商并行(配置/启动增强)

  • 支持 MODEL_PROVIDER 为数组或逗号分隔字符串,启动期标准化为 DEFAULT_MODEL_PROVIDERS,首个为默认;按
    DEFAULT_MODEL_PROVIDERS + 号池键集合 预初始化,日志展示“Primary + Additional Providers”。
  • src/api-server.js:132(normalizeConfiguredProviders)、177(启动期标准化)、455(预初始化集合)、
    701(启动日志展示)

🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.

## 📋 Pull Request Information **Original PR:** https://github.com/justlovemaki/AIClient-2-API/pull/52 **Author:** [@d7185540](https://github.com/d7185540) **Created:** 9/18/2025 **Status:** ✅ Merged **Merged:** 9/18/2025 **Merged by:** [@justlovemaki](https://github.com/justlovemaki) **Base:** `main` ← **Head:** `feature/qwen-auth-and-providers` --- ### 📝 Commits (1) - [`e7d8b23`](https://github.com/justlovemaki/AIClient-2-API/commit/e7d8b238b815b9a31e62ae9806bb85a57b113dfb) feat(server): 多提供商数组配置与启动初始化; fix(qwen-auth): 复用缓存凭据与账号级刷新清理 (src-only) ### 📊 Changes **2 files changed** (+272 additions, -113 deletions) <details> <summary>View changed files</summary> 📝 `src/api-server.js` (+117 -28) 📝 `src/openai/qwen-core.js` (+155 -85) </details> ### 📄 Description 概述 - 修复 Qwen OAuth 在号池多账号场景下的两处关键问题(缓存凭据不生效、刷新清理路径错配),显著降低频繁设备 授权与刷新失败。 - 增强多提供商同时启用的配置与启动体验(数组/逗号分隔配置、启动期预初始化与更清晰的日志)。 - 提交仅包含 src/* 目录变更,便于审阅与合入。 历史问题与现象 - 频繁设备授权:即使本地已保存有效凭据,服务仍反复触发设备授权,影响稳定性。 - 刷新失败持续:refresh_token 失效(HTTP 400)后仍然不断失败、难以自愈,号池中的 Qwen 账号易被标记为不 健康。 - 多账号轮询存在但不稳定:ProviderPoolManager 可轮询到多个 Qwen 代理,但由于上面两个问题,Qwen 账号经常 失败。 根因分析(对照历史代码) - 缓存可用性判断恒为失败 - 旧版 _loadCachedQwenCredentials 设置完凭据后调用了不存在的 client.getAccessToken(),异常被吞、结果 恒为 false,后续总进入设备授权流。 - 参考旧实现: fe42aed 的 src/openai/qwen-core.js:297, 302-304(逻辑分布,调用 getAccessToken 的位置) - 刷新失败时清理了“错误路径” - 旧版在 HTTP 400 时删除固定路径 ~/.qwen/oauth_creds.json,与号池中“每个账号自定义的凭据路径”不一致, 导致对应账号坏凭据未被清理,持续失败。 - 参考旧实现: fe42aed 的 src/openai/qwen-core.js:663 - 管理器未按账号路径隔离 - 旧版 SharedTokenManager 内部用默认路径方法(如 getCredentialFilePath),与服务层基于账号路径写入的 缓存错位,导致“服务读写 A 文件,管理器刷新 B 文件”。 本次修复(核心改动) - 按账号路径做缓存/刷新/清理(路径对齐、账号隔离) - 服务层显式传入账号的凭据路径,管理器基于该路径维护独立的缓存/锁/读写。 - src/openai/qwen-core.js:11(构造时注入 tokenManagerOptions),31–37(getValidCredentials(..., this.tokenManagerOptions)),552–606(getContext/resolveCredentialFilePath/resolveLockFilePath) - 缓存凭据正确复用(避免无谓设备授权) - 使用 access_token 存在且 expiry_date 未临近过期判断缓存可用;可用则直接返回,不再跑设备授权。 - src/openai/qwen-core.js:59–66(可用即返回)、322–333(移除 getAccessToken 调用,改为 access_token + expiry_date 判定) - 刷新 400 时按账号路径清理(避免误删) - 刷新 400 不再直接删除默认路径文件,而是抛 status=400;共享管理器捕获后删除“当前上下文账号”的凭据文 件 context.credentialFilePath。 - src/openai/qwen-core.js:796(抛出 err.status=400)、721(按 context.credentialFilePath 删除) 多提供商并行(配置/启动增强) - 支持 MODEL_PROVIDER 为数组或逗号分隔字符串,启动期标准化为 DEFAULT_MODEL_PROVIDERS,首个为默认;按 DEFAULT_MODEL_PROVIDERS + 号池键集合 预初始化,日志展示“Primary + Additional Providers”。 - src/api-server.js:132(normalizeConfiguredProviders)、177(启动期标准化)、455(预初始化集合)、 701(启动日志展示) --- <sub>🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.</sub>
kerem 2026-02-27 07:18:41 +03:00
Sign in to join this conversation.
No labels
pull-request
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
starred/AIClient-2-API-justlovemaki#250
No description provided.