better-opencode-openai-codex-auth 0.1.1 → 0.1.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.
Files changed (78) hide show
  1. package/README.md +24 -0
  2. package/config/README.md +19 -93
  3. package/config/opencode-modern.json +149 -42
  4. package/dist/index.d.ts +0 -12
  5. package/dist/index.d.ts.map +1 -1
  6. package/dist/index.js +215 -109
  7. package/dist/index.js.map +1 -1
  8. package/dist/lib/account-pool.d.ts +29 -3
  9. package/dist/lib/account-pool.d.ts.map +1 -1
  10. package/dist/lib/account-pool.js +211 -44
  11. package/dist/lib/account-pool.js.map +1 -1
  12. package/dist/lib/auth/auth.d.ts +55 -4
  13. package/dist/lib/auth/auth.d.ts.map +1 -1
  14. package/dist/lib/auth/auth.js +142 -13
  15. package/dist/lib/auth/auth.js.map +1 -1
  16. package/dist/lib/auth/server.d.ts.map +1 -1
  17. package/dist/lib/auth/server.js +12 -8
  18. package/dist/lib/auth/server.js.map +1 -1
  19. package/dist/lib/auth/ui/account-menu.d.ts +50 -0
  20. package/dist/lib/auth/ui/account-menu.d.ts.map +1 -0
  21. package/dist/lib/auth/ui/account-menu.js +258 -0
  22. package/dist/lib/auth/ui/account-menu.js.map +1 -0
  23. package/dist/lib/auth/ui/ansi.d.ts +23 -0
  24. package/dist/lib/auth/ui/ansi.d.ts.map +1 -0
  25. package/dist/lib/auth/ui/ansi.js +37 -0
  26. package/dist/lib/auth/ui/ansi.js.map +1 -0
  27. package/dist/lib/auth/ui/confirm.d.ts +2 -0
  28. package/dist/lib/auth/ui/confirm.d.ts.map +1 -0
  29. package/dist/lib/auth/ui/confirm.js +8 -0
  30. package/dist/lib/auth/ui/confirm.js.map +1 -0
  31. package/dist/lib/auth/ui/select.d.ts +21 -0
  32. package/dist/lib/auth/ui/select.d.ts.map +1 -0
  33. package/dist/lib/auth/ui/select.js +208 -0
  34. package/dist/lib/auth/ui/select.js.map +1 -0
  35. package/dist/lib/config.d.ts.map +1 -1
  36. package/dist/lib/config.js +13 -4
  37. package/dist/lib/config.js.map +1 -1
  38. package/dist/lib/constants.d.ts +76 -3
  39. package/dist/lib/constants.d.ts.map +1 -1
  40. package/dist/lib/constants.js +80 -3
  41. package/dist/lib/constants.js.map +1 -1
  42. package/dist/lib/logger.d.ts +6 -0
  43. package/dist/lib/logger.d.ts.map +1 -1
  44. package/dist/lib/logger.js +11 -2
  45. package/dist/lib/logger.js.map +1 -1
  46. package/dist/lib/prompts/codex.d.ts +1 -1
  47. package/dist/lib/prompts/codex.d.ts.map +1 -1
  48. package/dist/lib/prompts/codex.js +15 -2
  49. package/dist/lib/prompts/codex.js.map +1 -1
  50. package/dist/lib/refresh-queue.d.ts +56 -0
  51. package/dist/lib/refresh-queue.d.ts.map +1 -0
  52. package/dist/lib/refresh-queue.js +148 -0
  53. package/dist/lib/refresh-queue.js.map +1 -0
  54. package/dist/lib/request/fetch-helpers.d.ts +2 -1
  55. package/dist/lib/request/fetch-helpers.d.ts.map +1 -1
  56. package/dist/lib/request/fetch-helpers.js +25 -5
  57. package/dist/lib/request/fetch-helpers.js.map +1 -1
  58. package/dist/lib/request/helpers/input-utils.d.ts.map +1 -1
  59. package/dist/lib/request/helpers/input-utils.js +12 -10
  60. package/dist/lib/request/helpers/input-utils.js.map +1 -1
  61. package/dist/lib/request/helpers/model-map.d.ts.map +1 -1
  62. package/dist/lib/request/helpers/model-map.js +14 -1
  63. package/dist/lib/request/helpers/model-map.js.map +1 -1
  64. package/dist/lib/request/request-transformer.d.ts.map +1 -1
  65. package/dist/lib/request/request-transformer.js +33 -29
  66. package/dist/lib/request/request-transformer.js.map +1 -1
  67. package/dist/lib/request/response-handler.d.ts.map +1 -1
  68. package/dist/lib/request/response-handler.js +17 -13
  69. package/dist/lib/request/response-handler.js.map +1 -1
  70. package/dist/lib/schemas.d.ts +85 -0
  71. package/dist/lib/schemas.d.ts.map +1 -0
  72. package/dist/lib/schemas.js +93 -0
  73. package/dist/lib/schemas.js.map +1 -0
  74. package/dist/lib/types.d.ts +18 -2
  75. package/dist/lib/types.d.ts.map +1 -1
  76. package/package.json +6 -7
  77. package/scripts/install-opencode-codex-auth.js +7 -27
  78. package/config/opencode-legacy.json +0 -571
package/dist/index.js CHANGED
@@ -21,28 +21,57 @@
21
21
  * @author ShivamB25 (fork maintainer); originally by numman-ali
22
22
  * @repository https://github.com/ShivamB25/better-opencode-openai-codex-auth
23
23
  */
24
- import { createAuthorizationFlow, decodeJWT, exchangeAuthorizationCode, parseAuthorizationInput, refreshAccessToken, REDIRECT_URI, } from "./lib/auth/auth.js";
24
+ import os from "node:os";
25
+ import { createAuthorizationFlow, createDeviceAuthorizationFlow, extractAccountId, extractAccountIdFromToken, exchangeAuthorizationCode, parseAuthorizationInput, refreshAccessTokenShared, REDIRECT_URI, } from "./lib/auth/auth.js";
25
26
  import { openBrowserUrl } from "./lib/auth/browser.js";
26
27
  import { startLocalOAuthServer } from "./lib/auth/server.js";
28
+ import { showAccountManager } from "./lib/auth/ui/account-menu.js";
27
29
  import { getCodexMode, loadPluginConfig } from "./lib/config.js";
28
- import { AUTH_LABELS, CODEX_BASE_URL, DUMMY_API_KEY, ERROR_MESSAGES, JWT_CLAIM_PATH, LOG_STAGES, PLUGIN_NAME, PROVIDER_ID, } from "./lib/constants.js";
30
+ import { AUTH_LABELS, CODEX_BASE_URL, DUMMY_API_KEY, ERROR_MESSAGES, LOG_STAGES, MAX_RECOVERY_WAIT_MS, PLUGIN_NAME, PLUGIN_VERSION, PROVIDER_ID, } from "./lib/constants.js";
29
31
  import { logRequest, logDebug, logWarn } from "./lib/logger.js";
30
32
  import { createCodexHeaders, extractRequestUrl, handleErrorResponse, handleSuccessResponse, rewriteUrlForCodex, transformRequestForCodex, } from "./lib/request/fetch-helpers.js";
31
33
  import { AccountPool } from "./lib/account-pool.js";
