mseptiaan/opencode-qwencode-oauth
GitHub: mseptiaan/opencode-qwencode-oauth
OpenCode 的 Qwen OAuth 认证插件,提供多账号智能轮换、API 格式转换和流式响应桥接,让用户在 OpenCode 中直接使用通义千问模型。
Stars: 49 | Forks: 5
# OpenCode Qwen Auth 插件
[](https://www.npmjs.com/package/opencode-qwencode-oauth)
[](https://www.npmjs.com/package/opencode-qwencode-oauth)
[](https://github.com/mseptiaan/opencode-qwencode-oauth/actions)
[](LICENSE)
[](https://bun.sh)
[OpenCode](https://opencode.ai) 的 Qwen OAuth 认证插件,支持多账号轮换、主动 token 刷新和自动 API 转换。
## 功能
- **Device Flow OAuth** - PKCE 安全认证,适用于无头/CI 环境
- **多账号支持** - 存储并在多个 Qwen 账号之间进行轮换
- **混合账号轮换** - 使用健康分数、令牌桶和 LRU 进行智能选择
- **主动 Token 刷新** - 在 token 过期前自动刷新
- **速率限制处理** - 检测 429 响应,轮换账号,遵循 retry-after
- **API 转换** - 桥接 OpenAI Responses API ↔ Chat Completions API
- **流式支持** - 完整的 SSE 转换,用于实时响应
- **跨平台** - 适用于 macOS、Linux 和 Windows
## 安装说明
### 让 LLM 来做
将此内容粘贴到任何 LLM 代理(Claude Code、OpenCode、Cursor 等)中:
```
Install the opencode-qwencode-oauth plugin by following: https://raw.githubusercontent.com/mseptiaan/opencode-qwencode-oauth/main/README.md
```
### 快速安装(推荐)
添加到你的 `opencode.json` 中:
```
{
"$schema": "https://opencode.ai/config.json",
"plugin": ["opencode-qwencode-oauth"],
"provider": {
"qwen": {
"npm": "@ai-sdk/openai",
"options": {
"baseURL": "https://portal.qwen.ai/v1",
"compatibility": "strict"
},
"models": {
"coder-model": {
"id": "coder-model",
"name": "Qwen Coder",
"limit": {
"context": 1048576,
"output": 65536
},
"modalities": {
"input": [
"text",
"image"
],
"output": [
"text"
]
},
"attachment": true
}
}
}
}
}
```
## 快速开始
1. 在你的项目目录中启动 OpenCode:
opencode
2. 使用 Qwen 进行身份验证:
/connect
选择 **Qwen OAuth** 并按照设备流程说明进行操作。
3. 开始使用 Qwen 模型进行编码:
/model qwen/coder-model
## 配置
**无需配置。** 该插件开箱即用,并具有合理的默认设置。
配置按层级加载,后者优先级高于前者:
1. 内置默认值
2. 用户配置(`~/.config/opencode/qwen.json`)
3. 项目配置(`.opencode/qwen.json`)
4. 环境变量
### 可用选项
| 选项 | 默认值 | 描述 |
| ------ | ------- | ----------- |
| `rotation_strategy` | `"hybrid"` | 账号轮换策略(`hybrid`、`round-robin`、`sequential`) |
| `proactive_refresh` | `true` | 在 token 过期前刷新 |
| `refresh_window_seconds` | `300` | 触发主动刷新的过期前秒数 |
| `max_rate_limit_wait_seconds` | `300` | 当所有账号都受速率限制时的最大等待时间(0 = 无限制) |
| `quiet_mode` | `false` | 抑制信息日志输出 |
| `pid_offset_enabled` | `false` | 在运行并行会话时按进程 PID 分配负载 |
| `health_score` | (见下文) | 微调健康分数参数 |
| `token_bucket` | (见下文) | 微调令牌桶参数 |
### 环境变量
| 变量 | 配置键 |
| -------- | ---------- |
| `QWEN_OAUTH_CLIENT_ID` | `client_id` |
| `QWEN_OAUTH_BASE_URL` | `oauth_base_url` |
| `QWEN_API_BASE_URL` | `base_url` |
| `QWEN_ROTATION_STRATEGY` | `rotation_strategy` |
| `QWEN_PROACTIVE_REFRESH` | `proactive_refresh` |
| `QWEN_REFRESH_WINDOW_SECONDS` | `refresh_window_seconds` |
| `QWEN_MAX_RATE_LIMIT_WAIT_SECONDS` | `max_rate_limit_wait_seconds` |
| `QWEN_QUIET_MODE` | `quiet_mode` |
| `QWEN_PID_OFFSET_ENABLED` | `pid_offset_enabled` |
## 模型
### 可通过 OAuth 使用
| 模型 | 上下文窗口 | 特性 |
| ----- | -------------- | -------- |
| `coder-model` | 1M tokens | 文本 + 图像输入,流式传输 |
## 多账号轮换
添加多个账号以实现更高吞吐量:
1. 运行 `/connect` 并完成首次登录
2. 再次运行 `/connect` 以添加其他账号
3. 插件会自动在账号之间进行轮换
### 轮换策略
- **hybrid**(默认):结合健康分数、令牌桶速率限制和 LRU 的智能选择。账号随时间被动恢复健康状态。
- **round-robin**:每次请求循环使用账号。
- **sequential**:使用一个账号直到受到速率限制,然后切换。
#### 混合策略详情
混合策略使用加权评分算法:
- **健康分数 (0-100)**:跟踪账号健康状况。成功奖励 (+1),速率限制惩罚 (-10),失败惩罚更重 (-20)。账号在休息时被动恢复 +2 点/小时。
- **令牌桶**:客户端速率限制(最大 50 个 token,每分钟恢复 6 个)以防止达到服务器 429 错误。
- **LRU 新鲜度**:优先选择最近未使用的账号。
分数公式:
```
Score = (healthScore × 2) + ((tokens / maxTokens) × 100 × 5) + (min(secondsSinceUsed, 3600) × 0.1)
```
最大可能的组件值(总最大值 ≈ 1060 点):
| 组件 | 最大点数 | 影响 |
| --------- | ---------- | --------- |
| 健康分数 | 200 pts | ~19% |
| 令牌余额 | 500 pts | ~47% |
| 新鲜度 (LRU) | 360 pts | ~34% |
健康分数低于 `min_usable`(默认值:50)或令牌桶耗尽的账号将被排除在选择范围之外。
当运行多个并行会话(例如 oh-my-opencode)时,启用 `pid_offset_enabled: true` 以在账号之间分配负载。
#### 自定义健康分数
```
{
"health_score": {
"initial": 70,
"success_reward": 1,
"rate_limit_penalty": -10,
"failure_penalty": -20,
"recovery_rate_per_hour": 2,
"min_usable": 50
}
}
```
#### 自定义令牌桶
```
{
"token_bucket": {
"max_tokens": 50,
"regeneration_rate_per_minute": 6
}
}
```
## 工作原理
此插件桥接了 OpenCode 的 Responses API 格式与 Qwen 的 Chat Completions API:
```
OpenCode → [Responses API] → Plugin → [Chat Completions] → Qwen
↓
OpenCode ← [Responses API] ← Plugin ← [Chat Completions] ← Qwen
```
### 请求转换
| Responses API | Chat Completions API |
| ------------- | -------------------- |
| `input` | `messages` |
| `input_text` | `text` 内容类型 |
| `input_image` | `image_url` 内容类型 |
| `instructions` | System 消息 |
| `max_output_tokens` | `max_tokens` |
| `text.format` | `response_format` |
### 响应转换(流式传输)
将 SSE 事件从 Chat Completions 转换为 Responses API 格式:
- `response.created`
- `response.output_item.added`
- `response.content_part.added`
- `response.output_text.delta`
- `response.completed`
## 存储位置
| 数据 | Linux / macOS | Windows |
| ---- | ------------- | ------- |
| 用户配置 | `~/.config/opencode/qwen.json` | `%APPDATA%\opencode\qwen.json` |
| 项目配置 | `.opencode/qwen.json` | `.opencode/qwen.json` |
| 账号 Token | `~/.config/opencode/qwen-auth-accounts.json` | `%APPDATA%\opencode\qwen-auth-accounts.json` |
| 追踪器状态 | `~/.config/opencode/qwen-auth-tracker-state.json` | `%APPDATA%\opencode\qwen-auth-tracker-state.json` |
在 Linux/macOS 上遵循 `XDG_CONFIG_HOME` 配置。
**安全说明**:所有 token 和状态文件均以受限权限 (0600) 存储。请确保适当的文件系统安全性。
## 故障排除
### 身份验证问题
**"invalid_grant" 错误**
- 你的刷新 token 已过期或已被撤销。该账号会自动从轮换中排除。运行 `/connect` 以重新进行身份验证。
**设备代码已过期**
- 在启动 `/connect` 后的 5 分钟内完成浏览器登录。
### 速率限制
**频繁的 429 错误**
- 使用 `/connect` 添加更多账号。
- 在配置中增加 `max_rate_limit_wait_seconds`。
- 混合策略的令牌桶在达到服务器限制之前提供了客户端保护。
### 调试日志
设置 `QWEN_DEBUG=1` 以向 stderr(以及可选的日志文件)启用详细调试输出。
### 重置插件状态
要重新开始,请删除账号和跟踪器状态文件:
```
rm ~/.config/opencode/qwen-auth-accounts.json
rm ~/.config/opencode/qwen-auth-tracker-state.json
```
## 开发
本项目使用 [Bun](https://bun.sh) 进行开发。
### 前置条件
- [Bun](https://bun.sh) 1.0+
- Node.js 20+(为了 npm 兼容性)
### 快速入门
```
# 安装 dependencies
bun install
# Build
bun run build
# 运行 tests (135 个 tests)
bun test
# 以 watch 模式运行 tests
bun test --watch
# 运行 with coverage
bun test --coverage
# Lint
bun run lint
# Auto-fix lint 问题
bun run lint:fix
# Type-check
bun run typecheck
# 运行 e2e test (需要经过身份验证的 Qwen 账户)
bun run test:e2e
# Link 用于本地测试
bun link
```
### 使用 npm
```
npm install
npm run build
npm test
```
## 已知限制
- Qwen 不支持音频输入(`input_audio`),会被转换为占位符文本。
## 许可证
MIT 许可证。详见 [LICENSE](LICENSE)。
[OpenCode](https://opencode.ai) 的 Qwen OAuth 认证插件,支持多账号轮换、主动 token 刷新和自动 API 转换。
## 功能
- **Device Flow OAuth** - PKCE 安全认证,适用于无头/CI 环境
- **多账号支持** - 存储并在多个 Qwen 账号之间进行轮换
- **混合账号轮换** - 使用健康分数、令牌桶和 LRU 进行智能选择
- **主动 Token 刷新** - 在 token 过期前自动刷新
- **速率限制处理** - 检测 429 响应,轮换账号,遵循 retry-after
- **API 转换** - 桥接 OpenAI Responses API ↔ Chat Completions API
- **流式支持** - 完整的 SSE 转换,用于实时响应
- **跨平台** - 适用于 macOS、Linux 和 Windows
## 安装说明
### 让 LLM 来做
将此内容粘贴到任何 LLM 代理(Claude Code、OpenCode、Cursor 等)中:
```
Install the opencode-qwencode-oauth plugin by following: https://raw.githubusercontent.com/mseptiaan/opencode-qwencode-oauth/main/README.md
```
### 快速安装(推荐)
添加到你的 `opencode.json` 中:
```
{
"$schema": "https://opencode.ai/config.json",
"plugin": ["opencode-qwencode-oauth"],
"provider": {
"qwen": {
"npm": "@ai-sdk/openai",
"options": {
"baseURL": "https://portal.qwen.ai/v1",
"compatibility": "strict"
},
"models": {
"coder-model": {
"id": "coder-model",
"name": "Qwen Coder",
"limit": {
"context": 1048576,
"output": 65536
},
"modalities": {
"input": [
"text",
"image"
],
"output": [
"text"
]
},
"attachment": true
}
}
}
}
}
```
## 快速开始
1. 在你的项目目录中启动 OpenCode:
opencode
2. 使用 Qwen 进行身份验证:
/connect
选择 **Qwen OAuth** 并按照设备流程说明进行操作。
3. 开始使用 Qwen 模型进行编码:
/model qwen/coder-model
## 配置
**无需配置。** 该插件开箱即用,并具有合理的默认设置。
配置按层级加载,后者优先级高于前者:
1. 内置默认值
2. 用户配置(`~/.config/opencode/qwen.json`)
3. 项目配置(`.opencode/qwen.json`)
4. 环境变量
### 可用选项
| 选项 | 默认值 | 描述 |
| ------ | ------- | ----------- |
| `rotation_strategy` | `"hybrid"` | 账号轮换策略(`hybrid`、`round-robin`、`sequential`) |
| `proactive_refresh` | `true` | 在 token 过期前刷新 |
| `refresh_window_seconds` | `300` | 触发主动刷新的过期前秒数 |
| `max_rate_limit_wait_seconds` | `300` | 当所有账号都受速率限制时的最大等待时间(0 = 无限制) |
| `quiet_mode` | `false` | 抑制信息日志输出 |
| `pid_offset_enabled` | `false` | 在运行并行会话时按进程 PID 分配负载 |
| `health_score` | (见下文) | 微调健康分数参数 |
| `token_bucket` | (见下文) | 微调令牌桶参数 |
### 环境变量
| 变量 | 配置键 |
| -------- | ---------- |
| `QWEN_OAUTH_CLIENT_ID` | `client_id` |
| `QWEN_OAUTH_BASE_URL` | `oauth_base_url` |
| `QWEN_API_BASE_URL` | `base_url` |
| `QWEN_ROTATION_STRATEGY` | `rotation_strategy` |
| `QWEN_PROACTIVE_REFRESH` | `proactive_refresh` |
| `QWEN_REFRESH_WINDOW_SECONDS` | `refresh_window_seconds` |
| `QWEN_MAX_RATE_LIMIT_WAIT_SECONDS` | `max_rate_limit_wait_seconds` |
| `QWEN_QUIET_MODE` | `quiet_mode` |
| `QWEN_PID_OFFSET_ENABLED` | `pid_offset_enabled` |
## 模型
### 可通过 OAuth 使用
| 模型 | 上下文窗口 | 特性 |
| ----- | -------------- | -------- |
| `coder-model` | 1M tokens | 文本 + 图像输入,流式传输 |
## 多账号轮换
添加多个账号以实现更高吞吐量:
1. 运行 `/connect` 并完成首次登录
2. 再次运行 `/connect` 以添加其他账号
3. 插件会自动在账号之间进行轮换
### 轮换策略
- **hybrid**(默认):结合健康分数、令牌桶速率限制和 LRU 的智能选择。账号随时间被动恢复健康状态。
- **round-robin**:每次请求循环使用账号。
- **sequential**:使用一个账号直到受到速率限制,然后切换。
#### 混合策略详情
混合策略使用加权评分算法:
- **健康分数 (0-100)**:跟踪账号健康状况。成功奖励 (+1),速率限制惩罚 (-10),失败惩罚更重 (-20)。账号在休息时被动恢复 +2 点/小时。
- **令牌桶**:客户端速率限制(最大 50 个 token,每分钟恢复 6 个)以防止达到服务器 429 错误。
- **LRU 新鲜度**:优先选择最近未使用的账号。
分数公式:
```
Score = (healthScore × 2) + ((tokens / maxTokens) × 100 × 5) + (min(secondsSinceUsed, 3600) × 0.1)
```
最大可能的组件值(总最大值 ≈ 1060 点):
| 组件 | 最大点数 | 影响 |
| --------- | ---------- | --------- |
| 健康分数 | 200 pts | ~19% |
| 令牌余额 | 500 pts | ~47% |
| 新鲜度 (LRU) | 360 pts | ~34% |
健康分数低于 `min_usable`(默认值:50)或令牌桶耗尽的账号将被排除在选择范围之外。
当运行多个并行会话(例如 oh-my-opencode)时,启用 `pid_offset_enabled: true` 以在账号之间分配负载。
#### 自定义健康分数
```
{
"health_score": {
"initial": 70,
"success_reward": 1,
"rate_limit_penalty": -10,
"failure_penalty": -20,
"recovery_rate_per_hour": 2,
"min_usable": 50
}
}
```
#### 自定义令牌桶
```
{
"token_bucket": {
"max_tokens": 50,
"regeneration_rate_per_minute": 6
}
}
```
## 工作原理
此插件桥接了 OpenCode 的 Responses API 格式与 Qwen 的 Chat Completions API:
```
OpenCode → [Responses API] → Plugin → [Chat Completions] → Qwen
↓
OpenCode ← [Responses API] ← Plugin ← [Chat Completions] ← Qwen
```
### 请求转换
| Responses API | Chat Completions API |
| ------------- | -------------------- |
| `input` | `messages` |
| `input_text` | `text` 内容类型 |
| `input_image` | `image_url` 内容类型 |
| `instructions` | System 消息 |
| `max_output_tokens` | `max_tokens` |
| `text.format` | `response_format` |
### 响应转换(流式传输)
将 SSE 事件从 Chat Completions 转换为 Responses API 格式:
- `response.created`
- `response.output_item.added`
- `response.content_part.added`
- `response.output_text.delta`
- `response.completed`
## 存储位置
| 数据 | Linux / macOS | Windows |
| ---- | ------------- | ------- |
| 用户配置 | `~/.config/opencode/qwen.json` | `%APPDATA%\opencode\qwen.json` |
| 项目配置 | `.opencode/qwen.json` | `.opencode/qwen.json` |
| 账号 Token | `~/.config/opencode/qwen-auth-accounts.json` | `%APPDATA%\opencode\qwen-auth-accounts.json` |
| 追踪器状态 | `~/.config/opencode/qwen-auth-tracker-state.json` | `%APPDATA%\opencode\qwen-auth-tracker-state.json` |
在 Linux/macOS 上遵循 `XDG_CONFIG_HOME` 配置。
**安全说明**:所有 token 和状态文件均以受限权限 (0600) 存储。请确保适当的文件系统安全性。
## 故障排除
### 身份验证问题
**"invalid_grant" 错误**
- 你的刷新 token 已过期或已被撤销。该账号会自动从轮换中排除。运行 `/connect` 以重新进行身份验证。
**设备代码已过期**
- 在启动 `/connect` 后的 5 分钟内完成浏览器登录。
### 速率限制
**频繁的 429 错误**
- 使用 `/connect` 添加更多账号。
- 在配置中增加 `max_rate_limit_wait_seconds`。
- 混合策略的令牌桶在达到服务器限制之前提供了客户端保护。
### 调试日志
设置 `QWEN_DEBUG=1` 以向 stderr(以及可选的日志文件)启用详细调试输出。
### 重置插件状态
要重新开始,请删除账号和跟踪器状态文件:
```
rm ~/.config/opencode/qwen-auth-accounts.json
rm ~/.config/opencode/qwen-auth-tracker-state.json
```
## 开发
本项目使用 [Bun](https://bun.sh) 进行开发。
### 前置条件
- [Bun](https://bun.sh) 1.0+
- Node.js 20+(为了 npm 兼容性)
### 快速入门
```
# 安装 dependencies
bun install
# Build
bun run build
# 运行 tests (135 个 tests)
bun test
# 以 watch 模式运行 tests
bun test --watch
# 运行 with coverage
bun test --coverage
# Lint
bun run lint
# Auto-fix lint 问题
bun run lint:fix
# Type-check
bun run typecheck
# 运行 e2e test (需要经过身份验证的 Qwen 账户)
bun run test:e2e
# Link 用于本地测试
bun link
```
### 使用 npm
```
npm install
npm run build
npm test
```
## 已知限制
- Qwen 不支持音频输入(`input_audio`),会被转换为占位符文本。
## 许可证
MIT 许可证。详见 [LICENSE](LICENSE)。
法律声明
### 预期用途 - 仅限个人/内部开发使用 - 遵守内部配额和数据处理政策 - 不得用于生产服务或绕过预期限制 ### 警告 使用此插件即表示你承认: - **服务条款风险** — 此方法可能违反 AI 模型提供商的 ToS - **账号风险** — 提供商可能会暂停或封禁账号 - **不作保证** — API 可能会随时更改,恕不另行通知 - **风险承担** — 你需承担所有法律、财务和技术风险 ### 免责声明 - 与 QWEN 和阿里巴巴没有关联。这是一个独立的开源项目。 - "QWEN" 和 "Alibaba" 是阿里巴巴公司的商标。标签:API转换, Bun, Chat Completions, DLL 劫持, LLM代理, MITM代理, NPM包, OAuth认证, OpenAI兼容, OpenCode, OSV-Scalibr, PKCE, Qwen, SSE流式传输, Token刷新, TypeScript, 人工智能, 多账号轮换, 大语言模型, 安全插件, 开源, 插件开发, 无头环境, 暗色界面, 用户模式Hook绕过, 自动化攻击, 通义千问, 限流处理