qwen-opencode-provider 1.0.3 → 1.0.5

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.
Files changed (3) hide show
  1. package/README.md +55 -114
  2. package/index.js +67 -173
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -1,144 +1,85 @@
1
1
  # OpenCode Qwen Plugin
2
2
 
3
- Plugin cho OpenCode để thêm Qwen AI provider với đầy đủ models.
3
+ OpenCode plugin for Qwen AI - auto-configures models when provider is added.
4
4
 
5
- ## Tính năng
5
+ ## Installation
6
6
 
7
- - **Tự động thêm Qwen provider** vào OpenCode config
8
- - ✅ **28+ Qwen models** được tích hợp sẵn
9
- - ✅ **Custom tools** để làm việc với Qwen API:
10
- - `qwen-validate-token` - Validate Qwen token
11
- - `qwen-list-models` - Liệt kê models
12
- - `qwen-setup` - Hướng dẫn cài đặt
13
- - `qwen-test` - Test kết nối API
14
-
15
- ## Cài đặt
16
-
17
- ### Cách 1: Local Plugin (Khuyến nghị)
18
-
19
- 1. **Tạo thư mục plugins:**
20
- ```bash
21
- mkdir -p ~/.config/opencode/plugins
22
- ```
23
-
24
- 2. **Copy plugin vào thư mục:**
25
- ```bash
26
- cp -r opencode-qwen-plugin/* ~/.config/opencode/plugins/qwen/
27
- ```
28
-
29
- 3. **Tạo package.json trong config directory:**
30
- ```bash
31
- mkdir -p ~/.config/opencode
32
- cp opencode-qwen-plugin/package.json ~/.config/opencode/
33
- ```
34
-
35
- 4. **Khởi động lại OpenCode**
36
-
37
- ### Cách 2: NPM Package
38
-
39
- Thêm vào `opencode.json`:
7
+ Add to `opencode.json`:
40
8
  ```json
41
9
  {
42
10
  "plugin": ["qwen-opencode-provider"]
43
11
  }
44
12
  ```
45
13
 
46
- ## Cách lấy Qwen API Token
47
-
48
- ### Bước 1: Đăng nhập Qwen
49
- Truy cập https://chat.qwen.ai và đăng nhập
50
-
51
- ### Bước 2: Lấy Token
52
- Mở Developer Console (F12) và chạy:
53
- ```javascript
54
- localStorage.getItem('token')
55
- ```
56
-
57
- Hoặc sử dụng bookmarklet:
58
- ```javascript
59
- javascript:(function(){if(window.location.hostname!=="chat.qwen.ai"){alert("🚀 This code is for chat.qwen.ai");window.open("https://chat.qwen.ai","_blank");return;}function getApiKeyData(){const token=localStorage.getItem(!token){alert("token");if("❌ qwen access_token not found !!!");return null;}return token;}async function copyToClipboard(text){try{await navigator.clipboard.writeText(text);return true;}catch(err){console.error("❌ Failed to copy to clipboard:",err);const textarea=document.createElement("textarea");textarea.value=text;textarea.style.position="fixed";textarea.style.opacity="0";document.body.appendChild(textarea);textarea.focus();textarea.select();const success=document.execCommand("copy");document.body.removeChild(textarea);return success;}}const apiKeyData=getApiKeyData();if(!apiKeyData)return;copyToClipboard(apiKeyData).then((success)=>{if(success){alert("🔑 Qwen access_token copied to clipboard !!! 🎉");}else{prompt("🔰 Qwen access_token:",apiKeyData);}});})();
60
- ```
61
-
62
- ### Bước 3: Thêm vào OpenCode
63
- ```bash
64
- /connect
65
- ```
66
- Tìm "Qwen" và nhập token của bạn.
14
+ ## Setup Provider
67
15
 
68
- ## Sử dụng
16
+ ### Step 1: Add Provider Config
69
17
 
