🎉 first commit

This commit is contained in:
LIlGG
2025-09-24 13:06:25 +08:00
commit 1f4fb103e9
409 changed files with 61222 additions and 0 deletions

View File

@@ -0,0 +1,117 @@
import { createAmazonBedrock } from '@ai-sdk/amazon-bedrock';
import { type LanguageModel } from 'ai';
import { BaseProvider } from '~/lib/modules/llm/base-provider';
import type { ModelInfo } from '~/lib/modules/llm/types';
import type { IProviderSetting } from '~/types/model';
interface AWSBedRockConfig {
region: string;
accessKeyId: string;
secretAccessKey: string;
sessionToken?: string;
}
export default class AmazonBedrockProvider extends BaseProvider {
name = 'AmazonBedrock';
getApiKeyLink = 'https://console.aws.amazon.com/iam/home';
config = {
apiTokenKey: 'AWS_BEDROCK_CONFIG',
};
staticModels: ModelInfo[] = [
{
name: 'anthropic.claude-3-5-sonnet-20241022-v2:0',
label: 'Claude 3.5 Sonnet v2 (Bedrock)',
provider: 'AmazonBedrock',
maxTokenAllowed: 200000,
},
{
name: 'anthropic.claude-3-5-sonnet-20240620-v1:0',
label: 'Claude 3.5 Sonnet (Bedrock)',
provider: 'AmazonBedrock',
maxTokenAllowed: 4096,
},
{
name: 'anthropic.claude-3-sonnet-20240229-v1:0',
label: 'Claude 3 Sonnet (Bedrock)',
provider: 'AmazonBedrock',
maxTokenAllowed: 4096,
},
{
name: 'anthropic.claude-3-haiku-20240307-v1:0',
label: 'Claude 3 Haiku (Bedrock)',
provider: 'AmazonBedrock',
maxTokenAllowed: 4096,
},
{
name: 'amazon.nova-pro-v1:0',
label: 'Amazon Nova Pro (Bedrock)',
provider: 'AmazonBedrock',
maxTokenAllowed: 5120,
},
{
name: 'amazon.nova-lite-v1:0',
label: 'Amazon Nova Lite (Bedrock)',
provider: 'AmazonBedrock',
maxTokenAllowed: 5120,
},
{
name: 'mistral.mistral-large-2402-v1:0',
label: 'Mistral Large 24.02 (Bedrock)',
provider: 'AmazonBedrock',
maxTokenAllowed: 8192,
},
];
private _parseAndValidateConfig(apiKey: string): AWSBedRockConfig {
let parsedConfig: AWSBedRockConfig;
try {
parsedConfig = JSON.parse(apiKey);
} catch {
throw new Error(
'Invalid AWS Bedrock configuration format. Please provide a valid JSON string containing region, accessKeyId, and secretAccessKey.',
);
}
const { region, accessKeyId, secretAccessKey, sessionToken } = parsedConfig;
if (!region || !accessKeyId || !secretAccessKey) {
throw new Error(
'Missing required AWS credentials. Configuration must include region, accessKeyId, and secretAccessKey.',
);
}
return {
region,
accessKeyId,
secretAccessKey,
...(sessionToken && { sessionToken }),
};
}
getModelInstance(options: {
model: string;
apiKeys?: Record<string, string>;
providerSettings?: Record<string, IProviderSetting>;
}): LanguageModel {
const { model, apiKeys, providerSettings } = options;
const { apiKey } = this.getProviderBaseUrlAndKey({
apiKeys,
providerSettings: providerSettings?.[this.name],
defaultBaseUrlKey: '',
defaultApiTokenKey: 'AWS_BEDROCK_CONFIG',
});
if (!apiKey) {
throw new Error(`Missing API key for ${this.name} provider`);
}
const config = this._parseAndValidateConfig(apiKey);
const bedrock = createAmazonBedrock(config);
return bedrock(model);
}
}

View File

@@ -0,0 +1,95 @@
import { createAnthropic } from '@ai-sdk/anthropic';
import type { LanguageModel } from 'ai';
import { BaseProvider } from '~/lib/modules/llm/base-provider';
import type { ModelInfo } from '~/lib/modules/llm/types';
import type { IProviderSetting } from '~/types/model';
export default class AnthropicProvider extends BaseProvider {
name = 'Anthropic';
getApiKeyLink = 'https://console.anthropic.com/settings/keys';
config = {
apiTokenKey: 'ANTHROPIC_API_KEY',
};
staticModels: ModelInfo[] = [
{
name: 'claude-3-7-sonnet-20250219',
label: 'Claude 3.7 Sonnet',
provider: 'Anthropic',
maxTokenAllowed: 8000,
},
{
name: 'claude-3-5-sonnet-latest',
label: 'Claude 3.5 Sonnet (new)',
provider: 'Anthropic',
maxTokenAllowed: 8000,
},
{
name: 'claude-3-5-sonnet-20240620',
label: 'Claude 3.5 Sonnet (old)',
provider: 'Anthropic',
maxTokenAllowed: 8000,
},
{
name: 'claude-3-5-haiku-latest',
label: 'Claude 3.5 Haiku (new)',
provider: 'Anthropic',
maxTokenAllowed: 8000,
},
{ name: 'claude-3-opus-latest', label: 'Claude 3 Opus', provider: 'Anthropic', maxTokenAllowed: 8000 },
{ name: 'claude-3-sonnet-20240229', label: 'Claude 3 Sonnet', provider: 'Anthropic', maxTokenAllowed: 8000 },
{ name: 'claude-3-haiku-20240307', label: 'Claude 3 Haiku', provider: 'Anthropic', maxTokenAllowed: 8000 },
];
async getDynamicModels(apiKeys?: Record<string, string>, settings?: IProviderSetting): Promise<ModelInfo[]> {
const { apiKey } = this.getProviderBaseUrlAndKey({
apiKeys,
providerSettings: settings,
defaultBaseUrlKey: '',
defaultApiTokenKey: 'ANTHROPIC_API_KEY',
});
if (!apiKey) {
throw `Missing Api Key configuration for ${this.name} provider`;
}
const response = await fetch(`https://api.anthropic.com/v1/models`, {
headers: {
'x-api-key': `${apiKey}`,
'anthropic-version': '2023-06-01',
},
});
const res = (await response.json()) as any;
const staticModelIds = this.staticModels.map((m) => m.name);
const data = res.data.filter((model: any) => model.type === 'model' && !staticModelIds.includes(model.id));
return data.map((m: any) => ({
name: m.id,
label: `${m.display_name}`,
provider: this.name,
maxTokenAllowed: 32000,
}));
}
getModelInstance: (options: {
model: string;
apiKeys?: Record<string, string>;
providerSettings?: Record<string, IProviderSetting>;
}) => LanguageModel = (options) => {
const { apiKeys, providerSettings, model } = options;
const { apiKey } = this.getProviderBaseUrlAndKey({
apiKeys,
providerSettings,
defaultBaseUrlKey: '',
defaultApiTokenKey: 'ANTHROPIC_API_KEY',
});
const anthropic = createAnthropic({
apiKey,
});
return anthropic(model);
};
}

