opencode-openai-codex-multi-auth 4.4.0
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 +37 -0
- package/README.md +89 -0
- package/assets/openai-codex-auth-config.schema.json +63 -0
- package/assets/opencode-logo-ornate-dark.svg +18 -0
- package/assets/readme-hero.svg +31 -0
- package/config/README.md +103 -0
- package/config/minimal-opencode.json +12 -0
- package/config/opencode-legacy.json +571 -0
- package/config/opencode-modern.json +239 -0
- package/dist/index.d.ts +42 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +564 -0
- package/dist/index.js.map +1 -0
- package/dist/lib/accounts.d.ts +58 -0
- package/dist/lib/accounts.d.ts.map +1 -0
- package/dist/lib/accounts.js +405 -0
- package/dist/lib/accounts.js.map +1 -0
- package/dist/lib/auth/auth.d.ts +43 -0
- package/dist/lib/auth/auth.d.ts.map +1 -0
- package/dist/lib/auth/auth.js +163 -0
- package/dist/lib/auth/auth.js.map +1 -0
- package/dist/lib/auth/browser.d.ts +17 -0
- package/dist/lib/auth/browser.d.ts.map +1 -0
- package/dist/lib/auth/browser.js +76 -0
- package/dist/lib/auth/browser.js.map +1 -0
- package/dist/lib/auth/server.d.ts +10 -0
- package/dist/lib/auth/server.d.ts.map +1 -0
- package/dist/lib/auth/server.js +78 -0
- package/dist/lib/auth/server.js.map +1 -0
- package/dist/lib/cli.d.ts +8 -0
- package/dist/lib/cli.d.ts.map +1 -0
- package/dist/lib/cli.js +36 -0
- package/dist/lib/cli.js.map +1 -0
- package/dist/lib/config.d.ts +25 -0
- package/dist/lib/config.d.ts.map +1 -0
- package/dist/lib/config.js +112 -0
- package/dist/lib/config.js.map +1 -0
- package/dist/lib/constants.d.ts +67 -0
- package/dist/lib/constants.d.ts.map +1 -0
- package/dist/lib/constants.js +67 -0
- package/dist/lib/constants.js.map +1 -0
- package/dist/lib/logger.d.ts +21 -0
- package/dist/lib/logger.d.ts.map +1 -0
- package/dist/lib/logger.js +77 -0
- package/dist/lib/logger.js.map +1 -0
- package/dist/lib/oauth-success.html +712 -0
- package/dist/lib/prompts/codex-opencode-bridge.d.ts +19 -0
- package/dist/lib/prompts/codex-opencode-bridge.d.ts.map +1 -0
- package/dist/lib/prompts/codex-opencode-bridge.js +152 -0
- package/dist/lib/prompts/codex-opencode-bridge.js.map +1 -0
- package/dist/lib/prompts/codex.d.ts +28 -0
- package/dist/lib/prompts/codex.d.ts.map +1 -0
- package/dist/lib/prompts/codex.js +248 -0
- package/dist/lib/prompts/codex.js.map +1 -0
- package/dist/lib/prompts/opencode-codex.d.ts +21 -0
- package/dist/lib/prompts/opencode-codex.d.ts.map +1 -0
- package/dist/lib/prompts/opencode-codex.js +91 -0
- package/dist/lib/prompts/opencode-codex.js.map +1 -0
- package/dist/lib/request/fetch-helpers.d.ts +73 -0
- package/dist/lib/request/fetch-helpers.d.ts.map +1 -0
- package/dist/lib/request/fetch-helpers.js +221 -0
- package/dist/lib/request/fetch-helpers.js.map +1 -0
- package/dist/lib/request/helpers/input-utils.d.ts +6 -0
- package/dist/lib/request/helpers/input-utils.d.ts.map +1 -0
- package/dist/lib/request/helpers/input-utils.js +174 -0
- package/dist/lib/request/helpers/input-utils.js.map +1 -0
- package/dist/lib/request/helpers/model-map.d.ts +28 -0
- package/dist/lib/request/helpers/model-map.d.ts.map +1 -0
- package/dist/lib/request/helpers/model-map.js +109 -0
- package/dist/lib/request/helpers/model-map.js.map +1 -0
- package/dist/lib/request/request-transformer.d.ts +93 -0
- package/dist/lib/request/request-transformer.d.ts.map +1 -0
- package/dist/lib/request/request-transformer.js +403 -0
- package/dist/lib/request/request-transformer.js.map +1 -0
- package/dist/lib/request/response-handler.d.ts +14 -0
- package/dist/lib/request/response-handler.d.ts.map +1 -0
- package/dist/lib/request/response-handler.js +88 -0
- package/dist/lib/request/response-handler.js.map +1 -0
- package/dist/lib/storage.d.ts +5 -0
- package/dist/lib/storage.d.ts.map +1 -0
- package/dist/lib/storage.js +46 -0
- package/dist/lib/storage.js.map +1 -0
- package/dist/lib/types.d.ts +236 -0
- package/dist/lib/types.d.ts.map +1 -0
- package/dist/lib/types.js +2 -0
- package/dist/lib/types.js.map +1 -0
- package/package.json +77 -0
- package/scripts/install-opencode-codex-auth.js +450 -0
- package/scripts/test-all-models.sh +259 -0
- package/scripts/validate-model-map.sh +97 -0
package/dist/index.js
ADDED
|
@@ -0,0 +1,564 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* OpenAI ChatGPT (Codex) OAuth Authentication Plugin for opencode
|
|
3
|
+
*
|
|
4
|
+
* COMPLIANCE NOTICE:
|
|
5
|
+
* This plugin uses OpenAI's official OAuth authentication flow (the same method
|
|
6
|
+
* used by OpenAI's official Codex CLI at https://github.com/openai/codex).
|
|
7
|
+
*
|
|
8
|
+
* INTENDED USE: Personal development and coding assistance with your own
|
|
9
|
+
* ChatGPT Plus/Pro subscription.
|
|
10
|
+
*
|
|
11
|
+
* NOT INTENDED FOR: Commercial resale, multi-user services, high-volume
|
|
12
|
+
* automated extraction, or any use that violates OpenAI's Terms of Service.
|
|
13
|
+
*
|
|
14
|
+
* Users are responsible for ensuring their usage complies with:
|
|
15
|
+
* - OpenAI Terms of Use: https://openai.com/policies/terms-of-use/
|
|
16
|
+
* - OpenAI Usage Policies: https://openai.com/policies/usage-policies/
|
|
17
|
+
*
|
|
18
|
+
* For production applications, use the OpenAI Platform API: https://platform.openai.com/
|
|
19
|
+
*
|
|
20
|
+
* @license MIT with Usage Disclaimer (see LICENSE file)
|
|
21
|
+
* @author numman-ali
|
|
22
|
+
* @repository https://github.com/numman-ali/opencode-openai-codex-auth
|
|
23
|
+
*/
|
|
24
|
+
import { tool } from "@opencode-ai/plugin";
|
|
25
|
+
import { createAuthorizationFlow, exchangeAuthorizationCode, parseAuthorizationInput, REDIRECT_URI, refreshAccessToken, } from "./lib/auth/auth.js";
|
|
26
|
+
import { openBrowserUrl } from "./lib/auth/browser.js";
|
|
27
|
+
import { startLocalOAuthServer } from "./lib/auth/server.js";
|
|
28
|
+
import { getAccountSelectionStrategy, getCodexMode, getPidOffsetEnabled, getQuietMode, getRateLimitToastDebounceMs, getRetryAllAccountsMaxRetries, getRetryAllAccountsMaxWaitMs, getRetryAllAccountsRateLimited, getTokenRefreshSkewMs, loadPluginConfig, } from "./lib/config.js";
|
|
29
|
+
import { AUTH_LABELS, CODEX_BASE_URL, DUMMY_API_KEY, HTTP_STATUS, LOG_STAGES, PLUGIN_NAME, PROVIDER_ID, } from "./lib/constants.js";
|
|
30
|
+
import { logRequest, logDebug } from "./lib/logger.js";
|
|
31
|
+
import { createCodexHeaders, extractRequestUrl, handleErrorResponse, handleSuccessResponse, rewriteUrlForCodex, transformRequestForCodex, } from "./lib/request/fetch-helpers.js";
|
|
32
|
+
import { AccountManager, extractAccountEmail, extractAccountId, formatAccountLabel, formatWaitTime, isOAuthAuth, sanitizeEmail, } from "./lib/accounts.js";
|
|
33
|
+
import { promptAddAnotherAccount, promptLoginMode } from "./lib/cli.js";
|
|
34
|
+
import { getStoragePath, loadAccounts, saveAccounts } from "./lib/storage.js";
|
|
35
|
+
import { getModelFamily, MODEL_FAMILIES } from "./lib/prompts/codex.js";
|
|
36
|
+
const RATE_LIMIT_SHORT_RETRY_THRESHOLD_MS = 5_000;
|
|
37
|
+
const AUTH_FAILURE_COOLDOWN_MS = 60_000;
|
|
38
|
+
const MAX_ACCOUNTS = 10;
|
|
39
|
+
function shouldRefreshToken(auth, skewMs) {
|
|
40
|
+
return !auth.access || auth.expires <= Date.now() + Math.max(0, Math.floor(skewMs));
|
|
41
|
+
}
|
|
42
|
+
function parseRetryAfterMs(headers) {
|
|
43
|
+
const retryAfterMs = headers.get("retry-after-ms");
|
|
44
|
+
if (retryAfterMs) {
|
|
45
|
+
const parsed = Number(retryAfterMs);
|
|
46
|
+
if (Number.isFinite(parsed) && parsed > 0)
|
|
47
|
+
return Math.floor(parsed);
|
|
48
|
+
}
|
|
49
|
+
const retryAfter = headers.get("retry-after");
|
|
50
|
+
if (!retryAfter)
|
|
51
|
+
return null;
|
|
52
|
+
const seconds = Number(retryAfter);
|
|
53
|
+
if (Number.isFinite(seconds) && seconds > 0)
|
|
54
|
+
return Math.floor(seconds * 1000);
|
|
55
|
+
return null;
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* OpenAI Codex OAuth authentication plugin for opencode
|
|
59
|
+
*
|
|
60
|
+
* This plugin enables opencode to use OpenAI's Codex backend via ChatGPT Plus/Pro
|
|
61
|
+
* OAuth authentication, allowing users to leverage their ChatGPT subscription
|
|
62
|
+
* instead of OpenAI Platform API credits.
|
|
63
|
+
*
|
|
64
|
+
* @example
|
|
65
|
+
* ```json
|
|
66
|
+
* {
|
|
67
|
+
* "plugin": ["opencode-openai-codex-auth"],
|
|
68
|
+
* "model": "openai/gpt-5-codex"
|
|
69
|
+
* }
|
|
70
|
+
* ```
|
|
71
|
+
*/
|
|
72
|
+
export const OpenAIAuthPlugin = async ({ client }) => {
|
|
73
|
+
let cachedAccountManager = null;
|
|
74
|
+
const showToast = async (message, variant = "info", quietMode = false) => {
|
|
75
|
+
if (quietMode)
|
|
76
|
+
return;
|
|
77
|
+
try {
|
|
78
|
+
await client.tui.showToast({ body: { message, variant } });
|
|
79
|
+
}
|
|
80
|
+
catch {
|
|
81
|
+
// ignore (non-TUI contexts)
|
|
82
|
+
}
|
|
83
|
+
};
|
|
84
|
+
const buildManualOAuthFlow = (pkce, url, onSuccess) => ({
|
|
85
|
+
url,
|
|
86
|
+
method: "code",
|
|
87
|
+
instructions: AUTH_LABELS.INSTRUCTIONS_MANUAL,
|
|
88
|
+
callback: async (input) => {
|
|
89
|
+
const parsed = parseAuthorizationInput(input);
|
|
90
|
+
if (!parsed.code) {
|
|
91
|
+
return { type: "failed" };
|
|
92
|
+
}
|
|
93
|
+
const tokens = await exchangeAuthorizationCode(parsed.code, pkce.verifier, REDIRECT_URI);
|
|
94
|
+
if (tokens?.type === "success" && onSuccess) {
|
|
95
|
+
await onSuccess(tokens);
|
|
96
|
+
}
|
|
97
|
+
return tokens?.type === "success" ? tokens : { type: "failed" };
|
|
98
|
+
},
|
|
99
|
+
});
|
|
100
|
+
const persistAccount = async (token) => {
|
|
101
|
+
const now = Date.now();
|
|
102
|
+
const stored = await loadAccounts();
|
|
103
|
+
const accounts = stored?.accounts ? [...stored.accounts] : [];
|
|
104
|
+
const accountId = extractAccountId(token.access);
|
|
105
|
+
const email = sanitizeEmail(extractAccountEmail(token.access));
|
|
106
|
+
const matchIndex = (accountId ? accounts.findIndex((a) => a.accountId === accountId) : -1) ?? -1;
|
|
107
|
+
const matchIndexByEmail = email ? accounts.findIndex((a) => a.email === email) : -1;
|
|
108
|
+
const matchIndexByToken = accounts.findIndex((a) => a.refreshToken === token.refresh);
|
|
109
|
+
const existingIndex = matchIndex >= 0
|
|
110
|
+
? matchIndex
|
|
111
|
+
: matchIndexByEmail >= 0
|
|
112
|
+
? matchIndexByEmail
|
|
113
|
+
: matchIndexByToken;
|
|
114
|
+
if (existingIndex === -1) {
|
|
115
|
+
accounts.push({
|
|
116
|
+
refreshToken: token.refresh,
|
|
117
|
+
accountId,
|
|
118
|
+
email,
|
|
119
|
+
addedAt: now,
|
|
120
|
+
lastUsed: now,
|
|
121
|
+
});
|
|
122
|
+
}
|
|
123
|
+
else {
|
|
124
|
+
const existing = accounts[existingIndex];
|
|
125
|
+
if (existing) {
|
|
126
|
+
existing.refreshToken = token.refresh;
|
|
127
|
+
existing.accountId = accountId ?? existing.accountId;
|
|
128
|
+
existing.email = email ?? existing.email;
|
|
129
|
+
existing.lastUsed = now;
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
const activeIndex = stored?.activeIndex ?? 0;
|
|
133
|
+
await saveAccounts({
|
|
134
|
+
version: 3,
|
|
135
|
+
accounts,
|
|
136
|
+
activeIndex: Math.max(0, Math.min(activeIndex, accounts.length - 1)),
|
|
137
|
+
activeIndexByFamily: stored?.activeIndexByFamily ?? {},
|
|
138
|
+
});
|
|
139
|
+
};
|
|
140
|
+
return {
|
|
141
|
+
auth: {
|
|
142
|
+
provider: PROVIDER_ID,
|
|
143
|
+
/**
|
|
144
|
+
* Loader function that configures OAuth authentication and request handling
|
|
145
|
+
*
|
|
146
|
+
* This function:
|
|
147
|
+
* 1. Validates OAuth authentication
|
|
148
|
+
* 2. Extracts ChatGPT account ID from access token
|
|
149
|
+
* 3. Loads user configuration from opencode.json
|
|
150
|
+
* 4. Fetches Codex system instructions from GitHub (cached)
|
|
151
|
+
* 5. Returns SDK configuration with custom fetch implementation
|
|
152
|
+
*
|
|
153
|
+
* @param getAuth - Function to retrieve current auth state
|
|
154
|
+
* @param provider - Provider configuration from opencode.json
|
|
155
|
+
* @returns SDK configuration object or empty object for non-OAuth auth
|
|
156
|
+
*/
|
|
157
|
+
async loader(getAuth, provider) {
|
|
158
|
+
const auth = await getAuth();
|
|
159
|
+
if (!isOAuthAuth(auth)) {
|
|
160
|
+
return {};
|
|
161
|
+
}
|
|
162
|
+
const accountManager = await AccountManager.loadFromDisk(auth);
|
|
163
|
+
cachedAccountManager = accountManager;
|
|
164
|
+
if (accountManager.getAccountCount() === 0) {
|
|
165
|
+
logDebug(`[${PLUGIN_NAME}] No OAuth accounts available (run opencode auth login)`);
|
|
166
|
+
return {};
|
|
167
|
+
}
|
|
168
|
+
// Extract user configuration (global + per-model options)
|
|
169
|
+
const providerConfig = provider;
|
|
170
|
+
const userConfig = {
|
|
171
|
+
global: providerConfig?.options || {},
|
|
172
|
+
models: providerConfig?.models || {},
|
|
173
|
+
};
|
|
174
|
+
const pluginConfig = loadPluginConfig();
|
|
175
|
+
const codexMode = getCodexMode(pluginConfig);
|
|
176
|
+
const accountSelectionStrategy = getAccountSelectionStrategy(pluginConfig);
|
|
177
|
+
const pidOffsetEnabled = getPidOffsetEnabled(pluginConfig);
|
|
178
|
+
const quietMode = getQuietMode(pluginConfig);
|
|
179
|
+
const tokenRefreshSkewMs = getTokenRefreshSkewMs(pluginConfig);
|
|
180
|
+
const toastDebounceMs = getRateLimitToastDebounceMs(pluginConfig);
|
|
181
|
+
const retryAllAccountsRateLimited = getRetryAllAccountsRateLimited(pluginConfig);
|
|
182
|
+
const retryAllAccountsMaxWaitMs = getRetryAllAccountsMaxWaitMs(pluginConfig);
|
|
183
|
+
const retryAllAccountsMaxRetries = getRetryAllAccountsMaxRetries(pluginConfig);
|
|
184
|
+
// Return SDK configuration
|
|
185
|
+
return {
|
|
186
|
+
apiKey: DUMMY_API_KEY,
|
|
187
|
+
baseURL: CODEX_BASE_URL,
|
|
188
|
+
/**
|
|
189
|
+
* Custom fetch implementation for Codex API
|
|
190
|
+
*
|
|
191
|
+
* Handles:
|
|
192
|
+
* - Token refresh when expired
|
|
193
|
+
* - URL rewriting for Codex backend
|
|
194
|
+
* - Request body transformation
|
|
195
|
+
* - OAuth header injection
|
|
196
|
+
* - SSE to JSON conversion for non-tool requests
|
|
197
|
+
* - Error handling and logging
|
|
198
|
+
*
|
|
199
|
+
* @param input - Request URL or Request object
|
|
200
|
+
* @param init - Request options
|
|
201
|
+
* @returns Response from Codex API
|
|
202
|
+
*/
|
|
203
|
+
async fetch(input, init) {
|
|
204
|
+
// Step 2: Extract and rewrite URL for Codex backend
|
|
205
|
+
const originalUrl = extractRequestUrl(input);
|
|
206
|
+
const url = rewriteUrlForCodex(originalUrl);
|
|
207
|
+
// Step 3: Transform request body with model-specific Codex instructions
|
|
208
|
+
// Instructions are fetched per model family (codex-max, codex, gpt-5.1)
|
|
209
|
+
// Capture original stream value before transformation
|
|
210
|
+
// generateText() sends no stream field, streamText() sends stream=true
|
|
211
|
+
const originalBody = init?.body ? JSON.parse(init.body) : {};
|
|
212
|
+
const isStreaming = originalBody.stream === true;
|
|
213
|
+
const transformation = await transformRequestForCodex(init, url, userConfig, codexMode);
|
|
214
|
+
const requestInit = transformation?.updatedInit ?? init;
|
|
215
|
+
const model = transformation?.body.model;
|
|
216
|
+
const modelFamily = model ? getModelFamily(model) : "gpt-5.1";
|
|
217
|
+
const usePidOffset = pidOffsetEnabled && accountManager.getAccountCount() > 1;
|
|
218
|
+
const abortSignal = requestInit?.signal ?? init?.signal ?? null;
|
|
219
|
+
const sleep = (ms) => new Promise((resolve, reject) => {
|
|
220
|
+
if (abortSignal?.aborted) {
|
|
221
|
+
reject(new Error("Aborted"));
|
|
222
|
+
return;
|
|
223
|
+
}
|
|
224
|
+
const timeout = setTimeout(() => {
|
|
225
|
+
cleanup();
|
|
226
|
+
resolve();
|
|
227
|
+
}, ms);
|
|
228
|
+
const onAbort = () => {
|
|
229
|
+
cleanup();
|
|
230
|
+
reject(new Error("Aborted"));
|
|
231
|
+
};
|
|
232
|
+
const cleanup = () => {
|
|
233
|
+
clearTimeout(timeout);
|
|
234
|
+
abortSignal?.removeEventListener("abort", onAbort);
|
|
235
|
+
};
|
|
236
|
+
abortSignal?.addEventListener("abort", onAbort, { once: true });
|
|
237
|
+
});
|
|
238
|
+
let allRateLimitedRetries = 0;
|
|
239
|
+
while (true) {
|
|
240
|
+
const accountCount = accountManager.getAccountCount();
|
|
241
|
+
const attempted = new Set();
|
|
242
|
+
while (attempted.size < Math.max(1, accountCount)) {
|
|
243
|
+
const account = accountManager.getCurrentOrNextForFamily(modelFamily, model, accountSelectionStrategy, usePidOffset);
|
|
244
|
+
if (!account || attempted.has(account.index))
|
|
245
|
+
break;
|
|
246
|
+
attempted.add(account.index);
|
|
247
|
+
let accountAuth = accountManager.toAuthDetails(account);
|
|
248
|
+
if (shouldRefreshToken(accountAuth, tokenRefreshSkewMs)) {
|
|
249
|
+
const refreshed = await refreshAccessToken(account.refreshToken);
|
|
250
|
+
if (refreshed.type !== "success") {
|
|
251
|
+
accountManager.markAccountCoolingDown(account, AUTH_FAILURE_COOLDOWN_MS, "auth-failure");
|
|
252
|
+
await accountManager.saveToDisk();
|
|
253
|
+
await showToast(`Auth refresh failed. Cooling down ${formatAccountLabel(account, account.index)}.`, "warning", quietMode);
|
|
254
|
+
continue;
|
|
255
|
+
}
|
|
256
|
+
accountAuth = {
|
|
257
|
+
type: "oauth",
|
|
258
|
+
access: refreshed.access,
|
|
259
|
+
refresh: refreshed.refresh,
|
|
260
|
+
expires: refreshed.expires,
|
|
261
|
+
};
|
|
262
|
+
accountManager.updateFromAuth(account, accountAuth);
|
|
263
|
+
await accountManager.saveToDisk();
|
|
264
|
+
// Keep OpenCode's stored auth aligned with the last-used account.
|
|
265
|
+
await client.auth.set({
|
|
266
|
+
path: { id: PROVIDER_ID },
|
|
267
|
+
body: accountAuth,
|
|
268
|
+
});
|
|
269
|
+
}
|
|
270
|
+
const accountId = account.accountId ?? extractAccountId(accountAuth.access);
|
|
271
|
+
if (!accountId) {
|
|
272
|
+
accountManager.markAccountCoolingDown(account, AUTH_FAILURE_COOLDOWN_MS, "auth-failure");
|
|
273
|
+
await accountManager.saveToDisk();
|
|
274
|
+
continue;
|
|
275
|
+
}
|
|
276
|
+
account.accountId = accountId;
|
|
277
|
+
if (accountCount > 1 &&
|
|
278
|
+
accountManager.shouldShowAccountToast(account.index, toastDebounceMs)) {
|
|
279
|
+
await showToast(`Using ${formatAccountLabel(account, account.index)} (${account.index + 1}/${accountCount})`, "info", quietMode);
|
|
280
|
+
accountManager.markToastShown(account.index);
|
|
281
|
+
}
|
|
282
|
+
const headers = createCodexHeaders(requestInit, accountId, accountAuth.access, {
|
|
283
|
+
model,
|
|
284
|
+
promptCacheKey: transformation?.body?.prompt_cache_key,
|
|
285
|
+
});
|
|
286
|
+
while (true) {
|
|
287
|
+
const res = await fetch(url, { ...requestInit, headers });
|
|
288
|
+
logRequest(LOG_STAGES.RESPONSE, {
|
|
289
|
+
status: res.status,
|
|
290
|
+
ok: res.ok,
|
|
291
|
+
statusText: res.statusText,
|
|
292
|
+
headers: Object.fromEntries(res.headers.entries()),
|
|
293
|
+
accountIndex: account.index,
|
|
294
|
+
accountCount,
|
|
295
|
+
});
|
|
296
|
+
if (res.ok) {
|
|
297
|
+
return await handleSuccessResponse(res, isStreaming);
|
|
298
|
+
}
|
|
299
|
+
const handled = await handleErrorResponse(res);
|
|
300
|
+
if (handled.status !== HTTP_STATUS.TOO_MANY_REQUESTS) {
|
|
301
|
+
return handled;
|
|
302
|
+
}
|
|
303
|
+
const retryAfterMs = parseRetryAfterMs(handled.headers) ?? 60_000;
|
|
304
|
+
if (retryAfterMs <= RATE_LIMIT_SHORT_RETRY_THRESHOLD_MS) {
|
|
305
|
+
await showToast(`Rate limited. Retrying in ${formatWaitTime(retryAfterMs)}...`, "warning", quietMode);
|
|
306
|
+
await sleep(retryAfterMs);
|
|
307
|
+
continue;
|
|
308
|
+
}
|
|
309
|
+
accountManager.markRateLimited(account, retryAfterMs, modelFamily, model);
|
|
310
|
+
accountManager.markSwitched(account, "rate-limit", modelFamily);
|
|
311
|
+
await accountManager.saveToDisk();
|
|
312
|
+
await showToast(`Rate limited. Switching accounts (retry in ${formatWaitTime(retryAfterMs)}).`, "warning", quietMode);
|
|
313
|
+
break;
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
const waitMs = accountManager.getMinWaitTimeForFamily(modelFamily, model);
|
|
317
|
+
if (retryAllAccountsRateLimited &&
|
|
318
|
+
accountManager.getAccountCount() > 0 &&
|
|
319
|
+
waitMs > 0 &&
|
|
320
|
+
(retryAllAccountsMaxWaitMs === 0 || waitMs <= retryAllAccountsMaxWaitMs) &&
|
|
321
|
+
allRateLimitedRetries < retryAllAccountsMaxRetries) {
|
|
322
|
+
allRateLimitedRetries += 1;
|
|
323
|
+
await showToast(`All ${accountManager.getAccountCount()} account(s) are rate-limited. Waiting ${formatWaitTime(waitMs)}...`, "warning", quietMode);
|
|
324
|
+
await sleep(waitMs);
|
|
325
|
+
continue;
|
|
326
|
+
}
|
|
327
|
+
const storePath = getStoragePath();
|
|
328
|
+
const waitLabel = waitMs > 0 ? formatWaitTime(waitMs) : "a bit";
|
|
329
|
+
const message = accountManager.getAccountCount() === 0
|
|
330
|
+
? "No OpenAI accounts configured. Run `opencode auth login`."
|
|
331
|
+
: `All ${accountManager.getAccountCount()} account(s) are rate-limited. Try again in ${waitLabel} or add another account with \`opencode auth login\`. (Storage: ${storePath})`;
|
|
332
|
+
return new Response(JSON.stringify({ error: { message } }), {
|
|
333
|
+
status: 429,
|
|
334
|
+
headers: { "content-type": "application/json; charset=utf-8" },
|
|
335
|
+
});
|
|
336
|
+
}
|
|
337
|
+
},
|
|
338
|
+
};
|
|
339
|
+
},
|
|
340
|
+
methods: [
|
|
341
|
+
{
|
|
342
|
+
label: AUTH_LABELS.OAUTH,
|
|
343
|
+
type: "oauth",
|
|
344
|
+
/**
|
|
345
|
+
* OAuth authorization flow
|
|
346
|
+
*
|
|
347
|
+
* Steps:
|
|
348
|
+
* 1. Generate PKCE challenge and state for security
|
|
349
|
+
* 2. Start local OAuth callback server on port 1455
|
|
350
|
+
* 3. Open browser to OpenAI authorization page
|
|
351
|
+
* 4. Wait for user to complete login
|
|
352
|
+
* 5. Exchange authorization code for tokens
|
|
353
|
+
*
|
|
354
|
+
* @returns Authorization flow configuration
|
|
355
|
+
*/
|
|
356
|
+
authorize: async (inputs) => {
|
|
357
|
+
const pluginConfig = loadPluginConfig();
|
|
358
|
+
const quietMode = getQuietMode(pluginConfig);
|
|
359
|
+
const noBrowser = inputs?.noBrowser === "true" ||
|
|
360
|
+
inputs?.["no-browser"] === "true" ||
|
|
361
|
+
process.env.OPENCODE_NO_BROWSER === "1";
|
|
362
|
+
const promptOAuthCallbackValue = async (message) => {
|
|
363
|
+
const { createInterface } = await import("node:readline/promises");
|
|
364
|
+
const { stdin, stdout } = await import("node:process");
|
|
365
|
+
const rl = createInterface({ input: stdin, output: stdout });
|
|
366
|
+
try {
|
|
367
|
+
return (await rl.question(message)).trim();
|
|
368
|
+
}
|
|
369
|
+
finally {
|
|
370
|
+
rl.close();
|
|
371
|
+
}
|
|
372
|
+
};
|
|
373
|
+
const runOAuthFlow = async () => {
|
|
374
|
+
const { pkce, state, url } = await createAuthorizationFlow();
|
|
375
|
+
console.log("\nOAuth URL:\n" + url + "\n");
|
|
376
|
+
if (noBrowser) {
|
|
377
|
+
const callbackInput = await promptOAuthCallbackValue("Paste the redirect URL (or just the code) here: ");
|
|
378
|
+
const parsed = parseAuthorizationInput(callbackInput);
|
|
379
|
+
if (!parsed.code)
|
|
380
|
+
return { type: "failed" };
|
|
381
|
+
return await exchangeAuthorizationCode(parsed.code, pkce.verifier, REDIRECT_URI);
|
|
382
|
+
}
|
|
383
|
+
let serverInfo = null;
|
|
384
|
+
try {
|
|
385
|
+
serverInfo = await startLocalOAuthServer({ state });
|
|
386
|
+
}
|
|
387
|
+
catch {
|
|
388
|
+
serverInfo = null;
|
|
389
|
+
}
|
|
390
|
+
openBrowserUrl(url);
|
|
391
|
+
if (!serverInfo || !serverInfo.ready) {
|
|
392
|
+
serverInfo?.close();
|
|
393
|
+
const callbackInput = await promptOAuthCallbackValue("Paste the redirect URL (or just the code) here: ");
|
|
394
|
+
const parsed = parseAuthorizationInput(callbackInput);
|
|
395
|
+
if (!parsed.code)
|
|
396
|
+
return { type: "failed" };
|
|
397
|
+
return await exchangeAuthorizationCode(parsed.code, pkce.verifier, REDIRECT_URI);
|
|
398
|
+
}
|
|
399
|
+
const result = await serverInfo.waitForCode(state);
|
|
400
|
+
serverInfo.close();
|
|
401
|
+
if (!result)
|
|
402
|
+
return { type: "failed" };
|
|
403
|
+
return await exchangeAuthorizationCode(result.code, pkce.verifier, REDIRECT_URI);
|
|
404
|
+
};
|
|
405
|
+
const authenticated = [];
|
|
406
|
+
let startFresh = true;
|
|
407
|
+
const existingStorage = await loadAccounts();
|
|
408
|
+
if (existingStorage && existingStorage.accounts.length > 0) {
|
|
409
|
+
const existingLabels = existingStorage.accounts.map((a, index) => ({
|
|
410
|
+
index,
|
|
411
|
+
email: a.email,
|
|
412
|
+
accountId: a.accountId,
|
|
413
|
+
}));
|
|
414
|
+
const mode = await promptLoginMode(existingLabels);
|
|
415
|
+
startFresh = mode === "fresh";
|
|
416
|
+
}
|
|
417
|
+
if (startFresh) {
|
|
418
|
+
await saveAccounts({
|
|
419
|
+
version: 3,
|
|
420
|
+
accounts: [],
|
|
421
|
+
activeIndex: 0,
|
|
422
|
+
activeIndexByFamily: {},
|
|
423
|
+
});
|
|
424
|
+
}
|
|
425
|
+
while (authenticated.length < MAX_ACCOUNTS) {
|
|
426
|
+
console.log(`\n=== OpenAI OAuth (Account ${authenticated.length + 1}) ===`);
|
|
427
|
+
const result = await runOAuthFlow();
|
|
428
|
+
if (result.type !== "success") {
|
|
429
|
+
if (authenticated.length === 0) {
|
|
430
|
+
return {
|
|
431
|
+
url: "",
|
|
432
|
+
instructions: "Authentication failed.",
|
|
433
|
+
method: "auto",
|
|
434
|
+
callback: async () => ({ type: "failed" }),
|
|
435
|
+
};
|
|
436
|
+
}
|
|
437
|
+
break;
|
|
438
|
+
}
|
|
439
|
+
authenticated.push(result);
|
|
440
|
+
await persistAccount(result);
|
|
441
|
+
await showToast(`Account ${authenticated.length} authenticated`, "success", quietMode);
|
|
442
|
+
const currentStorage = await loadAccounts();
|
|
443
|
+
const count = currentStorage?.accounts.length ?? authenticated.length;
|
|
444
|
+
if (!(await promptAddAnotherAccount(count, MAX_ACCOUNTS)))
|
|
445
|
+
break;
|
|
446
|
+
}
|
|
447
|
+
const primary = authenticated[0];
|
|
448
|
+
if (!primary) {
|
|
449
|
+
return {
|
|
450
|
+
url: "",
|
|
451
|
+
instructions: "Authentication cancelled",
|
|
452
|
+
method: "auto",
|
|
453
|
+
callback: async () => ({ type: "failed" }),
|
|
454
|
+
};
|
|
455
|
+
}
|
|
456
|
+
const finalStorage = await loadAccounts();
|
|
457
|
+
const finalCount = finalStorage?.accounts.length ?? authenticated.length;
|
|
458
|
+
return {
|
|
459
|
+
url: "",
|
|
460
|
+
instructions: `Multi-account setup complete (${finalCount} account(s)).\nStorage: ${getStoragePath()}`,
|
|
461
|
+
method: "auto",
|
|
462
|
+
callback: async () => primary,
|
|
463
|
+
};
|
|
464
|
+
},
|
|
465
|
+
},
|
|
466
|
+
{
|
|
467
|
+
label: AUTH_LABELS.OAUTH_MANUAL,
|
|
468
|
+
type: "oauth",
|
|
469
|
+
authorize: async () => {
|
|
470
|
+
const { pkce, url } = await createAuthorizationFlow();
|
|
471
|
+
return buildManualOAuthFlow(pkce, url, async (tokens) => {
|
|
472
|
+
await persistAccount(tokens);
|
|
473
|
+
});
|
|
474
|
+
},
|
|
475
|
+
},
|
|
476
|
+
{
|
|
477
|
+
label: AUTH_LABELS.API_KEY,
|
|
478
|
+
type: "api",
|
|
479
|
+
},
|
|
480
|
+
],
|
|
481
|
+
},
|
|
482
|
+
tool: {
|
|
483
|
+
"openai-accounts": tool({
|
|
484
|
+
description: "List all configured OpenAI OAuth accounts.",
|
|
485
|
+
args: {},
|
|
486
|
+
async execute() {
|
|
487
|
+
const storage = await loadAccounts();
|
|
488
|
+
const storePath = getStoragePath();
|
|
489
|
+
if (!storage || storage.accounts.length === 0) {
|
|
490
|
+
return [
|
|
491
|
+
"No OpenAI accounts configured.",
|
|
492
|
+
"",
|
|
493
|
+
"Add accounts:",
|
|
494
|
+
" opencode auth login",
|
|
495
|
+
"",
|
|
496
|
+
`Storage: ${storePath}`,
|
|
497
|
+
].join("\n");
|
|
498
|
+
}
|
|
499
|
+
const activeIndex = typeof storage.activeIndex === "number" && Number.isFinite(storage.activeIndex)
|
|
500
|
+
? storage.activeIndex
|
|
501
|
+
: 0;
|
|
502
|
+
const now = Date.now();
|
|
503
|
+
const lines = [
|
|
504
|
+
`OpenAI Accounts (${storage.accounts.length}):`,
|
|
505
|
+
"",
|
|
506
|
+
" # Label Status",
|
|
507
|
+
"----------------------------------------------- ---------------------",
|
|
508
|
+
];
|
|
509
|
+
storage.accounts.forEach((account, index) => {
|
|
510
|
+
const label = formatAccountLabel(account, index);
|
|
511
|
+
const statuses = [];
|
|
512
|
+
if (index === activeIndex)
|
|
513
|
+
statuses.push("active");
|
|
514
|
+
const rateLimited = account.rateLimitResetTimes &&
|
|
515
|
+
Object.values(account.rateLimitResetTimes).some((t) => typeof t === "number" && t > now);
|
|
516
|
+
if (rateLimited)
|
|
517
|
+
statuses.push("rate-limited");
|
|
518
|
+
if (typeof account.coolingDownUntil === "number" &&
|
|
519
|
+
account.coolingDownUntil > now) {
|
|
520
|
+
statuses.push("cooldown");
|
|
521
|
+
}
|
|
522
|
+
lines.push(`${String(index + 1).padEnd(3)} ${label.padEnd(40)} ${statuses.length > 0 ? statuses.join(", ") : "ok"}`);
|
|
523
|
+
});
|
|
524
|
+
lines.push("", `Storage: ${storePath}`);
|
|
525
|
+
return lines.join("\n");
|
|
526
|
+
},
|
|
527
|
+
}),
|
|
528
|
+
"openai-accounts-switch": tool({
|
|
529
|
+
description: "Switch active OpenAI account by index (1-based).",
|
|
530
|
+
args: {
|
|
531
|
+
index: tool.schema.number().describe("Account number (1-based)"),
|
|
532
|
+
},
|
|
533
|
+
async execute({ index }) {
|
|
534
|
+
const storage = await loadAccounts();
|
|
535
|
+
if (!storage || storage.accounts.length === 0) {
|
|
536
|
+
return "No OpenAI accounts configured. Run: opencode auth login";
|
|
537
|
+
}
|
|
538
|
+
const targetIndex = Math.floor((index ?? 0) - 1);
|
|
539
|
+
if (targetIndex < 0 || targetIndex >= storage.accounts.length) {
|
|
540
|
+
return `Invalid account number: ${index}\nValid range: 1-${storage.accounts.length}`;
|
|
541
|
+
}
|
|
542
|
+
storage.activeIndex = targetIndex;
|
|
543
|
+
storage.activeIndexByFamily = storage.activeIndexByFamily ?? {};
|
|
544
|
+
for (const family of MODEL_FAMILIES) {
|
|
545
|
+
storage.activeIndexByFamily[family] = targetIndex;
|
|
546
|
+
}
|
|
547
|
+
const account = storage.accounts[targetIndex];
|
|
548
|
+
if (account) {
|
|
549
|
+
account.lastUsed = Date.now();
|
|
550
|
+
account.lastSwitchReason = "rotation";
|
|
551
|
+
}
|
|
552
|
+
await saveAccounts(storage);
|
|
553
|
+
if (cachedAccountManager) {
|
|
554
|
+
cachedAccountManager.setActiveIndex(targetIndex);
|
|
555
|
+
await cachedAccountManager.saveToDisk();
|
|
556
|
+
}
|
|
557
|
+
return `Switched to ${formatAccountLabel(account, targetIndex)}`;
|
|
558
|
+
},
|
|
559
|
+
}),
|
|
560
|
+
},
|
|
561
|
+
};
|
|
562
|
+
};
|
|
563
|
+
export default OpenAIAuthPlugin;
|
|
564
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../index.ts"],"names":[],"mappings":"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"}
|