mirror of
https://github.com/stackblitz-labs/bolt.diy
synced 2025-06-26 18:26:38 +00:00
feat: custom order method for llm models
This commit is contained in:
parent
50dd74de07
commit
31383bc9a6
@ -115,6 +115,10 @@ export abstract class BaseProvider implements ProviderInfo {
|
||||
apiKeys?: Record<string, string>;
|
||||
providerSettings?: Record<string, IProviderSetting>;
|
||||
}): LanguageModelV1;
|
||||
|
||||
sort(models: ModelInfo[]): ModelInfo[] {
|
||||
return models.sort((a, b) => a.name.localeCompare(b.name));
|
||||
}
|
||||
}
|
||||
|
||||
type OptionalApiKey = string | undefined;
|
||||
|
@ -1,6 +1,6 @@
|
||||
import type { IProviderSetting } from '~/types/model';
|
||||
import { BaseProvider } from './base-provider';
|
||||
import type { ModelInfo, ProviderInfo } from './types';
|
||||
import type { ModelInfo } from './types';
|
||||
import * as providers from './registry';
|
||||
import { createScopedLogger } from '~/utils/logger';
|
||||
|
||||
@ -88,44 +88,44 @@ export class LLMManager {
|
||||
}
|
||||
|
||||
// Get dynamic models from all providers that support them
|
||||
const dynamicModels = await Promise.all(
|
||||
const models = await Promise.all(
|
||||
Array.from(this._providers.values())
|
||||
.filter((provider) => enabledProviders.includes(provider.name))
|
||||
.filter(
|
||||
(provider): provider is BaseProvider & Required<Pick<ProviderInfo, 'getDynamicModels'>> =>
|
||||
!!provider.getDynamicModels,
|
||||
)
|
||||
.map(async (provider) => {
|
||||
const cachedModels = provider.getModelsFromCache(options);
|
||||
let dynamicModels: ModelInfo[] | null = [];
|
||||
|
||||
if (cachedModels) {
|
||||
return cachedModels;
|
||||
if (provider.getDynamicModels) {
|
||||
dynamicModels = provider.getModelsFromCache(options);
|
||||
|
||||
if (!dynamicModels) {
|
||||
dynamicModels = await provider
|
||||
.getDynamicModels(apiKeys, providerSettings?.[provider.name], serverEnv)
|
||||
.then((models) => {
|
||||
logger.info(`Caching ${models.length} dynamic models for ${provider.name}`);
|
||||
provider.storeDynamicModels(options, models);
|
||||
|
||||
return models;
|
||||
})
|
||||
.catch((err) => {
|
||||
logger.error(`Error getting dynamic models ${provider.name} :`, err);
|
||||
return [];
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
const dynamicModels = await provider
|
||||
.getDynamicModels(apiKeys, providerSettings?.[provider.name], serverEnv)
|
||||
.then((models) => {
|
||||
logger.info(`Caching ${models.length} dynamic models for ${provider.name}`);
|
||||
provider.storeDynamicModels(options, models);
|
||||
const models = provider.sort([
|
||||
...dynamicModels,
|
||||
...provider.staticModels.filter(
|
||||
(staticModel) => !dynamicModels.some((dynamicModel) => dynamicModel.name === staticModel.name),
|
||||
),
|
||||
]);
|
||||
|
||||
return models;
|
||||
})
|
||||
.catch((err) => {
|
||||
logger.error(`Error getting dynamic models ${provider.name} :`, err);
|
||||
return [];
|
||||
});
|
||||
|
||||
return dynamicModels;
|
||||
return models;
|
||||
}),
|
||||
);
|
||||
const staticModels = Array.from(this._providers.values()).flatMap((p) => p.staticModels || []);
|
||||
const dynamicModelsFlat = dynamicModels.flat();
|
||||
const dynamicModelKeys = dynamicModelsFlat.map((d) => `${d.name}-${d.provider}`);
|
||||
const filteredStaticModesl = staticModels.filter((m) => !dynamicModelKeys.includes(`${m.name}-${m.provider}`));
|
||||
|
||||
// Combine static and dynamic models
|
||||
const modelList = [...dynamicModelsFlat, ...filteredStaticModesl];
|
||||
modelList.sort((a, b) => a.name.localeCompare(b.name));
|
||||
const modelList = models.flat();
|
||||
this._modelList = modelList;
|
||||
|
||||
return modelList;
|
||||
@ -155,35 +155,35 @@ export class LLMManager {
|
||||
|
||||
const { apiKeys, providerSettings, serverEnv } = options;
|
||||
|
||||
const cachedModels = provider.getModelsFromCache({
|
||||
let dynamicModels = provider.getModelsFromCache({
|
||||
apiKeys,
|
||||
providerSettings,
|
||||
serverEnv,
|
||||
});
|
||||
|
||||
if (cachedModels) {
|
||||
logger.info(`Found ${cachedModels.length} cached models for ${provider.name}`);
|
||||
return [...cachedModels, ...staticModels];
|
||||
if (!dynamicModels) {
|
||||
logger.info(`Getting dynamic models for ${provider.name}`);
|
||||
|
||||
dynamicModels = await provider
|
||||
.getDynamicModels?.(apiKeys, providerSettings?.[provider.name], serverEnv)
|
||||
.then((models) => {
|
||||
logger.info(`Got ${models.length} dynamic models for ${provider.name}`);
|
||||
provider.storeDynamicModels(options, models);
|
||||
|
||||
return models;
|
||||
})
|
||||
.catch((err) => {
|
||||
logger.error(`Error getting dynamic models ${provider.name} :`, err);
|
||||
return [];
|
||||
});
|
||||
}
|
||||
|
||||
logger.info(`Getting dynamic models for ${provider.name}`);
|
||||
|
||||
const dynamicModels = await provider
|
||||
.getDynamicModels?.(apiKeys, providerSettings?.[provider.name], serverEnv)
|
||||
.then((models) => {
|
||||
logger.info(`Got ${models.length} dynamic models for ${provider.name}`);
|
||||
provider.storeDynamicModels(options, models);
|
||||
|
||||
return models;
|
||||
})
|
||||
.catch((err) => {
|
||||
logger.error(`Error getting dynamic models ${provider.name} :`, err);
|
||||
return [];
|
||||
});
|
||||
const dynamicModelsName = dynamicModels.map((d) => d.name);
|
||||
const filteredStaticList = staticModels.filter((m) => !dynamicModelsName.includes(m.name));
|
||||
const modelList = [...dynamicModels, ...filteredStaticList];
|
||||
modelList.sort((a, b) => a.name.localeCompare(b.name));
|
||||
const modelList = provider.sort([
|
||||
...dynamicModels,
|
||||
...staticModels.filter(
|
||||
(staticModel) => !dynamicModels.some((dynamicModel) => dynamicModel.name === staticModel.name),
|
||||
),
|
||||
]);
|
||||
|
||||
return modelList;
|
||||
}
|
||||
|
@ -18,28 +18,51 @@ export default class AnthropicProvider extends BaseProvider {
|
||||
label: 'Claude 3.7 Sonnet',
|
||||
provider: 'Anthropic',
|
||||
maxTokenAllowed: 8000,
|
||||
createdAt: '2025-02-24T00:00:00Z',
|
||||
},
|
||||
{
|
||||
name: 'claude-3-5-sonnet-latest',
|
||||
label: 'Claude 3.5 Sonnet (new)',
|
||||
label: 'Claude 3.5 Sonnet (Latest)',
|
||||
provider: 'Anthropic',
|
||||
maxTokenAllowed: 8000,
|
||||
createdAt: '2024-10-22T00:00:00Z',
|
||||
},
|
||||
{
|
||||
name: 'claude-3-5-sonnet-20240620',
|
||||
label: 'Claude 3.5 Sonnet (old)',
|
||||
label: 'Claude 3.5 Sonnet (Old)',
|
||||
provider: 'Anthropic',
|
||||
maxTokenAllowed: 8000,
|
||||
createdAt: '2024-06-20T00:00:00Z',
|
||||
},
|
||||
{
|
||||
name: 'claude-3-5-haiku-latest',
|
||||
label: 'Claude 3.5 Haiku (new)',
|
||||
label: 'Claude 3.5 Haiku (Latest)',
|
||||
provider: 'Anthropic',
|
||||
maxTokenAllowed: 8000,
|
||||
createdAt: '2024-10-22T00:00:00Z',
|
||||
},
|
||||
|
||||
{
|
||||
name: 'claude-3-opus-latest',
|
||||
label: 'Claude 3 Opus',
|
||||
provider: 'Anthropic',
|
||||
maxTokenAllowed: 8000,
|
||||
createdAt: '2024-02-29T00:00:00Z',
|
||||
},
|
||||
{
|
||||
name: 'claude-3-sonnet-20240229',
|
||||
label: 'Claude 3 Sonnet',
|
||||
provider: 'Anthropic',
|
||||
maxTokenAllowed: 8000,
|
||||
createdAt: '2024-02-29T00:00:00Z',
|
||||
},
|
||||
{
|
||||
name: 'claude-3-haiku-20240307',
|
||||
label: 'Claude 3 Haiku',
|
||||
provider: 'Anthropic',
|
||||
maxTokenAllowed: 8000,
|
||||
createdAt: '2024-03-07T00:00:00Z',
|
||||
},
|
||||
{ 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(
|
||||
@ -76,6 +99,7 @@ export default class AnthropicProvider extends BaseProvider {
|
||||
label: `${m.display_name}`,
|
||||
provider: this.name,
|
||||
maxTokenAllowed: 32000,
|
||||
createdAt: m.created_at ?? '0000-00-00T00:00:00Z',
|
||||
}));
|
||||
}
|
||||
|
||||
@ -99,4 +123,11 @@ export default class AnthropicProvider extends BaseProvider {
|
||||
|
||||
return anthropic(model);
|
||||
};
|
||||
|
||||
sort(models: ModelInfo[]): ModelInfo[] {
|
||||
return models.sort((a, b) => {
|
||||
const compare = b.createdAt!.localeCompare(a.createdAt!);
|
||||
return compare === 0 ? b.name.localeCompare(a.name) : compare;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -6,6 +6,7 @@ export interface ModelInfo {
|
||||
label: string;
|
||||
provider: string;
|
||||
maxTokenAllowed: number;
|
||||
createdAt?: string;
|
||||
}
|
||||
|
||||
export interface ProviderInfo {
|
||||
|
Loading…
Reference in New Issue
Block a user