View File

@@ -0,0 +1,52 @@
import { createCohere } from '@ai-sdk/cohere';
import type { LanguageModel } from 'ai';
import { BaseProvider } from '~/lib/modules/llm/base-provider';
import type { ModelInfo } from '~/lib/modules/llm/types';
import type { IProviderSetting } from '~/types/model';
export default class CohereProvider extends BaseProvider {
name = 'Cohere';
getApiKeyLink = 'https://dashboard.cohere.com/api-keys';
config = {
apiTokenKey: 'COHERE_API_KEY',
};
staticModels: ModelInfo[] = [
{ name: 'command-r-plus-08-2024', label: 'Command R plus Latest', provider: 'Cohere', maxTokenAllowed: 4096 },
{ name: 'command-r-08-2024', label: 'Command R Latest', provider: 'Cohere', maxTokenAllowed: 4096 },
{ name: 'command-r-plus', label: 'Command R plus', provider: 'Cohere', maxTokenAllowed: 4096 },
{ name: 'command-r', label: 'Command R', provider: 'Cohere', maxTokenAllowed: 4096 },
{ name: 'command', label: 'Command', provider: 'Cohere', maxTokenAllowed: 4096 },
{ name: 'command-nightly', label: 'Command Nightly', provider: 'Cohere', maxTokenAllowed: 4096 },
{ name: 'command-light', label: 'Command Light', provider: 'Cohere', maxTokenAllowed: 4096 },
{ name: 'command-light-nightly', label: 'Command Light Nightly', provider: 'Cohere', maxTokenAllowed: 4096 },
{ name: 'c4ai-aya-expanse-8b', label: 'c4AI Aya Expanse 8b', provider: 'Cohere', maxTokenAllowed: 4096 },
{ name: 'c4ai-aya-expanse-32b', label: 'c4AI Aya Expanse 32b', provider: 'Cohere', maxTokenAllowed: 4096 },
];
getModelInstance(options: {
model: string;
apiKeys?: Record<string, string>;
providerSettings?: Record<string, IProviderSetting>;
}): LanguageModel {
const { model, apiKeys, providerSettings } = options;
const { apiKey } = this.getProviderBaseUrlAndKey({
apiKeys,
providerSettings: providerSettings?.[this.name],
defaultBaseUrlKey: '',
defaultApiTokenKey: 'COHERE_API_KEY',
});
if (!apiKey) {
throw new Error(`Missing API key for ${this.name} provider`);
}
const cohere = createCohere({
apiKey,
});
return cohere(model);
}
}

View File

@@ -0,0 +1,45 @@
import { createDeepSeek } from '@ai-sdk/deepseek';
import type { LanguageModel } from 'ai';
import { BaseProvider } from '~/lib/modules/llm/base-provider';
import type { ModelInfo } from '~/lib/modules/llm/types';
import type { IProviderSetting } from '~/types/model';
export default class DeepseekProvider extends BaseProvider {
name = 'Deepseek';
getApiKeyLink = 'https://platform.deepseek.com/apiKeys';
config = {
apiTokenKey: 'DEEPSEEK_API_KEY',
};
staticModels: ModelInfo[] = [
{ name: 'deepseek-coder', label: 'Deepseek-Coder', provider: 'Deepseek', maxTokenAllowed: 8000 },
{ name: 'deepseek-chat', label: 'Deepseek-Chat', provider: 'Deepseek', maxTokenAllowed: 8000 },
{ name: 'deepseek-reasoner', label: 'Deepseek-Reasoner', provider: 'Deepseek', maxTokenAllowed: 8000 },
];
getModelInstance(options: {
model: string;
apiKeys?: Record<string, string>;
providerSettings?: Record<string, IProviderSetting>;
}): LanguageModel {
const { model, apiKeys, providerSettings } = options;
const { apiKey } = this.getProviderBaseUrlAndKey({
apiKeys,
providerSettings: providerSettings?.[this.name],
defaultBaseUrlKey: '',
defaultApiTokenKey: 'DEEPSEEK_API_KEY',
});
if (!apiKey) {
throw new Error(`Missing API key for ${this.name} provider`);
}
const deepseek = createDeepSeek({
apiKey,
});
return deepseek(model);
}
}

View File

@@ -0,0 +1,51 @@
import { createOpenAI } from '@ai-sdk/openai';
import type { LanguageModel } from 'ai';
import { BaseProvider } from '~/lib/modules/llm/base-provider';
import type { ModelInfo } from '~/lib/modules/llm/types';
import type { IProviderSetting } from '~/types/model';
export default class GithubProvider extends BaseProvider {
name = 'Github';
getApiKeyLink = 'https://github.com/settings/personal-access-tokens';
config = {
apiTokenKey: 'GITHUB_API_KEY',
};
// find more in https://github.com/marketplace?type=models
staticModels: ModelInfo[] = [
{ name: 'gpt-4o', label: 'GPT-4o', provider: 'Github', maxTokenAllowed: 8000 },
{ name: 'o1', label: 'o1-preview', provider: 'Github', maxTokenAllowed: 100000 },
{ name: 'o1-mini', label: 'o1-mini', provider: 'Github', maxTokenAllowed: 8000 },
{ name: 'gpt-4o-mini', label: 'GPT-4o Mini', provider: 'Github', maxTokenAllowed: 8000 },
{ name: 'gpt-4-turbo', label: 'GPT-4 Turbo', provider: 'Github', maxTokenAllowed: 8000 },
{ name: 'gpt-4', label: 'GPT-4', provider: 'Github', maxTokenAllowed: 8000 },
{ name: 'gpt-3.5-turbo', label: 'GPT-3.5 Turbo', provider: 'Github', maxTokenAllowed: 8000 },
];
getModelInstance(options: {
model: string;
apiKeys?: Record<string, string>;
providerSettings?: Record<string, IProviderSetting>;
}): LanguageModel {
const { model, apiKeys, providerSettings } = options;
const { apiKey } = this.getProviderBaseUrlAndKey({
apiKeys,
providerSettings: providerSettings?.[this.name],
defaultBaseUrlKey: '',
defaultApiTokenKey: 'GITHUB_API_KEY',
});
if (!apiKey) {
throw new Error(`Missing API key for ${this.name} provider`);
}
const openai = createOpenAI({
baseURL: 'https://models.inference.ai.azure.com',
apiKey,
});
return openai(model);
}
}

