opencode-puter-auth 1.0.37 → 1.0.39

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,200 @@
1
+ /**
2
+ * Fallback Manager for opencode-puter-auth
3
+ *
4
+ * Provides automatic model fallback when rate limits are encountered.
5
+ * When a model returns a rate limit error (429/403), the manager:
6
+ * 1. Adds the model to a cooldown list
7
+ * 2. Tries alternative free models in order
8
+ * 3. Returns to the original model after cooldown expires
9
+ *
10
+ * @example
11
+ * ```ts
12
+ * const manager = new FallbackManager({
13
+ * fallbackModels: ['openrouter:xiaomi/mimo-v2-flash:free'],
14
+ * cooldownMs: 60000,
15
+ * });
16
+ *
17
+ * const result = await manager.executeWithFallback(
18
+ * 'claude-opus-4-5',
19
+ * async (model) => puter.ai.chat(messages, { model }),
20
+ * logger
21
+ * );
22
+ *
23
+ * if (result.wasFallback) {
24
+ * console.log(`Used fallback model: ${result.usedModel}`);
25
+ * }
26
+ * ```
27
+ */
28
+ import type { Logger } from './logger.js';
29
+ /**
30
+ * Default fallback models - FREE OpenRouter models via Puter gateway.
31
+ * Ordered by quality/capability (best first).
32
+ */
33
+ export declare const DEFAULT_FALLBACK_MODELS: string[];
34
+ /**
35
+ * Default cooldown duration in milliseconds (60 seconds)
36
+ */
37
+ export declare const DEFAULT_COOLDOWN_MS = 60000;
38
+ /**
39
+ * Configuration options for FallbackManager
40
+ */
41
+ export interface FallbackOptions {
42
+ /** List of fallback models to try when primary fails */
43
+ fallbackModels?: string[];
44
+ /** Cooldown duration in milliseconds */
45
+ cooldownMs?: number;
46
+ /** Whether fallback is enabled */
47
+ enabled?: boolean;
48
+ }
49
+ /**
50
+ * Record of a single model attempt
51
+ */
52
+ export interface FallbackAttempt {
53
+ /** Model that was tried */
54
+ model: string;
55
+ /** Whether the attempt succeeded */
56
+ success: boolean;
57
+ /** Error message if failed */
58
+ error?: string;
59
+ /** Whether the error was a rate limit */
60
+ isRateLimit?: boolean;
61
+ /** Duration of the attempt in ms */
62
+ durationMs?: number;
63
+ }
64
+ /**
65
+ * Result of executeWithFallback
66
+ */
67
+ export interface FallbackResult<T> {
68
+ /** The result from the successful model */
69
+ result: T;
70
+ /** The model that was actually used */
71
+ usedModel: string;
72
+ /** Whether a fallback model was used instead of the primary */
73
+ wasFallback: boolean;
74
+ /** All attempts made (for debugging/logging) */
75
+ attempts: FallbackAttempt[];
76
+ }
77
+ /**
78
+ * Error thrown when all models (primary + fallbacks) have failed
79
+ */
80
+ export declare class FallbackExhaustedError extends Error {
81
+ readonly attempts: FallbackAttempt[];
82
+ constructor(attempts: FallbackAttempt[]);
83
+ }
84
+ /**
85
+ * Check if an error indicates a rate limit
86
+ *
87
+ * Detects various rate limit error patterns from different providers:
88
+ * - HTTP 429 (Too Many Requests)
89
+ * - HTTP 403 (Forbidden) - Puter uses this for account limits
90
+ * - Various error message patterns
91
+ *
92
+ * @param error - The error to check
93
+ * @returns true if the error is a rate limit error
94
+ */
95
+ export declare function isRateLimitError(error: unknown): boolean;
96
+ /**
97
+ * Manages automatic model fallback when rate limits are encountered.
98
+ *
99
+ * This is a singleton-style class designed to be shared across all
100
+ * PuterChatLanguageModel instances so cooldown state is consistent.
101
+ */
102
+ export declare class FallbackManager {
103
+ private cooldownMap;
104
+ private fallbackModels;
105
+ private cooldownMs;
106
+ private enabled;
107
+ constructor(options?: FallbackOptions);
108
+ /**
109
+ * Check if a model is currently on cooldown
110
+ *
111
+ * @param model - Model ID to check
112
+ * @returns true if the model is on cooldown
113
+ */
114
+ isModelOnCooldown(model: string): boolean;
115
+ /**
116
+ * Get remaining cooldown time for a model in milliseconds
117
+ *
118
+ * @param model - Model ID to check
119
+ * @returns Remaining cooldown in ms, or 0 if not on cooldown
120
+ */
121
+ getCooldownRemaining(model: string): number;
122
+ /**
123
+ * Add a model to the cooldown list
124
+ *
125
+ * @param model - Model ID to add to cooldown
126
+ * @param reason - Reason for the cooldown (e.g., error message)
127
+ * @param durationMs - Optional custom cooldown duration
128
+ */
129
+ addToCooldown(model: string, reason: string, durationMs?: number): void;
130
+ /**
131
+ * Remove a model from cooldown (e.g., if it's working again)
132
+ *
133
+ * @param model - Model ID to remove from cooldown
134
+ */
135
+ removeFromCooldown(model: string): void;
136
+ /**
137
+ * Get all models currently on cooldown
138
+ *
139
+ * @returns Map of model IDs to their cooldown info
140
+ */
141
+ getCooldownStatus(): Map<string, {
142
+ remainingMs: number;
143
+ reason: string;
144
+ }>;
145
+ /**
146
+ * Build the queue of models to try, respecting cooldowns
147
+ *
148
+ * @param primaryModel - The primary model requested
149
+ * @returns Ordered array of models to try
150
+ */
151
+ buildModelQueue(primaryModel: string): string[];
152
+ /**
153
+ * Execute an operation with automatic model fallback
154
+ *
155
+ * Tries the primary model first, and if it fails with a rate limit error,
156
+ * automatically tries fallback models in order.
157
+ *
158
+ * @param primaryModel - The primary model to try first
159
+ * @param operation - Function that performs the API call with the given model
160
+ * @param logger - Optional logger for debugging
161
+ * @returns Result including which model was used and all attempts
162
+ * @throws FallbackExhaustedError if all models fail
163
+ *
164
+ * @example
165
+ * ```ts
166
+ * const result = await manager.executeWithFallback(
167
+ * 'claude-opus-4-5',
168
+ * async (model) => {
169
+ * return await puter.ai.chat(messages, { model });
170
+ * },
171
+ * logger
172
+ * );
173
+ * ```
174
+ */
175
+ executeWithFallback<T>(primaryModel: string, operation: (model: string) => Promise<T>, logger?: Logger): Promise<FallbackResult<T>>;
176
+ /**
177
+ * Clear all cooldowns (useful for testing or manual reset)
178
+ */
179
+ clearCooldowns(): void;
180
+ /**
181
+ * Update configuration
182
+ */
183
+ configure(options: Partial<FallbackOptions>): void;
184
+ /**
185
+ * Get current configuration
186
+ */
187
+ getConfig(): Required<FallbackOptions>;
188
+ }
189
+ /**
190
+ * Get the global FallbackManager instance, creating it if needed
191
+ *
192
+ * @param options - Configuration options (only used when creating)
193
+ * @returns The global FallbackManager instance
194
+ */
195
+ export declare function getGlobalFallbackManager(options?: FallbackOptions): FallbackManager;
196
+ /**
197
+ * Reset the global FallbackManager (useful for testing)
198
+ */
199
+ export declare function resetGlobalFallbackManager(): void;
200
+ //# sourceMappingURL=fallback.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fallback.d.ts","sourceRoot":"","sources":["../src/fallback.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,380 @@
1
+ /**
2
+ * Fallback Manager for opencode-puter-auth
3
+ *
4
+ * Provides automatic model fallback when rate limits are encountered.
5
+ * When a model returns a rate limit error (429/403), the manager:
6
+ * 1. Adds the model to a cooldown list
7
+ * 2. Tries alternative free models in order
8
+ * 3. Returns to the original model after cooldown expires
9
+ *
10
+ * @example
11
+ * ```ts
12
+ * const manager = new FallbackManager({
13
+ * fallbackModels: ['openrouter:xiaomi/mimo-v2-flash:free'],
14
+ * cooldownMs: 60000,
15
+ * });
16
+ *
17
+ * const result = await manager.executeWithFallback(
18
+ * 'claude-opus-4-5',
19
+ * async (model) => puter.ai.chat(messages, { model }),
20
+ * logger
21
+ * );
22
+ *
23
+ * if (result.wasFallback) {
24
+ * console.log(`Used fallback model: ${result.usedModel}`);
25
+ * }
26
+ * ```
27
+ */
28
+ /**
29
+ * Default fallback models - FREE OpenRouter models via Puter gateway.
30
+ * Ordered by quality/capability (best first).
31
+ */
32
+ export const DEFAULT_FALLBACK_MODELS = [
33
+ // Tier 1: Best free models (try these first)
34
+ 'openrouter:xiaomi/mimo-v2-flash:free', // 309B MoE, #1 SWE-bench
35
+ 'openrouter:deepseek/deepseek-r1-0528:free', // 671B MoE, o1-level reasoning
36
+ 'openrouter:mistralai/devstral-2512:free', // 123B, agentic coding
37
+ // Tier 2: Other quality free models
38
+ 'openrouter:qwen/qwen3-coder:free', // 480B MoE coding model
39
+ 'openrouter:google/gemini-2.0-flash-exp:free', // Google's experimental
40
+ // Tier 3: Fallback free models
41
+ 'openrouter:meta-llama/llama-4-maverick:free',
42
+ 'openrouter:openai/gpt-oss-120b:free',
43
+ ];
44
+ /**
45
+ * Default cooldown duration in milliseconds (60 seconds)
46
+ */
47
+ export const DEFAULT_COOLDOWN_MS = 60000;
48
+ /**
49
+ * Error thrown when all models (primary + fallbacks) have failed
50
+ */
51
+ export class FallbackExhaustedError extends Error {
52
+ attempts;
53
+ constructor(attempts) {
54
+ const modelsTried = attempts.map(a => a.model).join(', ');
55
+ super(`All models exhausted. Tried: ${modelsTried}`);
56
+ this.name = 'FallbackExhaustedError';
57
+ this.attempts = attempts;
58
+ }
59
+ }
60
+ /**
61
+ * Check if an error indicates a rate limit
62
+ *
63
+ * Detects various rate limit error patterns from different providers:
64
+ * - HTTP 429 (Too Many Requests)
65
+ * - HTTP 403 (Forbidden) - Puter uses this for account limits
66
+ * - Various error message patterns
67
+ *
68
+ * @param error - The error to check
69
+ * @returns true if the error is a rate limit error
70
+ */
71
+ export function isRateLimitError(error) {
72
+ if (!(error instanceof Error))
73
+ return false;
74
+ const message = error.message.toLowerCase();
75
+ // HTTP status codes that indicate rate limiting
76
+ if (message.includes('(429)') || message.includes('status 429'))
77
+ return true;
78
+ if (message.includes('(403)') || message.includes('status 403'))
79
+ return true;
80
+ // Error message patterns from various providers
81
+ const rateLimitPatterns = [
82
+ 'rate limit',
83
+ 'rate_limit',
84
+ 'ratelimit',
85
+ 'too many requests',
86
+ 'quota exceeded',
87
+ 'quota_exceeded',
88
+ 'limit exceeded',
89
+ 'request limit',
90
+ 'credits exhausted',
91
+ 'insufficient credits',
92
+ 'usage limit',
93
+ 'capacity',
94
+ 'overloaded',
95
+ 'try again later',
96
+ ];
97
+ return rateLimitPatterns.some(pattern => message.includes(pattern));
98
+ }
99
+ /**
100
+ * Manages automatic model fallback when rate limits are encountered.
101
+ *
102
+ * This is a singleton-style class designed to be shared across all
103
+ * PuterChatLanguageModel instances so cooldown state is consistent.
104
+ */
105
+ export class FallbackManager {
106
+ cooldownMap = new Map();
107
+ fallbackModels;
108
+ cooldownMs;
109
+ enabled;
110
+ constructor(options = {}) {
111
+ this.fallbackModels = options.fallbackModels ?? DEFAULT_FALLBACK_MODELS;
112
+ this.cooldownMs = options.cooldownMs ?? DEFAULT_COOLDOWN_MS;
113
+ this.enabled = options.enabled ?? true;
114
+ }
115
+ /**
116
+ * Check if a model is currently on cooldown
117
+ *
118
+ * @param model - Model ID to check
119
+ * @returns true if the model is on cooldown
120
+ */
121
+ isModelOnCooldown(model) {
122
+ const entry = this.cooldownMap.get(model);
123
+ if (!entry)
124
+ return false;
125
+ // Check if cooldown has expired
126
+ if (Date.now() >= entry.expiresAt) {
127
+ this.cooldownMap.delete(model);
128
+ return false;
129
+ }
130
+ return true;
131
+ }
132
+ /**
133
+ * Get remaining cooldown time for a model in milliseconds
134
+ *
135
+ * @param model - Model ID to check
136
+ * @returns Remaining cooldown in ms, or 0 if not on cooldown
137
+ */
138
+ getCooldownRemaining(model) {
139
+ const entry = this.cooldownMap.get(model);
140
+ if (!entry)
141
+ return 0;
142
+ const remaining = entry.expiresAt - Date.now();
143
+ if (remaining <= 0) {
144
+ this.cooldownMap.delete(model);
145
+ return 0;
146
+ }
147
+ return remaining;
148
+ }
149
+ /**
150
+ * Add a model to the cooldown list
151
+ *
152
+ * @param model - Model ID to add to cooldown
153
+ * @param reason - Reason for the cooldown (e.g., error message)
154
+ * @param durationMs - Optional custom cooldown duration
155
+ */
156
+ addToCooldown(model, reason, durationMs) {
157
+ this.cooldownMap.set(model, {
158
+ expiresAt: Date.now() + (durationMs ?? this.cooldownMs),
159
+ reason,
160
+ });
161
+ }
162
+ /**
163
+ * Remove a model from cooldown (e.g., if it's working again)
164
+ *
165
+ * @param model - Model ID to remove from cooldown
166
+ */
167
+ removeFromCooldown(model) {
168
+ this.cooldownMap.delete(model);
169
+ }
170
+ /**
171
+ * Get all models currently on cooldown
172
+ *
173
+ * @returns Map of model IDs to their cooldown info
174
+ */
175
+ getCooldownStatus() {
176
+ const status = new Map();
177
+ const now = Date.now();
178
+ for (const [model, entry] of this.cooldownMap) {
179
+ const remaining = entry.expiresAt - now;
180
+ if (remaining > 0) {
181
+ status.set(model, { remainingMs: remaining, reason: entry.reason });
182
+ }
183
+ else {
184
+ // Clean up expired entries
185
+ this.cooldownMap.delete(model);
186
+ }
187
+ }
188
+ return status;
189
+ }
190
+ /**
191
+ * Build the queue of models to try, respecting cooldowns
192
+ *
193
+ * @param primaryModel - The primary model requested
194
+ * @returns Ordered array of models to try
195
+ */
196
+ buildModelQueue(primaryModel) {
197
+ const queue = [];
198
+ // Add primary model first if not on cooldown
199
+ if (!this.isModelOnCooldown(primaryModel)) {
200
+ queue.push(primaryModel);
201
+ }
202
+ // Add fallback models that aren't on cooldown
203
+ for (const model of this.fallbackModels) {
204
+ // Skip if it's the primary (already added) or on cooldown
205
+ if (model === primaryModel)
206
+ continue;
207
+ if (this.isModelOnCooldown(model))
208
+ continue;
209
+ queue.push(model);
210
+ }
211
+ // If primary was on cooldown but we have no fallbacks, add it anyway
212
+ // (better to try and fail than to give up immediately)
213
+ if (queue.length === 0 && this.isModelOnCooldown(primaryModel)) {
214
+ queue.push(primaryModel);
215
+ }
216
+ return queue;
217
+ }
218
+ /**
219
+ * Execute an operation with automatic model fallback
220
+ *
221
+ * Tries the primary model first, and if it fails with a rate limit error,
222
+ * automatically tries fallback models in order.
223
+ *
224
+ * @param primaryModel - The primary model to try first
225
+ * @param operation - Function that performs the API call with the given model
226
+ * @param logger - Optional logger for debugging
227
+ * @returns Result including which model was used and all attempts
228
+ * @throws FallbackExhaustedError if all models fail
229
+ *
230
+ * @example
231
+ * ```ts
232
+ * const result = await manager.executeWithFallback(
233
+ * 'claude-opus-4-5',
234
+ * async (model) => {
235
+ * return await puter.ai.chat(messages, { model });
236
+ * },
237
+ * logger
238
+ * );
239
+ * ```
240
+ */
241
+ async executeWithFallback(primaryModel, operation, logger) {
242
+ // If fallback is disabled, just run the operation directly
243
+ if (!this.enabled) {
244
+ const startTime = Date.now();
245
+ try {
246
+ const result = await operation(primaryModel);
247
+ return {
248
+ result,
249
+ usedModel: primaryModel,
250
+ wasFallback: false,
251
+ attempts: [{
252
+ model: primaryModel,
253
+ success: true,
254
+ durationMs: Date.now() - startTime,
255
+ }],
256
+ };
257
+ }
258
+ catch (error) {
259
+ throw error;
260
+ }
261
+ }
262
+ const modelQueue = this.buildModelQueue(primaryModel);
263
+ const attempts = [];
264
+ logger?.debug('Fallback queue built', {
265
+ primary: primaryModel,
266
+ queue: modelQueue.join(', '),
267
+ cooldowns: this.cooldownMap.size,
268
+ });
269
+ for (const model of modelQueue) {
270
+ const startTime = Date.now();
271
+ const isFallback = model !== primaryModel;
272
+ if (isFallback) {
273
+ logger?.info(`Trying fallback model: ${model}`);
274
+ }
275
+ try {
276
+ const result = await operation(model);
277
+ // Success! If this was a fallback, log it
278
+ if (isFallback) {
279
+ logger?.info(`Fallback model succeeded: ${model}`);
280
+ }
281
+ attempts.push({
282
+ model,
283
+ success: true,
284
+ durationMs: Date.now() - startTime,
285
+ });
286
+ return {
287
+ result,
288
+ usedModel: model,
289
+ wasFallback: isFallback,
290
+ attempts,
291
+ };
292
+ }
293
+ catch (error) {
294
+ const durationMs = Date.now() - startTime;
295
+ const isRateLimit = isRateLimitError(error);
296
+ const errorMessage = error instanceof Error ? error.message : String(error);
297
+ attempts.push({
298
+ model,
299
+ success: false,
300
+ error: errorMessage,
301
+ isRateLimit,
302
+ durationMs,
303
+ });
304
+ if (isRateLimit) {
305
+ // Add to cooldown and continue to next model
306
+ this.addToCooldown(model, errorMessage);
307
+ const cooldownSecs = Math.round(this.cooldownMs / 1000);
308
+ logger?.warn(`Model ${model} rate limited, cooldown ${cooldownSecs}s`);
309
+ }
310
+ else {
311
+ // Non-rate-limit error - might be a real problem
312
+ // Still try fallbacks but log it differently
313
+ logger?.warn(`Model ${model} failed: ${errorMessage}`);
314
+ }
315
+ // Continue to next model in queue
316
+ }
317
+ }
318
+ // All models exhausted
319
+ logger?.error('All models exhausted', new FallbackExhaustedError(attempts));
320
+ throw new FallbackExhaustedError(attempts);
321
+ }
322
+ /**
323
+ * Clear all cooldowns (useful for testing or manual reset)
324
+ */
325
+ clearCooldowns() {
326
+ this.cooldownMap.clear();
327
+ }
328
+ /**
329
+ * Update configuration
330
+ */
331
+ configure(options) {
332
+ if (options.fallbackModels !== undefined) {
333
+ this.fallbackModels = options.fallbackModels;
334
+ }
335
+ if (options.cooldownMs !== undefined) {
336
+ this.cooldownMs = options.cooldownMs;
337
+ }
338
+ if (options.enabled !== undefined) {
339
+ this.enabled = options.enabled;
340
+ }
341
+ }
342
+ /**
343
+ * Get current configuration
344
+ */
345
+ getConfig() {
346
+ return {
347
+ fallbackModels: [...this.fallbackModels],
348
+ cooldownMs: this.cooldownMs,
349
+ enabled: this.enabled,
350
+ };
351
+ }
352
+ }
353
+ /**
354
+ * Global FallbackManager instance shared across all model instances.
355
+ * This ensures cooldown state is consistent across the application.
356
+ */
357
+ let globalFallbackManager = null;
358
+ /**
359
+ * Get the global FallbackManager instance, creating it if needed
360
+ *
361
+ * @param options - Configuration options (only used when creating)
362
+ * @returns The global FallbackManager instance
363
+ */
364
+ export function getGlobalFallbackManager(options) {
365
+ if (!globalFallbackManager) {
366
+ globalFallbackManager = new FallbackManager(options);
367
+ }
368
+ else if (options) {
369
+ // Update config if options provided
370
+ globalFallbackManager.configure(options);
371
+ }
372
+ return globalFallbackManager;
373
+ }
374
+ /**
375
+ * Reset the global FallbackManager (useful for testing)
376
+ */
377
+ export function resetGlobalFallbackManager() {
378
+ globalFallbackManager = null;
379
+ }
380
+ //# sourceMappingURL=fallback.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fallback.js","sourceRoot":"","sources":["../src/fallback.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAIH;;;GAGG;AACH,MAAM,CAAC,MAAM,uBAAuB,GAAG;IACrC,6CAA6C;IAC7C,sCAAsC,EAAQ,yBAAyB;IACvE,2CAA2C,EAAG,+BAA+B;IAC7E,yCAAyC,EAAK,uBAAuB;IAErE,oCAAoC;IACpC,kCAAkC,EAAY,wBAAwB;IACtE,6CAA6C,EAAC,wBAAwB;IAEtE,+BAA+B;IAC/B,6CAA6C;IAC7C,qCAAqC;CACtC,CAAC;AAEF;;GAEG;AACH,MAAM,CAAC,MAAM,mBAAmB,GAAG,KAAK,CAAC;AA4CzC;;GAEG;AACH,MAAM,OAAO,sBAAuB,SAAQ,KAAK;IAC/B,QAAQ,CAAoB;IAE5C,YAAY,QAA2B;QACrC,MAAM,WAAW,GAAG,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC1D,KAAK,CAAC,gCAAgC,WAAW,EAAE,CAAC,CAAC;QACrD,IAAI,CAAC,IAAI,GAAG,wBAAwB,CAAC;QACrC,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC;IAC3B,CAAC;CACF;AAED;;;;;;;;;;GAUG;AACH,MAAM,UAAU,gBAAgB,CAAC,KAAc;IAC7C,IAAI,CAAC,CAAC,KAAK,YAAY,KAAK,CAAC;QAAE,OAAO,KAAK,CAAC;IAE5C,MAAM,OAAO,GAAG,KAAK,CAAC,OAAO,CAAC,WAAW,EAAE,CAAC;IAE5C,gDAAgD;IAChD,IAAI,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAC,IAAI,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAC;QAAE,OAAO,IAAI,CAAC;IAC7E,IAAI,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAC,IAAI,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAC;QAAE,OAAO,IAAI,CAAC;IAE7E,gDAAgD;IAChD,MAAM,iBAAiB,GAAG;QACxB,YAAY;QACZ,YAAY;QACZ,WAAW;QACX,mBAAmB;QACnB,gBAAgB;QAChB,gBAAgB;QAChB,gBAAgB;QAChB,eAAe;QACf,mBAAmB;QACnB,sBAAsB;QACtB,aAAa;QACb,UAAU;QACV,YAAY;QACZ,iBAAiB;KAClB,CAAC;IAEF,OAAO,iBAAiB,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC;AACtE,CAAC;AAYD;;;;;GAKG;AACH,MAAM,OAAO,eAAe;IAClB,WAAW,GAA+B,IAAI,GAAG,EAAE,CAAC;IACpD,cAAc,CAAW;IACzB,UAAU,CAAS;IACnB,OAAO,CAAU;IAEzB,YAAY,UAA2B,EAAE;QACvC,IAAI,CAAC,cAAc,GAAG,OAAO,CAAC,cAAc,IAAI,uBAAuB,CAAC;QACxE,IAAI,CAAC,UAAU,GAAG,OAAO,CAAC,UAAU,IAAI,mBAAmB,CAAC;QAC5D,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC,OAAO,IAAI,IAAI,CAAC;IACzC,CAAC;IAED;;;;;OAKG;IACI,iBAAiB,CAAC,KAAa;QACpC,MAAM,KAAK,GAAG,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;QAC1C,IAAI,CAAC,KAAK;YAAE,OAAO,KAAK,CAAC;QAEzB,gCAAgC;QAChC,IAAI,IAAI,CAAC,GAAG,EAAE,IAAI,KAAK,CAAC,SAAS,EAAE,CAAC;YAClC,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;YAC/B,OAAO,KAAK,CAAC;QACf,CAAC;QAED,OAAO,IAAI,CAAC;IACd,CAAC;IAED;;;;;OAKG;IACI,oBAAoB,CAAC,KAAa;QACvC,MAAM,KAAK,GAAG,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;QAC1C,IAAI,CAAC,KAAK;YAAE,OAAO,CAAC,CAAC;QAErB,MAAM,SAAS,GAAG,KAAK,CAAC,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QAC/C,IAAI,SAAS,IAAI,CAAC,EAAE,CAAC;YACnB,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;YAC/B,OAAO,CAAC,CAAC;QACX,CAAC;QAED,OAAO,SAAS,CAAC;IACnB,CAAC;IAED;;;;;;OAMG;IACI,aAAa,CAAC,KAAa,EAAE,MAAc,EAAE,UAAmB;QACrE,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,KAAK,EAAE;YAC1B,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,CAAC,UAAU,IAAI,IAAI,CAAC,UAAU,CAAC;YACvD,MAAM;SACP,CAAC,CAAC;IACL,CAAC;IAED;;;;OAIG;IACI,kBAAkB,CAAC,KAAa;QACrC,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IACjC,CAAC;IAED;;;;OAIG;IACI,iBAAiB;QACtB,MAAM,MAAM,GAAG,IAAI,GAAG,EAAmD,CAAC;QAC1E,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QAEvB,KAAK,MAAM,CAAC,KAAK,EAAE,KAAK,CAAC,IAAI,IAAI,CAAC,WAAW,EAAE,CAAC;YAC9C,MAAM,SAAS,GAAG,KAAK,CAAC,SAAS,GAAG,GAAG,CAAC;YACxC,IAAI,SAAS,GAAG,CAAC,EAAE,CAAC;gBAClB,MAAM,CAAC,GAAG,CAAC,KAAK,EAAE,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,EAAE,KAAK,CAAC,MAAM,EAAE,CAAC,CAAC;YACtE,CAAC;iBAAM,CAAC;gBACN,2BAA2B;gBAC3B,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;YACjC,CAAC;QACH,CAAC;QAED,OAAO,MAAM,CAAC;IAChB,CAAC;IAED;;;;;OAKG;IACI,eAAe,CAAC,YAAoB;QACzC,MAAM,KAAK,GAAa,EAAE,CAAC;QAE3B,6CAA6C;QAC7C,IAAI,CAAC,IAAI,CAAC,iBAAiB,CAAC,YAAY,CAAC,EAAE,CAAC;YAC1C,KAAK,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;QAC3B,CAAC;QAED,8CAA8C;QAC9C,KAAK,MAAM,KAAK,IAAI,IAAI,CAAC,cAAc,EAAE,CAAC;YACxC,0DAA0D;YAC1D,IAAI,KAAK,KAAK,YAAY;gBAAE,SAAS;YACrC,IAAI,IAAI,CAAC,iBAAiB,CAAC,KAAK,CAAC;gBAAE,SAAS;YAC5C,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACpB,CAAC;QAED,qEAAqE;QACrE,uDAAuD;QACvD,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,IAAI,IAAI,CAAC,iBAAiB,CAAC,YAAY,CAAC,EAAE,CAAC;YAC/D,KAAK,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;QAC3B,CAAC;QAED,OAAO,KAAK,CAAC;IACf,CAAC;IAED;;;;;;;;;;;;;;;;;;;;;;OAsBG;IACI,KAAK,CAAC,mBAAmB,CAC9B,YAAoB,EACpB,SAAwC,EACxC,MAAe;QAEf,2DAA2D;QAC3D,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC;YAClB,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;YAC7B,IAAI,CAAC;gBACH,MAAM,MAAM,GAAG,MAAM,SAAS,CAAC,YAAY,CAAC,CAAC;gBAC7C,OAAO;oBACL,MAAM;oBACN,SAAS,EAAE,YAAY;oBACvB,WAAW,EAAE,KAAK;oBAClB,QAAQ,EAAE,CAAC;4BACT,KAAK,EAAE,YAAY;4BACnB,OAAO,EAAE,IAAI;4BACb,UAAU,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS;yBACnC,CAAC;iBACH,CAAC;YACJ,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,MAAM,KAAK,CAAC;YACd,CAAC;QACH,CAAC;QAED,MAAM,UAAU,GAAG,IAAI,CAAC,eAAe,CAAC,YAAY,CAAC,CAAC;QACtD,MAAM,QAAQ,GAAsB,EAAE,CAAC;QAEvC,MAAM,EAAE,KAAK,CAAC,sBAAsB,EAAE;YACpC,OAAO,EAAE,YAAY;YACrB,KAAK,EAAE,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC;YAC5B,SAAS,EAAE,IAAI,CAAC,WAAW,CAAC,IAAI;SACjC,CAAC,CAAC;QAEH,KAAK,MAAM,KAAK,IAAI,UAAU,EAAE,CAAC;YAC/B,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;YAC7B,MAAM,UAAU,GAAG,KAAK,KAAK,YAAY,CAAC;YAE1C,IAAI,UAAU,EAAE,CAAC;gBACf,MAAM,EAAE,IAAI,CAAC,0BAA0B,KAAK,EAAE,CAAC,CAAC;YAClD,CAAC;YAED,IAAI,CAAC;gBACH,MAAM,MAAM,GAAG,MAAM,SAAS,CAAC,KAAK,CAAC,CAAC;gBAEtC,0CAA0C;gBAC1C,IAAI,UAAU,EAAE,CAAC;oBACf,MAAM,EAAE,IAAI,CAAC,6BAA6B,KAAK,EAAE,CAAC,CAAC;gBACrD,CAAC;gBAED,QAAQ,CAAC,IAAI,CAAC;oBACZ,KAAK;oBACL,OAAO,EAAE,IAAI;oBACb,UAAU,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS;iBACnC,CAAC,CAAC;gBAEH,OAAO;oBACL,MAAM;oBACN,SAAS,EAAE,KAAK;oBAChB,WAAW,EAAE,UAAU;oBACvB,QAAQ;iBACT,CAAC;YACJ,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,MAAM,UAAU,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS,CAAC;gBAC1C,MAAM,WAAW,GAAG,gBAAgB,CAAC,KAAK,CAAC,CAAC;gBAC5C,MAAM,YAAY,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;gBAE5E,QAAQ,CAAC,IAAI,CAAC;oBACZ,KAAK;oBACL,OAAO,EAAE,KAAK;oBACd,KAAK,EAAE,YAAY;oBACnB,WAAW;oBACX,UAAU;iBACX,CAAC,CAAC;gBAEH,IAAI,WAAW,EAAE,CAAC;oBAChB,6CAA6C;oBAC7C,IAAI,CAAC,aAAa,CAAC,KAAK,EAAE,YAAY,CAAC,CAAC;oBACxC,MAAM,YAAY,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC,CAAC;oBACxD,MAAM,EAAE,IAAI,CAAC,SAAS,KAAK,2BAA2B,YAAY,GAAG,CAAC,CAAC;gBACzE,CAAC;qBAAM,CAAC;oBACN,iDAAiD;oBACjD,6CAA6C;oBAC7C,MAAM,EAAE,IAAI,CAAC,SAAS,KAAK,YAAY,YAAY,EAAE,CAAC,CAAC;gBACzD,CAAC;gBAED,kCAAkC;YACpC,CAAC;QACH,CAAC;QAED,uBAAuB;QACvB,MAAM,EAAE,KAAK,CAAC,sBAAsB,EAAE,IAAI,sBAAsB,CAAC,QAAQ,CAAC,CAAC,CAAC;QAC5E,MAAM,IAAI,sBAAsB,CAAC,QAAQ,CAAC,CAAC;IAC7C,CAAC;IAED;;OAEG;IACI,cAAc;QACnB,IAAI,CAAC,WAAW,CAAC,KAAK,EAAE,CAAC;IAC3B,CAAC;IAED;;OAEG;IACI,SAAS,CAAC,OAAiC;QAChD,IAAI,OAAO,CAAC,cAAc,KAAK,SAAS,EAAE,CAAC;YACzC,IAAI,CAAC,cAAc,GAAG,OAAO,CAAC,cAAc,CAAC;QAC/C,CAAC;QACD,IAAI,OAAO,CAAC,UAAU,KAAK,SAAS,EAAE,CAAC;YACrC,IAAI,CAAC,UAAU,GAAG,OAAO,CAAC,UAAU,CAAC;QACvC,CAAC;QACD,IAAI,OAAO,CAAC,OAAO,KAAK,SAAS,EAAE,CAAC;YAClC,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC;QACjC,CAAC;IACH,CAAC;IAED;;OAEG;IACI,SAAS;QACd,OAAO;YACL,cAAc,EAAE,CAAC,GAAG,IAAI,CAAC,cAAc,CAAC;YACxC,UAAU,EAAE,IAAI,CAAC,UAAU;YAC3B,OAAO,EAAE,IAAI,CAAC,OAAO;SACtB,CAAC;IACJ,CAAC;CACF;AAED;;;GAGG;AACH,IAAI,qBAAqB,GAA2B,IAAI,CAAC;AAEzD;;;;;GAKG;AACH,MAAM,UAAU,wBAAwB,CAAC,OAAyB;IAChE,IAAI,CAAC,qBAAqB,EAAE,CAAC;QAC3B,qBAAqB,GAAG,IAAI,eAAe,CAAC,OAAO,CAAC,CAAC;IACvD,CAAC;SAAM,IAAI,OAAO,EAAE,CAAC;QACnB,oCAAoC;QACpC,qBAAqB,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC;IAC3C,CAAC;IACD,OAAO,qBAAqB,CAAC;AAC/B,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,0BAA0B;IACxC,qBAAqB,GAAG,IAAI,CAAC;AAC/B,CAAC"}
package/dist/index.d.ts CHANGED
@@ -5,6 +5,8 @@
5
5
  * and 500+ AI models through Puter.com's "User-Pays" model.