34
+ import { ProactiveRefreshQueue } from "./lib/refresh-queue.js";
35
+ /**
36
+ * Parse a ChatGPT error code from a 429 response body.
37
+ * Used for tiered cooldown durations (#10).
38
+ */
39
+ async function parseErrorCode(response) {
40
+ try {
41
+ const clone = response.clone();
42
+ const text = await clone.text();
43
+ if (!text)
44
+ return undefined;
45
+ const parsed = JSON.parse(text);
46
+ return (parsed?.error?.code ?? parsed?.error?.type) || undefined;
47
+ }
48
+ catch {
49
+ return undefined;
50
+ }
51
+ }
52
+ /**
53
+ * Build a 429 response when all accounts are rate-limited
54
+ * @param retryAfterMs - Minimum retry-after time from pool, or null
55
+ */
56
+ function buildAllRateLimitedResponse(retryAfterMs) {
57
+ const retryAfterSeconds = retryAfterMs ? Math.max(1, Math.ceil(retryAfterMs / 1000)) : null;
58
+ return new Response(JSON.stringify({
59
+ error: {
60
+ code: "usage_limit_reached",
61
+ message: "All ChatGPT accounts are temporarily rate-limited",
62
+ },
63
+ }), {
64
+ status: 429,
65
+ headers: {
66
+ "content-type": "application/json",
67
+ ...(retryAfterSeconds
68
+ ? { "retry-after": String(retryAfterSeconds) }
69
+ : {}),
70
+ },
71
+ });
72
+ }
32
73
  /**
33
74
  * OpenAI Codex OAuth authentication plugin for opencode
34
- *
35
- * This plugin enables opencode to use OpenAI's Codex backend via ChatGPT Plus/Pro
36
- * OAuth authentication, allowing users to leverage their ChatGPT subscription
37
- * instead of OpenAI Platform API credits.
38
- *
39
- * @example
40
- * ```json
41
- * {
42
- * "plugin": ["better-opencode-openai-codex-auth"],
43
- * "model": "openai/gpt-5-codex"
44
- * }
45
- * ```
46
75
  */
47
76
  export const OpenAIAuthPlugin = async ({ client }) => {
48
77
  const buildManualOAuthFlow = (pkce, url) => ({
@@ -55,35 +84,36 @@ export const OpenAIAuthPlugin = async ({ client }) => {
55
84
  return { type: "failed" };
56
85
  }
57
86
  const tokens = await exchangeAuthorizationCode(parsed.code, pkce.verifier, REDIRECT_URI);
58
- return tokens?.type === "success" ? tokens : { type: "failed" };
87
+ if (tokens?.type !== "success")
88
+ return { type: "failed" };
89
+ return {
90
+ ...tokens,
91
+ accountId: extractAccountId({
92
+ access_token: tokens.access,
93
+ id_token: tokens.id_token,
94
+ }),
95
+ };
59
96
  },
60
97
  });