View File

@@ -0,0 +1,86 @@
import { createGoogleGenerativeAI } from '@ai-sdk/google';
import type { LanguageModel } from 'ai';
import { BaseProvider } from '~/lib/modules/llm/base-provider';
import type { ModelInfo } from '~/lib/modules/llm/types';
import type { IProviderSetting } from '~/types/model';
export default class GoogleProvider extends BaseProvider {
name = 'Google';
getApiKeyLink = 'https://aistudio.google.com/app/apikey';
config = {
apiTokenKey: 'GOOGLE_GENERATIVE_AI_API_KEY',
};
staticModels: ModelInfo[] = [
{ name: 'gemini-1.5-flash-latest', label: 'Gemini 1.5 Flash', provider: 'Google', maxTokenAllowed: 8192 },
{
name: 'gemini-2.0-flash-thinking-exp-01-21',
label: 'Gemini 2.0 Flash-thinking-exp-01-21',
provider: 'Google',
maxTokenAllowed: 65536,
},
{ name: 'gemini-2.0-flash-exp', label: 'Gemini 2.0 Flash', provider: 'Google', maxTokenAllowed: 8192 },
{ name: 'gemini-1.5-flash-002', label: 'Gemini 1.5 Flash-002', provider: 'Google', maxTokenAllowed: 8192 },
{ name: 'gemini-1.5-flash-8b', label: 'Gemini 1.5 Flash-8b', provider: 'Google', maxTokenAllowed: 8192 },
{ name: 'gemini-1.5-pro-latest', label: 'Gemini 1.5 Pro', provider: 'Google', maxTokenAllowed: 8192 },
{ name: 'gemini-1.5-pro-002', label: 'Gemini 1.5 Pro-002', provider: 'Google', maxTokenAllowed: 8192 },
{ name: 'gemini-exp-1206', label: 'Gemini exp-1206', provider: 'Google', maxTokenAllowed: 8192 },
];
async getDynamicModels(apiKeys?: Record<string, string>, settings?: IProviderSetting): Promise<ModelInfo[]> {
const { apiKey } = this.getProviderBaseUrlAndKey({
apiKeys,
providerSettings: settings,
defaultBaseUrlKey: '',
defaultApiTokenKey: 'GOOGLE_GENERATIVE_AI_API_KEY',
});
if (!apiKey) {
throw `Missing Api Key configuration for ${this.name} provider`;
}
const response = await fetch(`https://generativelanguage.googleapis.com/v1beta/models?key=${apiKey}`, {
headers: {
// biome-ignore lint: ignore Content-Type header
['Content-Type']: 'application/json',
},
});
const res = (await response.json()) as any;
const data = res.models.filter((model: any) => model.outputTokenLimit > 8000);
return data.map((m: any) => ({
name: m.name.replace('models/', ''),
label: `${m.displayName} - context ${Math.floor((m.inputTokenLimit + m.outputTokenLimit) / 1000) + 'k'}`,
provider: this.name,
maxTokenAllowed: m.inputTokenLimit + m.outputTokenLimit || 8000,
}));
}
getModelInstance(options: {
model: string;
apiKeys?: Record<string, string>;
providerSettings?: Record<string, IProviderSetting>;
}): LanguageModel {
const { model, apiKeys, providerSettings } = options;
const { apiKey } = this.getProviderBaseUrlAndKey({
apiKeys,
providerSettings: providerSettings?.[this.name],
defaultBaseUrlKey: '',
defaultApiTokenKey: 'GOOGLE_GENERATIVE_AI_API_KEY',
});
if (!apiKey) {
throw new Error(`Missing API key for ${this.name} provider`);
}
const google = createGoogleGenerativeAI({
apiKey,
});
return google(model);
}
}

View File

@@ -0,0 +1,87 @@
import { createOpenAI } from '@ai-sdk/openai';
import type { LanguageModel } from 'ai';
import { BaseProvider } from '~/lib/modules/llm/base-provider';
import type { ModelInfo } from '~/lib/modules/llm/types';
import type { IProviderSetting } from '~/types/model';
export default class GroqProvider extends BaseProvider {
name = 'Groq';
getApiKeyLink = 'https://console.groq.com/keys';
config = {
apiTokenKey: 'GROQ_API_KEY',
};
staticModels: ModelInfo[] = [
{ name: 'llama-3.1-8b-instant', label: 'Llama 3.1 8b (Groq)', provider: 'Groq', maxTokenAllowed: 8000 },
{ name: 'llama-3.2-11b-vision-preview', label: 'Llama 3.2 11b (Groq)', provider: 'Groq', maxTokenAllowed: 8000 },
{ name: 'llama-3.2-90b-vision-preview', label: 'Llama 3.2 90b (Groq)', provider: 'Groq', maxTokenAllowed: 8000 },
{ name: 'llama-3.2-3b-preview', label: 'Llama 3.2 3b (Groq)', provider: 'Groq', maxTokenAllowed: 8000 },
{ name: 'llama-3.2-1b-preview', label: 'Llama 3.2 1b (Groq)', provider: 'Groq', maxTokenAllowed: 8000 },
{ name: 'llama-3.3-70b-versatile', label: 'Llama 3.3 70b (Groq)', provider: 'Groq', maxTokenAllowed: 8000 },
{
name: 'deepseek-r1-distill-llama-70b',
label: 'Deepseek R1 Distill Llama 70b (Groq)',
provider: 'Groq',
maxTokenAllowed: 131072,
},
];
async getDynamicModels(apiKeys?: Record<string, string>, settings?: IProviderSetting): Promise<ModelInfo[]> {
const { apiKey } = this.getProviderBaseUrlAndKey({
apiKeys,
providerSettings: settings,
defaultBaseUrlKey: '',
defaultApiTokenKey: 'GROQ_API_KEY',
});
if (!apiKey) {
throw `Missing Api Key configuration for ${this.name} provider`;
}
const response = await fetch(`https://api.groq.com/openai/v1/models`, {
headers: {
Authorization: `Bearer ${apiKey}`,
},
});
const res = (await response.json()) as any;
const data = res.data.filter(
(model: any) => model.object === 'model' && model.active && model.context_window > 8000,
);
return data.map((m: any) => ({
name: m.id,
label: `${m.id} - context ${m.context_window ? Math.floor(m.context_window / 1000) + 'k' : 'N/A'} [ by ${m.owned_by}]`,
provider: this.name,
maxTokenAllowed: m.context_window || 8000,
}));
}
getModelInstance(options: {
model: string;
apiKeys?: Record<string, string>;
providerSettings?: Record<string, IProviderSetting>;
}): LanguageModel {
const { model, apiKeys, providerSettings } = options;
const { apiKey } = this.getProviderBaseUrlAndKey({
apiKeys,
providerSettings: providerSettings?.[this.name],
defaultBaseUrlKey: '',
defaultApiTokenKey: 'GROQ_API_KEY',
});
if (!apiKey) {
throw new Error(`Missing API key for ${this.name} provider`);
}
const openai = createOpenAI({
baseURL: 'https://api.groq.com/openai/v1',
apiKey,
});
return openai(model);
}
}