6
6
  * Free tier available with undocumented limits.
7
7
  *
8
+ * Features automatic model fallback when rate limits are encountered.
9
+ *
8
10
  * @author chindris-mihai-alexandru
9
11
  * @license MIT
10
12
  */
@@ -12,5 +14,9 @@ export { PuterAuthPlugin } from './plugin.js';
12
14
  export { createPuter as default } from './ai-provider/index.js';
13
15
  export { createPuter } from './ai-provider/index.js';
14
16
  export type { PuterProvider, PuterChatSettings, PuterProviderConfig, PuterChatConfig } from './ai-provider/index.js';
17
+ export { createLogger, createLoggerFromConfig, nullLogger, LogLevel } from './logger.js';
18
+ export type { Logger, LoggerOptions } from './logger.js';
19
+ export { FallbackManager, getGlobalFallbackManager, resetGlobalFallbackManager, isRateLimitError, FallbackExhaustedError, DEFAULT_FALLBACK_MODELS, DEFAULT_COOLDOWN_MS, } from './fallback.js';
20
+ export type { FallbackOptions, FallbackResult, FallbackAttempt, } from './fallback.js';
15
21
  export type { PuterConfig, PuterAccount, PuterChatOptions, PuterChatResponse, PuterChatMessage, PuterChatStreamChunk, PuterModelInfo } from './types.js';
