mirror of
https://github.com/stackblitz-labs/bolt.diy.git
synced 2025-06-18 01:49:07 +01:00
Merge branch 'stackblitz-labs:main' into FEAT_BoltDYI_NEW_SETTINGS_UI_V2
This commit is contained in:
commit
3c8b9d107b
@ -118,12 +118,14 @@ export class LLMManager {
|
||||
return dynamicModels;
|
||||
}),
|
||||
);
|
||||
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 = [
|
||||
...dynamicModels.flat(),
|
||||
...Array.from(this._providers.values()).flatMap((p) => p.staticModels || []),
|
||||
];
|
||||
const modelList = [...dynamicModelsFlat, ...filteredStaticModesl];
|
||||
modelList.sort((a, b) => a.name.localeCompare(b.name));
|
||||
this._modelList = modelList;
|
||||
|
||||
return modelList;
|
||||
@ -178,8 +180,12 @@ export class LLMManager {
|
||||
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));
|
||||
|
||||
return [...dynamicModels, ...staticModels];
|
||||
return modelList;
|
||||
}
|
||||
getStaticModelListFromProvider(providerArg: BaseProvider) {
|
||||
const provider = this._providers.get(providerArg.name);
|
||||
|
@ -14,6 +14,12 @@ export default class GoogleProvider extends BaseProvider {
|
||||
|
||||
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 },
|
||||
@ -22,6 +28,41 @@ export default class GoogleProvider extends BaseProvider {
|
||||
{ name: 'gemini-exp-1206', label: 'Gemini exp-1206', provider: 'Google', maxTokenAllowed: 8192 },
|
||||
];
|
||||
|
||||
async getDynamicModels(
|
||||
apiKeys?: Record<string, string>,
|
||||
settings?: IProviderSetting,
|
||||
serverEnv?: Record<string, string>,
|
||||
): Promise<ModelInfo[]> {
|
||||
const { apiKey } = this.getProviderBaseUrlAndKey({
|
||||
apiKeys,
|
||||
providerSettings: settings,
|
||||
serverEnv: serverEnv as any,
|
||||
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: {
|
||||
['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;
|
||||
serverEnv: any;
|
||||
|
@ -27,6 +27,43 @@ export default class GroqProvider extends BaseProvider {
|
||||
},
|
||||
];
|
||||
|
||||
async getDynamicModels(
|
||||
apiKeys?: Record<string, string>,
|
||||
settings?: IProviderSetting,
|
||||
serverEnv?: Record<string, string>,
|
||||
): Promise<ModelInfo[]> {
|
||||
const { apiKey } = this.getProviderBaseUrlAndKey({
|
||||
apiKeys,
|
||||
providerSettings: settings,
|
||||
serverEnv: serverEnv as any,
|
||||
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;
|
||||
serverEnv: Env;
|
||||
|
@ -67,11 +67,11 @@ export async function loader({
|
||||
const provider = llmManager.getProvider(params.provider);
|
||||
|
||||
if (provider) {
|
||||
const staticModels = provider.staticModels;
|
||||
const dynamicModels = provider.getDynamicModels
|
||||
? await provider.getDynamicModels(apiKeys, providerSettings, context.cloudflare?.env)
|
||||
: [];
|
||||
modelList = [...staticModels, ...dynamicModels];
|
||||
modelList = await llmManager.getModelListFromProvider(provider, {
|
||||
apiKeys,
|
||||
providerSettings,
|
||||
serverEnv: context.cloudflare?.env,
|
||||
});
|
||||
}
|
||||
} else {
|
||||
// Update all models
|
||||
|
@ -54,8 +54,28 @@ export const allowedHTMLElements = [
|
||||
'tr',
|
||||
'ul',
|
||||
'var',
|
||||
'think',
|
||||
];
|
||||
|
||||
// Add custom rehype plugin
|
||||
function remarkThinkRawContent() {
|
||||
return (tree: any) => {
|
||||
visit(tree, (node: any) => {
|
||||
if (node.type === 'html' && node.value && node.value.startsWith('<think>')) {
|
||||
const cleanedContent = node.value.slice(7);
|
||||
node.value = `<div class="__boltThought__">${cleanedContent}`;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (node.type === 'html' && node.value && node.value.startsWith('</think>')) {
|
||||
const cleanedContent = node.value.slice(8);
|
||||
node.value = `</div>${cleanedContent}`;
|
||||
}
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
const rehypeSanitizeOptions: RehypeSanitizeOptions = {
|
||||
...defaultSchema,
|
||||
tagNames: allowedHTMLElements,
|
||||
@ -79,6 +99,8 @@ export function remarkPlugins(limitedMarkdown: boolean) {
|
||||
plugins.unshift(limitedMarkdownPlugin);
|
||||
}
|
||||
|
||||
plugins.unshift(remarkThinkRawContent);
|
||||
|
||||
return plugins;
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user