foxswat/opencode-qwen-auth
GitHub: foxswat/opencode-qwen-auth
为 OpenCode 提供 Qwen OAuth 认证的插件,支持多账户智能轮换和主动 Token 刷新以应对速率限制。
Stars: 25 | Forks: 1
# OpenCode Qwen Auth 插件
[](https://www.npmjs.com/package/opencode-qwen-auth)
[](https://www.npmjs.com/package/opencode-qwen-auth)
[](https://github.com/foxswat/opencode-qwen-auth/actions)
[](LICENSE)
[](https://bun.sh)
[](https://ko-fi.com/fox445353) [](#-donate-crypto-addresses) [](#-donate-crypto-addresses) [](#-donate-crypto-addresses)
为 [OpenCode](https://opencode.ai) 提供的 Qwen OAuth 认证插件,支持多账户轮换、主动 Token 刷新和自动 API 转换。
## 功能特性
- **Device Flow OAuth** - 基于 PKCE 安全认证,适用于无头/CI 环境
- **多账户支持** - 存储并在多个 Qwen 账户之间轮换
- **混合账户轮换** - 使用健康评分、Token Bucket 和 LRU 进行智能选择
- **主动 Token 刷新** - 在 Token 过期前自动刷新
- **速率限制处理** - 检测 429 响应,轮换账户,遵守 retry-after
- **API 转换** - 桥接 OpenAI Responses API 与 Chat Completions API
- **流式支持** - 完整的 SSE 转换以实现实时响应
## 安装
### 让 LLM 代劳
将此内容粘贴到任何 LLM 代理(Claude Code、OpenCode、Cursor 等)中:
```
Install the opencode-qwen-auth plugin by following: https://raw.githubusercontent.com/foxswat/opencode-qwen-auth/main/README.md
```
### 快速安装(推荐)
运行一个命令即可自动配置 OpenCode:
```
bunx opencode-qwen-auth install
# 或
npx opencode-qwen-auth install
```
这会将插件和 Qwen provider 配置添加到您的 `opencode.json` 中。
### 手动安装
如果您更喜欢手动设置:
```
# 使用 Bun
bun add opencode-qwen-auth
# 使用 npm
npm install opencode-qwen-auth
```
然后添加到您的 `opencode.json`:
```
{
"$schema": "https://opencode.ai/config.json",
"plugin": ["opencode-qwen-auth"],
"provider": {
"qwen": {
"npm": "@ai-sdk/openai",
"options": {
"baseURL": "https://portal.qwen.ai/v1",
"compatibility": "strict"
},
"models": {
"qwen3-coder-plus": {},
"qwen3-vl-plus": { "attachment": true }
}
}
}
}
```
## 快速开始
1. 在您的项目目录中启动 OpenCode:
opencode
2. 使用 Qwen 进行认证:
/connect
选择 **Qwen OAuth** 并按照设备流程说明操作。
3. 开始使用 Qwen 模型进行编码:
/model qwen/qwen3-coder-plus
## 配置
**无需配置。** 该插件开箱即用,具有合理的默认值。
要自定义行为,请在 `.opencode/qwen.json`(项目级)或 `~/.config/opencode/qwen.json`(用户级)中创建文件,仅包含您想要覆盖的选项:
```
{
// API endpoint (default: https://portal.qwen.ai/v1)
"base_url": "https://portal.qwen.ai/v1",
// OAuth client ID (default: built-in)
"client_id": "your-client-id",
// OAuth server URL (default: https://chat.qwen.ai)
"oauth_base_url": "https://chat.qwen.ai",
// Account rotation: "hybrid", "round-robin", or "sequential" (default: hybrid)
"rotation_strategy": "hybrid",
// Enable PID-based offset for multi-session load distribution (default: false)
"pid_offset_enabled": false,
// Refresh tokens before expiry (default: true)
"proactive_refresh": true,
// Seconds before expiry to trigger refresh (default: 300)
"refresh_window_seconds": 300,
// Maximum wait time when rate limited (default: 300)
"max_rate_limit_wait_seconds": 300,
// Suppress informational messages (default: false)
"quiet_mode": true
}
```
### 配置选项
| 选项 | 默认值 | 描述 |
| ----------------------------- | --------------------------- | ---------------------------------------------------------------- |
| `base_url` | `https://portal.qwen.ai/v1` | Qwen 请求的 API endpoint |
| `client_id` | (built-in) | OAuth client ID |
| `oauth_base_url` | `https://chat.qwen.ai` | OAuth 服务器 URL |
| `rotation_strategy` | `hybrid` | 账户轮换:`hybrid`、`round-robin` 或 `sequential` |
| `pid_offset_enabled` | `false` | 使用 PID offset 在账户间分配并行会话 |
| `proactive_refresh` | `true` | 在过期前刷新 Token |
| `refresh_window_seconds` | `300` | 触发刷新的过期前秒数 |
| `max_rate_limit_wait_seconds` | `300` | 被限流时的最大等待时间 |
| `quiet_mode` | `false` | 隐藏信息性消息 |
### 环境变量
所有选项都可以通过环境变量覆盖:
- `QWEN_API_BASE_URL`
- `QWEN_OAUTH_CLIENT_ID`
- `QWEN_OAUTH_BASE_URL`
- `QWEN_ROTATION_STRATEGY`
- `QWEN_PID_OFFSET_ENABLED`
- `QWEN_PROACTIVE_REFRESH`
- `QWEN_REFRESH_WINDOW_SECONDS`
- `QWEN_MAX_RATE_LIMIT_WAIT_SECONDS`
- `QWEN_QUIET_MODE`
## 模型
### 通过 OAuth 可用
| Model | Context Window | Features |
| ------------------ | -------------- | ---------------------------- |
| `qwen3-coder-plus` | 1M tokens | 针对编码任务优化 |
| `qwen3-vl-plus` | 256K tokens | 视觉 + 语言多模态 |
## 多账户轮换
添加多个账户以获得更高的吞吐量:
1. 运行 `/connect` 并完成首次登录
2. 再次运行 `/connect` 以添加其他账户
3. 插件会自动在账户之间轮换
### 轮换策略
- **hybrid**(默认):结合健康评分、Token Bucket 速率限制和 LRU 的智能选择。账户会随时间推移被动恢复健康值。
- **round-robin**:在每次请求时循环使用账户
- **sequential**:使用一个账户直到被限流,然后切换
#### Hybrid 策略详情
Hybrid 策略使用加权评分算法:
- **健康评分 (0-100)**:跟踪账户健康状况。成功奖励 (+1),速率限制惩罚 (-10),失败惩罚更多 (-20)。休息时账户被动恢复 +2 点/小时。
- **Token Bucket**:客户端速率限制(最大 50 个 Token,每分钟恢复 6 个)以防止触发服务器 429。
- **LRU Freshness**:优先选择最近未使用的账户。
评分公式:`(health × 2) + (tokens × 5) + (freshness × 0.1)`
当运行多个并行会话(例如 oh-my-opencode)时,启用 `pid_offset_enabled: true` 以将负载分配到不同账户。
## 工作原理
此插件将 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` content type |
| `input_image` | `image_url` content type |
| `instructions` | System message |
| `max_output_tokens` | `max_tokens` |
### 响应转换(流式)
将 SSE 事件从 Chat Completions 转换为 Responses API 格式:
- `response.created`
- `response.output_item.added`
- `response.content_part.added`
- `response.output_text.delta`
- `response.completed`
## 存储位置
| Data | Location |
| -------------- | -------------------------------------------- |
| User config | `~/.config/opencode/qwen.json` |
| Project config | `.opencode/qwen.json` |
| Account tokens | `~/.config/opencode/qwen-auth-accounts.json` |
**安全提示**:Token 以受限权限 (0600) 存储。请确保适当的文件系统安全。
## 故障排除
### 认证问题
**"invalid_grant" 错误**
- 您的 refresh token 已过期。运行 `/connect` 重新认证。
**Device code 过期**
- 在启动 `/connect` 后 5 分钟内完成浏览器登录。
### 速率限制
**频繁出现 429 错误**
- 使用 `/connect` 添加更多账户
- 在配置中增加 `max_rate_limit_wait_seconds`
### 重置插件状态
要重新开始,请删除账户文件:
```
rm ~/.config/opencode/qwen-auth-accounts.json
```
## 开发
本项目使用 [Bun](https://bun.sh) 进行开发。
### 前置条件
- [Bun](https://bun.sh) 1.0+(推荐)
- Node.js 20+(用于 npm 兼容性)
### 开始使用
```
# 安装依赖
bun install
# 构建
bun run build
# 运行测试
bun test
# 在 watch 模式下运行测试
bun test --watch
# 运行 e2e 测试 (需要经过认证的 Qwen 账户)
bun run test:e2e
# 链接以进行本地测试
bun link
```
### 使用 npm
该项目也适用于 npm:
```
npm install
npm run build
npm test
```
## 已知限制
- Qwen 不支持音频输入 (`input_audio`),将其转换为占位符文本
## 许可证
Apache-2.0
## 路线图
未来版本计划的功能和改进:
### 🔴 下一版本 (v0.4.0)
| Feature | Description | Status |
|---------|-------------|--------|
| **Rate Limit Deduplication** | 忽略 2 秒窗口内的重复 429 以防止连锁退避 | Planned |
| **Exponential Backoff with Jitter** | 为重试延迟增加随机性以防止惊群效应 | Planned |
| **Schema Cleaning** | 移除导致 API 拒绝的不支持的 JSON Schema 键(`const`、`$ref`、`$defs`) | Planned |
### 🟡 短期 (v0.5.0)
| Feature | Description | Status |
|---------|-------------|--------|
| **Circuit Breaker** | 在连续失败后暂时停止向失败账户发送请求 | Planned |
| **Proactive Health Checks** | 在使用前验证 Token,而不仅仅是在失败后 | Planned |
| **CLI: Status Command** | `bunx opencode-qwen-auth status` 显示账户健康和 Token 信息 | Planned |
### 🟢 中期
| Feature | Description | Status |
|---------|-------------|--------|
| **Session Recovery** | 处理中断对话中的 `tool_result_missing` 错误 | Research |
| **CLI: Uninstall Command** | 从 opencode.json 中干净地移除 | Planned |
| **Configurable Retry Strategies** | 用户可选的激进/保守重试模式 | Research |
### 🔵 未来考虑
| Feature | Description | Status |
|---------|-------------|--------|
| **Dual Quota System** | 如果 Qwen 支持,跟踪每个 API endpoint 的单独配额 | Research |
| **OAuth Server Fallback** | 当主服务器失败时尝试备用认证服务器 | Research |
| **Rate Limit Prediction** | 使用历史模式预测何时会遇到限制 | Research |
### ✅ 已完成
| Feature | Version | Description |
|---------|---------|-------------|
| CLI Installer Safety | v0.3.4 | 预览、备份、用于 CI 自动化的 `--yes` 标志 |
| Hybrid Account Rotation | v0.3.0 | 健康评分、Token Bucket、LRU freshness |
| PID Offset | v0.3.0 | 多会话负载分配 |
**想要贡献?** 请参阅 [AGENTS.md](AGENTS.md) 了解开发指南。
标签:API 转换, Bun, Device Flow, LLM 工具, OAuth 2.0, OpenCode, PKCE, Qwen, Rate Limit, SSE, TypeScript, 令牌刷新, 多账号轮换, 安全插件, 插件, 暗色界面, 流式响应, 漏洞探测, 网络安全, 自动化攻击, 认证中间件, 通义千问, 隐私保护