qwen-opencode-provider 2.0.1 → 2.0.3
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/index.js +49 -10
- package/package.json +1 -1
package/index.js
CHANGED
|
@@ -10,7 +10,8 @@ import fs from 'fs';
|
|
|
10
10
|
import path from 'path';
|
|
11
11
|
import os from 'os';
|
|
12
12
|
|
|
13
|
-
const
|
|
13
|
+
const LOG_DIR = path.join(os.homedir(), '.cache', 'opencode', 'qwen-plugin');
|
|
14
|
+
const LOG_FILE = path.join(LOG_DIR, 'debug.log');
|
|
14
15
|
const PROVIDER_ID = 'qwen';
|
|
15
16
|
const API_BASE_URL = 'https://qwen.aikit.club/v1';
|
|
16
17
|
|
|
@@ -35,8 +36,17 @@ const QWEN_MODELS = {
|
|
|
35
36
|
'qwen-cogview': { name: 'Qwen CogView' }
|
|
36
37
|
};
|
|
37
38
|
|
|
39
|
+
function ensureLogDir() {
|
|
40
|
+
try {
|
|
41
|
+
if (!fs.existsSync(LOG_DIR)) {
|
|
42
|
+
fs.mkdirSync(LOG_DIR, { recursive: true });
|
|
43
|
+
}
|
|
44
|
+
} catch (e) { }
|
|
45
|
+
}
|
|
46
|
+
|
|
38
47
|
function log(msg) {
|
|
39
48
|
try {
|
|
49
|
+
ensureLogDir();
|
|
40
50
|
fs.appendFileSync(LOG_FILE, `[${new Date().toISOString()}] ${msg}\n`);
|
|
41
51
|
} catch (e) { }
|
|
42
52
|
}
|
|
@@ -49,21 +59,39 @@ function getAuthFilePath() {
|
|
|
49
59
|
function readApiKeyFromAuth() {
|
|
50
60
|
try {
|
|
51
61
|
const authPath = getAuthFilePath();
|
|
62
|
+
log(`[Auth] Checking auth file: ${authPath}`);
|
|
63
|
+
|
|
52
64
|
if (fs.existsSync(authPath)) {
|
|
53
65
|
const content = fs.readFileSync(authPath, 'utf-8');
|
|
54
66
|
const auth = JSON.parse(content);
|
|
55
67
|
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
68
|
+
log(`[Auth] Auth file contents keys: ${Object.keys(auth).join(', ')}`);
|
|
69
|
+
|
|
70
|
+
// Try both apiKey and key fields
|
|
71
|
+
const providerAuth = auth[PROVIDER_ID];
|
|
72
|
+
if (providerAuth) {
|
|
73
|
+
const apiKey = providerAuth.apiKey || providerAuth.key || providerAuth.token || null;
|
|
74
|
+
if (apiKey) {
|
|
75
|
+
const keyPreview = apiKey.substring(0, 20) + '...';
|
|
76
|
+
log(`[Auth] Found API key for ${PROVIDER_ID}: ${keyPreview}`);
|
|
77
|
+
return apiKey;
|
|
78
|
+
} else {
|
|
79
|
+
log(`[Auth] Provider exists but no key field: ${JSON.stringify(providerAuth)}`);
|
|
80
|
+
}
|
|
81
|
+
} else {
|
|
82
|
+
log(`[Auth] No provider found for ${PROVIDER_ID}`);
|
|
59
83
|
}
|
|
84
|
+
} else {
|
|
85
|
+
log(`[Auth] Auth file does not exist`);
|
|
60
86
|
}
|
|
61
87
|
} catch (e) {
|
|
62
|
-
log(`[Auth] Error reading auth: ${e.message}`);
|
|
88
|
+
log(`[Auth] Error reading auth: ${e.message}\n${e.stack}`);
|
|
63
89
|
}
|
|
64
90
|
return null;
|
|
65
91
|
}
|
|
66
92
|
|
|
93
|
+
let serverInstance = null;
|
|
94
|
+
|
|
67
95
|
function startProxy() {
|
|
68
96
|
return new Promise((resolve) => {
|
|
69
97
|
const server = http.createServer(async (req, res) => {
|
|
@@ -91,7 +119,8 @@ function startProxy() {
|
|
|
91
119
|
if (req.url.startsWith('/v1/')) {
|
|
92
120
|
const apiKey = readApiKeyFromAuth();
|
|
93
121
|
|
|
94
|
-
log(`[Proxy] Request: ${req.method} ${req.url}
|
|
122
|
+
log(`[Proxy] Request: ${req.method} ${req.url}`);
|
|
123
|
+
log(`[Proxy] Has API key: ${!!apiKey}`);
|
|
95
124
|
|
|
96
125
|
const options = {
|
|
97
126
|
hostname: 'qwen.aikit.club',
|
|
@@ -100,18 +129,20 @@ function startProxy() {
|
|
|
100
129
|
method: req.method,
|
|
101
130
|
headers: {
|
|
102
131
|
...req.headers,
|
|
103
|
-
'Host': 'qwen.aikit.club'
|
|
132
|
+
'Host': 'qwen.aikit.club',
|
|
133
|
+
'Content-Type': 'application/json'
|
|
104
134
|
}
|
|
105
135
|
};
|
|
106
136
|
|
|
107
137
|
if (apiKey) {
|
|
108
138
|
options.headers['Authorization'] = `Bearer ${apiKey}`;
|
|
109
|
-
log(`[Proxy] Added Authorization
|
|
139
|
+
log(`[Proxy] Added Authorization: Bearer ${apiKey.substring(0, 20)}...`);
|
|
110
140
|
} else {
|
|
111
|
-
log(`[Proxy]
|
|
141
|
+
log(`[Proxy] NO API KEY - this will likely fail!`);
|
|
112
142
|
}
|
|
113
143
|
|
|
114
144
|
const proxyReq = https.request(options, (proxyRes) => {
|
|
145
|
+
log(`[Proxy] Response status: ${proxyRes.statusCode}`);
|
|
115
146
|
res.writeHead(proxyRes.statusCode, proxyRes.headers);
|
|
116
147
|
proxyRes.pipe(res, { end: true });
|
|
117
148
|
});
|
|
@@ -126,6 +157,7 @@ function startProxy() {
|
|
|
126
157
|
return;
|
|
127
158
|
}
|
|
128
159
|
|
|
160
|
+
log(`[Proxy] Unknown request: ${req.method} ${req.url}`);
|
|
129
161
|
res.writeHead(404);
|
|
130
162
|
res.end('Not Found');
|
|
131
163
|
});
|
|
@@ -133,6 +165,7 @@ function startProxy() {
|
|
|
133
165
|
server.listen(0, '127.0.0.1', () => {
|
|
134
166
|
const port = server.address().port;
|
|
135
167
|
log(`[Proxy] Started on port ${port}`);
|
|
168
|
+
serverInstance = server;
|
|
136
169
|
resolve(port);
|
|
137
170
|
});
|
|
138
171
|
|
|
@@ -144,7 +177,13 @@ function startProxy() {
|
|
|
144
177
|
}
|
|
145
178
|
|
|
146
179
|
export const QwenPlugin = async (ctx) => {
|
|
147
|
-
log('[Plugin]
|
|
180
|
+
log('[Plugin] ====== Qwen Plugin Starting ======');
|
|
181
|
+
log(`[Plugin] Home: ${os.homedir()}`);
|
|
182
|
+
log(`[Plugin] Log file: ${LOG_FILE}`);
|
|
183
|
+
|
|
184
|
+
// Check auth immediately
|
|
185
|
+
const existingKey = readApiKeyFromAuth();
|
|
186
|
+
log(`[Plugin] Initial auth check - has key: ${!!existingKey}`);
|
|
148
187
|
|
|
149
188
|
const port = await startProxy();
|
|
150
189
|
const localBaseUrl = `http://127.0.0.1:${port}/v1`;
|