61
98
  return {
62
99
  auth: {
63
100
  provider: PROVIDER_ID,
64
101
  /**
65
- * Loader function that configures OAuth authentication and request handling
66
- *
67
- * This function:
68
- * 1. Validates OAuth authentication
69
- * 2. Extracts ChatGPT account ID from access token
70
- * 3. Loads user configuration from opencode.json
71
- * 4. Fetches Codex system instructions from GitHub (cached)
72
- * 5. Returns SDK configuration with custom fetch implementation
73
- *
74
- * @param getAuth - Function to retrieve current auth state
75
- * @param provider - Provider configuration from opencode.json
76
- * @returns SDK configuration object or empty object for non-OAuth auth
102
+ * Loader: validates OAuth auth, sets up per-account token management,
103
+ * starts proactive background refresh, and returns the custom fetch.
77
104
  */
78
105
  async loader(getAuth, provider) {
79
106
  const auth = await getAuth();
80
- // Only handle OAuth auth type, skip API key auth
107
+ // Only handle OAuth auth type
81
108
  if (auth.type !== "oauth") {
82
109
  return {};
83
110
  }
84
- // Extract ChatGPT account ID from JWT access token
85
- const decoded = decodeJWT(auth.access);
86
- const accountId = decoded?.[JWT_CLAIM_PATH]?.chatgpt_account_id;
111
+ // Extract ChatGPT account ID prefer stored accountId (#5), then id_token,
112
+ // then decode access token (checks root + nested JWT claim locations)
113
+ const authWithAccount = auth;
114
+ let accountId = authWithAccount.accountId ||
115
+ (authWithAccount.id_token ? extractAccountIdFromToken(authWithAccount.id_token) : undefined) ||
116
+ extractAccountIdFromToken(auth.access);
87
117
  if (!accountId) {
88
118
  logDebug(`[${PLUGIN_NAME}] ${ERROR_MESSAGES.NO_ACCOUNT_ID} (skipping plugin)`);
89
119
  return {};
@@ -94,8 +124,7 @@ export const OpenAIAuthPlugin = async ({ client }) => {
94
124
  global: providerConfig?.options || {},
95
125
  models: providerConfig?.models || {},
96
126
  };
97
- // Load plugin configuration and determine CODEX_MODE
98
- // Priority: CODEX_MODE env var > config file > default (true)
127
+ // Load plugin configuration
99
128
  const pluginConfig = loadPluginConfig();
100
129
  const codexMode = getCodexMode(pluginConfig);
101
130
  const accountSelectionStrategy = pluginConfig.accountSelectionStrategy === "sticky" ? "sticky" : "round-robin";
@@ -109,62 +138,47 @@ export const OpenAIAuthPlugin = async ({ client }) => {
109
138
  logWarn("Failed to persist account pool", error);
110
139
  }
111
140
  };
141
+ // Sync current auth into pool
112
142
  accountPool.upsert({
113
143
  accountId,
114
144
  access: auth.access,
115
145
  refresh: auth.refresh,
116
146
  expires: auth.expires,
117
- email: typeof decoded?.email === "string"
118
- ? decoded.email
147
+ email: typeof auth.email === "string"
148
+ ? auth.email
119
149
  : undefined,
120
150
  });
121
151
  savePool();
122
- // Return SDK configuration
152
+ // Start proactive background token refresh (#8)
153
+ const refreshQueue = new ProactiveRefreshQueue(accountPool);
154
+ refreshQueue.start();
123
155
  return {
124
156
  apiKey: DUMMY_API_KEY,
125
157
  baseURL: CODEX_BASE_URL,
126
- /**
127
- * Custom fetch implementation for Codex API
128
- *
129
- * Handles:
130
- * - Per-account token refresh when expired (inside retry loop)
131
- * - URL rewriting for Codex backend
132
- * - Request body transformation
133
- * - OAuth header injection per selected account
134
- * - Automatic 429 rotation across account pool
135
- * - SSE to JSON conversion for non-tool requests
136
- * - Error handling and logging
137
- *
138
- * @param input - Request URL or Request object
139
- * @param init - Request options
140
- * @returns Response from Codex API
141
- */
142
158
  async fetch(input, init) {
143
159
  const latestAuth = await getAuth();
144
- let latestAccountIdFromAuth;
160
+ const latestWithAccount = latestAuth;
145
161
  if (latestAuth.type === "oauth") {
146
- const latestDecoded = decodeJWT(latestAuth.access);
147
- const latestAccountId = latestDecoded?.[JWT_CLAIM_PATH]?.chatgpt_account_id;
148
- latestAccountIdFromAuth = latestAccountId;
162
+ // Re-extract account ID with the priority chain (#5)
163
+ const latestAccountId = latestWithAccount.accountId ||
164
+ (latestWithAccount.id_token
165
+ ? extractAccountIdFromToken(latestWithAccount.id_token)
166
+ : undefined) ||
167
+ extractAccountIdFromToken(latestAuth.access);
149
168
  if (latestAccountId) {
169
+ accountId = latestAccountId;
150
170
  accountPool.upsert({
151
171
  accountId: latestAccountId,
152
172
  access: latestAuth.access,
153
173
  refresh: latestAuth.refresh,
154
174
  expires: latestAuth.expires,
155
- email: typeof latestDecoded?.email === "string"
156
- ? latestDecoded.email
157
- : undefined,
158
175
  });
159
176
  }
160
177
  }
161
- // Step 1: Extract and rewrite URL for Codex backend
178
+ // Step 1: Extract and rewrite URL for Codex backend (#7)
162
179
  const originalUrl = extractRequestUrl(input);
163
180
  const url = rewriteUrlForCodex(originalUrl);
164
- // Step 2: Transform request body with model-specific Codex instructions
165
- // Instructions are fetched per model family (codex-max, codex, gpt-5.1)
166
- // Capture original stream value before transformation
167
- // generateText() sends no stream field, streamText() sends stream=true
181
+ // Step 2: Transform request body
168
182
  let originalBody = {};
169
183
  if (typeof init?.body === "string") {
170
184
  try {
@@ -177,29 +191,32 @@ export const OpenAIAuthPlugin = async ({ client }) => {
177
191
  const isStreaming = originalBody.stream === true;
178
192
  const transformation = await transformRequestForCodex(init, url, userConfig, codexMode);
179
193
  const requestInit = transformation?.updatedInit ?? init;
194
+ // Step 3: Retry loop — one attempt per account
180
195
  const attempts = Math.max(accountPool.count(), 1);
181
196
  let lastRateLimitResponse = null;
182
197
  for (let i = 0; i < attempts; i++) {
183
198
  const selected = accountPool.next(accountSelectionStrategy);
184
- if (!selected) {
199
+ if (!selected)
185
200
  break;
186
- }
201
+ // Per-account token refresh when expired
202
+ // (Background queue handles this proactively; this is the safety net)
187
203
  if (selected.expires < Date.now()) {
188
204
  const selectedRefreshBefore = selected.refresh;
189
- const refreshed = await refreshAccessToken(selected.refresh);
205
+ const refreshed = await refreshAccessTokenShared(selected.accountId, selected.refresh);
190
206
  if (refreshed.type === "failed") {
191
- // Auth failure (revoked/invalid token) is NOT a rate limit.
192
- // Calling markRateLimited here would retry the same dead
193
- // token after cooldown, looping forever. Skip this account
194
- // for the current request without penalizing it.
207
+ // Auth failure (revoked/invalid token) track it (#9)
195
208
  logWarn("Token refresh failed for account, skipping", selected.accountId);
209
+ accountPool.markAuthFailure(selected.accountId);
196
210
  savePool();
197
211
  continue;
198
212
  }
213
+ // Clear failure counter on successful refresh
214
+ accountPool.clearAuthFailures(selected.accountId);
199
215
  accountPool.replaceAuth(selected.accountId, refreshed.access, refreshed.refresh, refreshed.expires);
216
+ // Keep opencode's stored auth in sync for the primary account
200
217
  if (latestAuth.type === "oauth" &&
201
218
  (latestAuth.refresh === selectedRefreshBefore ||
202
- latestAccountIdFromAuth === selected.accountId)) {
219
+ accountId === selected.accountId)) {
203
220
  try {
204
221
  await client.auth.set({
205
222
  path: { id: "openai" },
@@ -216,11 +233,13 @@ export const OpenAIAuthPlugin = async ({ client }) => {
216
233
  }
217
234
  }
218
235
  }
236
+ // Step 4: Build headers
219
237
  const headers = createCodexHeaders(requestInit, selected.accountId, selected.access, {
220
238
  model: transformation?.body.model,
221
239
  promptCacheKey: transformation?.body
222
240
  ?.prompt_cache_key,
223
241
  });
242
+ // Step 5: Execute request
224
243
  const response = await fetch(url, {
225
244
  ...requestInit,
226
245
  headers,
@@ -234,10 +253,13 @@ export const OpenAIAuthPlugin = async ({ client }) => {
234
253
  attempt: i + 1,
235
254
  totalAttempts: attempts,
236
255
  });
256
+ // Step 6: Handle response
237
257
  if (!response.ok) {
238
258
  const mapped = await handleErrorResponse(response);
239
259
  if (mapped.status === 429) {
240
- accountPool.markRateLimited(selected.accountId, mapped.headers, rateLimitCooldownMs);
260
+ // Parse error code for tiered cooldown (#10)
261
+ const errorCode = await parseErrorCode(mapped);
262
+ accountPool.markRateLimited(selected.accountId, mapped.headers, rateLimitCooldownMs, errorCode);
241
263
  savePool();
242
264
  lastRateLimitResponse = mapped;
243
265
  continue;
@@ -245,54 +267,89 @@ export const OpenAIAuthPlugin = async ({ client }) => {
245
267
  savePool();
246
268
  return mapped;
247
269
  }
270
+ // Success — clear any failure state
271
+ accountPool.clearAuthFailures(selected.accountId);
248
272
  savePool();
249
273
  return await handleSuccessResponse(response, isStreaming);
250
274
  }
275
+ // All accounts exhausted — wait for recovery if feasible (#11)
276
+ const minWaitMs = accountPool.getMinRetryAfterMs();
277
+ if (minWaitMs !== null && minWaitMs <= MAX_RECOVERY_WAIT_MS) {
278
+ logDebug(`All accounts rate-limited. Waiting ${Math.ceil(minWaitMs / 1000)}s for recovery...`);
279
+ await new Promise((r) => setTimeout(r, minWaitMs));
280
+ // One recovery attempt with the now-unblocked account
281
+ const recovered = accountPool.next(accountSelectionStrategy);
282
+ if (recovered) {
283
+ const recHeaders = createCodexHeaders(requestInit, recovered.accountId, recovered.access, {
284
+ model: transformation?.body.model,
285
+ promptCacheKey: transformation?.body
286
+ ?.prompt_cache_key,
287
+ });
288
+ const recResponse = await fetch(url, { ...requestInit, headers: recHeaders });
289
+ if (recResponse.ok) {
290
+ accountPool.clearAuthFailures(recovered.accountId);
291
+ savePool();
292
+ return await handleSuccessResponse(recResponse, isStreaming);
293
+ }
294
+ const recMapped = await handleErrorResponse(recResponse);
295
+ if (recMapped.status === 429) {
296
+ const errorCode = await parseErrorCode(recMapped);
297
+ accountPool.markRateLimited(recovered.accountId, recMapped.headers, rateLimitCooldownMs, errorCode);
298
+ lastRateLimitResponse = recMapped;
299
+ }
300
+ else {
301
+ savePool();
302
+ return recMapped;
303
+ }
304
+ }
305
+ }
251
306
  savePool();
252
307
  if (lastRateLimitResponse) {
253
308
  return lastRateLimitResponse;
254
309
  }
255
- const retryAfterMs = accountPool.getMinRetryAfterMs();
256
- const retryAfterSeconds = retryAfterMs ? Math.max(1, Math.ceil(retryAfterMs / 1000)) : null;
257
- return new Response(JSON.stringify({
258
- error: {
259
- code: "usage_limit_reached",
260
- message: "All ChatGPT accounts are temporarily rate-limited",
261
- },
262
- }), {
263
- status: 429,
264
- headers: {
265
- "content-type": "application/json",
266
- ...(retryAfterSeconds
267
- ? { "retry-after": String(retryAfterSeconds) }
268
- : {}),
269
- },
270
- });
310
+ return buildAllRateLimitedResponse(accountPool.getMinRetryAfterMs());
271
311
  },
272
312
  };
273
313
  },
274
314
  methods: [
315
+ // ── Account management (view / remove existing accounts) ───────────────
316
+ {
317
+ label: AUTH_LABELS.MANAGE_ACCOUNTS,
318
+ type: "oauth",
319
+ authorize: async () => {
320
+ const result = await showAccountManager();
321
+ // If user wants to add or refresh a token, tell them to pick
322
+ // an actual auth method from the list instead
323
+ if (result.action === "add" || result.action === "refresh-token") {
324
+ return {
325
+ url: "",
326
+ method: "code",
327
+ instructions: "Select one of the auth methods above (browser, manual, or headless) to add a new account.",
328
+ callback: async () => ({ type: "failed" }),
329
+ };
330
+ }
331
+ // User is done managing — nothing to store
332
+ return {
333
+ url: "",
334
+ method: "code",
335
+ instructions: "Done. No new account was added. Restart opencode.",
336
+ callback: async () => ({ type: "failed" }),
337
+ };
338
+ },
339
+ },
340
+ // ── Browser PKCE flow ──────────────────────────────────────────────────
275
341
  {
276
342
  label: AUTH_LABELS.OAUTH,
277
343
  type: "oauth",
278
- /**
279
- * OAuth authorization flow
280
- *
281
- * Steps:
282
- * 1. Generate PKCE challenge and state for security
283
- * 2. Start local OAuth callback server on port 1455
284
- * 3. Open browser to OpenAI authorization page
285
- * 4. Wait for user to complete login
286
- * 5. Exchange authorization code for tokens
287
- *
288
- * @returns Authorization flow configuration
289
- */
290
344
  authorize: async () => {
291
345
  const { pkce, state, url } = await createAuthorizationFlow();
292
346
  const serverInfo = await startLocalOAuthServer({ state });
293
- // Attempt to open browser automatically
294
- openBrowserUrl(url);
295
- if (!serverInfo.ready) {
347
+ const browserOpened = openBrowserUrl(url);
348
+ // Fall back immediately to manual paste when:
349
+ // - local callback server could not bind (port conflict)
350
+ // - browser could not be launched (headless / no DISPLAY)
351
+ // This avoids a 60-second timeout before showing the user the URL.
352
+ if (!serverInfo.ready || !browserOpened) {
296
353
  serverInfo.close();
297
354
  return buildManualOAuthFlow(pkce, url);
298
355
  }
@@ -303,17 +360,25 @@ export const OpenAIAuthPlugin = async ({ client }) => {
303
360
  callback: async () => {
304
361
  const result = await serverInfo.waitForCode(state);
305
362
  serverInfo.close();
306
- if (!result) {
363
+ if (!result)
307
364
  return { type: "failed" };
308
- }
309
365
  const tokens = await exchangeAuthorizationCode(result.code, pkce.verifier, REDIRECT_URI);
310
- return tokens?.type === "success"
311
- ? tokens
312
- : { type: "failed" };
366
+ if (tokens?.type !== "success")
367
+ return { type: "failed" };
368
+ // Return accountId so opencode stores it in auth — avoids JWT
369
+ // decode on every request (#5)
370
+ return {
371
+ ...tokens,
372
+ accountId: extractAccountId({
373
+ access_token: tokens.access,
374
+ id_token: tokens.id_token,
375
+ }),
376
+ };
313
377
  },
314
378
  };
315
379
  },
316
380
  },
381
+ // ── Manual URL paste ───────────────────────────────────────────────────
317
382
  {
318
383
  label: AUTH_LABELS.OAUTH_MANUAL,
319
384
  type: "oauth",
@@ -322,12 +387,53 @@ export const OpenAIAuthPlugin = async ({ client }) => {
322
387
  return buildManualOAuthFlow(pkce, url);
323
388
  },
324
389
  },
390
+ // ── Headless / device-code flow (#1) ──────────────────────────────────
391
+ {
392
+ label: AUTH_LABELS.OAUTH_DEVICE,
393
+ type: "oauth",
394
+ authorize: async () => {
395
+ const deviceFlow = await createDeviceAuthorizationFlow();
396
+ return {
397
+ url: deviceFlow.activateUrl,
398
+ method: "auto",
399
+ instructions: `${AUTH_LABELS.INSTRUCTIONS_DEVICE}\n\nCode: ${deviceFlow.userCode}\nURL: ${deviceFlow.activateUrl}`,
400
+ callback: async () => {
401
+ const tokens = await deviceFlow.poll();
402
+ if (tokens?.type !== "success")
403
+ return { type: "failed" };
404
+ return {
405
+ ...tokens,
406
+ accountId: extractAccountId({
407
+ access_token: tokens.access,
408
+ id_token: tokens.id_token,
409
+ }),
410
+ };
411
+ },
412
+ };
413
+ },
414
+ },
415
+ // ── API Key ────────────────────────────────────────────────────────────
325
416
  {
326
417
  label: AUTH_LABELS.API_KEY,
327
418
  type: "api",
328
419
  },
329
420
  ],
330
421
  },
422
+ /**
423
+ * chat.headers hook — injected before every LLM request (#2, #4, #6).
424
+ * Sets originator, User-Agent, and session_id using the platform session ID.
425
+ */
426
+ "chat.headers": async (hookInput, output) => {
427
+ if (hookInput.model.providerID !== PROVIDER_ID)
428
+ return;
429
+ // #2: correct originator (not codex_cli_rs)
430
+ output.headers["originator"] = "opencode";
431
+ // #4: use the platform session ID (not a static random UUID)
432
+ output.headers["session_id"] = hookInput.sessionID;
433
+ // #6: proper User-Agent with version + OS info
434
+ output.headers["User-Agent"] =
435
+ `better-opencode-openai-codex-auth/${PLUGIN_VERSION} (${os.platform()} ${os.release()}; ${os.arch()})`;
436
+ },
331
437
  };
332
438
  };
333
439
  export default OpenAIAuthPlugin;
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAEH,OAAO,EAAE,MAAM,SAAS,CAAC;AAGzB,OAAO,EACN,uBAAuB,EACvB,6BAA6B,EAC7B,gBAAgB,EAChB,yBAAyB,EACzB,yBAAyB,EACzB,uBAAuB,EACvB,wBAAwB,EACxB,YAAY,GACZ,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,EAAE,qBAAqB,EAAE,MAAM,sBAAsB,CAAC;AAC7D,OAAO,EAAE,kBAAkB,EAAE,MAAM,+BAA+B,CAAC;AACnE,OAAO,EAAE,YAAY,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AACjE,OAAO,EACN,WAAW,EACX,cAAc,EACd,aAAa,EACb,cAAc,EACd,UAAU,EACV,oBAAoB,EACpB,WAAW,EACX,cAAc,EACd,WAAW,GACX,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAE,UAAU,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAC;AAChE,OAAO,EACN,kBAAkB,EAClB,iBAAiB,EACjB,mBAAmB,EACnB,qBAAqB,EACrB,kBAAkB,EAClB,wBAAwB,GACxB,MAAM,gCAAgC,CAAC;AAExC,OAAO,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AACpD,OAAO,EAAE,qBAAqB,EAAE,MAAM,wBAAwB,CAAC;AAE/D;;;GAGG;AACH,KAAK,UAAU,cAAc,CAAC,QAAkB;IAC/C,IAAI,CAAC;QACJ,MAAM,KAAK,GAAG,QAAQ,CAAC,KAAK,EAAE,CAAC;QAC/B,MAAM,IAAI,GAAG,MAAM,KAAK,CAAC,IAAI,EAAE,CAAC;QAChC,IAAI,CAAC,IAAI;YAAE,OAAO,SAAS,CAAC;QAC5B,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAiD,CAAC;QAChF,OAAO,CAAC,MAAM,EAAE,KAAK,EAAE,IAAI,IAAI,MAAM,EAAE,KAAK,EAAE,IAAI,CAAC,IAAI,SAAS,CAAC;IAClE,CAAC;IAAC,MAAM,CAAC;QACR,OAAO,SAAS,CAAC;IAClB,CAAC;AACF,CAAC;AAED;;;GAGG;AACH,SAAS,2BAA2B,CAAC,YAA2B;IAC/D,MAAM,iBAAiB,GAAG,YAAY,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;IAC5F,OAAO,IAAI,QAAQ,CAClB,IAAI,CAAC,SAAS,CAAC;QACd,KAAK,EAAE;YACN,IAAI,EAAE,qBAAqB;YAC3B,OAAO,EAAE,mDAAmD;SAC5D;KACD,CAAC,EACF;QACC,MAAM,EAAE,GAAG;QACX,OAAO,EAAE;YACR,cAAc,EAAE,kBAAkB;YAClC,GAAG,CAAC,iBAAiB;gBACpB,CAAC,CAAC,EAAE,aAAa,EAAE,MAAM,CAAC,iBAAiB,CAAC,EAAE;gBAC9C,CAAC,CAAC,EAAE,CAAC;SACN;KACD,CACD,CAAC;AACH,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,MAAM,gBAAgB,GAAW,KAAK,EAAE,EAAE,MAAM,EAAe,EAAE,EAAE;IACzE,MAAM,oBAAoB,GAAG,CAAC,IAA0B,EAAE,GAAW,EAAE,EAAE,CAAC,CAAC;QAC1E,GAAG;QACH,MAAM,EAAE,MAAe;QACvB,YAAY,EAAE,WAAW,CAAC,mBAAmB;QAC7C,QAAQ,EAAE,KAAK,EAAE,KAAa,EAAE,EAAE;YACjC,MAAM,MAAM,GAAG,uBAAuB,CAAC,KAAK,CAAC,CAAC;YAC9C,IAAI,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC;gBAClB,OAAO,EAAE,IAAI,EAAE,QAAiB,EAAE,CAAC;YACpC,CAAC;YACD,MAAM,MAAM,GAAG,MAAM,yBAAyB,CAC7C,MAAM,CAAC,IAAI,EACX,IAAI,CAAC,QAAQ,EACb,YAAY,CACZ,CAAC;YACF,IAAI,MAAM,EAAE,IAAI,KAAK,SAAS;gBAAE,OAAO,EAAE,IAAI,EAAE,QAAiB,EAAE,CAAC;YACnE,OAAO;gBACN,GAAG,MAAM;gBACT,SAAS,EAAE,gBAAgB,CAAC;oBAC3B,YAAY,EAAE,MAAM,CAAC,MAAM;oBAC3B,QAAQ,EAAE,MAAM,CAAC,QAAQ;iBACzB,CAAC;aACF,CAAC;QACH,CAAC;KACD,CAAC,CAAC;IAEH,OAAO;QACN,IAAI,EAAE;YACL,QAAQ,EAAE,WAAW;YAErB;;;eAGG;YACH,KAAK,CAAC,MAAM,CAAC,OAA4B,EAAE,QAAiB;gBAC3D,MAAM,IAAI,GAAG,MAAM,OAAO,EAAE,CAAC;gBAE7B,8BAA8B;gBAC9B,IAAI,IAAI,CAAC,IAAI,KAAK,OAAO,EAAE,CAAC;oBAC3B,OAAO,EAAE,CAAC;gBACX,CAAC;gBAED,4EAA4E;gBAC5E,sEAAsE;gBACtE,MAAM,eAAe,GAAG,IAA+D,CAAC;gBACxF,IAAI,SAAS,GACZ,eAAe,CAAC,SAAS;oBACzB,CAAC,eAAe,CAAC,QAAQ,CAAC,CAAC,CAAC,yBAAyB,CAAC,eAAe,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;oBAC5F,yBAAyB,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;gBAExC,IAAI,CAAC,SAAS,EAAE,CAAC;oBAChB,QAAQ,CACP,IAAI,WAAW,KAAK,cAAc,CAAC,aAAa,oBAAoB,CACpE,CAAC;oBACF,OAAO,EAAE,CAAC;gBACX,CAAC;gBAED,0DAA0D;gBAC1D,MAAM,cAAc,GAAG,QAEX,CAAC;gBACb,MAAM,UAAU,GAAe;oBAC9B,MAAM,EAAE,cAAc,EAAE,OAAO,IAAI,EAAE;oBACrC,MAAM,EAAE,cAAc,EAAE,MAAM,IAAI,EAAE;iBACpC,CAAC;gBAEF,4BAA4B;gBAC5B,MAAM,YAAY,GAAG,gBAAgB,EAAE,CAAC;gBACxC,MAAM,SAAS,GAAG,YAAY,CAAC,YAAY,CAAC,CAAC;gBAC7C,MAAM,wBAAwB,GAC7B,YAAY,CAAC,wBAAwB,KAAK,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,aAAa,CAAC;gBAC/E,MAAM,mBAAmB,GAAG,YAAY,CAAC,mBAAmB,CAAC;gBAE7D,MAAM,WAAW,GAAG,WAAW,CAAC,IAAI,EAAE,CAAC;gBACvC,MAAM,QAAQ,GAAG,GAAG,EAAE;oBACrB,IAAI,CAAC;wBACJ,WAAW,CAAC,IAAI,EAAE,CAAC;oBACpB,CAAC;oBAAC,OAAO,KAAK,EAAE,CAAC;wBAChB,OAAO,CAAC,gCAAgC,EAAE,KAAK,CAAC,CAAC;oBAClD,CAAC;gBACF,CAAC,CAAC;gBAEF,8BAA8B;gBAC9B,WAAW,CAAC,MAAM,CAAC;oBAClB,SAAS;oBACT,MAAM,EAAE,IAAI,CAAC,MAAM;oBACnB,OAAO,EAAE,IAAI,CAAC,OAAO;oBACrB,OAAO,EAAE,IAAI,CAAC,OAAO;oBACrB,KAAK,EACJ,OAAQ,IAAgC,CAAC,KAAK,KAAK,QAAQ;wBAC1D,CAAC,CAAE,IAAgC,CAAC,KAAe;wBACnD,CAAC,CAAC,SAAS;iBACb,CAAC,CAAC;gBACH,QAAQ,EAAE,CAAC;gBAEX,gDAAgD;gBAChD,MAAM,YAAY,GAAG,IAAI,qBAAqB,CAAC,WAAW,CAAC,CAAC;gBAC5D,YAAY,CAAC,KAAK,EAAE,CAAC;gBAErB,OAAO;oBACN,MAAM,EAAE,aAAa;oBACrB,OAAO,EAAE,cAAc;oBAEvB,KAAK,CAAC,KAAK,CACV,KAA6B,EAC7B,IAAkB;wBAElB,MAAM,UAAU,GAAG,MAAM,OAAO,EAAE,CAAC;wBACnC,MAAM,iBAAiB,GAAG,UAGzB,CAAC;wBAEF,IAAI,UAAU,CAAC,IAAI,KAAK,OAAO,EAAE,CAAC;4BACjC,qDAAqD;4BACrD,MAAM,eAAe,GACpB,iBAAiB,CAAC,SAAS;gCAC3B,CAAC,iBAAiB,CAAC,QAAQ;oCAC1B,CAAC,CAAC,yBAAyB,CAAC,iBAAiB,CAAC,QAAQ,CAAC;oCACvD,CAAC,CAAC,SAAS,CAAC;gCACb,yBAAyB,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC;4BAE9C,IAAI,eAAe,EAAE,CAAC;gCACrB,SAAS,GAAG,eAAe,CAAC;gCAC5B,WAAW,CAAC,MAAM,CAAC;oCAClB,SAAS,EAAE,eAAe;oCAC1B,MAAM,EAAE,UAAU,CAAC,MAAM;oCACzB,OAAO,EAAE,UAAU,CAAC,OAAO;oCAC3B,OAAO,EAAE,UAAU,CAAC,OAAO;iCAC3B,CAAC,CAAC;4BACJ,CAAC;wBACF,CAAC;wBAED,yDAAyD;wBACzD,MAAM,WAAW,GAAG,iBAAiB,CAAC,KAAK,CAAC,CAAC;wBAC7C,MAAM,GAAG,GAAG,kBAAkB,CAAC,WAAW,CAAC,CAAC;wBAE5C,iCAAiC;wBACjC,IAAI,YAAY,GAAyB,EAAE,CAAC;wBAC5C,IAAI,OAAO,IAAI,EAAE,IAAI,KAAK,QAAQ,EAAE,CAAC;4BACpC,IAAI,CAAC;gCACJ,YAAY,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAyB,CAAC;4BAC9D,CAAC;4BAAC,MAAM,CAAC;gCACR,YAAY,GAAG,EAAE,CAAC;4BACnB,CAAC;wBACF,CAAC;wBACD,MAAM,WAAW,GAAG,YAAY,CAAC,MAAM,KAAK,IAAI,CAAC;wBAEjD,MAAM,cAAc,GAAG,MAAM,wBAAwB,CACpD,IAAI,EACJ,GAAG,EACH,UAAU,EACV,SAAS,CACT,CAAC;wBACF,MAAM,WAAW,GAAG,cAAc,EAAE,WAAW,IAAI,IAAI,CAAC;wBAExD,+CAA+C;wBAC/C,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,CAAC,WAAW,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,CAAC;wBAClD,IAAI,qBAAqB,GAAoB,IAAI,CAAC;wBAElD,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,QAAQ,EAAE,CAAC,EAAE,EAAE,CAAC;4BACnC,MAAM,QAAQ,GAAG,WAAW,CAAC,IAAI,CAAC,wBAAwB,CAAC,CAAC;4BAC5D,IAAI,CAAC,QAAQ;gCAAE,MAAM;4BAErB,yCAAyC;4BACzC,sEAAsE;4BACtE,IAAI,QAAQ,CAAC,OAAO,GAAG,IAAI,CAAC,GAAG,EAAE,EAAE,CAAC;gCACnC,MAAM,qBAAqB,GAAG,QAAQ,CAAC,OAAO,CAAC;gCAC/C,MAAM,SAAS,GAAG,MAAM,wBAAwB,CAC/C,QAAQ,CAAC,SAAS,EAClB,QAAQ,CAAC,OAAO,CAChB,CAAC;gCAEF,IAAI,SAAS,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;oCACjC,uDAAuD;oCACvD,OAAO,CAAC,4CAA4C,EAAE,QAAQ,CAAC,SAAS,CAAC,CAAC;oCAC1E,WAAW,CAAC,eAAe,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC;oCAChD,QAAQ,EAAE,CAAC;oCACX,SAAS;gCACV,CAAC;gCAED,8CAA8C;gCAC9C,WAAW,CAAC,iBAAiB,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC;gCAClD,WAAW,CAAC,WAAW,CACtB,QAAQ,CAAC,SAAS,EAClB,SAAS,CAAC,MAAM,EAChB,SAAS,CAAC,OAAO,EACjB,SAAS,CAAC,OAAO,CACjB,CAAC;gCAEF,8DAA8D;gCAC9D,IACC,UAAU,CAAC,IAAI,KAAK,OAAO;oCAC3B,CAAC,UAAU,CAAC,OAAO,KAAK,qBAAqB;wCAC5C,SAAS,KAAK,QAAQ,CAAC,SAAS,CAAC,EACjC,CAAC;oCACF,IAAI,CAAC;wCACJ,MAAM,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC;4CACrB,IAAI,EAAE,EAAE,EAAE,EAAE,QAAQ,EAAE;4CACtB,IAAI,EAAE;gDACL,IAAI,EAAE,OAAO;gDACb,MAAM,EAAE,SAAS,CAAC,MAAM;gDACxB,OAAO,EAAE,SAAS,CAAC,OAAO;gDAC1B,OAAO,EAAE,SAAS,CAAC,OAAO;6CAC1B;yCACD,CAAC,CAAC;oCACJ,CAAC;oCAAC,OAAO,KAAK,EAAE,CAAC;wCAChB,OAAO,CAAC,kCAAkC,EAAE,KAAK,CAAC,CAAC;oCACpD,CAAC;gCACF,CAAC;4BACF,CAAC;4BAED,wBAAwB;4BACxB,MAAM,OAAO,GAAG,kBAAkB,CACjC,WAAW,EACX,QAAQ,CAAC,SAAS,EAClB,QAAQ,CAAC,MAAM,EACf;gCACC,KAAK,EAAE,cAAc,EAAE,IAAI,CAAC,KAAK;gCACjC,cAAc,EAAG,cAAc,EAAE,IAAgC;oCAChE,EAAE,gBAAgB;6BACnB,CACD,CAAC;4BAEF,0BAA0B;4BAC1B,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,EAAE;gCACjC,GAAG,WAAW;gCACd,OAAO;6BACP,CAAC,CAAC;4BAEH,UAAU,CAAC,UAAU,CAAC,QAAQ,EAAE;gCAC/B,MAAM,EAAE,QAAQ,CAAC,MAAM;gCACvB,EAAE,EAAE,QAAQ,CAAC,EAAE;gCACf,UAAU,EAAE,QAAQ,CAAC,UAAU;gCAC/B,OAAO,EAAE,MAAM,CAAC,WAAW,CAAC,QAAQ,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC;gCACvD,SAAS,EAAE,QAAQ,CAAC,SAAS;gCAC7B,OAAO,EAAE,CAAC,GAAG,CAAC;gCACd,aAAa,EAAE,QAAQ;6BACvB,CAAC,CAAC;4BAEH,0BAA0B;4BAC1B,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;gCAClB,MAAM,MAAM,GAAG,MAAM,mBAAmB,CAAC,QAAQ,CAAC,CAAC;gCAEnD,IAAI,MAAM,CAAC,MAAM,KAAK,GAAG,EAAE,CAAC;oCAC3B,6CAA6C;oCAC7C,MAAM,SAAS,GAAG,MAAM,cAAc,CAAC,MAAM,CAAC,CAAC;oCAC/C,WAAW,CAAC,eAAe,CAC1B,QAAQ,CAAC,SAAS,EAClB,MAAM,CAAC,OAAO,EACd,mBAAmB,EACnB,SAAS,CACT,CAAC;oCACF,QAAQ,EAAE,CAAC;oCACX,qBAAqB,GAAG,MAAM,CAAC;oCAC/B,SAAS;gCACV,CAAC;gCAED,QAAQ,EAAE,CAAC;gCACX,OAAO,MAAM,CAAC;4BACf,CAAC;4BAED,oCAAoC;4BACpC,WAAW,CAAC,iBAAiB,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC;4BAClD,QAAQ,EAAE,CAAC;4BACX,OAAO,MAAM,qBAAqB,CAAC,QAAQ,EAAE,WAAW,CAAC,CAAC;wBAC3D,CAAC;wBAED,+DAA+D;wBAC/D,MAAM,SAAS,GAAG,WAAW,CAAC,kBAAkB,EAAE,CAAC;wBACnD,IAAI,SAAS,KAAK,IAAI,IAAI,SAAS,IAAI,oBAAoB,EAAE,CAAC;4BAC7D,QAAQ,CACP,sCAAsC,IAAI,CAAC,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC,mBAAmB,CACpF,CAAC;4BACF,MAAM,IAAI,OAAO,CAAO,CAAC,CAAC,EAAE,EAAE,CAAC,UAAU,CAAC,CAAC,EAAE,SAAS,CAAC,CAAC,CAAC;4BAEzD,sDAAsD;4BACtD,MAAM,SAAS,GAAG,WAAW,CAAC,IAAI,CAAC,wBAAwB,CAAC,CAAC;4BAC7D,IAAI,SAAS,EAAE,CAAC;gCACf,MAAM,UAAU,GAAG,kBAAkB,CACpC,WAAW,EACX,SAAS,CAAC,SAAS,EACnB,SAAS,CAAC,MAAM,EAChB;oCACC,KAAK,EAAE,cAAc,EAAE,IAAI,CAAC,KAAK;oCACjC,cAAc,EAAG,cAAc,EAAE,IAAgC;wCAChE,EAAE,gBAAgB;iCACnB,CACD,CAAC;gCACF,MAAM,WAAW,GAAG,MAAM,KAAK,CAAC,GAAG,EAAE,EAAE,GAAG,WAAW,EAAE,OAAO,EAAE,UAAU,EAAE,CAAC,CAAC;gCAC9E,IAAI,WAAW,CAAC,EAAE,EAAE,CAAC;oCACpB,WAAW,CAAC,iBAAiB,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC;oCACnD,QAAQ,EAAE,CAAC;oCACX,OAAO,MAAM,qBAAqB,CAAC,WAAW,EAAE,WAAW,CAAC,CAAC;gCAC9D,CAAC;gCACD,MAAM,SAAS,GAAG,MAAM,mBAAmB,CAAC,WAAW,CAAC,CAAC;gCACzD,IAAI,SAAS,CAAC,MAAM,KAAK,GAAG,EAAE,CAAC;oCAC9B,MAAM,SAAS,GAAG,MAAM,cAAc,CAAC,SAAS,CAAC,CAAC;oCAClD,WAAW,CAAC,eAAe,CAC1B,SAAS,CAAC,SAAS,EACnB,SAAS,CAAC,OAAO,EACjB,mBAAmB,EACnB,SAAS,CACT,CAAC;oCACF,qBAAqB,GAAG,SAAS,CAAC;gCACnC,CAAC;qCAAM,CAAC;oCACP,QAAQ,EAAE,CAAC;oCACX,OAAO,SAAS,CAAC;gCAClB,CAAC;4BACF,CAAC;wBACF,CAAC;wBAED,QAAQ,EAAE,CAAC;wBACX,IAAI,qBAAqB,EAAE,CAAC;4BAC3B,OAAO,qBAAqB,CAAC;wBAC9B,CAAC;wBACD,OAAO,2BAA2B,CAAC,WAAW,CAAC,kBAAkB,EAAE,CAAC,CAAC;oBACtE,CAAC;iBACD,CAAC;YACH,CAAC;YAED,OAAO,EAAE;gBACR,0EAA0E;gBAC1E;oBACC,KAAK,EAAE,WAAW,CAAC,eAAe;oBAClC,IAAI,EAAE,OAAgB;oBACtB,SAAS,EAAE,KAAK,IAAI,EAAE;wBACrB,MAAM,MAAM,GAAG,MAAM,kBAAkB,EAAE,CAAC;wBAE1C,6DAA6D;wBAC7D,8CAA8C;wBAC9C,IAAI,MAAM,CAAC,MAAM,KAAK,KAAK,IAAI,MAAM,CAAC,MAAM,KAAK,eAAe,EAAE,CAAC;4BAClE,OAAO;gCACN,GAAG,EAAE,EAAE;gCACP,MAAM,EAAE,MAAe;gCACvB,YAAY,EACX,2FAA2F;gCAC5F,QAAQ,EAAE,KAAK,IAAI,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,QAAiB,EAAE,CAAC;6BACnD,CAAC;wBACH,CAAC;wBAED,2CAA2C;wBAC3C,OAAO;4BACN,GAAG,EAAE,EAAE;4BACP,MAAM,EAAE,MAAe;4BACvB,YAAY,EAAE,mDAAmD;4BACjE,QAAQ,EAAE,KAAK,IAAI,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,QAAiB,EAAE,CAAC;yBACnD,CAAC;oBACH,CAAC;iBACD;gBAED,0EAA0E;gBAC1E;oBACC,KAAK,EAAE,WAAW,CAAC,KAAK;oBACxB,IAAI,EAAE,OAAgB;oBACtB,SAAS,EAAE,KAAK,IAAI,EAAE;wBACrB,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,EAAE,GAAG,MAAM,uBAAuB,EAAE,CAAC;wBAC7D,MAAM,UAAU,GAAG,MAAM,qBAAqB,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC;wBAE1D,MAAM,aAAa,GAAG,cAAc,CAAC,GAAG,CAAC,CAAC;wBAE1C,8CAA8C;wBAC9C,2DAA2D;wBAC3D,4DAA4D;wBAC5D,mEAAmE;wBACnE,IAAI,CAAC,UAAU,CAAC,KAAK,IAAI,CAAC,aAAa,EAAE,CAAC;4BACzC,UAAU,CAAC,KAAK,EAAE,CAAC;4BACnB,OAAO,oBAAoB,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;wBACxC,CAAC;wBAED,OAAO;4BACN,GAAG;4BACH,MAAM,EAAE,MAAe;4BACvB,YAAY,EAAE,WAAW,CAAC,YAAY;4BACtC,QAAQ,EAAE,KAAK,IAAI,EAAE;gCACpB,MAAM,MAAM,GAAG,MAAM,UAAU,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC;gCACnD,UAAU,CAAC,KAAK,EAAE,CAAC;gCAEnB,IAAI,CAAC,MAAM;oCAAE,OAAO,EAAE,IAAI,EAAE,QAAiB,EAAE,CAAC;gCAEhD,MAAM,MAAM,GAAG,MAAM,yBAAyB,CAC7C,MAAM,CAAC,IAAI,EACX,IAAI,CAAC,QAAQ,EACb,YAAY,CACZ,CAAC;gCACF,IAAI,MAAM,EAAE,IAAI,KAAK,SAAS;oCAAE,OAAO,EAAE,IAAI,EAAE,QAAiB,EAAE,CAAC;gCAEnE,8DAA8D;gCAC9D,+BAA+B;gCAC/B,OAAO;oCACN,GAAG,MAAM;oCACT,SAAS,EAAE,gBAAgB,CAAC;wCAC3B,YAAY,EAAE,MAAM,CAAC,MAAM;wCAC3B,QAAQ,EAAE,MAAM,CAAC,QAAQ;qCACzB,CAAC;iCACF,CAAC;4BACH,CAAC;yBACD,CAAC;oBACH,CAAC;iBACD;gBAED,0EAA0E;gBAC1E;oBACC,KAAK,EAAE,WAAW,CAAC,YAAY;oBAC/B,IAAI,EAAE,OAAgB;oBACtB,SAAS,EAAE,KAAK,IAAI,EAAE;wBACrB,MAAM,EAAE,IAAI,EAAE,GAAG,EAAE,GAAG,MAAM,uBAAuB,EAAE,CAAC;wBACtD,OAAO,oBAAoB,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;oBACxC,CAAC;iBACD;gBAED,yEAAyE;gBACzE;oBACC,KAAK,EAAE,WAAW,CAAC,YAAY;oBAC/B,IAAI,EAAE,OAAgB;oBACtB,SAAS,EAAE,KAAK,IAAI,EAAE;wBACrB,MAAM,UAAU,GAAG,MAAM,6BAA6B,EAAE,CAAC;wBAEzD,OAAO;4BACN,GAAG,EAAE,UAAU,CAAC,WAAW;4BAC3B,MAAM,EAAE,MAAe;4BACvB,YAAY,EAAE,GAAG,WAAW,CAAC,mBAAmB,aAAa,UAAU,CAAC,QAAQ,WAAW,UAAU,CAAC,WAAW,EAAE;4BACnH,QAAQ,EAAE,KAAK,IAAI,EAAE;gCACpB,MAAM,MAAM,GAAG,MAAM,UAAU,CAAC,IAAI,EAAE,CAAC;gCACvC,IAAI,MAAM,EAAE,IAAI,KAAK,SAAS;oCAAE,OAAO,EAAE,IAAI,EAAE,QAAiB,EAAE,CAAC;gCACnE,OAAO;oCACN,GAAG,MAAM;oCACT,SAAS,EAAE,gBAAgB,CAAC;wCAC3B,YAAY,EAAE,MAAM,CAAC,MAAM;wCAC3B,QAAQ,EAAE,MAAM,CAAC,QAAQ;qCACzB,CAAC;iCACF,CAAC;4BACH,CAAC;yBACD,CAAC;oBACH,CAAC;iBACD;gBAED,0EAA0E;gBAC1E;oBACC,KAAK,EAAE,WAAW,CAAC,OAAO;oBAC1B,IAAI,EAAE,KAAc;iBACpB;aACD;SACD;QAED;;;WAGG;QACH,cAAc,EAAE,KAAK,EACpB,SAGC,EACD,MAA2C,EAC1C,EAAE;YACH,IAAI,SAAS,CAAC,KAAK,CAAC,UAAU,KAAK,WAAW;gBAAE,OAAO;YAEvD,4CAA4C;YAC5C,MAAM,CAAC,OAAO,CAAC,YAAY,CAAC,GAAG,UAAU,CAAC;YAE1C,6DAA6D;YAC7D,MAAM,CAAC,OAAO,CAAC,YAAY,CAAC,GAAG,SAAS,CAAC,SAAS,CAAC;YAEnD,+CAA+C;YAC/C,MAAM,CAAC,OAAO,CAAC,YAAY,CAAC;gBAC3B,qCAAqC,cAAc,KAAK,EAAE,CAAC,QAAQ,EAAE,IAAI,EAAE,CAAC,OAAO,EAAE,KAAK,EAAE,CAAC,IAAI,EAAE,GAAG,CAAC;QACzG,CAAC;KACD,CAAC;AACH,CAAC,CAAC;AAEF,eAAe,gBAAgB,CAAC"}
@@ -8,10 +8,36 @@ export declare class AccountPool {
8
8
  count(): number;
9
9
  getAvailableCount(): number;
10
10
  getMinRetryAfterMs(): number | null;
11
- markRateLimited(accountId: string, headers: Headers, cooldownMs?: number): void;
11
+ /**
12
+ * Mark an account as rate-limited.
13
+ * Applies tiered cooldown based on the ChatGPT error code (#10):
14
+ * - usage_limit_reached → 4 hours
15
+ * - usage_not_included → 24 hours
16
+ * - rate_limit_exceeded → 60 seconds
17
+ * - unknown / no code → retry-after header or configured default
18
+ */
19
+ markRateLimited(accountId: string, headers: Headers, cooldownMs?: number, errorCode?: string): void;
20
+ /**
21
+ * Record an auth/token-refresh failure for an account (#9).
22
+ *
23
+ * Increments consecutiveFailures with a 2-hour TTL reset. After
24
+ * MAX_FAILURES consecutive failures the account is placed in cooldown
25
+ * for COOLDOWN_MS — during which it is skipped by next().
26
+ */
27
+ markAuthFailure(accountId: string): void;
28
+ /**
29
+ * Clear the failure counter and cooldown for an account (called on success).
30
+ */
31
+ clearAuthFailures(accountId: string): void;
12
32
  next(strategy: "sticky" | "round-robin"): AccountPoolEntry | null;
13
33
  replaceAuth(accountId: string, access: string, refresh: string, expires: number): void;
14
- private isLimited;
15
- private clearExpiredLimits;
34
+ /** Returns all accounts (for use by ProactiveRefreshQueue) */
35
+ getAccounts(): AccountPoolEntry[];
36
+ /** True if account is rate-limited OR in auth-failure cooldown */
37
+ private isUnavailable;
38
+ private isRateLimited;
39
+ private isCoolingDown;
40
+ /** Clear expired rate-limit and cooldown timestamps */
41
+ private clearExpiredStates;
16
42
  }
17
43
  //# sourceMappingURL=account-pool.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"account-pool.d.ts","sourceRoot":"","sources":["../../lib/account-pool.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,gBAAgB,EAAsB,MAAM,YAAY,CAAC;AA8FvE,qBAAa,WAAW;IACvB,OAAO,CAAC,QAAQ,CAA0B;IAC1C,OAAO,CAAC,WAAW,CAAK;IAExB,MAAM,CAAC,IAAI,IAAI,WAAW;IAgB1B,IAAI,IAAI,IAAI;IAuBZ,MAAM,CAAC,KAAK,EAAE,gBAAgB,GAAG,IAAI;IA8BrC,KAAK,IAAI,MAAM;IAIf,iBAAiB,IAAI,MAAM;IAK3B,kBAAkB,IAAI,MAAM,GAAG,IAAI;IAanC,eAAe,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI;IAQ/E,IAAI,CAAC,QAAQ,EAAE,QAAQ,GAAG,aAAa,GAAG,gBAAgB,GAAG,IAAI;IAuBjE,WAAW,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,IAAI;IAQtF,OAAO,CAAC,SAAS;IAIjB,OAAO,CAAC,kBAAkB;CAQ1B"}
1
+ {"version":3,"file":"account-pool.d.ts","sourceRoot":"","sources":["../../lib/account-pool.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,gBAAgB,EAAsB,MAAM,YAAY,CAAC;AAqMvE,qBAAa,WAAW;IACvB,OAAO,CAAC,QAAQ,CAA0B;IAC1C,OAAO,CAAC,WAAW,CAAK;IAExB,MAAM,CAAC,IAAI,IAAI,WAAW;IAgB1B,IAAI,IAAI,IAAI;IAgDZ,MAAM,CAAC,KAAK,EAAE,gBAAgB,GAAG,IAAI;IAoBrC,KAAK,IAAI,MAAM;IAIf,iBAAiB,IAAI,MAAM;IAS3B,kBAAkB,IAAI,MAAM,GAAG,IAAI;IAqBnC;;;;;;;OAOG;IACH,eAAe,CACd,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,OAAO,EAChB,UAAU,CAAC,EAAE,MAAM,EACnB,SAAS,CAAC,EAAE,MAAM,GAChB,IAAI;IAOP;;;;;;OAMG;IACH,eAAe,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI;IAmBxC;;OAEG;IACH,iBAAiB,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI;IAQ1C,IAAI,CAAC,QAAQ,EAAE,QAAQ,GAAG,aAAa,GAAG,gBAAgB,GAAG,IAAI;IAuBjE,WAAW,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,IAAI;IAQtF,8DAA8D;IAC9D,WAAW,IAAI,gBAAgB,EAAE;IAIjC,kEAAkE;IAClE,OAAO,CAAC,aAAa;IAIrB,OAAO,CAAC,aAAa;IAIrB,OAAO,CAAC,aAAa;IAIrB,uDAAuD;IACvD,OAAO,CAAC,kBAAkB;CAW1B"}