opencode-puter-auth 1.0.39 → 1.0.41

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.
@@ -0,0 +1,431 @@
1
+ /**
2
+ * Account Rotation Manager for opencode-puter-auth
3
+ *
4
+ * Provides automatic account rotation when rate limits are encountered.
5
+ * When an account returns a rate limit error (429/403), the manager:
6
+ * 1. Adds the account to a cooldown list
7
+ * 2. Switches to the next available account
8
+ * 3. Returns to the original account after cooldown expires
9
+ *
10
+ * This enables longer uninterrupted usage by cycling through multiple
11
+ * Puter accounts when individual accounts hit rate limits.
12
+ *
13
+ * @example
14
+ * ```ts
15
+ * const rotation = new AccountRotationManager(authManager, {
16
+ * cooldownMs: 300000, // 5 minutes
17
+ * enabled: true,
18
+ * });
19
+ *
20
+ * // Get the next available account (respecting cooldowns)
21
+ * const account = await rotation.getNextAvailableAccount();
22
+ *
23
+ * // Mark an account as rate-limited
24
+ * rotation.addToCooldown('mihai_chindris', 'Rate limit exceeded');
25
+ * ```
26
+ */
27
+ /**
28
+ * Default cooldown duration for rate-limited accounts (5 minutes)
29
+ * Accounts typically need longer cooldown than models since Puter's
30
+ * account-level limits are stricter.
31
+ */
32
+ export const DEFAULT_ACCOUNT_COOLDOWN_MS = 300000;
33
+ /**
34
+ * Error thrown when all accounts are on cooldown
35
+ */
36
+ export class AllAccountsOnCooldownError extends Error {
37
+ accountStatuses;
38
+ nextAvailableIn;
39
+ constructor(statuses) {
40
+ const usernames = statuses.map(s => s.username).join(', ');
41
+ const nextAvailable = Math.min(...statuses.map(s => s.cooldownRemainingMs));
42
+ super(`All accounts on cooldown: ${usernames}. Next available in ${Math.round(nextAvailable / 1000)}s`);
43
+ this.name = 'AllAccountsOnCooldownError';
44
+ this.accountStatuses = statuses;
45
+ this.nextAvailableIn = nextAvailable;
46
+ }
47
+ }
48
+ /**
49
+ * Manages automatic account rotation when rate limits are encountered.
50
+ *
51
+ * Works with PuterAuthManager to cycle through multiple accounts,
52
+ * ensuring uninterrupted service even when individual accounts
53
+ * hit their rate limits.
54
+ */
55
+ export class AccountRotationManager {
56
+ authManager;
57
+ cooldownMap = new Map();
58
+ usageStats = new Map();
59
+ cooldownMs;
60
+ enabled;
61
+ strategy;
62
+ currentIndex = 0;
63
+ logger;
64
+ /**
65
+ * Create a new AccountRotationManager
66
+ *
67
+ * @param authManager - The PuterAuthManager instance
68
+ * @param options - Configuration options
69
+ * @param logger - Optional logger for debugging
70
+ */
71
+ constructor(authManager, options = {}, logger) {
72
+ this.authManager = authManager;
73
+ this.cooldownMs = options.cooldownMs ?? DEFAULT_ACCOUNT_COOLDOWN_MS;
74
+ this.enabled = options.enabled ?? true;
75
+ this.strategy = options.strategy ?? 'round-robin';
76
+ this.logger = logger;
77
+ }
78
+ /**
79
+ * Check if an account is currently on cooldown
80
+ *
81
+ * @param username - Account username to check
82
+ * @returns true if the account is on cooldown
83
+ */
84
+ isAccountOnCooldown(username) {
85
+ const entry = this.cooldownMap.get(username);
86
+ if (!entry)
87
+ return false;
88
+ if (Date.now() >= entry.expiresAt) {
89
+ this.cooldownMap.delete(username);
90
+ return false;
91
+ }
92
+ return true;
93
+ }
94
+ /**
95
+ * Get remaining cooldown time for an account
96
+ *
97
+ * @param username - Account username to check
98
+ * @returns Remaining cooldown in ms, or 0 if not on cooldown
99
+ */
100
+ getCooldownRemaining(username) {
101
+ const entry = this.cooldownMap.get(username);
102
+ if (!entry)
103
+ return 0;
104
+ const remaining = entry.expiresAt - Date.now();
105
+ if (remaining <= 0) {
106
+ this.cooldownMap.delete(username);
107
+ return 0;
108
+ }
109
+ return remaining;
110
+ }
111
+ /**
112
+ * Add an account to the cooldown list
113
+ *
114
+ * Each consecutive rate limit increases the cooldown duration
115
+ * exponentially (up to 4x base cooldown).
116
+ *
117
+ * @param username - Account username to add to cooldown
118
+ * @param reason - Reason for the cooldown
119
+ */
120
+ addToCooldown(username, reason) {
121
+ const existing = this.cooldownMap.get(username);
122
+ const consecutiveRateLimits = (existing?.consecutiveRateLimits ?? 0) + 1;
123
+ // Exponential backoff: 1x, 2x, 3x, 4x (max)
124
+ const multiplier = Math.min(consecutiveRateLimits, 4);
125
+ const duration = this.cooldownMs * multiplier;
126
+ this.cooldownMap.set(username, {
127
+ expiresAt: Date.now() + duration,
128
+ reason,
129
+ consecutiveRateLimits,
130
+ });
131
+ // Update stats
132
+ const stats = this.usageStats.get(username) ?? { lastUsedAt: 0, rateLimitCount: 0 };
133
+ stats.rateLimitCount++;
134
+ this.usageStats.set(username, stats);
135
+ const durationSecs = Math.round(duration / 1000);
136
+ this.logger?.warn(`Account ${username} cooldown: ${durationSecs}s (${consecutiveRateLimits}x)`);
137
+ }
138
+ /**
139
+ * Remove an account from cooldown (e.g., after successful request)
140
+ *
141
+ * @param username - Account username to remove from cooldown
142
+ */
143
+ removeFromCooldown(username) {
144
+ if (this.cooldownMap.has(username)) {
145
+ this.cooldownMap.delete(username);
146
+ this.logger?.debug(`Account ${username} removed from cooldown`);
147
+ }
148
+ }
149
+ /**
150
+ * Mark an account as recently used
151
+ *
152
+ * @param username - Account username that was used
153
+ */
154
+ markAsUsed(username) {
155
+ const stats = this.usageStats.get(username) ?? { lastUsedAt: 0, rateLimitCount: 0 };
156
+ stats.lastUsedAt = Date.now();
157
+ this.usageStats.set(username, stats);
158
+ }
159
+ /**
160
+ * Get status of all accounts
161
+ *
162
+ * @returns Array of account statuses
163
+ */
164
+ getAccountStatuses() {
165
+ const accounts = this.authManager.getAllAccounts();
166
+ return accounts.map(account => {
167
+ const cooldownRemaining = this.getCooldownRemaining(account.username);
168
+ const entry = this.cooldownMap.get(account.username);
169
+ const stats = this.usageStats.get(account.username);
170
+ return {
171
+ username: account.username,
172
+ isOnCooldown: cooldownRemaining > 0,
173
+ cooldownRemainingMs: cooldownRemaining,
174
+ cooldownReason: entry?.reason,
175
+ lastUsedAt: stats?.lastUsedAt ?? account.lastUsed,
176
+ rateLimitCount: stats?.rateLimitCount ?? 0,
177
+ };
178
+ });
179
+ }
180
+ /**
181
+ * Get list of available accounts (not on cooldown)
182
+ *
183
+ * @returns Array of available accounts
184
+ */
185
+ getAvailableAccounts() {
186
+ return this.authManager.getAllAccounts().filter(account => !this.isAccountOnCooldown(account.username));
187
+ }
188
+ /**
189
+ * Get count of accounts currently on cooldown
190
+ *
191
+ * @returns Number of accounts on cooldown
192
+ */
193
+ getAccountsOnCooldownCount() {
194
+ const accounts = this.authManager.getAllAccounts();
195
+ return accounts.filter(a => this.isAccountOnCooldown(a.username)).length;
196
+ }
197
+ /**
198
+ * Select the next account to use based on strategy
199
+ *
200
+ * @param availableAccounts - List of available accounts
201
+ * @returns The selected account
202
+ */
203
+ selectNextAccount(availableAccounts) {
204
+ if (availableAccounts.length === 0) {
205
+ throw new Error('No available accounts');
206
+ }
207
+ if (availableAccounts.length === 1) {
208
+ return availableAccounts[0];
209
+ }
210
+ switch (this.strategy) {
211
+ case 'least-recently-used': {
212
+ // Find the account with the oldest lastUsedAt
213
+ let oldest = availableAccounts[0];
214
+ let oldestTime = this.usageStats.get(oldest.username)?.lastUsedAt ?? oldest.lastUsed ?? 0;
215
+ for (const account of availableAccounts) {
216
+ const lastUsed = this.usageStats.get(account.username)?.lastUsedAt ?? account.lastUsed ?? 0;
217
+ if (lastUsed < oldestTime) {
218
+ oldest = account;
219
+ oldestTime = lastUsed;
220
+ }
221
+ }
222
+ return oldest;
223
+ }
224
+ case 'round-robin':
225
+ default: {
226
+ // Cycle through accounts in order
227
+ const allAccounts = this.authManager.getAllAccounts();
228
+ // Find next available account starting from currentIndex
229
+ for (let i = 0; i < allAccounts.length; i++) {
230
+ const idx = (this.currentIndex + i) % allAccounts.length;
231
+ const account = allAccounts[idx];
232
+ if (availableAccounts.includes(account)) {
233
+ this.currentIndex = (idx + 1) % allAccounts.length;
234
+ return account;
235
+ }
236
+ }
237
+ // Fallback to first available
238
+ return availableAccounts[0];
239
+ }
240
+ }
241
+ }
242
+ /**
243
+ * Get the next available account, potentially rotating from current
244
+ *
245
+ * If the current account is on cooldown or has been rate-limited,
246
+ * switches to the next available account.
247
+ *
248
+ * @returns Rotation result with the selected account
249
+ * @throws AllAccountsOnCooldownError if all accounts are on cooldown
250
+ */
251
+ async getNextAvailableAccount() {
252
+ const allAccounts = this.authManager.getAllAccounts();
253
+ const totalAccounts = allAccounts.length;
254
+ if (totalAccounts === 0) {
255
+ throw new Error('No accounts configured. Run `puter-auth login` to add an account.');
256
+ }
257
+ // If rotation is disabled, just return current account
258
+ if (!this.enabled) {
259
+ const current = this.authManager.getActiveAccount();
260
+ if (!current) {
261
+ throw new Error('No active account');
262
+ }
263
+ return {
264
+ account: current,
265
+ wasRotated: false,
266
+ accountsOnCooldown: this.getAccountsOnCooldownCount(),
267
+ totalAccounts,
268
+ };
269
+ }
270
+ const availableAccounts = this.getAvailableAccounts();
271
+ const accountsOnCooldown = totalAccounts - availableAccounts.length;
272
+ // If all accounts are on cooldown, throw error with details
273
+ if (availableAccounts.length === 0) {
274
+ const statuses = this.getAccountStatuses();
275
+ throw new AllAccountsOnCooldownError(statuses);
276
+ }
277
+ const currentAccount = this.authManager.getActiveAccount();
278
+ const currentUsername = currentAccount?.username;
279
+ // Check if current account is available
280
+ const currentIsAvailable = currentAccount &&
281
+ availableAccounts.some(a => a.username === currentAccount.username);
282
+ if (currentIsAvailable && accountsOnCooldown === 0) {
283
+ // Current account is fine and no rotation needed
284
+ return {
285
+ account: currentAccount,
286
+ wasRotated: false,
287
+ accountsOnCooldown: 0,
288
+ totalAccounts,
289
+ };
290
+ }
291
+ // Need to select a (potentially different) account
292
+ const selectedAccount = this.selectNextAccount(availableAccounts);
293
+ const wasRotated = selectedAccount.username !== currentUsername;
294
+ // If we selected a different account, switch to it
295
+ if (wasRotated) {
296
+ const targetIndex = allAccounts.findIndex(a => a.username === selectedAccount.username);
297
+ if (targetIndex >= 0) {
298
+ await this.authManager.switchAccount(targetIndex);
299
+ this.logger?.info(`Rotated to account: ${selectedAccount.username}`);
300
+ }
301
+ }
302
+ // Mark as used
303
+ this.markAsUsed(selectedAccount.username);
304
+ return {
305
+ account: selectedAccount,
306
+ wasRotated,
307
+ previousUsername: wasRotated ? currentUsername : undefined,
308
+ accountsOnCooldown,
309
+ totalAccounts,
310
+ };
311
+ }
312
+ /**
313
+ * Handle a rate limit error by adding current account to cooldown
314
+ * and returning the next available account
315
+ *
316
+ * @param error - The rate limit error
317
+ * @returns Next available account, or null if all on cooldown
318
+ */
319
+ async handleRateLimitError(error) {
320
+ const currentAccount = this.authManager.getActiveAccount();
321
+ if (currentAccount) {
322
+ this.addToCooldown(currentAccount.username, error.message);
323
+ }
324
+ try {
325
+ return await this.getNextAvailableAccount();
326
+ }
327
+ catch (e) {
328
+ if (e instanceof AllAccountsOnCooldownError) {
329
+ return null;
330
+ }
331
+ throw e;
332
+ }
333
+ }
334
+ /**
335
+ * Clear all cooldowns (useful for testing or manual reset)
336
+ */
337
+ clearCooldowns() {
338
+ this.cooldownMap.clear();
339
+ this.logger?.debug('All account cooldowns cleared');
340
+ }
341
+ /**
342
+ * Reset all statistics
343
+ */
344
+ resetStats() {
345
+ this.usageStats.clear();
346
+ this.currentIndex = 0;
347
+ this.logger?.debug('Account rotation stats reset');
348
+ }
349
+ /**
350
+ * Update configuration
351
+ */
352
+ configure(options) {
353
+ if (options.cooldownMs !== undefined) {
354
+ this.cooldownMs = options.cooldownMs;
355
+ }
356
+ if (options.enabled !== undefined) {
357
+ this.enabled = options.enabled;
358
+ }
359
+ if (options.strategy !== undefined) {
360
+ this.strategy = options.strategy;
361
+ }
362
+ }
363
+ /**
364
+ * Get current configuration
365
+ */
366
+ getConfig() {
367
+ return {
368
+ cooldownMs: this.cooldownMs,
369
+ enabled: this.enabled,
370
+ strategy: this.strategy,
371
+ };
372
+ }
373
+ /**
374
+ * Check if rotation is needed (current account on cooldown)
375
+ */
376
+ isRotationNeeded() {
377
+ if (!this.enabled)
378
+ return false;
379
+ const current = this.authManager.getActiveAccount();
380
+ if (!current)
381
+ return false;
382
+ return this.isAccountOnCooldown(current.username);
383
+ }
384
+ /**
385
+ * Get a summary of the rotation state
386
+ */
387
+ getSummary() {
388
+ const allAccounts = this.authManager.getAllAccounts();
389
+ const available = this.getAvailableAccounts();
390
+ const current = this.authManager.getActiveAccount();
391
+ return {
392
+ enabled: this.enabled,
393
+ totalAccounts: allAccounts.length,
394
+ availableAccounts: available.length,
395
+ onCooldown: allAccounts.length - available.length,
396
+ currentAccount: current?.username ?? null,
397
+ strategy: this.strategy,
398
+ };
399
+ }
400
+ }
401
+ /**
402
+ * Global AccountRotationManager instance
403
+ */
404
+ let globalAccountRotationManager = null;
405
+ /**
406
+ * Get the global AccountRotationManager instance
407
+ *
408
+ * @param authManager - The auth manager (required on first call)
409
+ * @param options - Configuration options
410
+ * @param logger - Optional logger
411
+ * @returns The global AccountRotationManager instance
412
+ */
413
+ export function getGlobalAccountRotationManager(authManager, options, logger) {
414
+ if (!globalAccountRotationManager) {
415
+ if (!authManager) {
416
+ throw new Error('AuthManager required when creating AccountRotationManager');
417
+ }
418
+ globalAccountRotationManager = new AccountRotationManager(authManager, options, logger);
419
+ }
420
+ else if (options) {
421
+ globalAccountRotationManager.configure(options);
422
+ }
423
+ return globalAccountRotationManager;
424
+ }
425
+ /**
426
+ * Reset the global AccountRotationManager (useful for testing)
427
+ */
428
+ export function resetGlobalAccountRotationManager() {
429
+ globalAccountRotationManager = null;
430
+ }
431
+ //# sourceMappingURL=account-rotation.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"account-rotation.js","sourceRoot":"","sources":["../src/account-rotation.ts"],"names":[],"mappings":"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"}