UNPKG

llmforge

Version:

One API, every AI model, instant switching. Change from GPT-4 to Gemini to local models with a single config update. LLMForge is the lightweight, TypeScript-first solution for multi-provider AI applications with zero vendor lock-in.

85 lines 3.74 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.RetryHandler = void 0; const logger_1 = require("../../utils/logger"); const types_1 = require("../../types"); class RetryHandler { constructor(config = {}) { this.config = { maxRetries: config.maxRetries || 3, retryDelay: config.retryDelay || 1000, exponentialBackoff: config.exponentialBackoff !== false, retryableStatusCodes: config.retryableStatusCodes || [429, 500, 502, 503, 504], }; } async executeWithRetry(operation, context = 'operation') { var _a, _b, _c, _d; let lastError; for (let attempt = 0; attempt <= ((_b = (_a = this.config) === null || _a === void 0 ? void 0 : _a.maxRetries) !== null && _b !== void 0 ? _b : 1); attempt++) { try { const result = await operation(); if (attempt > 0) { logger_1.logger.info(`${context} succeeded on attempt ${attempt + 1}`); } return result; } catch (error) { lastError = error; if (attempt === ((_c = this.config) === null || _c === void 0 ? void 0 : _c.maxRetries)) { logger_1.logger.error(`${context} failed after ${((_d = this.config) === null || _d === void 0 ? void 0 : _d.maxRetries) + 1} attempts:`, lastError); break; } if (!this.isRetryableError(error)) { throw error; } const delay = this.calculateDelay(attempt); logger_1.logger.warn(`${context} failed on attempt ${attempt + 1}, retrying in ${delay}ms:`, lastError.message); await this.sleep(delay); } } throw lastError; } isRetryableError(error) { var _a, _b; // Check for specific error types if (error instanceof types_1.NonRetryableError) { return false; } if (error instanceof types_1.RetryableError) { return true; } if (error.name === 'TypeError' && error.message.includes('fetch')) { return true; } if (error.name === 'AbortError' || error.message.includes('timeout')) { return true; } // Check for HTTP status codes if (error.status || error.code) { const statusCode = error.status || error.code; return ((_b = (_a = this.config) === null || _a === void 0 ? void 0 : _a.retryableStatusCodes) === null || _b === void 0 ? void 0 : _b.includes(statusCode)) ? true : false; } // Default to non-retryable for unknown errors return false; } calculateDelay(attempt) { var _a, _b, _c, _d, _e; if (!((_a = this.config) === null || _a === void 0 ? void 0 : _a.exponentialBackoff)) { return (_c = (_b = this.config) === null || _b === void 0 ? void 0 : _b.retryDelay) !== null && _c !== void 0 ? _c : 1000; // Default to a fixed delay if exponential backoff is not enabled } const baseDelay = (_e = (_d = this.config) === null || _d === void 0 ? void 0 : _d.retryDelay) !== null && _e !== void 0 ? _e : 1000 * Math.pow(2, attempt); const jitter = Math.random() * 0.1 * baseDelay; return Math.floor(baseDelay + jitter); } sleep(ms) { return new Promise(resolve => setTimeout(resolve, ms)); } updateConfig(newConfig) { this.config = { ...this.config, ...newConfig }; } getConfig() { return { ...this.config }; } } exports.RetryHandler = RetryHandler; //# sourceMappingURL=expo.js.map