qwen-opencode-provider 1.0.4 → 1.0.6

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 +19 -24
  2. package/index.js +63 -118
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -1,12 +1,6 @@
1
1
  # OpenCode Qwen Plugin
2
2
 
3
- OpenCode plugin for Qwen AI - auto adds provider with 28+ models.
4
-
5
- ## Features
6
-
7
- - **Auto-configure**: Automatically adds Qwen provider to OpenCode
8
- - **28+ Models**: All Qwen models pre-configured
9
- - **Native auth**: Uses OpenCode's built-in auth system (`/connect`)
3
+ OpenCode plugin for Qwen AI - auto-registers provider with 28+ models.
10
4
 
11
5
  ## Installation
12
6
 
@@ -19,22 +13,35 @@ Add to `opencode.json`:
19
13
 
20
14
  ## Usage
21
15
 
22
- ### 1. Connect Qwen Account
16
+ ### Connect
17
+
23
18
  ```bash
24
19
  /connect
20
+ # Select: Other
21
+ # Enter: qwen
22
+ # Enter your Qwen token
25
23
  ```
26
- Search for "qwen" and enter your Qwen access token.
27
24
 
28
- ### 2. Get Your Token
25
+ ### Get Token
26
+
29
27
  1. Visit https://chat.qwen.ai and login
30
28
  2. Open Developer Console (F12)
31
29
  3. Run: `localStorage.getItem('token')`
32
30
 
33
- ### 3. Select Model
31
+ ### Select Model
32
+
34
33
  ```bash
35
34
  /models
35
+ # Choose any Qwen model
36
36
  ```
37
- Choose any Qwen model.
37
+
38
+ ## Features
39
+
40
+ - 👁️ Vision (image analysis)
41
+ - 🌐 Web Search
42
+ - 🧠 Thinking Mode
43
+ - 🎨 Image Generation
44
+ - 👨‍💻 Code Generation
38
45
 
39
46
  ## Supported Models
40
47
 
@@ -52,15 +59,3 @@ Choose any Qwen model.
52
59
  | qwen-web-dev | Web development |
53
60
  | qwen-full-stack | Full-stack apps |
54
61
  | qwen-cogview | Image generation |
55
-
56
- ## API Features
57
-
58
- - 👁️ Vision (image analysis)
59
- - 🌐 Web Search
60
- - 🧠 Thinking Mode
61
- - 🎨 Image Generation
62
- - 👨‍💻 Code Generation
63
-
64
- ## License
65
-
66
- MIT
package/index.js CHANGED
@@ -1,132 +1,77 @@
1
1
  /**
2
2
  * OpenCode Qwen API Plugin
3
3
  *
4
- * Automatically adds Qwen AI provider to OpenCode with 28+ models.
5
- * Uses OpenCode's built-in auth system (/connect).
4
+ * Automatically registers Qwen provider with OpenCode.
5
+ * No manual config needed - just add plugin to opencode.json!
6
6
  *
7
- * Provider ID: qwen
8
- * Base URL: https://qwen.aikit.club/v1
7
+ * Usage:
8
+ * 1. Add to opencode.json: { "plugin": ["qwen-opencode-provider"] }
9
+ * 2. Run /connect -> Select "Other" -> Enter "qwen"
9
10
  */
10
11
 
11
- import { readFileSync, writeFileSync, existsSync } from 'fs';
12
- import { join } from 'path';
13
- import { homedir } from 'os';
14
-
15
- const QWEN_BASE_URL = 'https://qwen.aikit.club/v1';
16
12
  const QWEN_PROVIDER_ID = 'qwen';
17
13
 
