fix(provider-pool): 将默认错误阈值从1调整为3

docs: 更新Qwen Code授权方式和README-EN协议图
feat(qwen-core): 添加工具支持并优化请求头
This commit is contained in:
hex2077 2025-09-02 01:10:20 +08:00
parent 55801682da
commit bc6e317638
4 changed files with 50 additions and 40 deletions

View file

@ -16,7 +16,7 @@
[![Node.js](https://img.shields.io/badge/Node.js-≥20.0.0-green.svg)](https://nodejs.org/)
[![docker](https://img.shields.io/badge/docker-≥20.0.0-green.svg)](https://aiproxy.justlikemaki.vip/en/docs/installation/docker-deployment.html)
[**中文**](./README.md) | [**English**](./README-EN.md) | [**More Detailed Documentation**](https://aiproxy.justlikemaki.vip/)
[**中文**](./README.md) | [**English**](./README-EN.md) | [**More Detailed Documentation**](https://aiproxy.justlikemaki.vip/en/)
</div>
@ -58,33 +58,33 @@
```mermaid
graph TD
subgraph Core_Protocols["核心协议"]
P_OPENAI[OpenAI Protocol]
P_GEMINI[Gemini Protocol]
P_CLAUDE[Claude Protocol]
end
subgraph Supported_Model_Providers["支持的模型提供商"]
MP_OPENAI[openai-custom]
MP_GEMINI[gemini-cli-oauth]
MP_CLAUDE_C[claude-custom]
MP_CLAUDE_K[claude-kiro-oauth]
end
P_OPENAI ---|支持| MP_OPENAI
P_OPENAI ---|支持| MP_GEMINI
P_OPENAI ---|支持| MP_CLAUDE_C
P_OPENAI ---|支持| MP_CLAUDE_K
P_GEMINI ---|支持| MP_GEMINI
P_CLAUDE ---|支持| MP_CLAUDE_C
P_CLAUDE ---|支持| MP_CLAUDE_K
P_CLAUDE ---|支持| MP_GEMINI
style P_OPENAI fill:#f9f,stroke:#333,stroke-width:2px
style P_GEMINI fill:#ccf,stroke:#333,stroke-width:2px
style P_CLAUDE fill:#cfc,stroke:#333,stroke-width:2px
subgraph Core_Protocols["Core Protocols"]
P_OPENAI[OpenAI Protocol]
P_GEMINI[Gemini Protocol]
P_CLAUDE[Claude Protocol]
end
subgraph Supported_Model_Providers["Supported Model Providers"]
MP_OPENAI[openai-custom]
MP_GEMINI[gemini-cli-oauth]
MP_CLAUDE_C[claude-custom]
MP_CLAUDE_K[claude-kiro-oauth]
end
P_OPENAI ---|Support| MP_OPENAI
P_OPENAI ---|Support| MP_GEMINI
P_OPENAI ---|Support| MP_CLAUDE_C
P_OPENAI ---|Support| MP_CLAUDE_K
P_GEMINI ---|Support| MP_GEMINI
P_CLAUDE ---|Support| MP_CLAUDE_C
P_CLAUDE ---|Support| MP_CLAUDE_K
P_CLAUDE ---|Support| MP_GEMINI
style P_OPENAI fill:#f9f,stroke:#333,stroke-width:2px
style P_GEMINI fill:#ccf,stroke:#333,stroke-width:2px
style P_CLAUDE fill:#cfc,stroke:#333,stroke-width:2px
```
@ -95,7 +95,7 @@
* **MCP Support**: While the built-in command functions of the original Gemini CLI are unavailable, this project fully supports MCP (Model Context Protocol), enabling powerful functional extensions when paired with MCP-compatible clients.
* **Multimodal Capabilities**: Supports multimodal inputs like images and documents, offering a richer interactive experience.
* **Latest Model Support**: Supports the latest **Kimi K2**, **GLM-4.5** and **Qwen Code** models. Simply configure the corresponding OpenAI or Claude compatible interfaces in `config.json` for use.
* **Qwen Code Support**: Using Qwen Code requires configuring the `QWEN_OAUTH_CREDS_FILE_PATH` environment variable, pointing to a JSON file containing Qwen OAuth credentials.
* **Qwen Code Support**: Using Qwen Code will automatically open an authorization page in the browser. After completing authorization, it will generate an `oauth_creds.json` file in the `~/.qwen` directory. Please use the official default parameters temperature=0 and top_p=1.
* **Kiro API**: Using the Kiro API requires [downloading the Kiro client](https://aibook.ren/archives/kiro-install) and completing authorized login to generate `kiro-auth-token.json`. **Recommended for optimal experience with Claude Code**. Note: New users who encounter **429** errors when using the service indicate that the Kiro service is **no longer available**, and may need to wait until Kiro fully opens registration before being able to use it.
### Default Authorization File Paths

View file

@ -95,8 +95,7 @@ claude-kiro-oauth。
* **MCP 支持**: 虽然原版 Gemini CLI 的内置命令功能不可用,但本项目完美支持 MCP (Model Context Protocol),可配合支持 MCP 的客户端实现更强大的功能扩展。
* **多模态能力**: 支持图片、文档等多模态输入,为您提供更丰富的交互体验。
* **最新模型支持**: 支持最新的 **Kimi K2**、**GLM-4.5** 和 **Qwen Code** 模型,只需在 `config.json` 中配置相应的 OpenAI 或 Claude 兼容接口即可使用。
* **Qwen Code 支持**: 使用 Qwen Code 需要配置 `QWEN_OAUTH_CREDS_FILE_PATH` 环境变量,指向包含 Qwen OAuth 凭据的 JSON 文件。
* **Qwen Code 支持**: 使用 Qwen Code 会自动在浏览器打开授权页面,完成授权后会在 `~/.qwen` 目录下生成 `oauth_creds.json` 文件。请使用官方默认参数 temperature=0 top_p=1。
* **Kiro API**: 使用 Kiro API 需要[下载kiro客户端](https://aibook.ren/archives/kiro-install)并完成授权登录生成 kiro-auth-token.json。**推荐配合 Claude Code 使用以获得最佳体验**。注意:新注册的用户,如果使用时报**429**,表示**已不可使用** Kiro 的服务可能需要等Kiro完全开放注册后才能使用。
### 授权文件默认路径

View file

@ -29,6 +29,7 @@ const QWEN_OAUTH_SCOPE = 'openid profile email model.completion';
const QWEN_OAUTH_GRANT_TYPE = 'urn:ietf:params:oauth:grant-type:device_code';
const DEFAULT_QWEN_BASE_URL = 'https://dashscope.aliyuncs.com/compatible-mode/v1';
// const DEFAULT_QWEN_BASE_URL = 'https://portal.qwen.ai/v1';
export const QwenOAuth2Event = {
AuthUri: 'auth-uri',
@ -116,12 +117,6 @@ export class QwenApiService {
this.currentAxiosInstance = null;
}
static async create(config) {
const instance = new QwenApiService(config);
await instance.initialize();
return instance;
}
async initialize() {
if (this.isInitialized) return;
console.log('[Qwen] Initializing Qwen API Service...');
@ -367,15 +362,31 @@ export class QwenApiService {
const maxRetries = (this.config && this.config.REQUEST_MAX_RETRIES) || 3;
const baseDelay = (this.config && this.config.REQUEST_BASE_DELAY) || 1000;
const version = "0.0.9";
const userAgent = `QwenCode/${version} (${process.platform}; ${process.arch})`;
console.log(`[QwenApiService] User-Agent: ${userAgent}`);
try {
const { token, endpoint: qwenBaseUrl } = await this.getValidToken();
this.currentAxiosInstance = axios.create({
baseURL: qwenBaseUrl,
headers: { 'Content-Type': 'application/json', 'Authorization': `Bearer ${token}` },
headers: { 'Content-Type': 'application/json', 'Authorization': `Bearer ${token}` ,
'X-DashScope-CacheControl': 'enable',
'X-DashScope-UserAgent': userAgent,
'X-DashScope-AuthType': 'qwen-oauth',
},
});
const requestBody = isStream ? { ...body, stream: true } : body;
const tools = [
{
"type": "function",
"function": {
"name": "ext"
}
}
];
const requestBody = isStream ? { ...body, stream: true, tools: tools } : { ...body, tools: tools };
const options = isStream ? { responseType: 'stream' } : {};
const response = await this.currentAxiosInstance.post(endpoint, requestBody, options);
return response.data;

View file

@ -10,7 +10,7 @@ export class ProviderPoolManager {
this.providerPools = providerPools;
this.providerStatus = {}; // Tracks health and usage for each provider instance
this.roundRobinIndex = {}; // Tracks the current index for round-robin selection for each provider type
this.maxErrorCount = options.maxErrorCount || 1; // Default to 1 errors before marking unhealthy
this.maxErrorCount = options.maxErrorCount || 3; // Default to 1 errors before marking unhealthy
this.healthCheckInterval = options.healthCheckInterval || 30 * 60 * 1000; // Default to 30 minutes
this.initializeProviderStatus();
}