70
- ### Chọn model:
71
- ```bash
72
- /models
73
- ```
74
- Chọn model Qwen bạn muốn sử dụng.
75
-
76
- ### Sử dụng custom tools:
77
-
78
- ```bash
79
- # Validate token
80
- qwen-validate-token --token YOUR_TOKEN
81
-
82
- # List models
83
- qwen-list-models --apiKey YOUR_API_KEY
84
-
85
- # Test connection
86
- qwen-test --apiKey YOUR_API_KEY --message "Hello!"
87
-
88
- # Xem hướng dẫn setup
89
- qwen-setup
90
- ```
91
-
92
- ## Models có sẵn
93
-
94
- | Model | Description |
95
- |-------|-------------|
96
- | `qwen-max` | Latest Qwen Max |
97
- | `qwen2.5-max` | Best overall with vision + web search |
98
- | `qwen2.5-turbo` | Fast responses |
99
- | `qwen2.5-plus` | Balanced performance |
100
- | `qwen2.5-coder-32b` | Code generation |
101
- | `qwen3-next-80b-a3b` | Next gen 80B |
102
- | `qwen3-coder` | Code + tool calling |
103
- | `qwen3-max` | Best Qwen3 |
104
- | `qwq-32b` | Reasoning with thinking |
105
- | `qwen-deep-research` | Research + web search |
106
- | `q | Web development |
107
- wen-web-dev`| `qwen-full-stack` | Full-stack apps |
108
-
109
- ## Tính năng Qwen API
110
-
111
- - 👁️ **Vision** - Phân tích hình ảnh
112
- - 🌐 **Web Search** - Tìm kiếm web
113
- - 🧠 **Thinking Mode** - Chế độ suy nghĩ
114
- - 🎨 **Image Generation** - Tạo hình ảnh
115
- - 👨‍💻 **Code Generation** - Viết code
116
-
117
- ## Cấu hình thủ công
118
-
119
- Nếu plugin không tự động thêm provider, thêm vào `~/.config/opencode/opencode.json`:
18
+ Add this to your `opencode.json`:
120
19
 
121
20
  ```json
122
21
  {
22
+ "$schema": "https://opencode.ai/config.json",
23
+ "plugin": ["qwen-opencode-provider"],
123
24
  "provider": {
124
25
  "qwen": {
125
26
  "npm": "@ai-sdk/openai-compatible",
126
27
  "name": "Qwen AI",
127
28
  "options": {
128
- "baseURL": "https://qwen.aikit.club/v1",
129
- "headers": {
130
- "Authorization": "Bearer ${QWEN_API_KEY}"
131
- }
29
+ "baseURL": "https://qwen.aikit.club/v1"
132
30
  },
133
31
  "models": {
32
+ "qwen-max": { "name": "Qwen Max" },
134
33
  "qwen2.5-max": { "name": "Qwen2.5 Max" },
135
- "qwen2.5-turbo": { "name": "Qwen2.5 Turbo" }
34
+ "qwen2.5-plus": { "name": "Qwen2.5 Plus" },
35
+ "qwen2.5-turbo": { "name": "Qwen2.5 Turbo" },
36
+ "qwen2.5-coder-32b-instruct": { "name": "Qwen2.5 Coder 32B" },
37
+ "qwen3-coder": { "name": "Qwen3 Coder" },
38
+ "qwen3-max": { "name": "Qwen3 Max" },
39
+ "qwq-32b": { "name": "QWQ 32B" },
40
+ "qwen-deep-research": { "name": "Qwen Deep Research" }
136
41
  }
137
42
  }
138
43
  }
139
44
  }
140
45
  ```
141
46
 
142
- ## License
47
+ ### Step 2: Connect
48
+
49
+ ```bash
50
+ /connect
51
+ # Select: Other
52
+ # Enter: qwen
53
+ # Enter your Qwen token
54
+ ```
55
+
56
+ ### Step 3: Get Token
57
+
58
+ 1. Visit https://chat.qwen.ai and login
59
+ 2. Open Developer Console (F12)
60
+ 3. Run: `localStorage.getItem('token')`
143
61
 
