opencode-qwen-auth 0.1.1
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/LICENSE +203 -0
- package/README.md +252 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +3 -0
- package/dist/index.js.map +1 -0
- package/dist/src/constants.d.ts +7 -0
- package/dist/src/constants.d.ts.map +1 -0
- package/dist/src/constants.js +12 -0
- package/dist/src/constants.js.map +1 -0
- package/dist/src/plugin/account.d.ts +40 -0
- package/dist/src/plugin/account.d.ts.map +1 -0
- package/dist/src/plugin/account.js +237 -0
- package/dist/src/plugin/account.js.map +1 -0
- package/dist/src/plugin/auth.d.ts +5 -0
- package/dist/src/plugin/auth.d.ts.map +1 -0
- package/dist/src/plugin/auth.js +16 -0
- package/dist/src/plugin/auth.js.map +1 -0
- package/dist/src/plugin/config/index.d.ts +4 -0
- package/dist/src/plugin/config/index.d.ts.map +1 -0
- package/dist/src/plugin/config/index.js +3 -0
- package/dist/src/plugin/config/index.js.map +1 -0
- package/dist/src/plugin/config/loader.d.ts +3 -0
- package/dist/src/plugin/config/loader.d.ts.map +1 -0
- package/dist/src/plugin/config/loader.js +69 -0
- package/dist/src/plugin/config/loader.js.map +1 -0
- package/dist/src/plugin/config/schema.d.ts +31 -0
- package/dist/src/plugin/config/schema.d.ts.map +1 -0
- package/dist/src/plugin/config/schema.js +15 -0
- package/dist/src/plugin/config/schema.js.map +1 -0
- package/dist/src/plugin/logger.d.ts +12 -0
- package/dist/src/plugin/logger.d.ts.map +1 -0
- package/dist/src/plugin/logger.js +74 -0
- package/dist/src/plugin/logger.js.map +1 -0
- package/dist/src/plugin/token.d.ts +8 -0
- package/dist/src/plugin/token.d.ts.map +1 -0
- package/dist/src/plugin/token.js +29 -0
- package/dist/src/plugin/token.js.map +1 -0
- package/dist/src/plugin/types.d.ts +96 -0
- package/dist/src/plugin/types.d.ts.map +1 -0
- package/dist/src/plugin/types.js +2 -0
- package/dist/src/plugin/types.js.map +1 -0
- package/dist/src/plugin.d.ts +11 -0
- package/dist/src/plugin.d.ts.map +1 -0
- package/dist/src/plugin.js +439 -0
- package/dist/src/plugin.js.map +1 -0
- package/dist/src/qwen/oauth.d.ts +29 -0
- package/dist/src/qwen/oauth.d.ts.map +1 -0
- package/dist/src/qwen/oauth.js +151 -0
- package/dist/src/qwen/oauth.js.map +1 -0
- package/dist/src/transform/index.d.ts +4 -0
- package/dist/src/transform/index.d.ts.map +1 -0
- package/dist/src/transform/index.js +4 -0
- package/dist/src/transform/index.js.map +1 -0
- package/dist/src/transform/request.d.ts +4 -0
- package/dist/src/transform/request.d.ts.map +1 -0
- package/dist/src/transform/request.js +106 -0
- package/dist/src/transform/request.js.map +1 -0
- package/dist/src/transform/response.d.ts +10 -0
- package/dist/src/transform/response.d.ts.map +1 -0
- package/dist/src/transform/response.js +52 -0
- package/dist/src/transform/response.js.map +1 -0
- package/dist/src/transform/sse.d.ts +10 -0
- package/dist/src/transform/sse.d.ts.map +1 -0
- package/dist/src/transform/sse.js +230 -0
- package/dist/src/transform/sse.js.map +1 -0
- package/package.json +78 -0
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
import type { PluginInput } from "@opencode-ai/plugin";
|
|
2
|
+
export interface OAuthAuthDetails {
|
|
3
|
+
type: "oauth";
|
|
4
|
+
refresh: string;
|
|
5
|
+
access?: string;
|
|
6
|
+
expires?: number;
|
|
7
|
+
resourceUrl?: string;
|
|
8
|
+
}
|
|
9
|
+
export interface NonOAuthAuthDetails {
|
|
10
|
+
type: string;
|
|
11
|
+
[key: string]: unknown;
|
|
12
|
+
}
|
|
13
|
+
export type AuthDetails = OAuthAuthDetails | NonOAuthAuthDetails;
|
|
14
|
+
export type GetAuth = () => Promise<AuthDetails>;
|
|
15
|
+
export interface ProviderModelCost {
|
|
16
|
+
input: number;
|
|
17
|
+
output: number;
|
|
18
|
+
cache: {
|
|
19
|
+
read: number;
|
|
20
|
+
write: number;
|
|
21
|
+
};
|
|
22
|
+
experimentalOver200K?: {
|
|
23
|
+
input: number;
|
|
24
|
+
output: number;
|
|
25
|
+
cache: {
|
|
26
|
+
read: number;
|
|
27
|
+
write: number;
|
|
28
|
+
};
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
export interface ProviderModel {
|
|
32
|
+
cost?: ProviderModelCost;
|
|
33
|
+
[key: string]: unknown;
|
|
34
|
+
}
|
|
35
|
+
export interface Provider {
|
|
36
|
+
models?: Record<string, ProviderModel>;
|
|
37
|
+
}
|
|
38
|
+
export interface LoaderResult {
|
|
39
|
+
apiKey: string;
|
|
40
|
+
fetch(input: RequestInfo | URL, init?: RequestInit): Promise<Response>;
|
|
41
|
+
}
|
|
42
|
+
export type PluginClient = PluginInput["client"];
|
|
43
|
+
export interface PluginContext {
|
|
44
|
+
client: PluginClient;
|
|
45
|
+
directory: string;
|
|
46
|
+
}
|
|
47
|
+
export type AuthPrompt = {
|
|
48
|
+
type: "text";
|
|
49
|
+
key: string;
|
|
50
|
+
message: string;
|
|
51
|
+
placeholder?: string;
|
|
52
|
+
validate?: (value: string) => string | undefined;
|
|
53
|
+
condition?: (inputs: Record<string, string>) => boolean;
|
|
54
|
+
} | {
|
|
55
|
+
type: "select";
|
|
56
|
+
key: string;
|
|
57
|
+
message: string;
|
|
58
|
+
options: Array<{
|
|
59
|
+
label: string;
|
|
60
|
+
value: string;
|
|
61
|
+
hint?: string;
|
|
62
|
+
}>;
|
|
63
|
+
condition?: (inputs: Record<string, string>) => boolean;
|
|
64
|
+
};
|
|
65
|
+
export type OAuthAuthorizationResult = {
|
|
66
|
+
url: string;
|
|
67
|
+
instructions: string;
|
|
68
|
+
} & ({
|
|
69
|
+
method: "auto";
|
|
70
|
+
callback: () => Promise<Record<string, unknown>>;
|
|
71
|
+
} | {
|
|
72
|
+
method: "code";
|
|
73
|
+
callback: (code: string) => Promise<Record<string, unknown>>;
|
|
74
|
+
});
|
|
75
|
+
export interface AuthMethod {
|
|
76
|
+
provider?: string;
|
|
77
|
+
label: string;
|
|
78
|
+
type: "oauth" | "api";
|
|
79
|
+
prompts?: AuthPrompt[];
|
|
80
|
+
authorize?: (inputs?: Record<string, string>) => Promise<OAuthAuthorizationResult>;
|
|
81
|
+
}
|
|
82
|
+
export interface PluginEventPayload {
|
|
83
|
+
event: {
|
|
84
|
+
type: string;
|
|
85
|
+
properties?: unknown;
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
export interface PluginResult {
|
|
89
|
+
auth: {
|
|
90
|
+
provider: string;
|
|
91
|
+
loader: (getAuth: GetAuth, provider: Provider) => Promise<LoaderResult | Record<string, unknown>>;
|
|
92
|
+
methods: AuthMethod[];
|
|
93
|
+
};
|
|
94
|
+
event?: (payload: PluginEventPayload) => void;
|
|
95
|
+
}
|
|
96
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/plugin/types.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/plugin/types.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { Plugin } from "@opencode-ai/plugin";
|
|
2
|
+
declare function sanitizeMalformedUrl(url: string): string;
|
|
3
|
+
declare function applyResourceUrl(input: RequestInfo | URL, baseUrl?: string): {
|
|
4
|
+
url: string;
|
|
5
|
+
};
|
|
6
|
+
export declare const createQwenOAuthPlugin: (providerId: string) => Plugin;
|
|
7
|
+
export declare const QwenCLIOAuthPlugin: Plugin;
|
|
8
|
+
export declare const QwenOAuthPlugin: Plugin;
|
|
9
|
+
export { sanitizeMalformedUrl, applyResourceUrl };
|
|
10
|
+
export default QwenOAuthPlugin;
|
|
11
|
+
//# sourceMappingURL=plugin.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"plugin.d.ts","sourceRoot":"","sources":["../../src/plugin.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAqFlD,iBAAS,oBAAoB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAcjD;AAED,iBAAS,gBAAgB,CACvB,KAAK,EAAE,WAAW,GAAG,GAAG,EACxB,OAAO,CAAC,EAAE,MAAM,GACf;IAAE,GAAG,EAAE,MAAM,CAAA;CAAE,CAgDjB;AA8ED,eAAO,MAAM,qBAAqB,GAC/B,YAAY,MAAM,KAAG,MAyWrB,CAAC;AAEJ,eAAO,MAAM,kBAAkB,QAAgC,CAAC;AAChE,eAAO,MAAM,eAAe,QAAqB,CAAC;AAElD,OAAO,EAAE,oBAAoB,EAAE,gBAAgB,EAAE,CAAC;AAElD,eAAe,eAAe,CAAC"}
|
|
@@ -0,0 +1,439 @@
|
|
|
1
|
+
import { QWEN_DEFAULT_SCOPES, QWEN_OAUTH_BASE_URL } from "./constants";
|
|
2
|
+
import { getMinRateLimitWait, loadAccounts, markRateLimited, recordFailure, recordSuccess, saveAccounts, selectAccount, updateAccount, upsertAccount, } from "./plugin/account";
|
|
3
|
+
import { accessTokenExpired, isOAuthAuth } from "./plugin/auth";
|
|
4
|
+
import { loadConfig } from "./plugin/config";
|
|
5
|
+
import { createLogger, initDebugFromEnv, setLoggerQuietMode, } from "./plugin/logger";
|
|
6
|
+
import { refreshAccessToken } from "./plugin/token";
|
|
7
|
+
import { authorizeQwenDevice, pollQwenDeviceToken, } from "./qwen/oauth";
|
|
8
|
+
import { transformResponsesToChatCompletions } from "./transform/request";
|
|
9
|
+
import { createTransformContext, transformChatCompletionsToResponses, } from "./transform/response";
|
|
10
|
+
import { createSSETransformContext, createSSETransformStream, } from "./transform/sse";
|
|
11
|
+
const logger = createLogger("plugin");
|
|
12
|
+
function normalizeUrl(value, fallback) {
|
|
13
|
+
if (typeof value !== "string") {
|
|
14
|
+
return fallback;
|
|
15
|
+
}
|
|
16
|
+
const trimmed = value.trim();
|
|
17
|
+
if (!trimmed)
|
|
18
|
+
return fallback;
|
|
19
|
+
if (trimmed.startsWith("http://") || trimmed.startsWith("https://")) {
|
|
20
|
+
return trimmed;
|
|
21
|
+
}
|
|
22
|
+
return `https://${trimmed}`;
|
|
23
|
+
}
|
|
24
|
+
function buildOAuthOptions(config) {
|
|
25
|
+
return {
|
|
26
|
+
clientId: config.client_id,
|
|
27
|
+
oauthBaseUrl: normalizeUrl(config.oauth_base_url, QWEN_OAUTH_BASE_URL),
|
|
28
|
+
scopes: QWEN_DEFAULT_SCOPES,
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
function ensureStorage(auth) {
|
|
32
|
+
return {
|
|
33
|
+
version: 1,
|
|
34
|
+
accounts: [
|
|
35
|
+
{
|
|
36
|
+
refreshToken: auth.refresh,
|
|
37
|
+
accessToken: auth.access,
|
|
38
|
+
expires: auth.expires,
|
|
39
|
+
resourceUrl: auth.resourceUrl,
|
|
40
|
+
addedAt: Date.now(),
|
|
41
|
+
lastUsed: Date.now(),
|
|
42
|
+
},
|
|
43
|
+
],
|
|
44
|
+
activeIndex: 0,
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
function sanitizeMalformedUrl(url) {
|
|
48
|
+
let result = url.trim();
|
|
49
|
+
// Strip leading sentinel prefix (undefined/null) only at start
|
|
50
|
+
// OpenCode may pass "undefined/chat/completions" when provider has no baseUrl
|
|
51
|
+
result = result.replace(/^(undefined|null)(?=\/|$)/, "");
|
|
52
|
+
// Prevent protocol-relative URL after stripping (e.g., "undefined//path" -> "//path" is dangerous)
|
|
53
|
+
// Collapse multiple leading slashes to single slash
|
|
54
|
+
if (result.startsWith("//")) {
|
|
55
|
+
result = `/${result.replace(/^\/+/, "")}`;
|
|
56
|
+
}
|
|
57
|
+
return result;
|
|
58
|
+
}
|
|
59
|
+
function applyResourceUrl(input, baseUrl) {
|
|
60
|
+
let rawUrl;
|
|
61
|
+
if (typeof input === "string") {
|
|
62
|
+
rawUrl = input;
|
|
63
|
+
}
|
|
64
|
+
else if (input instanceof URL) {
|
|
65
|
+
rawUrl = input.toString();
|
|
66
|
+
}
|
|
67
|
+
else {
|
|
68
|
+
rawUrl = input.url;
|
|
69
|
+
}
|
|
70
|
+
// Sanitize malformed URLs from OpenCode (e.g., "undefined/chat/completions")
|
|
71
|
+
rawUrl = sanitizeMalformedUrl(rawUrl);
|
|
72
|
+
// If sanitization resulted in empty string, treat as root path
|
|
73
|
+
if (!rawUrl) {
|
|
74
|
+
rawUrl = "/";
|
|
75
|
+
}
|
|
76
|
+
let originalUrl;
|
|
77
|
+
try {
|
|
78
|
+
originalUrl = new URL(rawUrl);
|
|
79
|
+
}
|
|
80
|
+
catch {
|
|
81
|
+
if (!baseUrl) {
|
|
82
|
+
throw new Error(`Qwen OAuth requires a base URL for ${rawUrl}`);
|
|
83
|
+
}
|
|
84
|
+
originalUrl = new URL(rawUrl, baseUrl);
|
|
85
|
+
}
|
|
86
|
+
if (!baseUrl) {
|
|
87
|
+
return { url: originalUrl.toString() };
|
|
88
|
+
}
|
|
89
|
+
const base = new URL(baseUrl);
|
|
90
|
+
const basePath = base.pathname.replace(/\/$/, "");
|
|
91
|
+
const originalPath = originalUrl.pathname;
|
|
92
|
+
let combinedPath = originalPath;
|
|
93
|
+
if (originalPath.startsWith(basePath)) {
|
|
94
|
+
combinedPath = `${basePath}${originalPath.slice(basePath.length)}`;
|
|
95
|
+
}
|
|
96
|
+
else {
|
|
97
|
+
combinedPath = `${basePath}${originalPath.startsWith("/") ? "" : "/"}${originalPath}`;
|
|
98
|
+
}
|
|
99
|
+
base.pathname = combinedPath;
|
|
100
|
+
base.search = originalUrl.search;
|
|
101
|
+
base.hash = originalUrl.hash;
|
|
102
|
+
return { url: base.toString() };
|
|
103
|
+
}
|
|
104
|
+
function extractRetryAfterMs(response) {
|
|
105
|
+
const retryAfterMs = response.headers.get("retry-after-ms");
|
|
106
|
+
if (retryAfterMs) {
|
|
107
|
+
const value = Number.parseInt(retryAfterMs, 10);
|
|
108
|
+
if (!Number.isNaN(value) && value > 0) {
|
|
109
|
+
return value;
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
const retryAfter = response.headers.get("retry-after");
|
|
113
|
+
if (retryAfter) {
|
|
114
|
+
const value = Number.parseInt(retryAfter, 10);
|
|
115
|
+
if (!Number.isNaN(value) && value > 0) {
|
|
116
|
+
return value * 1000;
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
return null;
|
|
120
|
+
}
|
|
121
|
+
const BACKOFF_TIERS = {
|
|
122
|
+
QUOTA_EXHAUSTED: [60_000, 300_000, 1800_000],
|
|
123
|
+
RATE_LIMIT_EXCEEDED: [30_000, 60_000],
|
|
124
|
+
SERVER_ERROR: [20_000, 40_000],
|
|
125
|
+
UNKNOWN: [60_000],
|
|
126
|
+
};
|
|
127
|
+
function parseRateLimitReason(response) {
|
|
128
|
+
const errorHeader = response.headers.get("x-error-code");
|
|
129
|
+
if (errorHeader) {
|
|
130
|
+
const upper = errorHeader.toUpperCase();
|
|
131
|
+
if (upper.includes("QUOTA"))
|
|
132
|
+
return "QUOTA_EXHAUSTED";
|
|
133
|
+
if (upper.includes("RATE"))
|
|
134
|
+
return "RATE_LIMIT_EXCEEDED";
|
|
135
|
+
if (upper.includes("SERVER") || upper.includes("CAPACITY"))
|
|
136
|
+
return "SERVER_ERROR";
|
|
137
|
+
}
|
|
138
|
+
if (response.status >= 500)
|
|
139
|
+
return "SERVER_ERROR";
|
|
140
|
+
return "UNKNOWN";
|
|
141
|
+
}
|
|
142
|
+
function getBackoffMs(reason, consecutiveFailures) {
|
|
143
|
+
const tier = BACKOFF_TIERS[reason];
|
|
144
|
+
return tier[Math.min(consecutiveFailures, tier.length - 1)];
|
|
145
|
+
}
|
|
146
|
+
function sleep(ms) {
|
|
147
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
148
|
+
}
|
|
149
|
+
async function ensureAuthInStorage(storage, auth) {
|
|
150
|
+
const now = Date.now();
|
|
151
|
+
const baseStorage = storage ?? ensureStorage(auth);
|
|
152
|
+
const updated = upsertAccount(baseStorage, {
|
|
153
|
+
refreshToken: auth.refresh,
|
|
154
|
+
accessToken: auth.access,
|
|
155
|
+
expires: auth.expires,
|
|
156
|
+
resourceUrl: auth.resourceUrl,
|
|
157
|
+
addedAt: now,
|
|
158
|
+
lastUsed: now,
|
|
159
|
+
});
|
|
160
|
+
await saveAccounts(updated);
|
|
161
|
+
return updated;
|
|
162
|
+
}
|
|
163
|
+
export const createQwenOAuthPlugin = (providerId) => async ({ client, directory }) => {
|
|
164
|
+
const config = loadConfig(directory);
|
|
165
|
+
setLoggerQuietMode(config.quiet_mode);
|
|
166
|
+
initDebugFromEnv();
|
|
167
|
+
logger.debug("Plugin initialized", { providerId, directory });
|
|
168
|
+
const oauthOptions = buildOAuthOptions(config);
|
|
169
|
+
return {
|
|
170
|
+
auth: {
|
|
171
|
+
provider: providerId,
|
|
172
|
+
async loader(getAuth, provider) {
|
|
173
|
+
const auth = (await getAuth());
|
|
174
|
+
if (!isOAuthAuth(auth)) {
|
|
175
|
+
return {};
|
|
176
|
+
}
|
|
177
|
+
let accountStorage = await ensureAuthInStorage(await loadAccounts(), auth);
|
|
178
|
+
if (provider.models) {
|
|
179
|
+
for (const model of Object.values(provider.models)) {
|
|
180
|
+
if (model) {
|
|
181
|
+
model.cost = {
|
|
182
|
+
input: 0,
|
|
183
|
+
output: 0,
|
|
184
|
+
cache: { read: 0, write: 0 },
|
|
185
|
+
};
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
return {
|
|
190
|
+
apiKey: "",
|
|
191
|
+
fetch: async (input, init) => {
|
|
192
|
+
let attempts = 0;
|
|
193
|
+
while (true) {
|
|
194
|
+
const now = Date.now();
|
|
195
|
+
const selection = selectAccount(accountStorage, config.rotation_strategy, now);
|
|
196
|
+
if (!selection) {
|
|
197
|
+
const waitMs = getMinRateLimitWait(accountStorage, now);
|
|
198
|
+
if (!waitMs) {
|
|
199
|
+
throw new Error("No available Qwen OAuth accounts. Re-authenticate to continue.");
|
|
200
|
+
}
|
|
201
|
+
const maxWaitMs = (config.max_rate_limit_wait_seconds ?? 0) * 1000;
|
|
202
|
+
if (maxWaitMs > 0 && waitMs > maxWaitMs) {
|
|
203
|
+
throw new Error("All Qwen OAuth accounts are rate-limited. Try again later.");
|
|
204
|
+
}
|
|
205
|
+
await sleep(waitMs);
|
|
206
|
+
continue;
|
|
207
|
+
}
|
|
208
|
+
accountStorage = selection.storage;
|
|
209
|
+
const account = selection.account;
|
|
210
|
+
const accountIndex = selection.index;
|
|
211
|
+
const authRecord = {
|
|
212
|
+
type: "oauth",
|
|
213
|
+
refresh: account.refreshToken,
|
|
214
|
+
access: account.accessToken,
|
|
215
|
+
expires: account.expires,
|
|
216
|
+
resourceUrl: account.resourceUrl,
|
|
217
|
+
};
|
|
218
|
+
const refreshBuffer = config.proactive_refresh
|
|
219
|
+
? config.refresh_window_seconds
|
|
220
|
+
: 0;
|
|
221
|
+
if (!authRecord.access ||
|
|
222
|
+
accessTokenExpired(authRecord, refreshBuffer)) {
|
|
223
|
+
logger.debug("Token refresh needed", {
|
|
224
|
+
accountIndex,
|
|
225
|
+
hasAccess: !!authRecord.access,
|
|
226
|
+
proactive: config.proactive_refresh,
|
|
227
|
+
});
|
|
228
|
+
try {
|
|
229
|
+
const refreshed = await refreshAccessToken(authRecord, oauthOptions, client, providerId);
|
|
230
|
+
if (!refreshed) {
|
|
231
|
+
throw new Error("Token refresh failed");
|
|
232
|
+
}
|
|
233
|
+
logger.debug("Token refreshed successfully", {
|
|
234
|
+
accountIndex,
|
|
235
|
+
});
|
|
236
|
+
accountStorage = updateAccount(accountStorage, accountIndex, {
|
|
237
|
+
refreshToken: refreshed.refresh,
|
|
238
|
+
accessToken: refreshed.access,
|
|
239
|
+
expires: refreshed.expires,
|
|
240
|
+
resourceUrl: refreshed.resourceUrl ?? account.resourceUrl,
|
|
241
|
+
lastUsed: now,
|
|
242
|
+
});
|
|
243
|
+
await saveAccounts(accountStorage);
|
|
244
|
+
}
|
|
245
|
+
catch (error) {
|
|
246
|
+
const refreshError = error;
|
|
247
|
+
logger.debug("Token refresh failed", {
|
|
248
|
+
accountIndex,
|
|
249
|
+
code: refreshError.code,
|
|
250
|
+
});
|
|
251
|
+
if (refreshError.code === "invalid_grant") {
|
|
252
|
+
accountStorage = updateAccount(accountStorage, accountIndex, { rateLimitResetAt: Date.now() + 60_000 });
|
|
253
|
+
await saveAccounts(accountStorage);
|
|
254
|
+
}
|
|
255
|
+
attempts += 1;
|
|
256
|
+
if (attempts >= accountStorage.accounts.length) {
|
|
257
|
+
throw error;
|
|
258
|
+
}
|
|
259
|
+
continue;
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
const latestAuth = (await getAuth());
|
|
263
|
+
if (!isOAuthAuth(latestAuth)) {
|
|
264
|
+
return fetch(input, init);
|
|
265
|
+
}
|
|
266
|
+
const activeAuth = latestAuth.access ? latestAuth : authRecord;
|
|
267
|
+
// Get URL from input - OpenCode already constructs full URLs
|
|
268
|
+
let rawUrl;
|
|
269
|
+
if (typeof input === "string") {
|
|
270
|
+
rawUrl = input;
|
|
271
|
+
}
|
|
272
|
+
else if (input instanceof URL) {
|
|
273
|
+
rawUrl = input.toString();
|
|
274
|
+
}
|
|
275
|
+
else {
|
|
276
|
+
rawUrl = input.url;
|
|
277
|
+
}
|
|
278
|
+
// Sanitize malformed URLs (e.g., "undefined/path")
|
|
279
|
+
rawUrl = sanitizeMalformedUrl(rawUrl);
|
|
280
|
+
let requestInit = init ??
|
|
281
|
+
(input instanceof Request
|
|
282
|
+
? {
|
|
283
|
+
method: input.method,
|
|
284
|
+
headers: input.headers,
|
|
285
|
+
body: input.body,
|
|
286
|
+
signal: input.signal,
|
|
287
|
+
}
|
|
288
|
+
: undefined);
|
|
289
|
+
if (!requestInit && !(input instanceof Request)) {
|
|
290
|
+
requestInit = {};
|
|
291
|
+
}
|
|
292
|
+
if (requestInit && !requestInit.headers) {
|
|
293
|
+
requestInit.headers = {};
|
|
294
|
+
}
|
|
295
|
+
const headers = new Headers(requestInit?.headers);
|
|
296
|
+
if (activeAuth.access) {
|
|
297
|
+
headers.set("Authorization", `Bearer ${activeAuth.access}`);
|
|
298
|
+
}
|
|
299
|
+
const needsResponsesTransform = rawUrl.endsWith("/responses");
|
|
300
|
+
const finalUrl = rawUrl.replace(/\/responses$/, "/chat/completions");
|
|
301
|
+
const finalInit = { ...requestInit };
|
|
302
|
+
if (needsResponsesTransform && requestInit?.body) {
|
|
303
|
+
try {
|
|
304
|
+
const bodyStr = typeof requestInit.body === "string"
|
|
305
|
+
? requestInit.body
|
|
306
|
+
: await new Response(requestInit.body).text();
|
|
307
|
+
const body = JSON.parse(bodyStr);
|
|
308
|
+
const transformed = transformResponsesToChatCompletions(body);
|
|
309
|
+
finalInit.body = JSON.stringify(transformed);
|
|
310
|
+
logger.verbose("Transformed request body", {
|
|
311
|
+
messagesCount: transformed.messages?.length,
|
|
312
|
+
hasTools: !!transformed.tools,
|
|
313
|
+
});
|
|
314
|
+
}
|
|
315
|
+
catch {
|
|
316
|
+
logger.debug("Body parse failed, using original");
|
|
317
|
+
}
|
|
318
|
+
}
|
|
319
|
+
logger.debug("Sending request", {
|
|
320
|
+
url: finalUrl,
|
|
321
|
+
method: finalInit.method ?? "POST",
|
|
322
|
+
needsTransform: needsResponsesTransform,
|
|
323
|
+
});
|
|
324
|
+
const response = await fetch(finalUrl, {
|
|
325
|
+
...finalInit,
|
|
326
|
+
headers,
|
|
327
|
+
});
|
|
328
|
+
logger.debug("Response received", {
|
|
329
|
+
status: response.status,
|
|
330
|
+
contentType: response.headers.get("content-type"),
|
|
331
|
+
});
|
|
332
|
+
// Transform streaming response from Chat Completions to Responses API format
|
|
333
|
+
if (needsResponsesTransform &&
|
|
334
|
+
response.ok &&
|
|
335
|
+
response.body &&
|
|
336
|
+
response.headers
|
|
337
|
+
.get("content-type")
|
|
338
|
+
?.includes("text/event-stream")) {
|
|
339
|
+
const sseCtx = createSSETransformContext(logger);
|
|
340
|
+
const transformStream = createSSETransformStream(sseCtx);
|
|
341
|
+
const transformedBody = response.body.pipeThrough(transformStream);
|
|
342
|
+
return new Response(transformedBody, {
|
|
343
|
+
status: response.status,
|
|
344
|
+
statusText: response.statusText,
|
|
345
|
+
headers: response.headers,
|
|
346
|
+
});
|
|
347
|
+
}
|
|
348
|
+
if (needsResponsesTransform &&
|
|
349
|
+
response.ok &&
|
|
350
|
+
!response.headers
|
|
351
|
+
.get("content-type")
|
|
352
|
+
?.includes("text/event-stream")) {
|
|
353
|
+
logger.debug("Transforming non-streaming response");
|
|
354
|
+
const chatBody = await response.json();
|
|
355
|
+
const ctx = createTransformContext();
|
|
356
|
+
const responsesBody = transformChatCompletionsToResponses(chatBody, ctx);
|
|
357
|
+
return new Response(JSON.stringify(responsesBody), {
|
|
358
|
+
status: response.status,
|
|
359
|
+
statusText: response.statusText,
|
|
360
|
+
headers: new Headers({
|
|
361
|
+
"content-type": "application/json",
|
|
362
|
+
}),
|
|
363
|
+
});
|
|
364
|
+
}
|
|
365
|
+
if (response.status === 429 || response.status >= 500) {
|
|
366
|
+
const reason = parseRateLimitReason(response);
|
|
367
|
+
const headerMs = extractRetryAfterMs(response);
|
|
368
|
+
const tieredMs = getBackoffMs(reason, attempts);
|
|
369
|
+
const retryAfterMs = headerMs ?? tieredMs;
|
|
370
|
+
logger.debug("Rate limited or server error", {
|
|
371
|
+
status: response.status,
|
|
372
|
+
reason,
|
|
373
|
+
accountIndex,
|
|
374
|
+
retryAfterMs,
|
|
375
|
+
attempts,
|
|
376
|
+
totalAccounts: accountStorage.accounts.length,
|
|
377
|
+
});
|
|
378
|
+
accountStorage = markRateLimited(accountStorage, accountIndex, retryAfterMs);
|
|
379
|
+
accountStorage = recordFailure(accountStorage, accountIndex);
|
|
380
|
+
await saveAccounts(accountStorage);
|
|
381
|
+
attempts += 1;
|
|
382
|
+
if (attempts >= accountStorage.accounts.length) {
|
|
383
|
+
const waitMs = getMinRateLimitWait(accountStorage, Date.now());
|
|
384
|
+
if (waitMs) {
|
|
385
|
+
logger.debug("All accounts rate limited, waiting", {
|
|
386
|
+
waitMs,
|
|
387
|
+
});
|
|
388
|
+
await sleep(waitMs);
|
|
389
|
+
attempts = 0;
|
|
390
|
+
continue;
|
|
391
|
+
}
|
|
392
|
+
return response;
|
|
393
|
+
}
|
|
394
|
+
continue;
|
|
395
|
+
}
|
|
396
|
+
accountStorage = recordSuccess(accountStorage, accountIndex);
|
|
397
|
+
await saveAccounts(accountStorage);
|
|
398
|
+
return response;
|
|
399
|
+
}
|
|
400
|
+
},
|
|
401
|
+
};
|
|
402
|
+
},
|
|
403
|
+
methods: [
|
|
404
|
+
{
|
|
405
|
+
label: "Qwen OAuth",
|
|
406
|
+
type: "oauth",
|
|
407
|
+
authorize: async () => {
|
|
408
|
+
const device = await authorizeQwenDevice(oauthOptions);
|
|
409
|
+
const url = device.verificationUriComplete ?? device.verificationUri;
|
|
410
|
+
const instructions = `Open ${device.verificationUri} and enter code ${device.userCode}`;
|
|
411
|
+
return {
|
|
412
|
+
url,
|
|
413
|
+
method: "auto",
|
|
414
|
+
instructions,
|
|
415
|
+
callback: async () => {
|
|
416
|
+
const result = await pollQwenDeviceToken(oauthOptions, device.deviceCode, device.intervalSeconds, device.expiresAt, device.codeVerifier);
|
|
417
|
+
if (result.type === "success") {
|
|
418
|
+
return {
|
|
419
|
+
type: "success",
|
|
420
|
+
refresh: result.refresh,
|
|
421
|
+
access: result.access,
|
|
422
|
+
expires: result.expires,
|
|
423
|
+
resourceUrl: result.resourceUrl,
|
|
424
|
+
};
|
|
425
|
+
}
|
|
426
|
+
return { type: "failed", error: result.error };
|
|
427
|
+
},
|
|
428
|
+
};
|
|
429
|
+
},
|
|
430
|
+
},
|
|
431
|
+
],
|
|
432
|
+
},
|
|
433
|
+
};
|
|
434
|
+
};
|
|
435
|
+
export const QwenCLIOAuthPlugin = createQwenOAuthPlugin("qwen");
|
|
436
|
+
export const QwenOAuthPlugin = QwenCLIOAuthPlugin;
|
|
437
|
+
export { sanitizeMalformedUrl, applyResourceUrl };
|
|
438
|
+
export default QwenOAuthPlugin;
|
|
439
|
+
//# sourceMappingURL=plugin.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"plugin.js","sourceRoot":"","sources":["../../src/plugin.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
export interface QwenOAuthOptions {
|
|
2
|
+
clientId: string;
|
|
3
|
+
oauthBaseUrl: string;
|
|
4
|
+
scopes?: string[];
|
|
5
|
+
}
|
|
6
|
+
export interface QwenDeviceAuthorization {
|
|
7
|
+
deviceCode: string;
|
|
8
|
+
userCode: string;
|
|
9
|
+
verificationUri: string;
|
|
10
|
+
verificationUriComplete?: string;
|
|
11
|
+
expiresAt: number;
|
|
12
|
+
intervalSeconds: number;
|
|
13
|
+
codeVerifier: string;
|
|
14
|
+
}
|
|
15
|
+
export type QwenTokenResult = {
|
|
16
|
+
type: "success";
|
|
17
|
+
access: string;
|
|
18
|
+
refresh: string;
|
|
19
|
+
expires: number;
|
|
20
|
+
resourceUrl?: string;
|
|
21
|
+
} | {
|
|
22
|
+
type: "failed";
|
|
23
|
+
error: string;
|
|
24
|
+
code?: string;
|
|
25
|
+
};
|
|
26
|
+
export declare function authorizeQwenDevice(options: QwenOAuthOptions): Promise<QwenDeviceAuthorization>;
|
|
27
|
+
export declare function pollQwenDeviceToken(options: QwenOAuthOptions, deviceCode: string, intervalSeconds: number, expiresAt: number, codeVerifier: string): Promise<QwenTokenResult>;
|
|
28
|
+
export declare function refreshQwenToken(options: QwenOAuthOptions, refreshToken: string): Promise<QwenTokenResult>;
|
|
29
|
+
//# sourceMappingURL=oauth.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"oauth.d.ts","sourceRoot":"","sources":["../../../src/qwen/oauth.ts"],"names":[],"mappings":"AAUA,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE,MAAM,CAAC;IACrB,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;CACnB;AAED,MAAM,WAAW,uBAAuB;IACtC,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,eAAe,EAAE,MAAM,CAAC;IACxB,uBAAuB,CAAC,EAAE,MAAM,CAAC;IACjC,SAAS,EAAE,MAAM,CAAC;IAClB,eAAe,EAAE,MAAM,CAAC;IACxB,YAAY,EAAE,MAAM,CAAC;CACtB;AAwBD,MAAM,MAAM,eAAe,GACvB;IACE,IAAI,EAAE,SAAS,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB,GACD;IACE,IAAI,EAAE,QAAQ,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;CACf,CAAC;AAsCN,wBAAsB,mBAAmB,CACvC,OAAO,EAAE,gBAAgB,GACxB,OAAO,CAAC,uBAAuB,CAAC,CAqClC;AAMD,wBAAsB,mBAAmB,CACvC,OAAO,EAAE,gBAAgB,EACzB,UAAU,EAAE,MAAM,EAClB,eAAe,EAAE,MAAM,EACvB,SAAS,EAAE,MAAM,EACjB,YAAY,EAAE,MAAM,GACnB,OAAO,CAAC,eAAe,CAAC,CA8D1B;AAED,wBAAsB,gBAAgB,CACpC,OAAO,EAAE,gBAAgB,EACzB,YAAY,EAAE,MAAM,GACnB,OAAO,CAAC,eAAe,CAAC,CAmC1B"}
|