16
22
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAOH,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAI9C,OAAO,EAAE,WAAW,IAAI,OAAO,EAAE,MAAM,wBAAwB,CAAC;AAGhE,OAAO,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AACrD,YAAY,EAAE,aAAa,EAAE,iBAAiB,EAAE,mBAAmB,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAGrH,YAAY,EAAE,WAAW,EAAE,YAAY,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,oBAAoB,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAOH,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAI9C,OAAO,EAAE,WAAW,IAAI,OAAO,EAAE,MAAM,wBAAwB,CAAC;AAGhE,OAAO,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AACrD,YAAY,EAAE,aAAa,EAAE,iBAAiB,EAAE,mBAAmB,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAGrH,OAAO,EAAE,YAAY,EAAE,sBAAsB,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AACzF,YAAY,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAGzD,OAAO,EACL,eAAe,EACf,wBAAwB,EACxB,0BAA0B,EAC1B,gBAAgB,EAChB,sBAAsB,EACtB,uBAAuB,EACvB,mBAAmB,GACpB,MAAM,eAAe,CAAC;AACvB,YAAY,EACV,eAAe,EACf,cAAc,EACd,eAAe,GAChB,MAAM,eAAe,CAAC;AAGvB,YAAY,EAAE,WAAW,EAAE,YAAY,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,oBAAoB,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC"}
package/dist/index.js CHANGED
@@ -5,6 +5,8 @@
5
5
  * and 500+ AI models through Puter.com's "User-Pays" model.
