type Message = { role: "system" | "user" | "assistant"; content: string; }; type OpenRouterConfig = { baseURL?: string; defaultModel?: string; }; export class OpenRouterClient { private apiKey: string; private baseURL: string; private defaultModel: string; private freeModels = [ "google/gemini-2.0-flash-exp:free", "deepseek/deepseek-chat:free", "meta/llama-3.3-70b-instruct:free", ]; private providers = ["openai", "google", "anthropic", "deepseek", "meta", "xai"]; constructor(apiKey: string, config?: OpenRouterConfig) { this.apiKey = apiKey; this.baseURL = config?.baseURL ?? "https://openrouter.ai/api/v1"; this.defaultModel = config?.defaultModel ?? "google/gemini-2.0-flash-exp:free"; } getFreeModels(): string[] { return [...this.freeModels]; } getProviders(): string[] { return [...this.providers]; } async createChatCompletion( messages: Message[], model?: string ): Promise { const response = await fetch(`${this.baseURL}/chat/completions`, { method: "POST", headers: { "Content-Type": "application/json", Authorization: `Bearer ${this.apiKey}`, "HTTP-Referer": "https://aitrader.local", "X-Title": "AITrader", }, body: JSON.stringify({ model: model ?? this.defaultModel, messages, }), }); if (!response.ok) { throw new Error(`OpenRouter API error: ${response.status}`); } return response.json(); } }