From 907a3622710179076f90cae8ab28f64aa000ec20 Mon Sep 17 00:00:00 2001 From: fit2cloud-chenyw Date: Wed, 30 Jul 2025 14:19:23 +0800 Subject: [PATCH 1/7] perf: Ai model validate --- backend/apps/system/api/aimodel.py | 42 ++++++++++------ frontend/src/api/system.ts | 3 +- frontend/src/views/system/model/Card.vue | 45 +++++++++++++++++- frontend/src/views/system/model/Model.vue | 58 ++++++++++++++++++----- 4 files changed, 118 insertions(+), 30 deletions(-) diff --git a/backend/apps/system/api/aimodel.py b/backend/apps/system/api/aimodel.py index eece4367..be5a46b9 100644 --- a/backend/apps/system/api/aimodel.py +++ b/backend/apps/system/api/aimodel.py @@ -1,5 +1,7 @@ import json from typing import List, Union + +from fastapi.responses import StreamingResponse from apps.ai_model.model_factory import LLMConfig, LLMFactory from apps.system.schemas.ai_model_schema import AiModelConfigItem, AiModelCreator, AiModelEditor, AiModelGridItem from fastapi import APIRouter, Query @@ -14,21 +16,31 @@ router = APIRouter(tags=["system/aimodel"], prefix="/system/aimodel") @router.post("/status") async def check_llm(info: AiModelCreator, trans: Trans): - try: - additional_params = {item.key: item.val for item in info.config_list} - config = LLMConfig( - model_type="openai", - model_name=info.base_model, - api_key=info.api_key, - api_base_url=info.api_domain, - additional_params=additional_params, - ) - llm_instance = LLMFactory.create_llm(config) - result = llm_instance.llm.invoke("who are you?") - SQLBotLogUtil.info(f"check_llm result: {result}") - except Exception as e: - SQLBotLogUtil.error(f"Error checking LLM: {e}") - raise Exception(trans('i18n_llm.validate_error', msg = str(e))) + async def generate(): + try: + additional_params = {item.key: item.val for item in info.config_list} + config = LLMConfig( + model_type="openai", + model_name=info.base_model, + api_key=info.api_key, + api_base_url=info.api_domain, + additional_params=additional_params, + ) + llm_instance = LLMFactory.create_llm(config) + + res = llm_instance.llm.stream("who are you?") + + for chunk in res: + if chunk and chunk.content: + SQLBotLogUtil.info(chunk) + yield json.dumps({"content": chunk.content}) + "\n" + + except Exception as e: + SQLBotLogUtil.error(f"Error checking LLM: {e}") + error_msg = trans('i18n_llm.validate_error', msg=str(e)) + yield json.dumps({"error": error_msg}) + "\n" + + return StreamingResponse(generate(), media_type="application/x-ndjson") @router.get("", response_model=list[AiModelGridItem]) async def query( diff --git a/frontend/src/api/system.ts b/frontend/src/api/system.ts index ee62cb57..9713ec9e 100644 --- a/frontend/src/api/system.ts +++ b/frontend/src/api/system.ts @@ -8,6 +8,5 @@ export const modelApi = { delete: (id: number) => request.delete(`/system/aimodel/${id}`), query: (id: number) => request.get(`/system/aimodel/${id}`), setDefault: (id: number) => request.put(`/system/aimodel/default/${id}`), - check: (data: any) => - request.post('/system/aimodel/status', data, { requestOptions: { silent: true } }), + check: (data: any) => request.fetchStream('/system/aimodel/status', data), } diff --git a/frontend/src/views/system/model/Card.vue b/frontend/src/views/system/model/Card.vue index 2029e46f..2efc3a12 100644 --- a/frontend/src/views/system/model/Card.vue +++ b/frontend/src/views/system/model/Card.vue @@ -2,7 +2,7 @@ import delIcon from '@/assets/svg/icon_delete.svg' import edit from '@/assets/svg/icon_edit_outlined.svg' import { get_supplier } from '@/entity/supplier' -import { computed } from 'vue' +import { computed, ref } from 'vue' const props = withDefaults( defineProps<{ name: string @@ -21,12 +21,22 @@ const props = withDefaults( supplier: 0, } ) +const errorMsg = ref('') const current_supplier = computed(() => { if (!props.supplier) { return null } return get_supplier(props.supplier) }) +const showErrorMask = (msg?: string) => { + if (!msg) { + return + } + errorMsg.value = msg + setTimeout(() => { + errorMsg.value = '' + }, 3000) +} const emits = defineEmits(['edit', 'del']) const handleEdit = () => { @@ -36,10 +46,17 @@ const handleEdit = () => { const handleDel = () => { emits('del', { id: props.id, name: props.name, default_model: props.isDefault }) } + +defineExpose({ showErrorMask })