refactor:移除后端和前端的自定义提供程序管理

- 删除了 system_router.py 中用于添加、更新和删除自定义提供程序的端点。
- 从 system_api.js 中移除了自定义提供程序 API 函数。
- 更新了 ModelProvidersComponent.vue,以反映自定义提供程序管理的移除,包括 UI 更改和迁移到新模型配置的提示。
- 清理了 ModelSelectorComponent.vue,移除了旧模型处理和不必要的依赖项。

Co-authored-by: Copilot <copilot@github.com>
This commit is contained in:
Wenjie Zhang 2026-04-26 16:24:54 +08:00
parent db13abaa63
commit f8acc48184
7 changed files with 70 additions and 1444 deletions

View File

@ -80,6 +80,11 @@ def load_chat_model(fully_specified_name: str, **kwargs) -> BaseChatModel:
f"Available chat models ({len(available_specs)}): {available_ids}"
)
logger.warning(
f"旧版本的模型选择逻辑已废弃,建议尽快迁移至新的模型配置;"
f"当前模型选择参数: {fully_specified_name=}"
)
# v1 逻辑spec 必须包含 /
if "/" not in fully_specified_name:
raise ValueError(

View File

@ -428,131 +428,6 @@ class Config(BaseModel):
except Exception as e:
logger.error(f"Failed to save models config to {self._config_file}: {e}")
# ============================================================
# 自定义供应商管理方法
# ============================================================
def add_custom_provider(self, provider_id: str, provider_data: dict[str, Any]) -> bool:
"""添加自定义供应商
Args:
provider_id: 供应商唯一标识符
provider_data: 供应商配置数据
Returns:
是否添加成功
"""
try:
# 处理环境变量,移除 ${} 包裹
if "env" in provider_data and provider_data["env"]:
env_value = provider_data["env"]
if isinstance(env_value, str) and env_value.startswith("${") and env_value.endswith("}"):
provider_data["env"] = env_value[2:-1]
# 确保标记为自定义供应商
provider_data["custom"] = True
# 检查供应商ID是否已存在无论是内置还是自定义
if provider_id in self.model_names:
logger.error(f"Provider ID already exists: {provider_id}")
return False
# 添加到配置中
self.model_names[provider_id] = ChatModelProvider(**provider_data)
# 保存到自定义供应商配置文件
self._save_custom_providers()
# 重新处理环境变量
self._handle_environment()
logger.info(f"Added custom provider: {provider_id}")
return True
except Exception as e:
logger.error(f"Failed to add custom provider {provider_id}: {e}")
return False
def update_custom_provider(self, provider_id: str, provider_data: dict) -> bool:
"""更新自定义供应商
Args:
provider_id: 供应商唯一标识符
provider_data: 新的供应商配置数据
Returns:
是否更新成功
"""
try:
# 处理环境变量,移除 ${} 包裹
if "env" in provider_data and provider_data["env"]:
env_value = provider_data["env"]
if isinstance(env_value, str) and env_value.startswith("${") and env_value.endswith("}"):
provider_data["env"] = env_value[2:-1]
# 检查供应商是否存在且为自定义供应商
if provider_id not in self.model_names:
logger.error(f"Provider not found: {provider_id}")
return False
if not self.model_names[provider_id].custom:
logger.error(f"Cannot update non-custom provider: {provider_id}")
return False
# 确保保持自定义供应商标记
provider_data["custom"] = True
# 更新供应商配置
self.model_names[provider_id] = ChatModelProvider(**provider_data)
# 保存到自定义供应商配置文件
self._save_custom_providers()
# 重新处理环境变量
self._handle_environment()
logger.info(f"Updated custom provider: {provider_id}")
return True
except Exception as e:
logger.error(f"Failed to update custom provider {provider_id}: {e}")
return False
def delete_custom_provider(self, provider_id: str) -> bool:
"""删除自定义供应商
Args:
provider_id: 供应商唯一标识符
Returns:
是否删除成功
"""
try:
# 检查供应商是否存在且为自定义供应商
if provider_id not in self.model_names:
logger.error(f"Provider not found: {provider_id}")
return False
if not self.model_names[provider_id].custom:
logger.error(f"Cannot delete non-custom provider: {provider_id}")
return False
# 从配置中删除
del self.model_names[provider_id]
# 保存到自定义供应商配置文件
self._save_custom_providers()
# 重新处理环境变量
self._handle_environment()
logger.info(f"Deleted custom provider: {provider_id}")
return True
except Exception as e:
logger.error(f"Failed to delete custom provider {provider_id}: {e}")
return False
def get_custom_providers(self) -> dict[str, ChatModelProvider]:
"""获取所有自定义供应商
@ -561,37 +436,6 @@ class Config(BaseModel):
"""
return {k: v for k, v in self.model_names.items() if v.custom}
def _save_custom_providers(self) -> None:
"""保存自定义供应商到独立配置文件"""
if not self._config_file:
logger.warning("Config file path not set")
return
custom_config_file = self._config_file.parent / "custom_providers.toml"
try:
# 获取所有自定义供应商
custom_providers = self.get_custom_providers()
# 创建配置数据
custom_config = {}
if custom_providers:
custom_config["model_names"] = {
provider: info.model_dump() for provider, info in custom_providers.items()
}
# 确保目录存在
custom_config_file.parent.mkdir(parents=True, exist_ok=True)
# 写入配置文件
with open(custom_config_file, "wb") as f:
tomli_w.dump(custom_config, f)
logger.info(f"Custom providers saved to {custom_config_file}")
except Exception as e:
logger.error(f"Failed to save custom providers to {custom_config_file}: {e}")
# 全局配置实例
config = Config()

View File

@ -133,6 +133,11 @@ def select_model(model_provider=None, model_name=None, model_spec=None):
if model_cache.is_v2_spec(model_spec):
return select_model_v2(model_spec)
logger.warning(
f"旧版本的模型选择逻辑已废弃,建议尽快迁移至新的模型配置;"
f"当前模型选择参数: provider={model_provider}, model_name={model_name}, spec={model_spec}"
)
if model_spec:
spec_provider, spec_model_name = split_model_spec(model_spec)
model_provider = model_provider or spec_provider

View File

@ -210,53 +210,3 @@ async def get_custom_providers(current_user: User = Depends(get_admin_user)):
except Exception as e:
logger.error(f"获取自定义供应商失败: {e}")
raise HTTPException(status_code=500, detail=f"获取自定义供应商失败: {str(e)}")
@system.post("/custom-providers")
async def add_custom_provider(
provider_id: str = Body(..., description="供应商ID"),
provider_data: dict = Body(..., description="供应商配置数据"),
current_user: User = Depends(get_admin_user),
):
"""添加自定义供应商"""
try:
success = config.add_custom_provider(provider_id, provider_data)
if success:
return {"message": f"自定义供应商 {provider_id} 添加成功"}
else:
raise HTTPException(status_code=400, detail=f"供应商ID {provider_id} 已存在请使用其他ID")
except Exception as e:
logger.error(f"添加自定义供应商失败 {provider_id}: {e}")
raise HTTPException(status_code=500, detail=f"添加自定义供应商失败: {str(e)}")
@system.put("/custom-providers/{provider_id}")
async def update_custom_provider(
provider_id: str,
provider_data: dict = Body(..., description="供应商配置数据"),
current_user: User = Depends(get_admin_user),
):
"""更新自定义供应商"""
try:
success = config.update_custom_provider(provider_id, provider_data)
if success:
return {"message": f"自定义供应商 {provider_id} 更新成功"}
else:
raise HTTPException(status_code=404, detail=f"自定义供应商 {provider_id} 不存在或更新失败")
except Exception as e:
logger.error(f"更新自定义供应商失败 {provider_id}: {e}")
raise HTTPException(status_code=500, detail=f"更新自定义供应商失败: {str(e)}")
@system.delete("/custom-providers/{provider_id}")
async def delete_custom_provider(provider_id: str, current_user: User = Depends(get_admin_user)):
"""删除自定义供应商"""
try:
success = config.delete_custom_provider(provider_id)
if success:
return {"message": f"自定义供应商 {provider_id} 删除成功"}
else:
raise HTTPException(status_code=404, detail=f"自定义供应商 {provider_id} 不存在或删除失败")
except Exception as e:
logger.error(f"删除自定义供应商失败 {provider_id}: {e}")
raise HTTPException(status_code=500, detail=f"删除自定义供应商失败: {str(e)}")

View File

@ -99,55 +99,6 @@ export const ocrApi = {
export const chatModelApi = {
}
// =============================================================================
// === 自定义供应商管理分组 ===
// =============================================================================
export const customProviderApi = {
/**
* 获取所有自定义供应商
* @returns {Promise} - 自定义供应商列表
*/
getCustomProviders: async () => {
return apiAdminGet('/api/system/custom-providers')
},
/**
* 添加自定义供应商
* @param {string} providerId - 供应商ID
* @param {Object} providerData - 供应商配置数据
* @returns {Promise} - 添加结果
*/
addCustomProvider: async (providerId, providerData) => {
return apiAdminPost('/api/system/custom-providers', {
provider_id: providerId,
provider_data: providerData
})
},
/**
* 更新自定义供应商
* @param {string} providerId - 供应商ID
* @param {Object} providerData - 供应商配置数据
* @returns {Promise} - 更新结果
*/
updateCustomProvider: async (providerId, providerData) => {
return apiAdminPut(
`/api/system/custom-providers/${encodeURIComponent(providerId)}`,
providerData
)
},
/**
* 删除自定义供应商
* @param {string} providerId - 供应商ID
* @returns {Promise} - 删除结果
*/
deleteCustomProvider: async (providerId) => {
return apiAdminDelete(`/api/system/custom-providers/${encodeURIComponent(providerId)}`)
}
}
// =============================================================================
// === 独立模型供应商配置分组 ===
// =============================================================================

File diff suppressed because it is too large Load Diff

View File

@ -58,21 +58,6 @@
{{ model.display_name }}
</a-menu-item>
</a-menu-item-group>
<!-- v1 模型列表Legacy弱化处理 -->
<a-menu-item-group v-for="(item, key) in modelKeys" :key="key">
<template #title>
<span>{{ modelNames[item]?.name }}</span>
<a-tag color="warning" size="small" class="provider-tag">Legacy</a-tag>
</template>
<a-menu-item
v-for="(model, idx) in modelNames[item]?.models"
:key="`${item}-${idx}`"
@click="handleSelectModel(item, model)"
>
{{ model }}
</a-menu-item>
</a-menu-item-group>
</a-menu>
</template>
</a-dropdown>
@ -80,7 +65,6 @@
<script setup>
import { computed, reactive, ref } from 'vue'
import { useConfigStore } from '@/stores/config'
import { modelProviderApi } from '@/apis/system_api'
import { RefreshCw } from 'lucide-vue-next'
@ -100,7 +84,6 @@ const props = defineProps({
}
})
const configStore = useConfigStore()
const emit = defineEmits(['select-model'])
// v2
@ -150,15 +133,6 @@ const state = reactive({
refreshingCache: false //
})
// configStore
const modelNames = computed(() => configStore.config?.model_names)
const modelStatus = computed(() => configStore.config?.model_provider_status)
// modelStatus key
const modelKeys = computed(() => {
return Object.keys(modelStatus.value || {}).filter((key) => modelStatus.value?.[key])
})
const resolvedSize = computed(() => props.size || 'small')
const modelSelectClasses = computed(() => ({
'model-select--middle': resolvedSize.value === 'middle',
@ -218,12 +192,6 @@ const getCurrentModelStatusTooltip = () => {
return `${statusText}: ${message}`
}
// v1 Legacy
const handleSelectModel = async (provider, name) => {
const spec = `${provider}/${name}`
emit('select-model', spec)
}
// v2
const handleSelectV2Model = (spec) => {
emit('select-model', spec)