refactor: extract provider logic into modular registry

Each AI provider now has its own module implementing a ProviderModule
interface with createGateway, getAuthHeaders, and fetchModels methods.
This replaces the monolithic switch statements in ai-provider.ts and
models.post.ts with a clean registry pattern.
This commit is contained in:
Zoe
2026-04-27 12:04:49 -05:00
parent 6ca4de4cab
commit 1d40812f2a
21 changed files with 1221 additions and 798 deletions
+89
View File
@@ -0,0 +1,89 @@
import openrouter from './openrouter';
import ollama from './ollama';
import vllm from './vllm';
import cerebras from './cerebras';
import google from './google';
import longcat from './longcat';
import cohere from './cohere';
import inception from './inception';
import mistral from './mistral';
import closedrouter from './closedrouter';
import nvidia from './nvidia';
import xiaomi from './xiaomi';
import openai from './openai';
import anthropic from './anthropic';
import type { Result } from '~~/types/result';
import type { Gateway, GatewayFetchError } from '~~/server/utils/ai-provider';
import type { Model as ModelDrizzle } from '~/composables/useModels';
export interface NormalizedModel {
id: string;
name?: string;
cost?: Record<string, string | undefined>;
attributes: {
inputModalities: string[];
outputModalities: string[];
capabilities: string[];
contextWindow?: number | null;
supported_parameters?: string[];
};
releasedAt?: number;
}
export interface ProviderModule {
id: string;
baseUrl: string;
modelsEndpoint: string | null;
createGateway(config: {
apiKey?: string;
baseURL: string;
model?: ModelDrizzle;
}): Result<Gateway, GatewayFetchError>;
getAuthHeaders(apiKey?: string): Record<string, string | undefined>;
fetchModels(config: {
baseURL: string;
apiKey?: string;
modelsDevData: any;
}): Promise<NormalizedModel[]>;
}
const providers = [
openrouter,
ollama,
vllm,
cerebras,
google,
longcat,
cohere,
inception,
mistral,
closedrouter,
nvidia,
xiaomi,
openai,
anthropic,
];
type ProviderId = typeof providers[number]['id'];
type Provider = typeof providers[number];
const registry = new Map<ProviderId, Provider>(providers.map((p) => [p.id, p]));
export function getProvider<T extends ProviderId>(id: T): Provider | undefined {
return registry.get(id);
}
export function getAllProviders() {
return Array.from(registry.values());
}
export function getProviderIds() {
return Array.from(registry.keys());
}
export function getProviderBaseUrl<T extends ProviderId>(id: T): string {
return registry.get(id)?.baseUrl ?? '';
}