Add quick LLM provider setup

This commit is contained in:
2026-07-07 13:12:27 +08:00
parent bcdf91c85d
commit dada4aafcd
5 changed files with 208 additions and 88 deletions

View File

@@ -43,7 +43,7 @@ const knowledgeForm = reactive({
});
const modelForm = reactive({
provider: "openai",
provider: "openai-compatible",
displayName: "",
apiType: "openai_compatible",
modelName: "",
@@ -66,58 +66,65 @@ const modelForm = reactive({
timeoutSecond: 30,
});
const modelPresets = [
const quickModelForm = reactive({
provider: "deepseek",
modelName: "deepseek-v4-pro",
apiKey: "",
});
const quickModelProviders = [
{
label: "OpenAI",
provider: "openai",
label: "DeepSeek",
provider: "deepseek",
apiType: "openai_compatible",
baseUrl: "https://api.deepseek.com",
authType: "bearer",
apiVersion: "",
temperature: 0.2,
topP: null,
maxToken: 1024,
contextWindow: 128000,
models: [
{ label: "deepseek-v4-pro", value: "deepseek-v4-pro" },
{ label: "deepseek-v4-flash", value: "deepseek-v4-flash" },
],
},
{
label: "MiniMax",
provider: "minimax",
apiType: "anthropic_messages",
baseUrl: "https://api.minimax.io/anthropic",
authType: "bearer",
apiVersion: "",
temperature: null,
topP: null,
maxToken: 1024,
contextWindow: 1000000,
models: [
{ label: "MiniMax-M3", value: "MiniMax-M3" },
{ label: "MiniMax-M2.7", value: "MiniMax-M2.7" },
{ label: "MiniMax-M2.7-highspeed", value: "MiniMax-M2.7-highspeed" },
{ label: "MiniMax-M2.5", value: "MiniMax-M2.5" },
{ label: "MiniMax-M2.5-highspeed", value: "MiniMax-M2.5-highspeed" },
{ label: "MiniMax-M2.1", value: "MiniMax-M2.1" },
{ label: "MiniMax-M2.1-highspeed", value: "MiniMax-M2.1-highspeed" },
{ label: "MiniMax-M2", value: "MiniMax-M2" },
],
},
] as const;
const protocolPresets = [
{
label: "OpenAI 兼容协议",
provider: "openai-compatible",
apiType: "openai_compatible",
baseUrl: "https://api.openai.com/v1",
apiUrl: "",
authType: "bearer",
},
{
label: "DeepSeek",
provider: "deepseek",
apiType: "openai_compatible",
baseUrl: "https://api.deepseek.com/v1",
apiUrl: "",
authType: "bearer",
},
{
label: "通义千问 DashScope",
provider: "qwen",
apiType: "openai_compatible",
baseUrl: "https://dashscope.aliyuncs.com/compatible-mode/v1",
apiUrl: "",
authType: "bearer",
},
{
label: "Kimi / Moonshot",
provider: "moonshot",
apiType: "openai_compatible",
baseUrl: "https://api.moonshot.cn/v1",
apiUrl: "",
authType: "bearer",
},
{
label: "硅基流动 SiliconFlow",
provider: "siliconflow",
apiType: "openai_compatible",
baseUrl: "https://api.siliconflow.cn/v1",
apiUrl: "",
authType: "bearer",
},
{
label: "火山方舟 Ark",
provider: "volcengine-ark",
apiType: "openai_compatible",
baseUrl: "https://ark.cn-beijing.volces.com/api/v3",
apiUrl: "",
authType: "bearer",
},
{
label: "Anthropic Claude",
provider: "anthropic",
label: "Anthropic Messages 协议",
provider: "anthropic-compatible",
apiType: "anthropic_messages",
baseUrl: "https://api.anthropic.com",
apiUrl: "",
@@ -127,17 +134,6 @@ const modelPresets = [
topP: null,
topK: null,
},
{
label: "Google Gemini",
provider: "gemini",
apiType: "gemini_generate_content",
baseUrl: "https://generativelanguage.googleapis.com/v1beta",
apiUrl: "",
authType: "api_key",
temperature: null,
topP: null,
topK: null,
},
];
const nullableModelFields = [
@@ -267,6 +263,52 @@ function buildModelPayload() {
return payload;
}
async function quickAddModel() {
const provider = selectedQuickProvider();
if (!provider) return;
if (!quickModelForm.apiKey) {
ElMessage.error("请填写 API Key");
return;
}
await api.createModel({
provider: provider.provider,
displayName: `${provider.label} ${quickModelForm.modelName}`,
apiType: provider.apiType,
modelName: quickModelForm.modelName,
baseUrl: provider.baseUrl,
apiUrl: "",
apiKey: quickModelForm.apiKey,
authType: provider.authType,
apiVersion: provider.apiVersion,
temperature: provider.temperature,
topP: provider.topP,
topK: null,
presencePenalty: null,
frequencyPenalty: null,
maxToken: provider.maxToken,
contextWindow: provider.contextWindow,
streamEnabled: 1,
responseFormat: null,
extraParams: null,
remark: "快速添加",
timeoutSecond: 30,
});
ElMessage.success(`${provider.label} 模型已新增`);
quickModelForm.apiKey = "";
await loadCurrentMenu();
}
function selectedQuickProvider() {
return quickModelProviders.find((item) => item.provider === quickModelForm.provider) ?? quickModelProviders[0];
}
function applyQuickProvider(provider: string) {
const target = quickModelProviders.find((item) => item.provider === provider);
if (!target) return;
quickModelForm.modelName = target.models[0]?.value ?? "";
}
async function enableModel(id: number) {
await api.enableModel(id);
ElMessage.success("模型已启用");
@@ -283,7 +325,7 @@ async function testModel(id: number) {
}
function applyModelPreset(label: string) {
const preset = modelPresets.find((item) => item.label === label);
const preset = protocolPresets.find((item) => item.label === label);
if (!preset) return;
Object.assign(
modelForm,
@@ -332,7 +374,7 @@ function editModel(row: ModelItem) {
function resetModelForm() {
editingModelId.value = null;
Object.assign(modelForm, {
provider: "openai",
provider: "openai-compatible",
displayName: "",
apiType: "openai_compatible",
modelName: "",
@@ -516,27 +558,64 @@ function buildChatQuery() {
<template v-if="activeMenu === 'models'">
<div class="page-head inline">
<div><h2>模型管理</h2><p>支持 OpenAI 兼容Anthropic MessagesGemini generateContent 和常见第三方 LLM</p></div>
<div><h2>模型管理</h2><p>DeepSeekMiniMax 可快速添加其他供应商按 OpenAI 兼容 Anthropic Messages 协议添加</p></div>
<el-button @click="resetModelForm">清空表单</el-button>
</div>
<section class="quick-model-panel">
<div class="quick-model-head">
<div>
<h3>快速添加</h3>
<p>适用于 DeepSeek MiniMax只需要填写 API Key 并选择模型</p>
</div>
</div>
<div class="quick-model-grid">
<el-form-item label="厂商">
<el-select v-model="quickModelForm.provider" @change="applyQuickProvider">
<el-option
v-for="provider in quickModelProviders"
:key="provider.provider"
:label="provider.label"
:value="provider.provider"
/>
</el-select>
</el-form-item>
<el-form-item label="模型">
<el-select v-model="quickModelForm.modelName">
<el-option
v-for="model in selectedQuickProvider()?.models"
:key="model.value"
:label="model.label"
:value="model.value"
/>
</el-select>
</el-form-item>
<el-form-item label="API Key">
<el-input v-model="quickModelForm.apiKey" placeholder="填写后保存,列表中只展示掩码" show-password />
</el-form-item>
<el-form-item label=" ">
<el-button type="primary" class="full-btn" @click="quickAddModel">快速新增</el-button>
</el-form-item>
</div>
</section>
<el-form class="model-config-panel" label-position="top" :model="modelForm">
<div class="model-config-grid">
<el-form-item label="供应商预设">
<el-select placeholder="选择预设" clearable @change="applyModelPreset">
<el-option v-for="preset in modelPresets" :key="preset.label" :label="preset.label" :value="preset.label" />
<el-form-item label="协议模板">
<el-select placeholder="选择协议模板" clearable @change="applyModelPreset">
<el-option v-for="preset in protocolPresets" :key="preset.label" :label="preset.label" :value="preset.label" />
</el-select>
</el-form-item>
<el-form-item label="供应商标识">
<el-input v-model="modelForm.provider" placeholder="openai / deepseek / qwen" />
<el-input v-model="modelForm.provider" placeholder="custom-openai / custom-anthropic" />
</el-form-item>
<el-form-item label="显示名称">
<el-input v-model="modelForm.displayName" placeholder="例如:DeepSeek V3 生产" />
<el-input v-model="modelForm.displayName" placeholder="例如:自建网关生产模型" />
</el-form-item>
<el-form-item label="协议类型">
<el-select v-model="modelForm.apiType">
<el-option label="OpenAI 兼容" value="openai_compatible" />
<el-option label="Anthropic Messages" value="anthropic_messages" />
<el-option label="Gemini generateContent" value="gemini_generate_content" />
</el-select>
</el-form-item>
<el-form-item label="模型名">