View File

@@ -0,0 +1,109 @@
import { createOpenAI } from '@ai-sdk/openai';
import type { LanguageModel } from 'ai';
import { BaseProvider } from '~/lib/modules/llm/base-provider';
import type { ModelInfo } from '~/lib/modules/llm/types';
import type { IProviderSetting } from '~/types/model';
export default class HuggingFaceProvider extends BaseProvider {
name = 'HuggingFace';
getApiKeyLink = 'https://huggingface.co/settings/tokens';
config = {
apiTokenKey: 'HuggingFace_API_KEY',
};
staticModels: ModelInfo[] = [
{
name: 'Qwen/Qwen2.5-Coder-32B-Instruct',
label: 'Qwen2.5-Coder-32B-Instruct (HuggingFace)',
provider: 'HuggingFace',
maxTokenAllowed: 8000,
},
{
name: '01-ai/Yi-1.5-34B-Chat',
label: 'Yi-1.5-34B-Chat (HuggingFace)',
provider: 'HuggingFace',
maxTokenAllowed: 8000,
},
{
name: 'codellama/CodeLlama-34b-Instruct-hf',
label: 'CodeLlama-34b-Instruct (HuggingFace)',
provider: 'HuggingFace',
maxTokenAllowed: 8000,
},
{
name: 'NousResearch/Hermes-3-Llama-3.1-8B',
label: 'Hermes-3-Llama-3.1-8B (HuggingFace)',
provider: 'HuggingFace',
maxTokenAllowed: 8000,
},
{
name: 'Qwen/Qwen2.5-Coder-32B-Instruct',
label: 'Qwen2.5-Coder-32B-Instruct (HuggingFace)',
provider: 'HuggingFace',
maxTokenAllowed: 8000,
},
{
name: 'Qwen/Qwen2.5-72B-Instruct',
label: 'Qwen2.5-72B-Instruct (HuggingFace)',
provider: 'HuggingFace',
maxTokenAllowed: 8000,
},
{
name: 'meta-llama/Llama-3.1-70B-Instruct',
label: 'Llama-3.1-70B-Instruct (HuggingFace)',
provider: 'HuggingFace',
maxTokenAllowed: 8000,
},
{
name: 'meta-llama/Llama-3.1-405B',
label: 'Llama-3.1-405B (HuggingFace)',
provider: 'HuggingFace',
maxTokenAllowed: 8000,
},
{
name: '01-ai/Yi-1.5-34B-Chat',
label: 'Yi-1.5-34B-Chat (HuggingFace)',
provider: 'HuggingFace',
maxTokenAllowed: 8000,
},
{
name: 'codellama/CodeLlama-34b-Instruct-hf',
label: 'CodeLlama-34b-Instruct (HuggingFace)',
provider: 'HuggingFace',
maxTokenAllowed: 8000,
},
{
name: 'NousResearch/Hermes-3-Llama-3.1-8B',
label: 'Hermes-3-Llama-3.1-8B (HuggingFace)',
provider: 'HuggingFace',
maxTokenAllowed: 8000,
},
];
getModelInstance(options: {
model: string;
apiKeys?: Record<string, string>;
providerSettings?: Record<string, IProviderSetting>;
}): LanguageModel {
const { model, apiKeys, providerSettings } = options;
const { apiKey } = this.getProviderBaseUrlAndKey({
apiKeys,
providerSettings: providerSettings?.[this.name],
defaultBaseUrlKey: '',
defaultApiTokenKey: 'HuggingFace_API_KEY',
});
if (!apiKey) {
throw new Error(`Missing API key for ${this.name} provider`);
}
const openai = createOpenAI({
baseURL: 'https://api-inference.huggingface.co/v1/',
apiKey,
});
return openai(model);
}
}

View File

@@ -0,0 +1,104 @@
import { createOpenAI } from '@ai-sdk/openai';
import type { LanguageModel } from 'ai';
import { BaseProvider } from '~/lib/modules/llm/base-provider';
import type { ModelInfo } from '~/lib/modules/llm/types';
import type { IProviderSetting } from '~/types/model';
export default class HyperbolicProvider extends BaseProvider {
name = 'Hyperbolic';
getApiKeyLink = 'https://app.hyperbolic.xyz/settings';
config = {
apiTokenKey: 'HYPERBOLIC_API_KEY',
};
staticModels: ModelInfo[] = [
{
name: 'Qwen/Qwen2.5-Coder-32B-Instruct',
label: 'Qwen 2.5 Coder 32B Instruct',
provider: 'Hyperbolic',
maxTokenAllowed: 8192,
},
{
name: 'Qwen/Qwen2.5-72B-Instruct',
label: 'Qwen2.5-72B-Instruct',
provider: 'Hyperbolic',
maxTokenAllowed: 8192,
},
{
name: 'deepseek-ai/DeepSeek-V2.5',
label: 'DeepSeek-V2.5',
provider: 'Hyperbolic',
maxTokenAllowed: 8192,
},
{
name: 'Qwen/QwQ-32B-Preview',
label: 'QwQ-32B-Preview',
provider: 'Hyperbolic',
maxTokenAllowed: 8192,
},
{
name: 'Qwen/Qwen2-VL-72B-Instruct',
label: 'Qwen2-VL-72B-Instruct',
provider: 'Hyperbolic',
maxTokenAllowed: 8192,
},
];
async getDynamicModels(apiKeys?: Record<string, string>, settings?: IProviderSetting): Promise<ModelInfo[]> {
const { baseUrl: fetchBaseUrl, apiKey } = this.getProviderBaseUrlAndKey({
apiKeys,
providerSettings: settings,
defaultBaseUrlKey: '',
defaultApiTokenKey: 'HYPERBOLIC_API_KEY',
});
const baseUrl = fetchBaseUrl || 'https://api.hyperbolic.xyz/v1';
if (!apiKey) {
throw `Missing Api Key configuration for ${this.name} provider`;
}
const response = await fetch(`${baseUrl}/models`, {
headers: {
Authorization: `Bearer ${apiKey}`,
},
});
const res = (await response.json()) as any;
const data = res.data.filter((model: any) => model.object === 'model' && model.supports_chat);
return data.map((m: any) => ({
name: m.id,
label: `${m.id} - context ${m.context_length ? Math.floor(m.context_length / 1000) + 'k' : 'N/A'}`,
provider: this.name,
maxTokenAllowed: m.context_length || 8000,
}));
}
getModelInstance(options: {
model: string;
apiKeys?: Record<string, string>;
providerSettings?: Record<string, IProviderSetting>;
}): LanguageModel {
const { model, apiKeys, providerSettings } = options;
const { apiKey } = this.getProviderBaseUrlAndKey({
apiKeys,
providerSettings: providerSettings?.[this.name],
defaultBaseUrlKey: '',
defaultApiTokenKey: 'HYPERBOLIC_API_KEY',
});
if (!apiKey) {
throw `Missing Api Key configuration for ${this.name} provider`;
}
const openai = createOpenAI({
baseURL: 'https://api.hyperbolic.xyz/v1/',
apiKey,
});
return openai(model);
}
}