144
- MIT
62
+ ## Supported Models
63
+
64
+ | Model | Description |
65
+ |-------|-------------|
66
+ | qwen-max | Latest Qwen Max |
67
+ | qwen2.5-max | Best overall + vision + web search |
68
+ | qwen2.5-turbo | Fast responses |
69
+ | qwen2.5-plus | Balanced performance |
70
+ | qwen2.5-coder-32b | Code generation |
71
+ | qwen3-coder | Code + tool calling |
72
+ | qwen3-max | Best Qwen3 |
73
+ | qwq-32b | Reasoning with thinking |
74
+ | qwen-deep-research | Research + web search |
75
+ | qwen-web-dev | Web development |
76
+ | qwen-full-stack | Full-stack apps |
77
+ | qwen-cogview | Image generation |
78
+
79
+ ## Features
80
+
81
+ - 👁️ Vision (image analysis)
82
+ - 🌐 Web Search
83
+ - 🧠 Thinking Mode
84
+ - 🎨 Image Generation
85
+ - 👨‍💻 Code Generation
package/index.js CHANGED
@@ -1,188 +1,82 @@
1
1
  /**
2
2
  * OpenCode Qwen API Plugin
3
3
  *
4
- * This plugin automatically adds Qwen AI provider to OpenCode config.
4
+ * Automatically configures Qwen AI models when provider is added.
5
+ * No auto-creation of config files.
5
6
  *
6
- * Provider ID: qwen
7
- * Base URL: https://qwen.aikit.club/v1
7
+ * Usage:
8
+ * 1. Add to opencode.json: { "plugin": ["qwen-opencode-provider"] }
9
+ * 2. Add provider "qwen" to config (see below)
10
+ * 3. Run /connect and select "Other" -> "qwen"
11
+ *
12
+ * Provider config for opencode.json:
13
+ * {
14
+ * "provider": {
15
+ * "qwen": {
16
+ * "npm": "@ai-sdk/openai-compatible",
17
+ * "name": "Qwen AI",
18
+ * "options": {
19
+ * "baseURL": "https://qwen.aikit.club/v1"
20
+ * },
21
+ * "models": {
22
+ * "qwen-max": { "name": "Qwen Max" },
23
+ * "qwen2.5-max": { "name": "Qwen2.5 Max" },
24
+ * ...
25
+ * }
26
+ * }
27
+ * }
28
+ * }
8
29
  */
9
30
 
10
- import { readFileSync, writeFileSync, existsSync } from 'fs';
11
- import { join, dirname } from 'path';
12
- import { homedir } from 'os';
13
-
14
- // Qwen API Configuration
15
- const QWEN_BASE_URL = 'https://qwen.aikit.club/v1';
16
31
  const QWEN_PROVIDER_ID = 'qwen';
17
32
 
18
- /**
19
- * Get the OpenCode config file path
20
- */
21
- function getConfigPath() {
22
- const homeDir = homedir();
23
- return join(homeDir, '.config', 'opencode', 'opencode.json');
24
- }
25
-
26
- /**
27
- * Read and parse OpenCode config
28
- */
29
- function readConfig() {
30
- const configPath = getConfigPath();
31
- if (!existsSync(configPath)) {
32
- return null;
33
- }
34
- try {
35
- const content = readFileSync(configPath, 'utf-8');
36
- return JSON.parse(content);
37
- } catch {
38
- return null;
39
- }
40
- }
41
-
42
- /**
43
- * Write OpenCode config
44
- */
45
- function writeConfig(config) {
46
- const configPath = getConfigPath();
47
- writeFileSync(configPath, JSON.stringify(config, null, 2));
48
- }
49
-
50
- /**
51
- * Check if Qwen provider is already configured
52
- */
53
- function isQwenProviderConfigured(config) {
54
- return config?.provider?.qwen !== undefined;
55
- }
33
+ const QWEN_MODELS = {
34
+ "qwen-max": { name: "Qwen Max", description: "Latest Qwen Max model" },
35
+ "qwen-max-latest": { name: "Qwen Max Latest", description: "Latest version of Qwen Max" },
36
+ "qwen2.5-max": { name: "Qwen2.5 Max", description: "Best overall with vision + web search" },
37
+ "qwen2.5-plus": { name: "Qwen2.5 Plus", description: "Balanced performance" },
38
+ "qwen2.5-turbo": { name: "Qwen2.5 Turbo", description: "Fast responses" },
39
+ "qwen2.5-14b-instruct-1m": { name: "Qwen2.5 14B Instruct 1M", description: "1M context" },
40
+ "qwen2.5-72b-instruct": { name: "Qwen2.5 72B Instruct", description: "72B parameters" },
41
+ "qwen2.5-coder-32b-instruct": { name: "Qwen2.5 Coder 32B", description: "Code generation" },
42
+ "qwen2.5-omni-7b": { name: "Qwen2.5 Omni 7B", description: "Multimodal" },
43
+ "qwen2.5-vl-32b-instruct": { name: "Qwen2.5 VL 32B", description: "Vision-language" },
44
+ "qwen3-next-80b-a3b": { name: "Qwen3 Next 80B A3B", description: "Next gen" },
45
+ "qwen3-235b-a22b-2507": { name: "Qwen3 235B A22B", description: "Large model" },
46
+ "qwen3-30b-a3b-2507": { name: "Qwen3 30B A3B", description: "Compact high-perf" },
47
+ "qwen3-coder": { name: "Qwen3 Coder", description: "Code + tool calling" },
48
+ "qwen3-coder-flash": { name: "Qwen3 Coder Flash", description: "Fast code" },
49
+ "qwen3-max": { name: "Qwen3 Max", description: "Best Qwen3" },
50
+ "qwen3-omni-flash": { name: "Qwen3 Omni Flash", description: "Fast multimodal" },
51
+ "qwen3-vl-235b-a22b": { name: "Qwen3 VL 235B", description: "Large vision" },
52
+ "qwen3-vl-32b": { name: "Qwen3 VL 32B", description: "Vision 32B" },
53
+ "qwen3-vl-30b-a3b": { name: "Qwen3 VL 30B A3B", description: "Compact vision" },
54
+ "qvq-max": { name: "QVQ Max", description: "Vision reasoning" },
55
+ "qwq-32b": { name: "QWQ 32B", description: "Reasoning with thinking" },
56
+ "qwen-deep-research": { name: "Qwen Deep Research", description: "Research + web search" },
57
+ "qwen-web-dev": { name: "Qwen Web Dev", description: "Web development" },
58
+ "qwen-full-stack": { name: "Qwen Full Stack", description: "Full-stack apps" },
59
+ "qwen-cogview": { name: "Qwen CogView", description: "Image generation" }
60
+ };
56
61
 
