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.
- package/README.md +114 -0
- package/dist/account-rotation.d.ts +243 -0
- package/dist/account-rotation.d.ts.map +1 -0
- package/dist/account-rotation.js +431 -0
- package/dist/account-rotation.js.map +1 -0
- package/dist/auth.d.ts +166 -18
- package/dist/auth.d.ts.map +1 -1
- package/dist/auth.js +167 -20
- package/dist/auth.js.map +1 -1
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/types.d.ts +6 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +4 -0
- package/dist/types.js.map +1 -1
- package/package.json +1 -1
|
@@ -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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"}
|