View File

@@ -0,0 +1,87 @@
import { createOpenAI } from '@ai-sdk/openai';
import type { LanguageModel } from 'ai';
import { BaseProvider } from '~/lib/modules/llm/base-provider';
import type { ModelInfo } from '~/lib/modules/llm/types';
import type { IProviderSetting } from '~/types/model';
import { logger } from '~/utils/logger';
export default class LMStudioProvider extends BaseProvider {
name = 'LMStudio';
getApiKeyLink = 'https://lmstudio.ai/';
labelForGetApiKey = 'Get LMStudio';
icon = 'i-ph:cloud-arrow-down';
config = {
baseUrlKey: 'LMSTUDIO_API_BASE_URL',
baseUrl: 'http://localhost:1234/',
};
staticModels: ModelInfo[] = [];
async getDynamicModels(apiKeys?: Record<string, string>, settings?: IProviderSetting): Promise<ModelInfo[]> {
let { baseUrl } = this.getProviderBaseUrlAndKey({
apiKeys,
providerSettings: settings,
defaultBaseUrlKey: 'LMSTUDIO_API_BASE_URL',
defaultApiTokenKey: '',
});
if (!baseUrl) {
throw new Error('No baseUrl found for LMStudio provider');
}
if (typeof window === 'undefined') {
/*
* Running in Server
* Backend: Check if we're running in Docker
*/
const isDocker = process?.env?.RUNNING_IN_DOCKER === 'true';
baseUrl = isDocker ? baseUrl.replace('localhost', 'host.docker.internal') : baseUrl;
baseUrl = isDocker ? baseUrl.replace('127.0.0.1', 'host.docker.internal') : baseUrl;
}
const response = await fetch(`${baseUrl}/v1/models`);
const data = (await response.json()) as { data: Array<{ id: string }> };
return data.data.map((model) => ({
name: model.id,
label: model.id,
provider: this.name,
maxTokenAllowed: 8000,
}));
}
getModelInstance: (options: {
model: string;
apiKeys?: Record<string, string>;
providerSettings?: Record<string, IProviderSetting>;
}) => LanguageModel = (options) => {
const { apiKeys, providerSettings, model } = options;
let { baseUrl } = this.getProviderBaseUrlAndKey({
apiKeys,
providerSettings: providerSettings?.[this.name],
defaultBaseUrlKey: 'LMSTUDIO_API_BASE_URL',
defaultApiTokenKey: '',
});
if (!baseUrl) {
throw new Error('No baseUrl found for LMStudio provider');
}
const isDocker = process?.env?.RUNNING_IN_DOCKER === 'true';
if (typeof window === 'undefined') {
baseUrl = isDocker ? baseUrl.replace('localhost', 'host.docker.internal') : baseUrl;
baseUrl = isDocker ? baseUrl.replace('127.0.0.1', 'host.docker.internal') : baseUrl;
}
logger.debug('LMStudio Base Url used: ', baseUrl);
const lmstudio = createOpenAI({
baseURL: `${baseUrl}/v1`,
apiKey: '',
});
return lmstudio(model);
};
}

View File

@@ -0,0 +1,51 @@
import { createMistral } from '@ai-sdk/mistral';
import type { LanguageModel } from 'ai';
import { BaseProvider } from '~/lib/modules/llm/base-provider';
import type { ModelInfo } from '~/lib/modules/llm/types';
import type { IProviderSetting } from '~/types/model';
export default class MistralProvider extends BaseProvider {
name = 'Mistral';
getApiKeyLink = 'https://console.mistral.ai/api-keys/';
config = {
apiTokenKey: 'MISTRAL_API_KEY',
};
staticModels: ModelInfo[] = [
{ name: 'open-mistral-7b', label: 'Mistral 7B', provider: 'Mistral', maxTokenAllowed: 8000 },
{ name: 'open-mixtral-8x7b', label: 'Mistral 8x7B', provider: 'Mistral', maxTokenAllowed: 8000 },
{ name: 'open-mixtral-8x22b', label: 'Mistral 8x22B', provider: 'Mistral', maxTokenAllowed: 8000 },
{ name: 'open-codestral-mamba', label: 'Codestral Mamba', provider: 'Mistral', maxTokenAllowed: 8000 },
{ name: 'open-mistral-nemo', label: 'Mistral Nemo', provider: 'Mistral', maxTokenAllowed: 8000 },
{ name: 'ministral-8b-latest', label: 'Mistral 8B', provider: 'Mistral', maxTokenAllowed: 8000 },
{ name: 'mistral-small-latest', label: 'Mistral Small', provider: 'Mistral', maxTokenAllowed: 8000 },
{ name: 'codestral-latest', label: 'Codestral', provider: 'Mistral', maxTokenAllowed: 8000 },
{ name: 'mistral-large-latest', label: 'Mistral Large Latest', provider: 'Mistral', maxTokenAllowed: 8000 },
];
getModelInstance(options: {
model: string;
apiKeys?: Record<string, string>;
providerSettings?: Record<string, IProviderSetting>;
}): LanguageModel {
const { model, apiKeys, providerSettings } = options;
const { apiKey } = this.getProviderBaseUrlAndKey({
apiKeys,
providerSettings: providerSettings?.[this.name],
defaultBaseUrlKey: '',
defaultApiTokenKey: 'MISTRAL_API_KEY',
});
if (!apiKey) {
throw new Error(`Missing API key for ${this.name} provider`);
}
const mistral = createMistral({
apiKey,
});
return mistral(model);
}
}