6
6
  * Free tier available with undocumented limits.
7
7
  *
8
+ * Features automatic model fallback when rate limits are encountered.
9
+ *
8
10
  * @author chindris-mihai-alexandru
9
11
  * @license MIT
10
12
  */
@@ -19,4 +21,8 @@ export { PuterAuthPlugin } from './plugin.js';
19
21
  export { createPuter as default } from './ai-provider/index.js';
20
22
  // AI SDK Provider exports
21
23
  export { createPuter } from './ai-provider/index.js';
24
+ // Logger exports for debug mode
25
+ export { createLogger, createLoggerFromConfig, nullLogger, LogLevel } from './logger.js';
26
+ // Fallback Manager exports for automatic model fallback
27
+ export { FallbackManager, getGlobalFallbackManager, resetGlobalFallbackManager, isRateLimitError, FallbackExhaustedError, DEFAULT_FALLBACK_MODELS, DEFAULT_COOLDOWN_MS, } from './fallback.js';
22
28
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,kDAAkD;AAClD,2DAA2D;AAC3D,wEAAwE;AACxE,yFAAyF;AACzF,gFAAgF;AAChF,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAE9C,gEAAgE;AAChE,uEAAuE;AACvE,OAAO,EAAE,WAAW,IAAI,OAAO,EAAE,MAAM,wBAAwB,CAAC;AAEhE,0BAA0B;AAC1B,OAAO,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,kDAAkD;AAClD,2DAA2D;AAC3D,wEAAwE;AACxE,yFAAyF;AACzF,gFAAgF;AAChF,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAE9C,gEAAgE;AAChE,uEAAuE;AACvE,OAAO,EAAE,WAAW,IAAI,OAAO,EAAE,MAAM,wBAAwB,CAAC;AAEhE,0BAA0B;AAC1B,OAAO,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AAGrD,gCAAgC;AAChC,OAAO,EAAE,YAAY,EAAE,sBAAsB,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAGzF,wDAAwD;AACxD,OAAO,EACL,eAAe,EACf,wBAAwB,EACxB,0BAA0B,EAC1B,gBAAgB,EAChB,sBAAsB,EACtB,uBAAuB,EACvB,mBAAmB,GACpB,MAAM,eAAe,CAAC"}