opencode-qwen-cli-auth 2.2.9 → 2.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,62 +1,261 @@
1
- # opencode-qwen-cli-auth (local fork)
2
-
3
- Plugin OAuth cho **OpenCode** để dùng Qwen theo cơ chế giống **qwen-code CLI** (free tier bằng Qwen account), không cần DashScope API key.
4
-
5
- ## Cấu hình nhanh
6
-
7
- `opencode.json`:
8
-
9
- ```json
10
- {
11
- "$schema": "https://opencode.ai/config.json",
12
- "plugin": ["opencode-qwen-cli-auth"],
13
- "model": "qwen-code/coder-model"
14
- }
15
- ```
16
-
17
- Đăng nhập:
18
-
19
- ```bash
20
- opencode auth login
21
- ```
22
-
23
- Chọn provider **Qwen Code (qwen.ai OAuth)**.
24
-
25
- ## sao plugin trước bị `insufficient_quota`?
26
-
27
- Từ việc đối chiếu với **qwen-code** (gốc), request free-tier cần:
28
-
29
- - Base URL đúng (DashScope OpenAI-compatible):
30
- - mặc định: `https://dashscope.aliyuncs.com/compatible-mode/v1`
31
- - có thể thay đổi theo `resource_url` trong `~/.qwen/oauth_creds.json`
32
- - Headers DashScope đặc thù:
33
- - `X-DashScope-AuthType: qwen-oauth`
34
- - `X-DashScope-CacheControl: enable`
35
- - `User-Agent` + `X-DashScope-UserAgent`
36
- - Giới hạn output token theo model (qwen-code):
37
- - `coder-model`: 65536
38
- - `vision-model`: 8192
39
-
40
- Fork này đã **inject headers ở tầng fetch** để vẫn hoạt động ngay cả khi OpenCode không gọi hook `chat.headers`.
41
-
42
- ## Debug / logging
43
-
44
- ```bash
45
- DEBUG_QWEN_PLUGIN=1 opencode run "hello" --model=qwen-code/coder-model
46
- ENABLE_PLUGIN_REQUEST_LOGGING=1 opencode run "hello" --model=qwen-code/coder-model
47
- ```
48
-
49
- Log path: `~/.opencode/logs/qwen-plugin/`
50
-
51
- ## Clear auth
52
-
53
- PowerShell:
54
-
55
- ```powershell
56
- Remove-Item -Recurse -Force "$HOME/.opencode/qwen"
57
- Remove-Item -Recurse -Force "$HOME/.qwen" # nếu muốn xoá token qwen-code luôn
58
- ```
59
-
60
- ## Ghi chú build
61
-
62
- Repo này chỉ chứa output `dist/` (không có `src/`/`tsconfig.json`), nên `npm run build/typecheck` sẽ không compile lại TS.
1
+ # opencode-qwen-cli-auth
2
+
3
+ OAuth plugin for [OpenCode](https://opencode.ai) to use Qwen for free via Qwen Account, compatible with the [qwen-code CLI](https://github.com/QwenLM/qwen-code) mechanism.
4
+
5
+ ## Features
6
+
7
+ - **OAuth 2.0 Device Authorization Grant** (RFC 8628) - login with your Qwen Account
8
+ - **No API key required** - utilize Qwen's free tier
9
+ - **Automatic token refresh** when expired
10
+ - **DashScope compatibility** - automatically injects required headers for the OAuth flow
11
+ - **Smart output token limit** - auto-caps tokens based on model (65K for coder-model, 8K for vision-model)
12
+ - **Retry & Fallback** - handles quota/rate limit errors with payload degradation mechanism
13
+ - **Logging & Debugging** - detailed debugging support via environment variables
14
+
15
+ ## Installation
16
+
17
+ ### Requirements
18
+
19
+ - Node.js >= 20.0.0
20
+ - OpenCode with plugin support
21
+ - Qwen Account (free)
22
+
23
+ ### Add to OpenCode
24
+
25
+ Configure in `opencode.json`:
26
+
27
+ ```json
28
+ {
29
+ "$schema": "https://opencode.ai/config.json",
30
+ "plugin": ["opencode-qwen-cli-auth"],
31
+ "model": "qwen-code/coder-model"
32
+ }
33
+ ```
34
+
35
+ ### Login
36
+
37
+ ```bash
38
+ opencode auth login
39
+ ```
40
+
41
+ Select provider **Qwen Code (qwen.ai OAuth)** and follow the instructions:
42
+
43
+ 1. Open the URL displayed in the terminal
44
+ 2. Enter the provided code
45
+ 3. The plugin will automatically poll and save the token
46
+
47
+ ## Supported Models
48
+
49
+ | Model | ID | Context | Max Output | Cost |
50
+ |-------|-----|---------|------------|---------|
51
+ | Qwen Coder (Qwen 3.5 Plus) | `coder-model` | 1M tokens | 65,536 tokens | Free |
52
+ | Qwen VL Plus (Vision) | `vision-model` | 128K tokens | 8,192 tokens | Free |
53
+
54
+ ## Configuration
55
+
56
+ ### Environment Variables
57
+
58
+ | Variable | Description | Value |
59
+ |------|-------|---------|
60
+ | `QWEN_CLI_PATH` | Path to qwen CLI (for fallback) | Default: auto-detect |
61
+ | `QWEN_MODE` | Qwen mode toggle | `1`/`true` (default) |
62
+ | `DEBUG_QWEN_PLUGIN=1` | Enable debug logging | Optional |
63
+ | `ENABLE_PLUGIN_REQUEST_LOGGING=1` | Enable request logging to file | Optional |
64
+ | `OPENCODE_QWEN_ENABLE_CLI_FALLBACK=1` | Enable CLI fallback on quota error | Optional |
65
+
66
+ ### Debug & Logging
67
+
68
+ ```bash
69
+ # Debug mode - logs to console
70
+ DEBUG_QWEN_PLUGIN=1 opencode run "hello" --model=qwen-code/coder-model
71
+
72
+ # Request logging - saves detailed JSON files
73
+ ENABLE_PLUGIN_REQUEST_LOGGING=1 opencode run "hello" --model=qwen-code/coder-model
74
+ ```
75
+
76
+ Log files are stored at: `~/.opencode/logs/qwen-plugin/`
77
+
78
+ ## How It Works
79
+
80
+ ### OAuth Flow
81
+
82
+ ```
83
+ 1. OpenCode requests auth -> Plugin
84
+ 2. Plugin requests device code from Qwen OAuth Server
85
+ 3. Displays URL + code to user
86
+ 4. User opens URL and enters code to authorize
87
+ 5. Plugin polls token from Qwen OAuth Server
88
+ 6. Saves token and returns to OpenCode
89
+ 7. All API requests are injected with headers and sent to DashScope
90
+ ```
91
+
92
+ ### Token Storage
93
+
94
+ - **Location**: `~/.qwen/oauth_creds.json`
95
+ - **Format**: JSON with access_token, refresh_token, expiry_date, resource_url
96
+ - **Auto-refresh**: Triggered when less than 30 seconds to expiration
97
+ - **Lock mechanism**: Safe multi-process token refresh
98
+
99
+ ### Required Headers
100
+
101
+ The plugin automatically injects required headers for DashScope OAuth:
102
+
103
+ ```
104
+ X-DashScope-AuthType: qwen-oauth
105
+ X-DashScope-CacheControl: enable
106
+ User-Agent: opencode-qwen-cli-auth/{version}
107
+ X-DashScope-UserAgent: opencode-qwen-cli-auth/{version}
108
+ ```
109
+
110
+ ## Error Handling
111
+
112
+ ### Insufficient Quota
113
+
114
+ When hitting a `429 insufficient_quota` error, the plugin automatically:
115
+
116
+ 1. **Degrades payload** - removes tools, reduces max_tokens to 1024
117
+ 2. **Retries** - attempts request with degraded payload
118
+ 3. **CLI fallback** (optional) - invokes `qwen` CLI if `OPENCODE_QWEN_ENABLE_CLI_FALLBACK=1` is set
119
+
120
+ ### Token Expiration
121
+
122
+ - Automatically uses refresh token
123
+ - Retries up to 2 times for transient errors (timeout, network)
124
+ - Clears token and requests re-auth on 401/403
125
+
126
+ ## Authentication Management
127
+
128
+ ### Check Status
129
+
130
+ ```bash
131
+ # View saved token
132
+ cat ~/.qwen/oauth_creds.json
133
+ ```
134
+
135
+ ### Remove Authentication
136
+
137
+ **PowerShell:**
138
+ ```powershell
139
+ Remove-Item -Recurse -Force "$HOME/.opencode/qwen"
140
+ Remove-Item -Force "$HOME/.qwen/oauth_creds.json"
141
+ ```
142
+
143
+ **Bash (Linux/macOS):**
144
+ ```bash
145
+ rm -rf ~/.opencode/qwen
146
+ rm ~/.qwen/oauth_creds.json
147
+ ```
148
+
149
+ ### Manual Refresh
150
+
151
+ ```bash
152
+ # Clear old token and login again
153
+ opencode auth logout
154
+ opencode auth login
155
+ ```
156
+
157
+ ## Plugin Architecture
158
+
159
+ ```
160
+ dist/
161
+ ├── index.js # Entry point, exports QwenAuthPlugin
162
+ ├── lib/
163
+ │ ├── auth/
164
+ │ │ ├── auth.js # OAuth flow: device code, poll token, refresh
165
+ │ │ └── browser.js # Browser opener utility
166
+ │ ├── config.js # Config paths, QWEN_MODE
167
+ │ ├── constants.js # Constants: OAuth endpoints, headers, errors
168
+ │ ├── logger.js # Logging utilities
169
+ │ └── types.js # TypeScript types
170
+ ```
171
+
172
+ ### Internal Hooks Used
173
+
174
+ | Hook | Purpose |
175
+ |------|----------|
176
+ | `auth.loader` | Provides apiKey, baseURL, custom fetch |
177
+ | `auth.methods.authorize` | Device Authorization OAuth flow |
178
+ | `config` | Registers provider and models |
179
+ | `chat.params` | Sets timeout, maxRetries, max_tokens limits |
180
+ | `chat.headers` | Injects DashScope headers |
181
+
182
+ ## Comparison with Previous Plugin
183
+
184
+ | Feature | Old Plugin | This Plugin |
185
+ |-----------|-----------|------------|
186
+ | OAuth Device Flow | ✓ | ✓ |
187
+ | Custom fetch layer | ✗ | ✓ |
188
+ | DashScope headers | ✗ | ✓ (auto-inject) |
189
+ | Output token capping | ✗ | ✓ |
190
+ | Quota degradation | ✗ | ✓ |
191
+ | CLI fallback | ✗ | ✓ (optional) |
192
+ | Multi-process lock | ✗ | ✓ |
193
+ | Legacy token migration | ✗ | ✓ |
194
+
195
+ ## Troubleshooting
196
+
197
+ ### Common Issues
198
+
199
+ **1. Persistent `insufficient_quota` errors**
200
+ - Your account may have exhausted the free tier quota
201
+ - Try deleting the token and logging in again
202
+ - Enable CLI fallback: `OPENCODE_QWEN_ENABLE_CLI_FALLBACK=1`
203
+
204
+ **2. OAuth timeout**
205
+ - Check network connection
206
+ - Increase timeout in config if needed
207
+ - View detailed logs with `DEBUG_QWEN_PLUGIN=1`
208
+
209
+ **3. Cannot find qwen CLI**
210
+ - Install qwen-code: `npm install -g @qwen-code/qwen-code`
211
+ - Or set env var: `QWEN_CLI_PATH=/path/to/qwen`
212
+
213
+ **4. Token not saving**
214
+ - Check write permissions for `~/.qwen/` directory
215
+ - View logs with `ENABLE_PLUGIN_REQUEST_LOGGING=1`
216
+
217
+ ## Development
218
+
219
+ ### Build
220
+
221
+ ```bash
222
+ npm install
223
+ npm run build
224
+ ```
225
+
226
+ ### Test
227
+
228
+ ```bash
229
+ npm test
230
+ ```
231
+
232
+ ### Type Check
233
+
234
+ ```bash
235
+ npm run typecheck
236
+ ```
237
+
238
+ ### Lint & Format
239
+
240
+ ```bash
241
+ npm run lint
242
+ npm run format
243
+ ```
244
+
245
+ ## License
246
+
247
+ MIT
248
+
249
+ ## Repository
250
+
251
+ - **Source**: https://github.com/TVD-00/opencode-qwen-cli-auth
252
+ - **Issues**: https://github.com/TVD-00/opencode-qwen-cli-auth/issues
253
+ - **NPM**: https://www.npmjs.com/package/opencode-qwen-cli-auth
254
+
255
+ ## Author
256
+
257
+ Geoff Hammond
258
+
259
+ ## Contributing
260
+
261
+ All contributions (PRs, issues, feedback) are welcome at the GitHub repository.
package/README.vi.md ADDED
@@ -0,0 +1,261 @@
1
+ # opencode-qwen-cli-auth
2
+
3
+ Plugin OAuth cho [OpenCode](https://opencode.ai) để sử dụng Qwen miễn phí thông qua Qwen Account, tương thích với cơ chế của [qwen-code CLI](https://github.com/QwenLM/qwen-code).
4
+
5
+ ## Tính năng
6
+
7
+ - **OAuth 2.0 Device Authorization Grant** (RFC 8628) - đăng nhập bằng Qwen Account
8
+ - **Không cần API key** - sử dụng free tier của Qwen
9
+ - **Tự động refresh token** khi hết hạn
10
+ - **Tương thích DashScope** - tự động inject headers cần thiết cho OAuth flow
11
+ - **Giới hạn output token thông minh** - tự động cap theo model (65K cho coder-model, 8K cho vision-model)
12
+ - **Retry & Fallback** - xử lý lỗi quota/rate limit với cơ chế degrade (giảm tải payload)
13
+ - **Logging & Debugging** - hỗ trợ debug chi tiết qua biến môi trường
14
+
15
+ ## Cài đặt
16
+
17
+ ### Yêu cầu
18
+
19
+ - Node.js >= 20.0.0
20
+ - OpenCode có hỗ trợ plugin
21
+ - Qwen Account (miễn phí)
22
+
23
+ ### Thêm vào OpenCode
24
+
25
+ Cấu hình trong file `opencode.json`:
26
+
27
+ ```json
28
+ {
29
+ "$schema": "https://opencode.ai/config.json",
30
+ "plugin": ["opencode-qwen-cli-auth"],
31
+ "model": "qwen-code/coder-model"
32
+ }
33
+ ```
34
+
35
+ ### Đăng nhập
36
+
37
+ ```bash
38
+ opencode auth login
39
+ ```
40
+
41
+ Chọn provider **Qwen Code (qwen.ai OAuth)** và làm theo hướng dẫn:
42
+
43
+ 1. Mở URL hiển thị trong terminal
44
+ 2. Nhập mã code được cung cấp
45
+ 3. Plugin sẽ tự động poll và lưu token
46
+
47
+ ## Models hỗ trợ
48
+
49
+ | Model | ID | Context | Max Output | Chi phí |
50
+ |-------|-----|---------|------------|---------|
51
+ | Qwen Coder (Qwen 3.5 Plus) | `coder-model` | 1M tokens | 65,536 tokens | Miễn phí |
52
+ | Qwen VL Plus (Vision) | `vision-model` | 128K tokens | 8,192 tokens | Miễn phí |
53
+
54
+ ## Cấu hình
55
+
56
+ ### Biến môi trường
57
+
58
+ | Biến | Mô tả | Giá trị |
59
+ |------|-------|---------|
60
+ | `QWEN_CLI_PATH` | Đường dẫn đến qwen CLI (cho fallback) | Mặc định: tự động tìm |
61
+ | `QWEN_MODE` | Bật/tắt Qwen mode | `1`/`true` (mặc định) |
62
+ | `DEBUG_QWEN_PLUGIN=1` | Bật debug logging | Tùy chọn |
63
+ | `ENABLE_PLUGIN_REQUEST_LOGGING=1` | Bật ghi log request ra file | Tùy chọn |
64
+ | `OPENCODE_QWEN_ENABLE_CLI_FALLBACK=1` | Bật tính năng gọi CLI khi hết quota | Tùy chọn |
65
+
66
+ ### Debug & Logging
67
+
68
+ ```bash
69
+ # Debug mode - in log ra console
70
+ DEBUG_QWEN_PLUGIN=1 opencode run "hello" --model=qwen-code/coder-model
71
+
72
+ # Request logging - lưu chi tiết vào file JSON
73
+ ENABLE_PLUGIN_REQUEST_LOGGING=1 opencode run "hello" --model=qwen-code/coder-model
74
+ ```
75
+
76
+ File log được lưu tại: `~/.opencode/logs/qwen-plugin/`
77
+
78
+ ## Cơ chế hoạt động
79
+
80
+ ### Luồng OAuth (OAuth Flow)
81
+
82
+ ```
83
+ 1. OpenCode yêu cầu xác thực -> Plugin
84
+ 2. Plugin xin cấp device code từ Qwen OAuth Server
85
+ 3. Hiển thị URL + code cho người dùng
86
+ 4. Người dùng mở URL và nhập code để ủy quyền
87
+ 5. Plugin liên tục gọi (poll) Qwen OAuth Server để lấy token
88
+ 6. Lưu token và trả về cho OpenCode
89
+ 7. Tất cả request API sẽ được đính kèm headers và gửi đến DashScope
90
+ ```
91
+
92
+ ### Lưu trữ Token
93
+
94
+ - **Vị trí**: `~/.qwen/oauth_creds.json`
95
+ - **Định dạng**: JSON chứa access_token, refresh_token, expiry_date, resource_url
96
+ - **Tự động refresh**: Kích hoạt khi token còn dưới 30 giây là hết hạn
97
+ - **Cơ chế khóa (Lock)**: Đảm bảo an toàn khi refresh token trong môi trường đa tiến trình (multi-process)
98
+
99
+ ### Headers Bắt buộc
100
+
101
+ Plugin tự động đính kèm các headers cần thiết cho DashScope OAuth:
102
+
103
+ ```
104
+ X-DashScope-AuthType: qwen-oauth
105
+ X-DashScope-CacheControl: enable
106
+ User-Agent: opencode-qwen-cli-auth/{version}
107
+ X-DashScope-UserAgent: opencode-qwen-cli-auth/{version}
108
+ ```
109
+
110
+ ## Xử lý lỗi
111
+
112
+ ### Hết Quota (Insufficient Quota)
113
+
114
+ Khi gặp lỗi `429 insufficient_quota`, plugin sẽ tự động:
115
+
116
+ 1. **Degrade payload** - loại bỏ mảng tools, giảm max_tokens xuống 1024
117
+ 2. **Retry** - thử gọi lại API với payload đã giảm tải
118
+ 3. **CLI fallback** (tùy chọn) - gọi `qwen` CLI nếu biến `OPENCODE_QWEN_ENABLE_CLI_FALLBACK=1` được bật
119
+
120
+ ### Token Hết Hạn
121
+
122
+ - Tự động sử dụng refresh token để lấy token mới
123
+ - Thử lại tối đa 2 lần đối với các lỗi tạm thời (timeout, lỗi mạng)
124
+ - Xóa token cũ và yêu cầu đăng nhập lại nếu nhận lỗi 401/403
125
+
126
+ ## Quản lý xác thực
127
+
128
+ ### Kiểm tra trạng thái
129
+
130
+ ```bash
131
+ # Xem token đang được lưu
132
+ cat ~/.qwen/oauth_creds.json
133
+ ```
134
+
135
+ ### Xóa xác thực
136
+
137
+ **PowerShell:**
138
+ ```powershell
139
+ Remove-Item -Recurse -Force "$HOME/.opencode/qwen"
140
+ Remove-Item -Force "$HOME/.qwen/oauth_creds.json"
141
+ ```
142
+
143
+ **Bash (Linux/macOS):**
144
+ ```bash
145
+ rm -rf ~/.opencode/qwen
146
+ rm ~/.qwen/oauth_creds.json
147
+ ```
148
+
149
+ ### Refresh thủ công
150
+
151
+ ```bash
152
+ # Xóa token cũ và đăng nhập lại
153
+ opencode auth logout
154
+ opencode auth login
155
+ ```
156
+
157
+ ## Kiến trúc Plugin
158
+
159
+ ```
160
+ dist/
161
+ ├── index.js # Entry point, exports QwenAuthPlugin
162
+ ├── lib/
163
+ │ ├── auth/
164
+ │ │ ├── auth.js # Luồng OAuth: device code, poll token, refresh
165
+ │ │ └── browser.js # Tiện ích mở trình duyệt
166
+ │ ├── config.js # Đường dẫn cấu hình, QWEN_MODE
167
+ │ ├── constants.js # Hằng số: OAuth endpoints, headers, mã lỗi
168
+ │ ├── logger.js # Tiện ích logging
169
+ │ └── types.js # Định nghĩa kiểu (TypeScript)
170
+ ```
171
+
172
+ ### Các Hook Sử Dụng
173
+
174
+ | Hook | Mục đích |
175
+ |------|----------|
176
+ | `auth.loader` | Cung cấp apiKey, baseURL, custom fetch |
177
+ | `auth.methods.authorize` | Thực hiện luồng Device Authorization OAuth |
178
+ | `config` | Đăng ký provider và models |
179
+ | `chat.params` | Thiết lập timeout, maxRetries, giới hạn max_tokens |
180
+ | `chat.headers` | Đính kèm các headers của DashScope |
181
+
182
+ ## So sánh với Plugin Cũ
183
+
184
+ | Tính năng | Plugin cũ | Plugin này |
185
+ |-----------|-----------|------------|
186
+ | OAuth Device Flow | ✓ | ✓ |
187
+ | Custom fetch layer | ✗ | ✓ |
188
+ | Headers của DashScope | ✗ | ✓ (tự động đính kèm) |
189
+ | Giới hạn Output token | ✗ | ✓ |
190
+ | Degradation khi hết quota| ✗ | ✓ |
191
+ | Fallback dùng CLI | ✗ | ✓ (tùy chọn) |
192
+ | Khóa đa tiến trình | ✗ | ✓ |
193
+ | Migrate token cũ | ✗ | ✓ |
194
+
195
+ ## Khắc phục sự cố (Troubleshooting)
196
+
197
+ ### Các lỗi thường gặp
198
+
199
+ **1. Bị lỗi `insufficient_quota` liên tục**
200
+ - Tài khoản của bạn có thể đã hết hạn mức miễn phí
201
+ - Hãy thử xóa token và đăng nhập lại
202
+ - Bật tính năng CLI fallback: `OPENCODE_QWEN_ENABLE_CLI_FALLBACK=1`
203
+
204
+ **2. OAuth timeout**
205
+ - Kiểm tra lại kết nối mạng
206
+ - Tăng timeout trong cấu hình nếu cần
207
+ - Xem log chi tiết bằng cách bật `DEBUG_QWEN_PLUGIN=1`
208
+
209
+ **3. Không tìm thấy qwen CLI**
210
+ - Cài đặt qwen-code: `npm install -g @qwen-code/qwen-code`
211
+ - Hoặc cấu hình biến: `QWEN_CLI_PATH=/path/to/qwen`
212
+
213
+ **4. Không lưu được token**
214
+ - Kiểm tra quyền ghi (write permissions) cho thư mục `~/.qwen/`
215
+ - Xem log bằng cách bật `ENABLE_PLUGIN_REQUEST_LOGGING=1`
216
+
217
+ ## Phát triển
218
+
219
+ ### Build
220
+
221
+ ```bash
222
+ npm install
223
+ npm run build
224
+ ```
225
+
226
+ ### Test
227
+
228
+ ```bash
229
+ npm test
230
+ ```
231
+
232
+ ### Type Check
233
+
234
+ ```bash
235
+ npm run typecheck
236
+ ```
237
+
238
+ ### Lint & Format
239
+
240
+ ```bash
241
+ npm run lint
242
+ npm run format
243
+ ```
244
+
245
+ ## Giấy phép (License)
246
+
247
+ MIT
248
+
249
+ ## Repository
250
+
251
+ - **Mã nguồn**: https://github.com/TVD-00/opencode-qwen-cli-auth
252
+ - **Báo lỗi (Issues)**: https://github.com/TVD-00/opencode-qwen-cli-auth/issues
253
+ - **NPM**: https://www.npmjs.com/package/opencode-qwen-cli-auth
254
+
255
+ ## Tác giả
256
+
257
+ Geoff Hammond
258
+
259
+ ## Đóng góp
260
+
261
+ Mọi sự đóng góp (PR, issue, feedback) đều được hoan nghênh tại GitHub repository.