feat: add better provider support, icons, regen, and a lot more

This commit is contained in:
Zoe
2026-02-12 14:56:13 +00:00
parent d5a5945c03
commit d29f95bacf
124 changed files with 6374 additions and 1861 deletions
+298 -9
View File
@@ -1,24 +1,313 @@
import {
LogoGrok,
LogoGemini
LogoGemini,
LogoQwen,
LogoOpenAI,
LogoArcee,
LogoAi2,
LogoOpenrouter,
LogoMoonshot,
LogoZAI,
LogoGLMV,
LogoChatGLM,
LogoNvidia,
LogoGemma,
LogoMistral,
LogoMeta,
LogoPerplexity,
LogoDeepCogito,
LogoDeepSeek,
LogoAnthropic,
LogoMorph,
LogoAi21,
LogoBaiduCloud,
LogoMinimax,
LogoNova,
LogoByteDance,
LogoLiquid,
LogoPaLM,
LogoUpstage,
LogoStepfun,
LogoXiaomiMiMo,
LogoRelace,
LogoEssentialAI,
LogoClaude,
LogoKwaipilot,
LogoIBM,
LogoInternLM,
LogoLongCat,
LogoWenxin,
LogoHunyuan,
LogoInception,
LogoCohere,
LogoAionLabs,
LogoMicrosoft,
LogoInflection,
LogoAya,
LogoDeepMind,
LogoVertexAI,
LogoGoogle
} from '#components';
import NousResearch from '~/components/Logo/NousResearch.vue';
interface ModelConfig {
icon: any;
Icon: any;
keywords: RegExp[];
brandColor: string;
props?: Record<string, any>;
}
const MODEL_MAPPINGS: ModelConfig[] = [
{ Icon: markRaw(LogoOpenAI), keywords: [/gpt-3/], props: { type: 'gpt3' } },
{ Icon: markRaw(LogoOpenAI), keywords: [/gpt-4/], props: { type: 'gpt4' } },
{ Icon: markRaw(LogoOpenAI), keywords: [/gpt-5/], props: { type: 'gpt5' } },
// { Icon: Sora, keywords: ['sora'] },
{ Icon: markRaw(LogoOpenAI), keywords: [/gpt-oss/], props: { type: 'oss' } },
{
icon: markRaw(LogoGrok),
keywords: [/^grok-/, /^x-ai\//],
brandColor: '#000000'
Icon: markRaw(LogoOpenAI),
keywords: [/o1-/, /^o1/, /\/o1/, /o3-/, /^o3/, /\/o3/, /o4-/, /^o4/, /\/o4/],
props: { type: 'o1' },
},
// { Icon: Dalle, keywords: ['dalle', 'dall-e'] },
{
Icon: markRaw(LogoOpenAI),
keywords: [
/text-embedding-/,
/tts-/,
/whisper-/,
/codex/,
/davinci/,
/babbage/,
/omni-moderation/,
/text-moderation/,
/text-adb/,
/text-ada/,
/computer-use/,
],
props: { type: 'platform' },
},
{
icon: markRaw(LogoGemini),
Icon: markRaw(LogoOpenAI),
keywords: [/^gpt-/, /\/gpt-/, /openai/],
},
{
Icon: markRaw(LogoGrok),
keywords: [/^grok-/, /^x-ai\//],
},
{
Icon: markRaw(LogoGemini),
keywords: [/gemini-/],
brandColor: '#000000'
},
{
Icon: markRaw(LogoGemma),
keywords: [/gemma-/, /^gemma/, /\/gemma/, /translategemma/],
},
{
Icon: markRaw(LogoDeepMind),
keywords: [/^imagen-/, /\/imagen-/, /^imagen\d\//, /\/imagen\d/]
},
{
Icon: markRaw(LogoVertexAI),
keywords: [/^veo-/, /\/veo-/]
},
{
Icon: markRaw(LogoGoogle),
keywords: [/google/, /learnlm/, /nano-banana/]
},
{
Icon: markRaw(LogoDeepCogito),
keywords: [/^deepcogito-/, /\/deepcogito-/, /^cogito-/, /\/cogito-/]
},
{
Icon: markRaw(LogoQwen),
keywords: [/qwen/, /qwq/, /qvq/, /wanx/, /wan\d/, /wan\d\.\d-/, /tongyi/],
},
{
Icon: markRaw(LogoArcee),
keywords: [
/^trinity-/,
/\/trinity-/,
/afm-4.5b/,
/caller-large/,
/spotlight/,
/maestro-reasoning/,
/virtuoso-medium-v2/,
/virtuoso-large/,
/coder-large/,
/arcee-blitz/,
],
},
{
Icon: markRaw(LogoAi2),
keywords: [
/allenai\//,
/olmo-/,
/\/olmo-/,
]
},
{
Icon: markRaw(LogoOpenrouter),
keywords: [
/openrouter\//,
]
},
{
Icon: markRaw(LogoMoonshot),
keywords: [/kimi/, /moonshot/]
},
{
Icon: markRaw(LogoZAI),
keywords: [/^glm-4/, /\/glm-4/, /zai-/, /-glm-4/, /glm-\d/]
},
{
Icon: markRaw(LogoGLMV),
keywords: [/^glm-(.*)v/, /\/glm-(.*)v/]
},
{
Icon: markRaw(LogoChatGLM),
keywords: [/^glm-/, /\/glm-/, /chatglm/]
},
{
Icon: markRaw(LogoNvidia),
keywords: [/nvidia\//, /nemotron/, /openreasoning/, /nemoretriever/, /neva-/, /nv-/]
},
{
Icon: markRaw(LogoMistral),
keywords: [
/mistral/,
/mixtral/,
/codestral/,
/mathstral/,
/\/mn-/,
/pixtral/,
/ministral/,
/magistral/,
/devstral/,
/voxtral/,
],
},
{
Icon: markRaw(LogoMeta),
keywords: [/llama/, /\/l3/, /meta-llama\//]
},
{
Icon: markRaw(LogoPerplexity),
keywords: [/pplx/, /sonar/, /perplexity\//]
},
{
Icon: markRaw(LogoDeepSeek),
keywords: [/deepseek/]
},
{
Icon: markRaw(LogoClaude),
keywords: [/claude/]
},
{
Icon: markRaw(LogoAnthropic),
keywords: [/anthropic/],
},
{
Icon: markRaw(LogoMorph),
keywords: [/^morph-/, /\/morph-/]
},
{
Icon: markRaw(NousResearch),
keywords: [/deephermes/, /hermes/, /genstruct/, /minos/]
},
{
Icon: markRaw(LogoAi21),
keywords: [/jamba/, /^j2/, /ai21/]
},
{
Icon: markRaw(LogoWenxin),
keywords: [/ernie/, /irag/]
},
{
Icon: markRaw(LogoBaiduCloud),
keywords: [/baidu/, /qianfan/]
},
{
Icon: markRaw(LogoMinimax),
keywords: [/minimax/, /abab/, /^image-/]
},
{
Icon: markRaw(LogoNova),
keywords: [/^nova-/, /\/nova-/]
},
{
Icon: markRaw(LogoByteDance),
keywords: [/bytedance/, /skylark/, /seed-/]
},
{
Icon: markRaw(LogoLiquid),
keywords: [/liquid/, /lfm/]
},
{
Icon: markRaw(LogoPaLM),
keywords: [/palm/]
},
{
Icon: markRaw(LogoUpstage),
keywords: [/^solar-/, /\/solar/]
},
{
Icon: markRaw(LogoStepfun),
keywords: [/step/]
},
{
Icon: markRaw(LogoXiaomiMiMo),
keywords: [/^mimo-/, /\/mimo-/]
},
{
Icon: markRaw(LogoRelace),
keywords: [/^relace-/, /\/relace-/]
},
{
Icon: markRaw(LogoEssentialAI),
keywords: [/^rnj-/, /\/rnj-/]
},
{
Icon: markRaw(LogoKwaipilot),
keywords: [/kat-/]
},
{
Icon: markRaw(LogoIBM),
keywords: [/ibm/, /granite/]
},
{
Icon: markRaw(LogoInternLM),
keywords: [/internlm/, /internvl/]
},
{
Icon: markRaw(LogoLongCat),
keywords: [/longcat/]
},
{
Icon: markRaw(LogoHunyuan),
keywords: [/hunyuan/]
},
{
Icon: markRaw(LogoInception),
keywords: [/^inception\//, /^mercury/, /\/mercury/]
},
{
Icon: markRaw(LogoAya),
keywords: [/aya/]
},
{
Icon: markRaw(LogoCohere),
keywords: [/command/, /cohere\//]
},
{
Icon: markRaw(LogoAionLabs),
keywords: [/aion-/]
},
{
Icon: markRaw(LogoMicrosoft),
keywords: [/wizardlm/, /phi-/, /^phi-/, /-phi-/, /mai-/, /microsoft/]
},
{
Icon: markRaw(LogoInflection),
keywords: [/inflection-/, /^inflection\//]
}
];
@@ -29,5 +318,5 @@ export function getModelConfig(modelId: string) {
cfg.keywords.some(regex => regex.test(cleanId))
);
return match || { icon: null, brandColor: '#64748b' };
return match || { Icon: null, props: {} };
}
+42
View File
@@ -0,0 +1,42 @@
import type { Model } from "~/types/model";
export const filterProvidersWithModel = (providers: ProviderWithModels[], query: string): ProviderWithModels[] => {
const rawQuery = query.trim().toLowerCase();
if (!rawQuery) return providers;
return providers
.map((provider) => {
const scoredModels = filterModels(provider.models as Model[], query);
return { ...provider, models: scoredModels };
})
}
export const filterModels = (models: Model[], query: string): Model[] => {
const rawQuery = query.trim().toLowerCase();
if (!rawQuery) return models;
// Split search into individual words (tokens)
const tokens = rawQuery.split(/\s+/);
return models.map(model => {
const name = model.name.toLowerCase();
const id = model.externalId.toLowerCase();
// Check if all tokens match
const matches = tokens.every(t => name.includes(t) || id.includes(t));
if (!matches) return null;
// Calculate simple relevance score
let score = 0;
if (name.startsWith(rawQuery) || id.startsWith(rawQuery)) score += 10;
if (name === rawQuery || id === rawQuery) score += 50;
return { model, score };
})
.filter(m => m !== null)
.sort((a, b) => b.score - a.score)
.map(m => m.model);
}
+21
View File
@@ -0,0 +1,21 @@
export const initSettings = async (userId: string) => {
const triplit = useTriplitClient();
console.log(userId);
const settings = await triplit.fetchOne(triplit.query('settings').Where('userId', '=', userId));
console.log(settings);
if (!settings) {
console.log('no settings');
await triplit.insert('settings', {
userId: userId,
systemAssistants: {
rename: {
enabled: false,
prompt: null,
modelId: null,
}
}
});
}
}