18
- const QWEN_MODELS = {
19
- "qwen-max": { name: "Qwen Max", description: "Latest Qwen Max model" },
20
- "qwen-max-latest": { name: "Qwen Max Latest", description: "Latest version of Qwen Max" },
21
- "qwen2.5-max": { name: "Qwen2.5 Max", description: "Best overall with vision + web search" },
22
- "qwen2.5-plus": { name: "Qwen2.5 Plus", description: "Balanced performance" },
23
- "qwen2.5-turbo": { name: "Qwen2.5 Turbo", description: "Fast responses" },
24
- "qwen2.5-14b-instruct-1m": { name: "Qwen2.5 14B Instruct 1M", description: "1M context" },
25
- "qwen2.5-72b-instruct": { name: "Qwen2.5 72B Instruct", description: "72B parameters" },
26
- "qwen2.5-coder-32b-instruct": { name: "Qwen2.5 Coder 32B", description: "Code generation" },
27
- "qwen2.5-omni-7b": { name: "Qwen2.5 Omni 7B", description: "Multimodal" },
28
- "qwen2.5-vl-32b-instruct": { name: "Qwen2.5 VL 32B", description: "Vision-language" },
29
- "qwen3-next-80b-a3b": { name: "Qwen3 Next 80B A3B", description: "Next gen" },
30
- "qwen3-235b-a22b-2507": { name: "Qwen3 235B A22B", description: "Large model" },
31
- "qwen3-30b-a3b-2507": { name: "Qwen3 30B A3B", description: "Compact high-perf" },
32
- "qwen3-coder": { name: "Qwen3 Coder", description: "Code + tool calling" },
33
- "qwen3-coder-flash": { name: "Qwen3 Coder Flash", description: "Fast code" },
34
- "qwen3-max": { name: "Qwen3 Max", description: "Best Qwen3" },
35
- "qwen3-omni-flash": { name: "Qwen3 Omni Flash", description: "Fast multimodal" },
36
- "qwen3-vl-235b-a22b": { name: "Qwen3 VL 235B", description: "Large vision" },
37
- "qwen3-vl-32b": { name: "Qwen3 VL 32B", description: "Vision 32B" },
38
- "qwen3-vl-30b-a3b": { name: "Qwen3 VL 30B A3B", description: "Compact vision" },
39
- "qvq-max": { name: "QVQ Max", description: "Vision reasoning" },
40
- "qwq-32b": { name: "QWQ 32B", description: "Reasoning with thinking" },
41
- "qwen-deep-research": { name: "Qwen Deep Research", description: "Research + web search" },
42
- "qwen-web-dev": { name: "Qwen Web Dev", description: "Web development" },
43
- "qwen-full-stack": { name: "Qwen Full Stack", description: "Full-stack apps" },
44
- "qwen-cogview": { name: "Qwen CogView", description: "Image generation" }
45
- };
46
-
47
- function getConfigPath() {
48
- return join(homedir(), '.config', 'opencode', 'opencode.json');
49
- }
50
-
51
- function readConfig() {
52
- const configPath = getConfigPath();
53
- if (!existsSync(configPath)) return null;
54
- try {
55
- return JSON.parse(readFileSync(configPath, 'utf-8'));
56
- } catch {
57
- return null;
58
- }
59
- }
60
-
61
- function writeConfig(config) {
62
- writeFileSync(getConfigPath(), JSON.stringify(config, null, 2));
63
- }
64
-
65
- function isQwenProviderConfigured(config) {
66
- return config?.provider?.[QWEN_PROVIDER_ID] !== undefined;
67
- }
68
-
69
- function addQwenProvider() {
70
- let config = readConfig();
71
-
72
- const qwenConfig = {
73
- npm: "@ai-sdk/openai-compatible",
74
- name: "Qwen AI",
75
- options: {
76
- baseURL: QWEN_BASE_URL,
77
- headers: {
78
- "Authorization": "Bearer ${QWEN_API_KEY}"
14
+ export const QwenPlugin = async (ctx) => {
15
+ return {
16
+ config: async (config) => {
17
+ // Auto-add Qwen provider to config
18
+ if (!config.provider) {
19
+ config.provider = {};
79
20
  }
80
- },
81
- models: QWEN_MODELS
82
- };
83
-
84
- if (!config) {
85
- config = {
86
- $schema: "https://opencode.ai/config.json",
87
- provider: {
88
- [QWEN_PROVIDER_ID]: qwenConfig
21
+
22
+ if (!config.provider[QWEN_PROVIDER_ID]) {
23
+ config.provider[QWEN_PROVIDER_ID] = {
24
+ npm: '@ai-sdk/openai-compatible',
25
+ name: 'Qwen AI',
26
+ options: {
27
+ baseURL: 'https://qwen.aikit.club/v1'
28
+ },
29
+ models: {
30
+ 'qwen-max': { name: 'Qwen Max' },
31
+ 'qwen-max-latest': { name: 'Qwen Max Latest' },
32
+ 'qwen2.5-max': { name: 'Qwen2.5 Max' },
33
+ 'qwen2.5-plus': { name: 'Qwen2.5 Plus' },
34
+ 'qwen2.5-turbo': { name: 'Qwen2.5 Turbo' },
35
+ 'qwen2.5-14b-instruct-1m': { name: 'Qwen2.5 14B Instruct 1M' },
36
+ 'qwen2.5-72b-instruct': { name: 'Qwen2.5 72B Instruct' },
37
+ 'qwen2.5-coder-32b-instruct': { name: 'Qwen2.5 Coder 32B' },
38
+ 'qwen2.5-omni-7b': { name: 'Qwen2.5 Omni 7B' },
39
+ 'qwen2.5-vl-32b-instruct': { name: 'Qwen2.5 VL 32B' },
40
+ 'qwen3-next-80b-a3b': { name: 'Qwen3 Next 80B A3B' },
41
+ 'qwen3-235b-a22b-2507': { name: 'Qwen3 235B A22B' },
42
+ 'qwen3-30b-a3b-2507': { name: 'Qwen3 30B A3B' },
43
+ 'qwen3-coder': { name: 'Qwen3 Coder' },
44
+ 'qwen3-coder-flash': { name: 'Qwen3 Coder Flash' },
45
+ 'qwen3-max': { name: 'Qwen3 Max' },
46
+ 'qwen3-omni-flash': { name: 'Qwen3 Omni Flash' },
47
+ 'qwen3-vl-235b-a22b': { name: 'Qwen3 VL 235B' },
48
+ 'qwen3-vl-32b': { name: 'Qwen3 VL 32B' },
49
+ 'qwen3-vl-30b-a3b': { name: 'Qwen3 VL 30B A3B' },
50
+ 'qvq-max': { name: 'QVQ Max' },
51
+ 'qwq-32b': { name: 'QWQ 32B' },
52
+ 'qwen-deep-research': { name: 'Qwen Deep Research' },
53
+ 'qwen-web-dev': { name: 'Qwen Web Dev' },
54
+ 'qwen-full-stack': { name: 'Qwen Full Stack' },
55
+ 'qwen-cogview': { name: 'Qwen CogView' }
56
+ }
57
+ };
89
58
  }
90
- };
91
- } else {
92
- if (!config.provider) config.provider = {};
93
- if (!isQwenProviderConfigured(config)) {
94
- config.provider[QWEN_PROVIDER_ID] = qwenConfig;
95
- }
96
- }
97
-
98
- writeConfig(config);
99
- return true;
100
- }
101
-
102
- export const QwenPlugin = async ({ client }) => {
103
- try {
104
- const config = readConfig();
105
- if (!isQwenProviderConfigured(config)) {
106
- addQwenProvider();
107
- await client.app.log({
108
- body: {
109
- service: "qwen-plugin",
110
- level: "info",
111
- message: "Qwen provider added to OpenCode config"
112
- }
113
- });
114
- }
115
- } catch (error) {
116
- // Silent fail
117
- }
118
-
119
- return {
120
- "installation.updated": async ({ installation }) {
121
- try {
122
- const config = readConfig();
123
- if (config?.provider?.[QWEN_PROVIDER_ID]) {
124
- config.provider[QWEN_PROVIDER_ID].models = QWEN_MODELS;
125
- writeConfig(config);
59
+ },
60
+
61
+ auth: {
62
+ provider: QWEN_PROVIDER_ID,
63
+ loader: async (auth, provider) => {
64
+ // Load and return the API key
65
+ return {
66
+ apiKey: auth?.apiKey || ''
67
+ };
68
+ },
69
+ methods: [
70
+ {
71
+ type: 'api',
72
+ label: 'API Key'
126
73
  }
127
- } catch (error) {
128
- // Silent fail
129
- }
74
+ ]
130
75
  }
131
76
  };
132
77
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "qwen-opencode-provider",
3
- "version": "1.0.4",
3
+ "version": "1.0.6",
4
4
  "description": "OpenCode plugin for Qwen API - auto adds provider with 28+ models",
5
5
  "main": "index.js",
6
6
  "type": "module",