feat: add OpenRouter API client with free model support
This commit is contained in:
@@ -0,0 +1,26 @@
|
||||
import { describe, it, expect } from "vitest";
|
||||
import { OpenRouterClient } from "../openrouter";
|
||||
|
||||
describe("OpenRouterClient", () => {
|
||||
it("should create instance with API key", () => {
|
||||
const client = new OpenRouterClient("test-api-key");
|
||||
expect(client).toBeInstanceOf(OpenRouterClient);
|
||||
});
|
||||
|
||||
it("should have default free models list", () => {
|
||||
const client = new OpenRouterClient("test-api-key");
|
||||
const models = client.getFreeModels();
|
||||
expect(models).toContain("google/gemini-2.0-flash-exp:free");
|
||||
});
|
||||
|
||||
it("should have available model providers", () => {
|
||||
const client = new OpenRouterClient("test-api-key");
|
||||
const providers = client.getProviders();
|
||||
expect(providers).toContain("openai");
|
||||
expect(providers).toContain("google");
|
||||
expect(providers).toContain("anthropic");
|
||||
expect(providers).toContain("deepseek");
|
||||
expect(providers).toContain("meta");
|
||||
expect(providers).toContain("xai");
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,60 @@
|
||||
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<unknown> {
|
||||
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();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user