57
- /**
58
- * Add Qwen provider to OpenCode config
59
- */
60
- function addQwenProvider() {
61
- const configPath = getConfigPath();
62
- let config = readConfig();
63
-
64
- if (!config) {
65
- config = {
66
- $schema: "https://opencode.ai/config.json",
67
- provider: {
68
- [QWEN_PROVIDER_ID]: {
69
- npm: "@ai-sdk/openai-compatible",
70
- name: "Qwen AI",
71
- options: {
72
- baseURL: QWEN_BASE_URL,
73
- headers: {
74
- "Authorization": "Bearer ${QWEN_API_KEY}"
75
- }
76
- },
77
- models: {
78
- "qwen-max": { name: "Qwen Max" },
79
- "qwen-max-latest": { name: "Qwen Max Latest" },
80
- "qwen2.5-max": { name: "Qwen2.5 Max" },
81
- "qwen2.5-plus": { name: "Qwen2.5 Plus" },
82
- "qwen2.5-turbo": { name: "Qwen2.5 Turbo" },
83
- "qwen2.5-14b-instruct-1m": { name: "Qwen2.5 14B Instruct 1M" },
84
- "qwen2.5-72b-instruct": { name: "Qwen2.5 72B Instruct" },
85
- "qwen2.5-coder-32b-instruct": { name: "Qwen2.5 Coder 32B" },
86
- "qwen2.5-omni-7b": { name: "Qwen2.5 Omni 7B" },
87
- "qwen2.5-vl-32b-instruct": { name: "Qwen2.5 VL 32B" },
88
- "qwen3-next-80b-a3b": { name: "Qwen3 Next 80B A3B" },
89
- "qwen3-235b-a22b-2507": { name: "Qwen3 235B A22B" },
90
- "qwen3-30b-a3b-2507": { name: "Qwen3 30B A3B" },
91
- "qwen3-coder": { name: "Qwen3 Coder" },
92
- "qwen3-coder-flash": { name: "Qwen3 Coder Flash" },
93
- "qwen3-max": { name: "Qwen3 Max" },
94
- "qwen3-omni-flash": { name: "Qwen3 Omni Flash" },
95
- "qwen3-vl-235b-a22b": { name: "Qwen3 VL 235B A22B" },
96
- "qwen3-vl-32b": { name: "Qwen3 VL 32B" },
97
- "qwen3-vl-30b-a3b": { name: "Qwen3 VL 30B A3B" },
98
- "qvq-max": { name: "QVQ Max" },
99
- "qwq-32b": { name: "QWQ 32B" },
100
- "qwen-deep-research": { name: "Qwen Deep Research" },
101
- "qwen-web-dev": { name: "Qwen Web Dev" },
102
- "qwen-full-stack": { name: "Qwen Full Stack" },
103
- "qwen-cogview": { name: "Qwen CogView" }
62
+ export const QwenPlugin = async ({ client }) => {
63
+ return {
64
+ "installation.updated": async ({ installation }) => {
65
+ // This hook runs when installation is updated
66
+ // Models are already defined in config, this is just for future updates
67
+ try {
68
+ await client.app.log({
69
+ body: {
70
+ service: "qwen-plugin",
71
+ level: "info",
72
+ message: "Qwen plugin loaded - use /connect and select Other -> qwen"
104
73
  }
105
- }
74
+ });
75
+ } catch (error) {
76
+ // Silent fail
106
77
  }
107
- };
108
- } else {
109
- if (!config.provider) {
110
- config.provider = {};
111
78
  }
112
-
113
- if (!isQwenProviderConfigured(config)) {
114
- config.provider[QWEN_PROVIDER_ID] = {
115
- npm: "@ai-sdk/openai-compatible",
116
- name: "Qwen AI",
117
- options: {
118
- baseURL: QWEN_BASE_URL,
119
- headers: {
120
- "Authorization": "Bearer ${QWEN_API_KEY}"
121
- }
122
- },
123
- models: {
124
- "qwen-max": { name: "Qwen Max" },
125
- "qwen-max-latest": { name: "Qwen Max Latest" },
126
- "qwen2.5-max": { name: "Qwen2.5 Max" },
127
- "qwen2.5-plus": { name: "Qwen2.5 Plus" },
128
- "qwen2.5-turbo": { name: "Qwen2.5 Turbo" },
129
- "qwen2.5-14b-instruct-1m": { name: "Qwen2.5 14B Instruct 1M" },
130
- "qwen2.5-72b-instruct": { name: "Qwen2.5 72B Instruct" },
131
- "qwen2.5-coder-32b-instruct": { name: "Qwen2.5 Coder 32B" },
132
- "qwen2.5-omni-7b": { name: "Qwen2.5 Omni 7B" },
133
- "qwen2.5-vl-32b-instruct": { name: "Qwen2.5 VL 32B" },
134
- "qwen3-next-80b-a3b": { name: "Qwen3 Next 80B A3B" },
135
- "qwen3-235b-a22b-2507": { name: "Qwen3 235B A22B" },
136
- "qwen3-30b-a3b-2507": { name: "Qwen3 30B A3B" },
137
- "qwen3-coder": { name: "Qwen3 Coder" },
138
- "qwen3-coder-flash": { name: "Qwen3 Coder Flash" },
139
- "qwen3-max": { name: "Qwen3 Max" },
140
- "qwen3-omni-flash": { name: "Qwen3 Omni Flash" },
141
- "qwen3-vl-235b-a22b": { name: "Qwen3 VL 235B A22B" },
142
- "qwen3-vl-32b": { name: "Qwen3 VL 32B" },
143
- "qwen3-vl-30b-a3b": { name: "Qwen3 VL 30B A3B" },
144
- "qvq-max": { name: "QVQ Max" },
145
- "qwq-32b": { name: "QWQ 32B" },
146
- "qwen-deep-research": { name: "Qwen Deep Research" },
147
- "qwen-web-dev": { name: "Qwen Web Dev" },
148
- "qwen-full-stack": { name: "Qwen Full Stack" },
149
- "qwen-cogview": { name: "Qwen CogView" }
150
- }
151
- };
152
- }
153
- }
154
-
155
- writeConfig(config);
156
- return true;
157
- }
158
-
159
- /**
160
- * OpenCode Plugin
161
- */
162
- export const QwenPlugin = async ({ client }) => {
163
- // Automatically add Qwen provider on first load
164
- try {
165
- const configPath = getConfigPath();
166
- if (!existsSync(dirname(configPath))) {
167
- return {};
168
- }
169
-
170
- const config = readConfig();
171
- if (!isQwenProviderConfigured(config)) {
172
- addQwenProvider();
173
- await client?.app?.log?.({
174
- body: {
175
- service: "qwen-plugin",
176
- level: "info",
177
- message: "Qwen provider added to OpenCode config",
178
- }
179
- });
180
- }
181
- } catch (error) {
182
- // Silently fail - provider can be added manually
183
- }
184
-
185
- return {};
79
+ };
186
80
  };
187
81
 
188
82
  export default QwenPlugin;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "qwen-opencode-provider",
3
- "version": "1.0.3",
3
+ "version": "1.0.5",
4
4
  "description": "OpenCode plugin for Qwen API - auto adds provider with 28+ models",
5
5
  "main": "index.js",
6
6
  "type": "module",