bolt.diy/app/routes/api.models.ts
Oliver Jägle e19644268c
Some checks are pending
Docker Publish / docker-build-publish (push) Waiting to run
Update Stable Branch / prepare-release (push) Waiting to run
feat: configure dynamic providers via .env (#1108)
* Use backend API route to fetch dynamic models

# Conflicts:
#	app/components/chat/BaseChat.tsx

* Override ApiKeys if provided in frontend

* Remove obsolete artifact

* Transport api keys from client to server in header

* Cache static provider information

* Restore reading provider settings from cookie

* Reload only a single provider on api key change

* Transport apiKeys and providerSettings via cookies.

While doing this, introduce a simple helper function for cookies
2025-01-18 03:39:19 +05:30

85 lines
2.5 KiB
TypeScript

import { json } from '@remix-run/cloudflare';
import { LLMManager } from '~/lib/modules/llm/manager';
import type { ModelInfo } from '~/lib/modules/llm/types';
import type { ProviderInfo } from '~/types/model';
import { getApiKeysFromCookie, getProviderSettingsFromCookie } from '~/lib/api/cookies';
interface ModelsResponse {
modelList: ModelInfo[];
providers: ProviderInfo[];
defaultProvider: ProviderInfo;
}
let cachedProviders: ProviderInfo[] | null = null;
let cachedDefaultProvider: ProviderInfo | null = null;
function getProviderInfo(llmManager: LLMManager) {
if (!cachedProviders) {
cachedProviders = llmManager.getAllProviders().map((provider) => ({
name: provider.name,
staticModels: provider.staticModels,
getApiKeyLink: provider.getApiKeyLink,
labelForGetApiKey: provider.labelForGetApiKey,
icon: provider.icon,
}));
}
if (!cachedDefaultProvider) {
const defaultProvider = llmManager.getDefaultProvider();
cachedDefaultProvider = {
name: defaultProvider.name,
staticModels: defaultProvider.staticModels,
getApiKeyLink: defaultProvider.getApiKeyLink,
labelForGetApiKey: defaultProvider.labelForGetApiKey,
icon: defaultProvider.icon,
};
}
return { providers: cachedProviders, defaultProvider: cachedDefaultProvider };
}
export async function loader({
request,
params,
}: {
request: Request;
params: { provider?: string };
}): Promise<Response> {
const llmManager = LLMManager.getInstance(import.meta.env);
// Get client side maintained API keys and provider settings from cookies
const cookieHeader = request.headers.get('Cookie');
const apiKeys = getApiKeysFromCookie(cookieHeader);
const providerSettings = getProviderSettingsFromCookie(cookieHeader);
const { providers, defaultProvider } = getProviderInfo(llmManager);
let modelList: ModelInfo[] = [];
if (params.provider) {
// Only update models for the specific provider
const provider = llmManager.getProvider(params.provider);
if (provider) {
const staticModels = provider.staticModels;
const dynamicModels = provider.getDynamicModels
? await provider.getDynamicModels(apiKeys, providerSettings, import.meta.env)
: [];
modelList = [...staticModels, ...dynamicModels];
}
} else {
// Update all models
modelList = await llmManager.updateModelList({
apiKeys,
providerSettings,
serverEnv: import.meta.env,
});
}
return json<ModelsResponse>({
modelList,
providers,
defaultProvider,
});
}