UNPKG

ai.libx.js

Version:

Unified API bridge for various AI models (LLMs, image/video generation, TTS, STT) - stateless, edge-compatible

92 lines (76 loc) 2.34 kB
import { IProviderAdapter } from '../../types/provider'; import { ChatOptions, ChatResponse, StreamChunk, ProviderConfig } from '../../types'; import { validateApiKey } from '../../utils/validation'; /** * Base adapter class with shared functionality for all providers */ export abstract class BaseAdapter implements IProviderAdapter { protected config: ProviderConfig; constructor(config: ProviderConfig = {}) { this.config = config; } abstract get name(): string; abstract chat(options: ChatOptions): Promise<ChatResponse | AsyncIterable<StreamChunk>>; /** * Get API key from options or config */ protected getApiKey(options: ChatOptions): string { const apiKey = options.apiKey || this.config.apiKey; return validateApiKey(apiKey, this.name); } /** * Get base URL from options or config, with default fallback */ protected getBaseUrl(defaultUrl: string): string { return this.config.baseUrl || defaultUrl; } /** * Create headers for API request */ protected createHeaders(apiKey: string, additionalHeaders: Record<string, string> = {}): Record<string, string> { return { 'Content-Type': 'application/json', ...additionalHeaders, }; } /** * Handle fetch errors consistently */ protected async handleFetchError(response: Response, provider: string): Promise<never> { let errorData: any; let errorMessage: string; try { errorData = await response.json(); errorMessage = errorData.error?.message || errorData.message || response.statusText; } catch { errorMessage = response.statusText || 'Unknown error'; errorData = {}; } const error: any = new Error(errorMessage); error.status = response.status; error.statusCode = response.status; error.error = errorData.error || errorData; // Extract retry-after header for rate limits if (response.status === 429) { const retryAfter = response.headers.get('retry-after'); if (retryAfter) { error.retryAfter = parseInt(retryAfter, 10); } } throw error; } /** * Make a fetch request with error handling */ protected async fetchWithErrorHandling( url: string, options: RequestInit, provider: string ): Promise<Response> { const response = await fetch(url, options); if (!response.ok) { await this.handleFetchError(response, provider); } return response; } }