@iamtoricool/opencool-qwen-auth 0.0.5-alpha → 0.0.7-alpha
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/dist/index.d.ts +1 -12
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +39 -176
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -9,19 +9,8 @@
|
|
|
9
9
|
import type { Plugin } from "@opencode-ai/plugin";
|
|
10
10
|
/**
|
|
11
11
|
* Qwen AI OAuth authentication plugin for opencode
|
|
12
|
-
*
|
|
13
|
-
* This plugin enables opencode to use Qwen AI models via OAuth authentication,
|
|
14
|
-
* allowing users to leverage their Qwen Chat subscription.
|
|
15
|
-
*
|
|
16
|
-
* @example
|
|
17
|
-
* ```json
|
|
18
|
-
* {
|
|
19
|
-
* "plugin": ["opencool-qwen-auth"],
|
|
20
|
-
* "model": "qwen/qwen3-max"
|
|
21
|
-
* }
|
|
22
|
-
* ```
|
|
23
12
|
*/
|
|
24
13
|
export declare const QwenAuthPlugin: Plugin;
|
|
25
14
|
export default QwenAuthPlugin;
|
|
26
|
-
export type { UserConfig,
|
|
15
|
+
export type { UserConfig, RequestBody, TokenResult, } from "./lib/types.js";
|
|
27
16
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,MAAM,EAAe,MAAM,qBAAqB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,MAAM,EAAe,MAAM,qBAAqB,CAAC;AA4B/D;;GAEG;AACH,eAAO,MAAM,cAAc,EAAE,MA2I5B,CAAC;AAEF,eAAe,cAAc,CAAC;AAE9B,YAAY,EACV,UAAU,EACV,WAAW,EACX,WAAW,GACZ,MAAM,gBAAgB,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -6,132 +6,57 @@
|
|
|
6
6
|
*
|
|
7
7
|
* @license MIT
|
|
8
8
|
*/
|
|
9
|
-
import {
|
|
10
|
-
import { REDIRECT_URI } from "./lib/constants.js";
|
|
9
|
+
import { decodeJWT, extractBrowserSession, } from "./lib/auth/auth.js";
|
|
11
10
|
import { openBrowserUrl } from "./lib/auth/browser.js";
|
|
12
|
-
import { startLocalOAuthServer } from "./lib/auth/server.js";
|
|
13
11
|
import { loadPluginConfig, parseUserConfig, initLogger } from "./lib/config.js";
|
|
14
|
-
import {
|
|
12
|
+
import { QWEN_BASE_URL, DUMMY_API_KEY, LOG_STAGES, PLUGIN_NAME, PROVIDER_ID, } from "./lib/constants.js";
|
|
15
13
|
import { logRequest, logDebug } from "./lib/logger.js";
|
|
16
14
|
import { createQwenHeaders, extractRequestUrl, handleErrorResponse, handleSuccessResponse, refreshAndUpdateToken, rewriteUrlForQwen, shouldRefreshToken, transformRequestForQwen, } from "./lib/request/fetch-helpers.js";
|
|
17
15
|
/**
|
|
18
16
|
* Qwen AI OAuth authentication plugin for opencode
|
|
19
|
-
*
|
|
20
|
-
* This plugin enables opencode to use Qwen AI models via OAuth authentication,
|
|
21
|
-
* allowing users to leverage their Qwen Chat subscription.
|
|
22
|
-
*
|
|
23
|
-
* @example
|
|
24
|
-
* ```json
|
|
25
|
-
* {
|
|
26
|
-
* "plugin": ["opencool-qwen-auth"],
|
|
27
|
-
* "model": "qwen/qwen3-max"
|
|
28
|
-
* }
|
|
29
|
-
* ```
|
|
30
17
|
*/
|
|
31
18
|
export const QwenAuthPlugin = async ({ client }) => {
|
|
32
|
-
// Initialize logger with plugin config
|
|
33
19
|
const pluginConfig = loadPluginConfig();
|
|
34
20
|
initLogger(pluginConfig);
|
|
35
|
-
/**
|
|
36
|
-
* Build manual OAuth flow for fallback when auto browser open fails
|
|
37
|
-
*/
|
|
38
|
-
const buildManualOAuthFlow = (pkce, url) => ({
|
|
39
|
-
url,
|
|
40
|
-
method: "code",
|
|
41
|
-
instructions: AUTH_LABELS.INSTRUCTIONS_MANUAL,
|
|
42
|
-
callback: async (input) => {
|
|
43
|
-
const parsed = parseAuthorizationInput(input);
|
|
44
|
-
if (!parsed.code) {
|
|
45
|
-
return { type: "failed" };
|
|
46
|
-
}
|
|
47
|
-
const tokens = await exchangeAuthorizationCode(parsed.code, pkce.verifier, REDIRECT_URI);
|
|
48
|
-
return tokens?.type === "success" ? tokens : { type: "failed" };
|
|
49
|
-
},
|
|
50
|
-
});
|
|
51
21
|
return {
|
|
52
22
|
auth: {
|
|
53
23
|
provider: PROVIDER_ID,
|
|
54
|
-
/**
|
|
55
|
-
* Loader function that configures OAuth authentication and request handling
|
|
56
|
-
*
|
|
57
|
-
* This function:
|
|
58
|
-
* 1. Validates OAuth authentication
|
|
59
|
-
* 2. Extracts user info from access token
|
|
60
|
-
* 3. Loads user configuration from opencode.json
|
|
61
|
-
* 4. Returns SDK configuration with custom fetch implementation
|
|
62
|
-
*
|
|
63
|
-
* @param getAuth - Function to retrieve current auth state
|
|
64
|
-
* @param provider - Provider configuration from opencode.json
|
|
65
|
-
* @returns SDK configuration object or empty object for non-OAuth auth
|
|
66
|
-
*/
|
|
67
24
|
async loader(getAuth, provider) {
|
|
68
25
|
const auth = await getAuth();
|
|
69
|
-
// Only handle OAuth auth type, skip API key auth
|
|
70
26
|
if (auth.type !== "oauth") {
|
|
71
27
|
return {};
|
|
72
28
|
}
|
|
73
|
-
// Decode JWT to verify it's valid
|
|
74
29
|
const decoded = decodeJWT(auth.access);
|
|
75
30
|
if (!decoded) {
|
|
76
|
-
logDebug(`[${PLUGIN_NAME}] Failed to decode access token
|
|
31
|
+
logDebug(`[${PLUGIN_NAME}] Failed to decode access token`);
|
|
77
32
|
return {};
|
|
78
33
|
}
|
|
79
34
|
logDebug(`[${PLUGIN_NAME}] Authenticated as:`, decoded.email || decoded.sub);
|
|
80
|
-
// Extract user configuration (global + per-model options)
|
|
81
35
|
const userConfig = parseUserConfig(provider);
|
|
82
|
-
// Return SDK configuration
|
|
83
36
|
return {
|
|
84
37
|
apiKey: DUMMY_API_KEY,
|
|
85
38
|
baseURL: QWEN_BASE_URL,
|
|
86
|
-
/**
|
|
87
|
-
* Custom fetch implementation for Qwen API
|
|
88
|
-
*
|
|
89
|
-
* Handles:
|
|
90
|
-
* - Token refresh when expired
|
|
91
|
-
* - URL rewriting for Qwen backend
|
|
92
|
-
* - Request body transformation
|
|
93
|
-
* - OAuth header injection
|
|
94
|
-
* - SSE to JSON conversion for non-streaming requests
|
|
95
|
-
* - Error handling and logging
|
|
96
|
-
*
|
|
97
|
-
* @param input - Request URL or Request object
|
|
98
|
-
* @param init - Request options
|
|
99
|
-
* @returns Response from Qwen API
|
|
100
|
-
*/
|
|
101
39
|
async fetch(input, init) {
|
|
102
|
-
// Step 1: Check and refresh token if needed
|
|
103
40
|
let currentAuth = await getAuth();
|
|
104
41
|
if (shouldRefreshToken(currentAuth)) {
|
|
105
42
|
currentAuth = await refreshAndUpdateToken(currentAuth, client);
|
|
106
43
|
}
|
|
107
|
-
// Step 2: Extract and rewrite URL for Qwen backend
|
|
108
44
|
const originalUrl = extractRequestUrl(input);
|
|
109
45
|
const url = rewriteUrlForQwen(originalUrl);
|
|
110
|
-
|
|
111
|
-
// Capture original stream value before transformation
|
|
112
|
-
const originalBody = init?.body
|
|
113
|
-
? JSON.parse(init.body)
|
|
114
|
-
: {};
|
|
46
|
+
const originalBody = init?.body ? JSON.parse(init.body) : {};
|
|
115
47
|
const isStreaming = originalBody.stream === true;
|
|
116
48
|
const transformation = await transformRequestForQwen(init, url, userConfig);
|
|
117
49
|
const requestInit = transformation?.updatedInit ?? init;
|
|
118
|
-
// Step 4: Create headers with OAuth token
|
|
119
50
|
const accessToken = currentAuth.type === "oauth" ? currentAuth.access : "";
|
|
120
51
|
const headers = createQwenHeaders(requestInit, accessToken);
|
|
121
|
-
// Step 5: Make request to Qwen API
|
|
122
52
|
logDebug(`[${PLUGIN_NAME}] Making request to:`, url);
|
|
123
|
-
const response = await fetch(url, {
|
|
124
|
-
...requestInit,
|
|
125
|
-
headers,
|
|
126
|
-
});
|
|
127
|
-
// Step 6: Log response
|
|
53
|
+
const response = await fetch(url, { ...requestInit, headers });
|
|
128
54
|
logRequest(LOG_STAGES.RESPONSE, {
|
|
129
55
|
status: response.status,
|
|
130
56
|
ok: response.ok,
|
|
131
57
|
statusText: response.statusText,
|
|
132
58
|
headers: Object.fromEntries(response.headers.entries()),
|
|
133
59
|
});
|
|
134
|
-
// Step 7: Handle error or success response
|
|
135
60
|
if (!response.ok) {
|
|
136
61
|
return await handleErrorResponse(response);
|
|
137
62
|
}
|
|
@@ -141,115 +66,27 @@ export const QwenAuthPlugin = async ({ client }) => {
|
|
|
141
66
|
},
|
|
142
67
|
methods: [
|
|
143
68
|
{
|
|
144
|
-
label: "
|
|
69
|
+
label: "Login with Qwen.ai",
|
|
145
70
|
type: "oauth",
|
|
146
71
|
authorize: async () => {
|
|
147
|
-
const
|
|
148
|
-
const serverInfo = await startLocalOAuthServer({ state });
|
|
149
|
-
// Attempt to open browser automatically
|
|
72
|
+
const url = "https://chat.qwen.ai";
|
|
150
73
|
openBrowserUrl(url);
|
|
151
|
-
if (!serverInfo.ready) {
|
|
152
|
-
serverInfo.close();
|
|
153
|
-
return {
|
|
154
|
-
url,
|
|
155
|
-
method: "code",
|
|
156
|
-
instructions: "A browser window should have opened.\n\n1. Sign in with your Google account on Qwen\n2. After login, copy the JWT token from the URL\n3. Paste it below\n\nNote: Qwen OAuth requires the official web client. If this doesn't work, use 'Paste JWT Token' method instead.",
|
|
157
|
-
callback: async (input) => {
|
|
158
|
-
const token = input?.trim();
|
|
159
|
-
if (!token)
|
|
160
|
-
return { type: "failed" };
|
|
161
|
-
const decoded = decodeJWT(token);
|
|
162
|
-
if (!decoded)
|
|
163
|
-
return { type: "failed" };
|
|
164
|
-
const exp = typeof decoded.exp === "number" ? decoded.exp : undefined;
|
|
165
|
-
if (exp && exp * 1000 < Date.now())
|
|
166
|
-
return { type: "failed" };
|
|
167
|
-
return {
|
|
168
|
-
type: "success",
|
|
169
|
-
access: token,
|
|
170
|
-
refresh: token,
|
|
171
|
-
expires: exp ? exp * 1000 : Date.now() + 3600000,
|
|
172
|
-
};
|
|
173
|
-
},
|
|
174
|
-
};
|
|
175
|
-
}
|
|
176
74
|
return {
|
|
177
75
|
url,
|
|
178
|
-
method: "auto",
|
|
179
|
-
instructions: "A browser window should have opened. Sign in with Google to authenticate with Qwen.",
|
|
180
|
-
callback: async () => {
|
|
181
|
-
const result = await serverInfo.waitForCode(state);
|
|
182
|
-
serverInfo.close();
|
|
183
|
-
if (!result) {
|
|
184
|
-
return { type: "failed" };
|
|
185
|
-
}
|
|
186
|
-
const tokens = await exchangeAuthorizationCode(result.code, pkce.verifier, REDIRECT_URI);
|
|
187
|
-
return tokens?.type === "success"
|
|
188
|
-
? tokens
|
|
189
|
-
: { type: "failed" };
|
|
190
|
-
},
|
|
191
|
-
};
|
|
192
|
-
},
|
|
193
|
-
},
|
|
194
|
-
{
|
|
195
|
-
label: "Extract from Browser Session (Firefox/Chrome)",
|
|
196
|
-
type: "oauth",
|
|
197
|
-
authorize: async () => {
|
|
198
|
-
// Try to extract session from browser
|
|
199
|
-
const token = await extractBrowserSession();
|
|
200
|
-
if (token) {
|
|
201
|
-
// Validate and exchange the token
|
|
202
|
-
const tokens = await exchangeAuthorizationCode(token);
|
|
203
|
-
if (tokens.type === "success") {
|
|
204
|
-
return {
|
|
205
|
-
url: "https://chat.qwen.ai",
|
|
206
|
-
method: "code",
|
|
207
|
-
instructions: "Browser session authenticated successfully!",
|
|
208
|
-
callback: async () => tokens,
|
|
209
|
-
};
|
|
210
|
-
}
|
|
211
|
-
}
|
|
212
|
-
// If browser session failed, provide manual instructions
|
|
213
|
-
const available = await isBrowserSessionAvailable();
|
|
214
|
-
if (!available) {
|
|
215
|
-
return {
|
|
216
|
-
url: "https://chat.qwen.ai",
|
|
217
|
-
method: "code",
|
|
218
|
-
instructions: "Browser session extraction requires better-sqlite3.\n\nInstall it with:\n cd ~/.config/opencode && npm install better-sqlite3\n\nThen try again, or use API key authentication instead.",
|
|
219
|
-
callback: async () => ({ type: "failed" }),
|
|
220
|
-
};
|
|
221
|
-
}
|
|
222
|
-
return {
|
|
223
|
-
url: "https://chat.qwen.ai",
|
|
224
76
|
method: "code",
|
|
225
|
-
instructions: "
|
|
226
|
-
callback: async () => ({ type: "failed" }),
|
|
227
|
-
};
|
|
228
|
-
},
|
|
229
|
-
},
|
|
230
|
-
{
|
|
231
|
-
label: "Paste JWT Token from Browser",
|
|
232
|
-
type: "oauth",
|
|
233
|
-
authorize: async () => {
|
|
234
|
-
return {
|
|
235
|
-
url: "https://chat.qwen.ai",
|
|
236
|
-
method: "code",
|
|
237
|
-
instructions: "To get your JWT token:\n\n1. Open Firefox/Chrome and go to https://chat.qwen.ai\n2. Sign in to your account\n3. Open DevTools (F12) → Application → Cookies\n4. Find the 'token' cookie for .qwen.ai\n5. Copy the cookie value (it's a JWT token)\n\nPaste the token below:",
|
|
77
|
+
instructions: "Browser opened to https://chat.qwen.ai\n\n1. Login to your Qwen account\n2. After login, copy the JWT token from:\n - URL fragment (after #token=) OR\n - DevTools → Application → Cookies → token\n3. Paste the token below:",
|
|
238
78
|
callback: async (input) => {
|
|
239
79
|
const token = input?.trim();
|
|
240
|
-
if (!token)
|
|
80
|
+
if (!token)
|
|
241
81
|
return { type: "failed" };
|
|
242
|
-
}
|
|
243
|
-
// Validate it's a JWT
|
|
244
82
|
const decoded = decodeJWT(token);
|
|
245
83
|
if (!decoded) {
|
|
246
|
-
console.error(`[${PLUGIN_NAME}] Invalid JWT token
|
|
84
|
+
console.error(`[${PLUGIN_NAME}] Invalid JWT token`);
|
|
247
85
|
return { type: "failed" };
|
|
248
86
|
}
|
|
249
|
-
// Check expiration
|
|
250
87
|
const exp = typeof decoded.exp === "number" ? decoded.exp : undefined;
|
|
251
88
|
if (exp && exp * 1000 < Date.now()) {
|
|
252
|
-
console.error(`[${PLUGIN_NAME}] Token
|
|
89
|
+
console.error(`[${PLUGIN_NAME}] Token expired`);
|
|
253
90
|
return { type: "failed" };
|
|
254
91
|
}
|
|
255
92
|
return {
|
|
@@ -263,8 +100,34 @@ export const QwenAuthPlugin = async ({ client }) => {
|
|
|
263
100
|
},
|
|
264
101
|
},
|
|
265
102
|
{
|
|
266
|
-
label:
|
|
267
|
-
type: "
|
|
103
|
+
label: "Auto-extract from Browser",
|
|
104
|
+
type: "oauth",
|
|
105
|
+
authorize: async () => {
|
|
106
|
+
const token = await extractBrowserSession();
|
|
107
|
+
if (token) {
|
|
108
|
+
const decoded = decodeJWT(token);
|
|
109
|
+
if (decoded) {
|
|
110
|
+
const exp = typeof decoded.exp === "number" ? decoded.exp : undefined;
|
|
111
|
+
return {
|
|
112
|
+
url: "https://chat.qwen.ai",
|
|
113
|
+
method: "code",
|
|
114
|
+
instructions: "Token extracted from browser successfully!",
|
|
115
|
+
callback: async () => ({
|
|
116
|
+
type: "success",
|
|
117
|
+
access: token,
|
|
118
|
+
refresh: token,
|
|
119
|
+
expires: exp ? exp * 1000 : Date.now() + 3600000,
|
|
120
|
+
}),
|
|
121
|
+
};
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
return {
|
|
125
|
+
url: "https://chat.qwen.ai",
|
|
126
|
+
method: "code",
|
|
127
|
+
instructions: "Could not extract token. Install better-sqlite3 or use 'Login with Qwen.ai' method.",
|
|
128
|
+
callback: async () => ({ type: "failed" }),
|
|
129
|
+
};
|
|
130
|
+
},
|
|
268
131
|
},
|
|
269
132
|
],
|
|
270
133
|
},
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAIH,OAAO,EACL,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../index.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@iamtoricool/opencool-qwen-auth",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.7-alpha",
|
|
4
4
|
"description": "Qwen AI OAuth Authentication Plugin for opencode - Access Qwen models via chat.qwen.ai subscription",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|