View File

@@ -0,0 +1,113 @@
import type { LanguageModel } from 'ai';
import { createOllama } from 'ollama-ai-provider-v2';
import { BaseProvider } from '~/lib/modules/llm/base-provider';
import type { ModelInfo } from '~/lib/modules/llm/types';
import type { IProviderSetting } from '~/types/model';
import { logger } from '~/utils/logger';
interface OllamaModelDetails {
parent_model: string;
format: string;
family: string;
families: string[];
parameter_size: string;
quantization_level: string;
}
export interface OllamaModel {
name: string;
model: string;
modified_at: string;
size: number;
digest: string;
details: OllamaModelDetails;
}
export interface OllamaApiResponse {
models: OllamaModel[];
}
export default class OllamaProvider extends BaseProvider {
name = 'Ollama';
getApiKeyLink = 'https://ollama.com/download';
labelForGetApiKey = 'Download Ollama';
icon = 'i-ph:cloud-arrow-down';
config = {
baseUrlKey: 'OLLAMA_API_BASE_URL',
};
staticModels: ModelInfo[] = [];
getDefaultNumCtx(): number {
return process.env.DEFAULT_NUM_CTX ? parseInt(process.env.DEFAULT_NUM_CTX, 10) : 32768;
}
async getDynamicModels(apiKeys?: Record<string, string>, settings?: IProviderSetting): Promise<ModelInfo[]> {
let { baseUrl } = this.getProviderBaseUrlAndKey({
apiKeys,
providerSettings: settings,
defaultBaseUrlKey: 'OLLAMA_API_BASE_URL',
defaultApiTokenKey: '',
});
if (!baseUrl) {
throw new Error('No baseUrl found for OLLAMA provider');
}
if (typeof window === 'undefined') {
/*
* Running in Server
* Backend: Check if we're running in Docker
*/
const isDocker = process?.env?.RUNNING_IN_DOCKER === 'true';
baseUrl = isDocker ? baseUrl.replace('localhost', 'host.docker.internal') : baseUrl;
baseUrl = isDocker ? baseUrl.replace('127.0.0.1', 'host.docker.internal') : baseUrl;
}
const response = await fetch(`${baseUrl}/api/tags`);
const data = (await response.json()) as OllamaApiResponse;
// console.log({ ollamamodels: data.models });
return data.models.map((model: OllamaModel) => ({
name: model.name,
label: `${model.name} (${model.details.parameter_size})`,
provider: this.name,
maxTokenAllowed: 8000,
}));
}
getModelInstance: (options: {
model: string;
apiKeys?: Record<string, string>;
providerSettings?: Record<string, IProviderSetting>;
}) => LanguageModel = (options) => {
const { apiKeys, providerSettings, model } = options;
let { baseUrl } = this.getProviderBaseUrlAndKey({
apiKeys,
providerSettings: providerSettings?.[this.name],
defaultBaseUrlKey: 'OLLAMA_API_BASE_URL',
defaultApiTokenKey: '',
});
// Backend: Check if we're running in Docker
if (!baseUrl) {
throw new Error('No baseUrl found for OLLAMA provider');
}
const isDocker = process?.env?.RUNNING_IN_DOCKER === 'true';
baseUrl = isDocker ? baseUrl.replace('localhost', 'host.docker.internal') : baseUrl;
baseUrl = isDocker ? baseUrl.replace('127.0.0.1', 'host.docker.internal') : baseUrl;
logger.debug('Ollama Base Url used: ', baseUrl);
const ollama = createOllama({
baseURL: `${baseUrl}/api`,
});
return ollama(model);
};
}

View File

@@ -0,0 +1,128 @@
import { createOpenRouter } from '@openrouter/ai-sdk-provider';
import type { LanguageModel } from 'ai';
import { BaseProvider } from '~/lib/modules/llm/base-provider';
import type { ModelInfo } from '~/lib/modules/llm/types';
import type { IProviderSetting } from '~/types/model';
interface OpenRouterModel {
name: string;
id: string;
context_length: number;
pricing: {
prompt: number;
completion: number;
};
}
interface OpenRouterModelsResponse {
data: OpenRouterModel[];
}
export default class OpenRouterProvider extends BaseProvider {
name = 'OpenRouter';
getApiKeyLink = 'https://openrouter.ai/settings/keys';
config = {
apiTokenKey: 'OPEN_ROUTER_API_KEY',
};
staticModels: ModelInfo[] = [
{
name: 'anthropic/claude-3.5-sonnet',
label: 'Anthropic: Claude 3.5 Sonnet (OpenRouter)',
provider: 'OpenRouter',
maxTokenAllowed: 8000,
},
{
name: 'anthropic/claude-3-haiku',
label: 'Anthropic: Claude 3 Haiku (OpenRouter)',
provider: 'OpenRouter',
maxTokenAllowed: 8000,
},
{
name: 'deepseek/deepseek-coder',
label: 'Deepseek-Coder V2 236B (OpenRouter)',
provider: 'OpenRouter',
maxTokenAllowed: 8000,
},
{
name: 'google/gemini-flash-1.5',
label: 'Google Gemini Flash 1.5 (OpenRouter)',
provider: 'OpenRouter',
maxTokenAllowed: 8000,
},
{
name: 'google/gemini-pro-1.5',
label: 'Google Gemini Pro 1.5 (OpenRouter)',
provider: 'OpenRouter',
maxTokenAllowed: 8000,
},
{ name: 'x-ai/grok-beta', label: 'xAI Grok Beta (OpenRouter)', provider: 'OpenRouter', maxTokenAllowed: 8000 },
{
name: 'mistralai/mistral-nemo',
label: 'OpenRouter Mistral Nemo (OpenRouter)',
provider: 'OpenRouter',
maxTokenAllowed: 8000,
},
{
name: 'qwen/qwen-110b-chat',
label: 'OpenRouter Qwen 110b Chat (OpenRouter)',
provider: 'OpenRouter',
maxTokenAllowed: 8000,
},
{ name: 'cohere/command', label: 'Cohere Command (OpenRouter)', provider: 'OpenRouter', maxTokenAllowed: 4096 },
];
async getDynamicModels(
_apiKeys?: Record<string, string>,
_settings?: IProviderSetting,
_serverEnv: Record<string, string> = {},
): Promise<ModelInfo[]> {
try {
const response = await fetch('https://openrouter.ai/api/v1/models', {
headers: {
'Content-Type': 'application/json',
},
});
const data = (await response.json()) as OpenRouterModelsResponse;
return data.data
.sort((a, b) => a.name.localeCompare(b.name))
.map((m) => ({
name: m.id,
label: `${m.name} - in:$${(m.pricing.prompt * 1_000_000).toFixed(2)} out:$${(m.pricing.completion * 1_000_000).toFixed(2)} - context ${Math.floor(m.context_length / 1000)}k`,
provider: this.name,
maxTokenAllowed: 8000,
}));
} catch (error) {
console.error('Error getting OpenRouter models:', error);
return [];
}
}
getModelInstance(options: {
model: string;
apiKeys?: Record<string, string>;
providerSettings?: Record<string, IProviderSetting>;
}): LanguageModel {
const { model, apiKeys, providerSettings } = options;
const { apiKey } = this.getProviderBaseUrlAndKey({
apiKeys,
providerSettings: providerSettings?.[this.name],
defaultBaseUrlKey: '',
defaultApiTokenKey: 'OPEN_ROUTER_API_KEY',
});
if (!apiKey) {
throw new Error(`Missing API key for ${this.name} provider`);
}
const openRouter = createOpenRouter({
apiKey,
});
return openRouter.chat(model);
}
}

