mirror of
https://github.com/router-for-me/Cli-Proxy-API-Management-Center.git
synced 2026-02-03 11:20:50 +08:00
feat: initialize new React application structure with TypeScript, ESLint, and Prettier configurations, while removing legacy files and adding new components and pages for enhanced functionality
This commit is contained in:
118
src/utils/models.ts
Normal file
118
src/utils/models.ts
Normal file
@@ -0,0 +1,118 @@
|
||||
/**
|
||||
* 模型工具函数
|
||||
* 迁移自基线 utils/models.js
|
||||
*/
|
||||
|
||||
export interface ModelInfo {
|
||||
name: string;
|
||||
alias?: string;
|
||||
description?: string;
|
||||
}
|
||||
|
||||
const MODEL_CATEGORIES = [
|
||||
{ id: 'gpt', label: 'GPT', patterns: [/gpt/i, /\bo\d\b/i, /\bo\d+\.?/i, /\bchatgpt/i] },
|
||||
{ id: 'claude', label: 'Claude', patterns: [/claude/i] },
|
||||
{ id: 'gemini', label: 'Gemini', patterns: [/gemini/i, /\bgai\b/i] },
|
||||
{ id: 'kimi', label: 'Kimi', patterns: [/kimi/i] },
|
||||
{ id: 'qwen', label: 'Qwen', patterns: [/qwen/i] },
|
||||
{ id: 'glm', label: 'GLM', patterns: [/glm/i, /chatglm/i] },
|
||||
{ id: 'grok', label: 'Grok', patterns: [/grok/i] },
|
||||
{ id: 'deepseek', label: 'DeepSeek', patterns: [/deepseek/i] }
|
||||
];
|
||||
|
||||
const matchCategory = (text: string) => {
|
||||
for (const category of MODEL_CATEGORIES) {
|
||||
if (category.patterns.some((pattern) => pattern.test(text))) {
|
||||
return category.id;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
};
|
||||
|
||||
export function normalizeModelList(payload: any, { dedupe = false } = {}): ModelInfo[] {
|
||||
const toModel = (entry: any): ModelInfo | null => {
|
||||
if (typeof entry === 'string') {
|
||||
return { name: entry };
|
||||
}
|
||||
if (!entry || typeof entry !== 'object') {
|
||||
return null;
|
||||
}
|
||||
const name = entry.id || entry.name || entry.model || entry.value;
|
||||
if (!name) return null;
|
||||
|
||||
const alias = entry.alias || entry.display_name || entry.displayName;
|
||||
const description = entry.description || entry.note || entry.comment;
|
||||
const model: ModelInfo = { name: String(name) };
|
||||
if (alias && alias !== name) {
|
||||
model.alias = String(alias);
|
||||
}
|
||||
if (description) {
|
||||
model.description = String(description);
|
||||
}
|
||||
return model;
|
||||
};
|
||||
|
||||
let models: (ModelInfo | null)[] = [];
|
||||
|
||||
if (Array.isArray(payload)) {
|
||||
models = payload.map(toModel);
|
||||
} else if (payload && typeof payload === 'object') {
|
||||
if (Array.isArray(payload.data)) {
|
||||
models = payload.data.map(toModel);
|
||||
} else if (Array.isArray(payload.models)) {
|
||||
models = payload.models.map(toModel);
|
||||
}
|
||||
}
|
||||
|
||||
const normalized = models.filter(Boolean) as ModelInfo[];
|
||||
if (!dedupe) {
|
||||
return normalized;
|
||||
}
|
||||
|
||||
const seen = new Set<string>();
|
||||
return normalized.filter((model) => {
|
||||
const key = (model?.name || '').toLowerCase();
|
||||
if (!key || seen.has(key)) {
|
||||
return false;
|
||||
}
|
||||
seen.add(key);
|
||||
return true;
|
||||
});
|
||||
}
|
||||
|
||||
export interface ModelGroup {
|
||||
id: string;
|
||||
label: string;
|
||||
items: ModelInfo[];
|
||||
}
|
||||
|
||||
export function classifyModels(models: ModelInfo[] = [], { otherLabel = 'Other' } = {}): ModelGroup[] {
|
||||
const groups: ModelGroup[] = MODEL_CATEGORIES.map((category) => ({
|
||||
id: category.id,
|
||||
label: category.label,
|
||||
items: []
|
||||
}));
|
||||
|
||||
const otherGroup: ModelGroup = { id: 'other', label: otherLabel, items: [] };
|
||||
|
||||
models.forEach((model) => {
|
||||
const name = (model?.name || '').toString();
|
||||
const alias = (model?.alias || '').toString();
|
||||
const haystack = `${name} ${alias}`.toLowerCase();
|
||||
const matchedId = matchCategory(haystack);
|
||||
const target = matchedId ? groups.find((group) => group.id === matchedId) : null;
|
||||
|
||||
if (target) {
|
||||
target.items.push(model);
|
||||
} else {
|
||||
otherGroup.items.push(model);
|
||||
}
|
||||
});
|
||||
|
||||
const populatedGroups = groups.filter((group) => group.items.length > 0);
|
||||
if (otherGroup.items.length) {
|
||||
populatedGroups.push(otherGroup);
|
||||
}
|
||||
|
||||
return populatedGroups;
|
||||
}
|
||||
Reference in New Issue
Block a user