From 8033c16533895fb20b4a6626a7e89a361ea52696 Mon Sep 17 00:00:00 2001 From: hex2077 Date: Sat, 6 Sep 2025 13:29:41 +0800 Subject: [PATCH] =?UTF-8?q?feat(qwen):=20=E6=9B=B4=E6=96=B0Qwen=E6=A8=A1?= =?UTF-8?q?=E5=9E=8B=E6=94=AF=E6=8C=81=E5=8F=8A=E6=96=87=E6=A1=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 调整Qwen模型列表顺序并更新默认API地址 - 在SharedTokenManager中添加凭证设置 - 更新README文档,添加Qwen支持说明及启动参数 --- README-EN.md | 216 ++++++++++++++++++++++++++++++++-------- README.md | 140 +++++++++++++++++++++++++- src/openai/qwen-core.js | 7 +- 3 files changed, 315 insertions(+), 48 deletions(-) diff --git a/README-EN.md b/README-EN.md index 25213b4..030f1bc 100644 --- a/README-EN.md +++ b/README-EN.md @@ -45,59 +45,58 @@ --- +## 🎨 Model Protocol and Provider Relationship Diagram -### 🎨 Model Protocol and Provider Relationship Diagram - - -- OpenAI Protocol (P_OPENAI): Supports all MODEL_PROVIDERs, including openai-custom, gemini-cli-oauth, claude-custom, and - claude-kiro-oauth. -- Claude Protocol (P_CLAUDE): Supports claude-custom, claude-kiro-oauth, and gemini-cli-oauth. +- OpenAI Protocol (P_OPENAI): Supports all MODEL_PROVIDERs, including openai-custom, gemini-cli-oauth, claude-custom, claude-kiro-oauth and openai-qwen-oauth. +- Claude Protocol (P_CLAUDE): Supports claude-custom, claude-kiro-oauth, gemini-cli-oauth and openai-qwen-oauth. - Gemini Protocol (P_GEMINI): Supports gemini-cli-oauth. - ```mermaid graph TD - 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 + 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] + MP_QWEN[openai-qwen-oauth] + end + + P_OPENAI ---|Support| MP_OPENAI + P_OPENAI ---|Support| MP_QWEN + 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 + P_CLAUDE ---|Support| MP_OPENAI + P_CLAUDE ---|Support| MP_QWEN + + 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 ``` --- -### 🔧 Usage Instructions +## 🔧 Usage Instructions * **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 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. - * **Using Different Providers in Claude Code**: Via Path routing, you can use different providers in Claude-related API calls: * `http://localhost:3000/claude-custom` - Use the Claude API provider defined in the configuration file * `http://localhost:3000/claude-kiro-oauth` - Access the Claude API using Kiro OAuth authentication @@ -120,24 +119,25 @@ ##### Linux / macOS ```bash - export ANTHROPIC_BASE_URL="https://api.anthropic.com" + export ANTHROPIC_BASE_URL="http://localhost:3000/claude-custom" export ANTHROPIC_AUTH_TOKEN="your-auth-token-here" - export ANTHROPIC_MODEL="claude-3-5-sonnet-20240620" + export ANTHROPIC_MODEL="your-model-name" ``` ##### Windows (CMD) ```cmd - set ANTHROPIC_BASE_URL=https://api.anthropic.com + set ANTHROPIC_BASE_URL=http://localhost:3000/claude-custom set ANTHROPIC_AUTH_TOKEN=your-auth-token-here - set ANTHROPIC_MODEL=claude-3-5-sonnet-20240620 + set ANTHROPIC_MODEL=your-model-name ``` ##### Windows (PowerShell) ```powershell - $env:ANTHROPIC_BASE_URL="https://api.anthropic.com" + $env:ANTHROPIC_BASE_URL="http://localhost:3000/claude-custom" $env:ANTHROPIC_AUTH_TOKEN="your-auth-token-here" - $env:ANTHROPIC_MODEL="claude-3-5-sonnet-20240620" + $env:ANTHROPIC_MODEL="your-model-name" ``` + ### Default Authorization File Paths The following are the default storage paths for authorization files for each service: @@ -184,8 +184,10 @@ These settings are effective only for the current PowerShell session. For perman **Please replace `your_proxy_address` and `port` with your actual proxy address and port.** +--- ## 🌟 Special Usage & Advanced Tips + * **🔌 Connect to Any OpenAI Client**: This is the fundamental feature of this project. Direct the API address of any OpenAI-compatible application (e.g., LobeChat, NextChat, VS Code extensions) to this service (`http://localhost:3000`) to seamlessly leverage all configured models. * **🔍 Centralized Request Monitoring & Auditing**: Set `"PROMPT_LOG_MODE": "file"` in `config.json` to capture all requests and responses and save them to a local log file. This is vital for analyzing, debugging, and optimizing prompts, and even for constructing private datasets. @@ -204,6 +206,136 @@ These settings are effective only for the current PowerShell session. For perman --- +## 🚀 Project Startup Parameters + +This project supports rich command-line parameter configuration, allowing flexible adjustment of service behavior as needed. The following is a detailed explanation of all startup parameters, displayed in functional groups: + +### 🔧 Server Configuration Parameters + +| Parameter | Type | Default Value | Description | +|------|------|--------|------| +| `--host` | string | localhost | Server listening address | +| `--port` | number | 3000 | Server listening port | +| `--api-key` | string | 123456 | API key required for authentication | + +### 🤖 Model Provider Configuration Parameters + +| Parameter | Type | Default Value | Description | +|------|------|--------|------| +| `--model-provider` | string | gemini-cli-oauth | AI model provider, optional values: openai-custom, claude-custom, gemini-cli-oauth, claude-kiro-oauth, openai-qwen-oauth | + +### 🧠 OpenAI Compatible Provider Parameters + +| Parameter | Type | Default Value | Description | +|------|------|--------|------| +| `--openai-api-key` | string | null | OpenAI API key (for openai-custom provider) | +| `--openai-base-url` | string | null | OpenAI API base URL (for openai-custom provider) | + +### 🖥️ Claude Compatible Provider Parameters + +| Parameter | Type | Default Value | Description | +|------|------|--------|------| +| `--claude-api-key` | string | null | Claude API key (for claude-custom provider) | +| `--claude-base-url` | string | null | Claude API base URL (for claude-custom provider) | + +### 🔐 Gemini OAuth Authentication Parameters + +| Parameter | Type | Default Value | Description | +|------|------|--------|------| +| `--gemini-oauth-creds-base64` | string | null | Base64 string of Gemini OAuth credentials | +| `--gemini-oauth-creds-file` | string | null | Gemini OAuth credentials JSON file path | +| `--project-id` | string | null | Google Cloud project ID (for gemini-cli provider) | + +### 🎮 Kiro OAuth Authentication Parameters + +| Parameter | Type | Default Value | Description | +|------|------|--------|------| +| `--kiro-oauth-creds-base64` | string | null | Base64 string of Kiro OAuth credentials | +| `--kiro-oauth-creds-file` | string | null | Kiro OAuth credentials JSON file path | + +### 🐼 Qwen OAuth Authentication Parameters + +| Parameter | Type | Default Value | Description | +|------|------|--------|------| +| `--qwen-oauth-creds-file` | string | null | Qwen OAuth credentials JSON file path | + +### 📝 System Prompt Configuration Parameters + +| Parameter | Type | Default Value | Description | +|------|------|--------|------| +| `--system-prompt-file` | string | input_system_prompt.txt | System prompt file path | +| `--system-prompt-mode` | string | overwrite | System prompt mode, optional values: overwrite, append | + +### 📊 Log Configuration Parameters + +| Parameter | Type | Default Value | Description | +|------|------|--------|------| +| `--log-prompts` | string | none | Prompt log mode, optional values: console, file, none | +| `--prompt-log-base-name` | string | prompt_log | Prompt log file base name | + +### 🔄 Retry Mechanism Parameters + +| Parameter | Type | Default Value | Description | +|------|------|--------|------| +| `--request-max-retries` | number | 3 | Maximum number of automatic retries when API requests fail | +| `--request-base-delay` | number | 1000 | Base delay time (milliseconds) between automatic retries, delay increases after each retry | + +### ⏰ Scheduled Task Parameters + +| Parameter | Type | Default Value | Description | +|------|------|--------|------| +| `--cron-near-minutes` | number | 15 | Interval time (minutes) for OAuth token refresh task schedule | +| `--cron-refresh-token` | boolean | true | Whether to enable automatic OAuth token refresh task | + +### 🎯 Account Pool Configuration Parameters + +| Parameter | Type | Default Value | Description | +|------|------|--------|------| +| `--provider-pools-file` | string | null | Provider account pool configuration file path | + +### Usage Examples + +```bash +# Basic usage +node src/api-server.js + +# Specify port and API key +node src/api-server.js --port 8080 --api-key my-secret-key + +# Use OpenAI provider +node src/api-server.js --model-provider openai-custom --openai-api-key sk-xxx --openai-base-url https://api.openai.com/v1 + +# Use Claude provider +node src/api-server.js --model-provider claude-custom --claude-api-key sk-ant-xxx --claude-base-url https://api.anthropic.com + +# Use Gemini provider (Base64 credentials) +node src/api-server.js --model-provider gemini-cli --gemini-oauth-creds-base64 eyJ0eXBlIjoi... --project-id your-project-id + +# Use Gemini provider (credentials file) +node src/api-server.js --model-provider gemini-cli --gemini-oauth-creds-file /path/to/credentials.json --project-id your-project-id + +# Configure system prompt +node src/api-server.js --system-prompt-file custom-prompt.txt --system-prompt-mode append + +# Configure logging +node src/api-server.js --log-prompts console +node src/api-server.js --log-prompts file --prompt-log-base-name my-logs + +# Complete example +node src/api-server.js \ + --host 0.0.0.0 \ + --port 3000 \ + --api-key my-secret-key \ + --model-provider gemini-cli-oauth \ + --project-id my-gcp-project \ + --gemini-oauth-creds-file ./credentials.json \ + --system-prompt-file ./custom-system-prompt.txt \ + --system-prompt-mode overwrite \ + --log-prompts file \ + --prompt-log-base-name api-logs +``` +--- + ## 📄 Open Source License This project operates under the [**GNU General Public License v3 (GPLv3)**](https://www.gnu.org/licenses/gpl-3.0). For complete details, please refer to the `LICENSE` file located in the root directory. diff --git a/README.md b/README.md index 70d02d2..d5e0735 100644 --- a/README.md +++ b/README.md @@ -49,9 +49,9 @@ ## 🎨 模型协议与提供商关系图 -- OpenAI 协议 (P_OPENAI): 支持所有 MODEL_PROVIDER,包括 openai-custom、gemini-cli-oauth、claude-custom 和 -claude-kiro-oauth。 -- Claude 协议 (P_CLAUDE): 支持 claude-custom、claude-kiro-oauth 和 gemini-cli-oauth。 +- OpenAI 协议 (P_OPENAI): 支持所有 MODEL_PROVIDER,包括 openai-custom、gemini-cli-oauth、claude-custom、 +claude-kiro-oauth 和 openai-qwen-oauth。 +- Claude 协议 (P_CLAUDE): 支持 claude-custom、claude-kiro-oauth、gemini-cli-oauth 和 openai-qwen-oauth。 - Gemini 协议 (P_GEMINI): 支持 gemini-cli-oauth。 @@ -69,9 +69,11 @@ claude-kiro-oauth。 MP_GEMINI[gemini-cli-oauth] MP_CLAUDE_C[claude-custom] MP_CLAUDE_K[claude-kiro-oauth] + MP_QWEN[openai-qwen-oauth] end P_OPENAI ---|支持| MP_OPENAI + P_OPENAI ---|支持| MP_QWEN P_OPENAI ---|支持| MP_GEMINI P_OPENAI ---|支持| MP_CLAUDE_C P_OPENAI ---|支持| MP_CLAUDE_K @@ -81,6 +83,8 @@ claude-kiro-oauth。 P_CLAUDE ---|支持| MP_CLAUDE_C P_CLAUDE ---|支持| MP_CLAUDE_K P_CLAUDE ---|支持| MP_GEMINI + P_CLAUDE ---|支持| MP_OPENAI + P_CLAUDE ---|支持| MP_QWEN style P_OPENAI fill:#f9f,stroke:#333,stroke-width:2px style P_GEMINI fill:#ccf,stroke:#333,stroke-width:2px @@ -207,6 +211,136 @@ $env:HTTP_PROXY="http://your_proxy_address:port" --- +## 🚀 项目启动参数 + +本项目支持丰富的命令行参数配置,可以根据需要灵活调整服务行为。以下是对所有启动参数的详细说明,按功能分组展示: + +### 🔧 服务器配置参数 + +| 参数 | 类型 | 默认值 | 说明 | +|------|------|--------|------| +| `--host` | string | localhost | 服务器监听地址 | +| `--port` | number | 3000 | 服务器监听端口 | +| `--api-key` | string | 123456 | 身份验证所需的 API 密钥 | + +### 🤖 模型提供商配置参数 + +| 参数 | 类型 | 默认值 | 说明 | +|------|------|--------|------| +| `--model-provider` | string | gemini-cli-oauth | AI 模型提供商,可选值:openai-custom, claude-custom, gemini-cli-oauth, claude-kiro-oauth, openai-qwen-oauth | + +### 🧠 OpenAI 兼容提供商参数 + +| 参数 | 类型 | 默认值 | 说明 | +|------|------|--------|------| +| `--openai-api-key` | string | null | OpenAI API 密钥 (用于 openai-custom 提供商) | +| `--openai-base-url` | string | null | OpenAI API 基础 URL (用于 openai-custom 提供商) | + +### 🖥️ Claude 兼容提供商参数 + +| 参数 | 类型 | 默认值 | 说明 | +|------|------|--------|------| +| `--claude-api-key` | string | null | Claude API 密钥 (用于 claude-custom 提供商) | +| `--claude-base-url` | string | null | Claude API 基础 URL (用于 claude-custom 提供商) | + +### 🔐 Gemini OAuth 认证参数 + +| 参数 | 类型 | 默认值 | 说明 | +|------|------|--------|------| +| `--gemini-oauth-creds-base64` | string | null | Gemini OAuth 凭据的 Base64 字符串 | +| `--gemini-oauth-creds-file` | string | null | Gemini OAuth 凭据 JSON 文件路径 | +| `--project-id` | string | null | Google Cloud 项目 ID (用于 gemini-cli 提供商) | + +### 🎮 Kiro OAuth 认证参数 + +| 参数 | 类型 | 默认值 | 说明 | +|------|------|--------|------| +| `--kiro-oauth-creds-base64` | string | null | Kiro OAuth 凭据的 Base64 字符串 | +| `--kiro-oauth-creds-file` | string | null | Kiro OAuth 凭据 JSON 文件路径 | + +### 🐼 Qwen OAuth 认证参数 + +| 参数 | 类型 | 默认值 | 说明 | +|------|------|--------|------| +| `--qwen-oauth-creds-file` | string | null | Qwen OAuth 凭据 JSON 文件路径 | + +### 📝 系统提示配置参数 + +| 参数 | 类型 | 默认值 | 说明 | +|------|------|--------|------| +| `--system-prompt-file` | string | input_system_prompt.txt | 系统提示文件路径 | +| `--system-prompt-mode` | string | overwrite | 系统提示模式,可选值:overwrite(覆盖), append(追加) | + +### 📊 日志配置参数 + +| 参数 | 类型 | 默认值 | 说明 | +|------|------|--------|------| +| `--log-prompts` | string | none | 提示日志模式,可选值:console(控制台), file(文件), none(无) | +| `--prompt-log-base-name` | string | prompt_log | 提示日志文件基础名称 | + +### 🔄 重试机制参数 + +| 参数 | 类型 | 默认值 | 说明 | +|------|------|--------|------| +| `--request-max-retries` | number | 3 | API 请求失败时,自动重试的最大次数 | +| `--request-base-delay` | number | 1000 | 自动重试之间的基础延迟时间(毫秒),每次重试后延迟会增加 | + +### ⏰ 定时任务参数 + +| 参数 | 类型 | 默认值 | 说明 | +|------|------|--------|------| +| `--cron-near-minutes` | number | 15 | OAuth 令牌刷新任务计划的间隔时间(分钟) | +| `--cron-refresh-token` | boolean | true | 是否开启 OAuth 令牌自动刷新任务 | + +### 🎯 号池配置参数 + +| 参数 | 类型 | 默认值 | 说明 | +|------|------|--------|------| +| `--provider-pools-file` | string | null | 提供商号池配置文件路径 | + +### 使用示例 + +```bash +# 基本用法 +node src/api-server.js + +# 指定端口和API密钥 +node src/api-server.js --port 8080 --api-key my-secret-key + +# 使用OpenAI提供商 +node src/api-server.js --model-provider openai-custom --openai-api-key sk-xxx --openai-base-url https://api.openai.com/v1 + +# 使用Claude提供商 +node src/api-server.js --model-provider claude-custom --claude-api-key sk-ant-xxx --claude-base-url https://api.anthropic.com + +# 使用Gemini提供商(Base64凭据) +node src/api-server.js --model-provider gemini-cli --gemini-oauth-creds-base64 eyJ0eXBlIjoi... --project-id your-project-id + +# 使用Gemini提供商(凭据文件) +node src/api-server.js --model-provider gemini-cli --gemini-oauth-creds-file /path/to/credentials.json --project-id your-project-id + +# 配置系统提示 +node src/api-server.js --system-prompt-file custom-prompt.txt --system-prompt-mode append + +# 配置日志 +node src/api-server.js --log-prompts console +node src/api-server.js --log-prompts file --prompt-log-base-name my-logs + +# 完整示例 +node src/api-server.js \ + --host 0.0.0.0 \ + --port 3000 \ + --api-key my-secret-key \ + --model-provider gemini-cli-oauth \ + --project-id my-gcp-project \ + --gemini-oauth-creds-file ./credentials.json \ + --system-prompt-file ./custom-system-prompt.txt \ + --system-prompt-mode overwrite \ + --log-prompts file \ + --prompt-log-base-name api-logs +``` +--- + ## 📄 开源许可 本项目遵循 [**GNU General Public License v3 (GPLv3)**](https://www.gnu.org/licenses/gpl-3.0) 开源许可。详情请查看根目录下的 `LICENSE` 文件。 diff --git a/src/openai/qwen-core.js b/src/openai/qwen-core.js index 3f8942d..00eb823 100644 --- a/src/openai/qwen-core.js +++ b/src/openai/qwen-core.js @@ -12,8 +12,8 @@ const QWEN_DIR = '.qwen'; const QWEN_CREDENTIAL_FILENAME = 'oauth_creds.json'; const QWEN_LOCK_FILENAME = 'oauth_creds.lock'; const QWEN_MODEL_LIST = [ - { id: 'qwen3-coder-flash', name: 'Qwen3 Coder Flash' }, { id: 'qwen3-coder-plus', name: 'Qwen3 Coder Plus' }, + { id: 'qwen3-coder-flash', name: 'Qwen3 Coder Flash' }, ]; const TOKEN_REFRESH_BUFFER_MS = 30 * 1000; @@ -32,8 +32,8 @@ const QWEN_OAUTH_CLIENT_ID = 'f0304373b74a44d2b584a3fb70ca9e56'; 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'; +// 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', @@ -578,6 +578,7 @@ class SharedTokenManager { } if (this.refreshPromise) return this.refreshPromise; + qwenClient.setCredentials(this.memoryCache.credentials); this.refreshPromise = this.performTokenRefresh(qwenClient, forceRefresh); const credentials = await this.refreshPromise; this.refreshPromise = null;