View File

@@ -0,0 +1,65 @@
import type { LanguageModel } from 'ai';
import { BaseProvider, getOpenAILikeModel } from '~/lib/modules/llm/base-provider';
import type { ModelInfo } from '~/lib/modules/llm/types';
import type { IProviderSetting } from '~/types/model';
export default class OpenAILikeProvider extends BaseProvider {
name = 'OpenAILike';
getApiKeyLink = undefined;
config = {
baseUrlKey: 'OPENAI_LIKE_API_BASE_URL',
apiTokenKey: 'OPENAI_LIKE_API_KEY',
};
staticModels: ModelInfo[] = [];
async getDynamicModels(apiKeys?: Record<string, string>, settings?: IProviderSetting): Promise<ModelInfo[]> {
const { baseUrl, apiKey } = this.getProviderBaseUrlAndKey({
apiKeys,
providerSettings: settings,
defaultBaseUrlKey: 'OPENAI_LIKE_API_BASE_URL',
defaultApiTokenKey: 'OPENAI_LIKE_API_KEY',
});
if (!baseUrl || !apiKey) {
return [];
}
const response = await fetch(`${baseUrl}/models`, {
headers: {
Authorization: `Bearer ${apiKey}`,
},
});
const res = (await response.json()) as any;
return res.data.map((model: any) => ({
name: model.id,
label: model.id,
provider: this.name,
maxTokenAllowed: 8000,
}));
}
getModelInstance(options: {
model: string;
apiKeys?: Record<string, string>;
providerSettings?: Record<string, IProviderSetting>;
}): LanguageModel {
const { model, apiKeys, providerSettings } = options;
const { baseUrl, apiKey } = this.getProviderBaseUrlAndKey({
apiKeys,
providerSettings: providerSettings?.[this.name],
defaultBaseUrlKey: 'OPENAI_LIKE_API_BASE_URL',
defaultApiTokenKey: 'OPENAI_LIKE_API_KEY',
});
if (!baseUrl || !apiKey) {
throw new Error(`Missing configuration for ${this.name} provider`);
}
return getOpenAILikeModel(baseUrl, apiKey, model);
}
}

View File

@@ -0,0 +1,83 @@
import { createOpenAI } from '@ai-sdk/openai';
import type { LanguageModel } from 'ai';
import { BaseProvider } from '~/lib/modules/llm/base-provider';
import type { ModelInfo } from '~/lib/modules/llm/types';
import type { IProviderSetting } from '~/types/model';
export default class OpenAIProvider extends BaseProvider {
name = 'OpenAI';
getApiKeyLink = 'https://platform.openai.com/api-keys';
config = {
apiTokenKey: 'OPENAI_API_KEY',
};
staticModels: ModelInfo[] = [
{ name: 'gpt-4o', label: 'GPT-4o', provider: 'OpenAI', maxTokenAllowed: 8000 },
{ name: 'gpt-4o-mini', label: 'GPT-4o Mini', provider: 'OpenAI', maxTokenAllowed: 8000 },
{ name: 'gpt-4-turbo', label: 'GPT-4 Turbo', provider: 'OpenAI', maxTokenAllowed: 8000 },
{ name: 'gpt-4', label: 'GPT-4', provider: 'OpenAI', maxTokenAllowed: 8000 },
{ name: 'gpt-3.5-turbo', label: 'GPT-3.5 Turbo', provider: 'OpenAI', maxTokenAllowed: 8000 },
];
async getDynamicModels(apiKeys?: Record<string, string>, settings?: IProviderSetting): Promise<ModelInfo[]> {
const { apiKey } = this.getProviderBaseUrlAndKey({
apiKeys,
providerSettings: settings,
defaultBaseUrlKey: '',
defaultApiTokenKey: 'OPENAI_API_KEY',
});
if (!apiKey) {
throw `Missing Api Key configuration for ${this.name} provider`;
}
const response = await fetch(`https://api.openai.com/v1/models`, {
headers: {
Authorization: `Bearer ${apiKey}`,
},
});
const res = (await response.json()) as any;
const staticModelIds = this.staticModels.map((m) => m.name);
const data = res.data.filter(
(model: any) =>
model.object === 'model' &&
(model.id.startsWith('gpt-') || model.id.startsWith('o') || model.id.startsWith('chatgpt-')) &&
!staticModelIds.includes(model.id),
);
return data.map((m: any) => ({
name: m.id,
label: `${m.id}`,
provider: this.name,
maxTokenAllowed: m.context_window || 32000,
}));
}
getModelInstance(options: {
model: string;
apiKeys?: Record<string, string>;
providerSettings?: Record<string, IProviderSetting>;
}): LanguageModel {
const { model, apiKeys, providerSettings } = options;
const { apiKey } = this.getProviderBaseUrlAndKey({
apiKeys,
providerSettings: providerSettings?.[this.name],
defaultBaseUrlKey: '',
defaultApiTokenKey: 'OPENAI_API_KEY',
});
if (!apiKey) {
throw new Error(`Missing API key for ${this.name} provider`);
}
const openai = createOpenAI({
apiKey,
});
return openai(model);
}
}

View File

@@ -0,0 +1,61 @@
import { createOpenAI } from '@ai-sdk/openai';
import type { LanguageModel } from 'ai';
import { BaseProvider } from '~/lib/modules/llm/base-provider';
import type { ModelInfo } from '~/lib/modules/llm/types';
import type { IProviderSetting } from '~/types/model';
export default class PerplexityProvider extends BaseProvider {
name = 'Perplexity';
getApiKeyLink = 'https://www.perplexity.ai/settings/api';
config = {
apiTokenKey: 'PERPLEXITY_API_KEY',
};
staticModels: ModelInfo[] = [
{
name: 'llama-3.1-sonar-small-128k-online',
label: 'Sonar Small Online',
provider: 'Perplexity',
maxTokenAllowed: 8192,
},
{
name: 'llama-3.1-sonar-large-128k-online',
label: 'Sonar Large Online',
provider: 'Perplexity',
maxTokenAllowed: 8192,
},
{
name: 'llama-3.1-sonar-huge-128k-online',
label: 'Sonar Huge Online',
provider: 'Perplexity',
maxTokenAllowed: 8192,
},
];
getModelInstance(options: {
model: string;
apiKeys?: Record<string, string>;
providerSettings?: Record<string, IProviderSetting>;
}): LanguageModel {
const { model, apiKeys, providerSettings } = options;
const { apiKey } = this.getProviderBaseUrlAndKey({
apiKeys,
providerSettings: providerSettings?.[this.name],
defaultBaseUrlKey: '',
defaultApiTokenKey: 'PERPLEXITY_API_KEY',
});
if (!apiKey) {
throw new Error(`Missing API key for ${this.name} provider`);
}
const perplexity = createOpenAI({
baseURL: 'https://api.perplexity.ai/',
apiKey,
});
return perplexity(model);
}
}

View File

@@ -0,0 +1,88 @@
import type { LanguageModel } from 'ai';
import { BaseProvider, getOpenAILikeModel } from '~/lib/modules/llm/base-provider';
import type { ModelInfo } from '~/lib/modules/llm/types';
import type { IProviderSetting } from '~/types/model';
export default class TogetherProvider extends BaseProvider {
name = 'Together';
getApiKeyLink = 'https://api.together.xyz/settings/api-keys';
config = {
baseUrlKey: 'TOGETHER_API_BASE_URL',
apiTokenKey: 'TOGETHER_API_KEY',
};
staticModels: ModelInfo[] = [
{
name: 'Qwen/Qwen2.5-Coder-32B-Instruct',
label: 'Qwen/Qwen2.5-Coder-32B-Instruct',
provider: 'Together',
maxTokenAllowed: 8000,
},
{
name: 'meta-llama/Llama-3.2-90B-Vision-Instruct-Turbo',
label: 'meta-llama/Llama-3.2-90B-Vision-Instruct-Turbo',
provider: 'Together',
maxTokenAllowed: 8000,
},
{
name: 'mistralai/Mixtral-8x7B-Instruct-v0.1',
label: 'Mixtral 8x7B Instruct',
provider: 'Together',
maxTokenAllowed: 8192,
},
];
async getDynamicModels(apiKeys?: Record<string, string>, settings?: IProviderSetting): Promise<ModelInfo[]> {
const { baseUrl: fetchBaseUrl, apiKey } = this.getProviderBaseUrlAndKey({
apiKeys,
providerSettings: settings,
defaultBaseUrlKey: 'TOGETHER_API_BASE_URL',
defaultApiTokenKey: 'TOGETHER_API_KEY',
});
const baseUrl = fetchBaseUrl || 'https://api.together.xyz/v1';
if (!baseUrl || !apiKey) {
return [];
}
// console.log({ baseUrl, apiKey });
const response = await fetch(`${baseUrl}/models`, {
headers: {
Authorization: `Bearer ${apiKey}`,
},
});
const res = (await response.json()) as any;
const data = (res || []).filter((model: any) => model.type === 'chat');
return data.map((m: any) => ({
name: m.id,
label: `${m.display_name} - in:$${m.pricing.input.toFixed(2)} out:$${m.pricing.output.toFixed(2)} - context ${Math.floor(m.context_length / 1000)}k`,
provider: this.name,
maxTokenAllowed: 8000,
}));
}
getModelInstance(options: {
model: string;
apiKeys?: Record<string, string>;
providerSettings?: Record<string, IProviderSetting>;
}): LanguageModel {
const { model, apiKeys, providerSettings } = options;
const { baseUrl, apiKey } = this.getProviderBaseUrlAndKey({
apiKeys,
providerSettings: providerSettings?.[this.name],
defaultBaseUrlKey: 'TOGETHER_API_BASE_URL',
defaultApiTokenKey: 'TOGETHER_API_KEY',
});
if (!baseUrl || !apiKey) {
throw new Error(`Missing configuration for ${this.name} provider`);
}
return getOpenAILikeModel(baseUrl, apiKey, model);
}
}

View File

@@ -0,0 +1,45 @@
import { createOpenAI } from '@ai-sdk/openai';
import type { LanguageModel } from 'ai';
import { BaseProvider } from '~/lib/modules/llm/base-provider';
import type { ModelInfo } from '~/lib/modules/llm/types';
import type { IProviderSetting } from '~/types/model';
export default class XAIProvider extends BaseProvider {
name = 'xAI';
getApiKeyLink = 'https://docs.x.ai/docs/quickstart#creating-an-api-key';
config = {
apiTokenKey: 'XAI_API_KEY',
};
staticModels: ModelInfo[] = [
{ name: 'grok-beta', label: 'xAI Grok Beta', provider: 'xAI', maxTokenAllowed: 8000 },
{ name: 'grok-2-1212', label: 'xAI Grok2 1212', provider: 'xAI', maxTokenAllowed: 8000 },
];
getModelInstance(options: {
model: string;
apiKeys?: Record<string, string>;
providerSettings?: Record<string, IProviderSetting>;
}): LanguageModel {
const { model, apiKeys, providerSettings } = options;
const { apiKey } = this.getProviderBaseUrlAndKey({
apiKeys,
providerSettings: providerSettings?.[this.name],
defaultBaseUrlKey: '',
defaultApiTokenKey: 'XAI_API_KEY',
});
if (!apiKey) {
throw new Error(`Missing API key for ${this.name} provider`);
}
const openai = createOpenAI({
baseURL: 'https://api.x.ai/v1',
apiKey,
});
return openai(model);
}
}