From c5f8146f25747dd9e00947fc6cb563d71a800de7 Mon Sep 17 00:00:00 2001 From: ulleo Date: Wed, 30 Jul 2025 15:08:49 +0800 Subject: [PATCH 01/17] feat: modify template --- backend/apps/chat/task/llm.py | 2 ++ backend/template.yaml | 6 +++--- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/backend/apps/chat/task/llm.py b/backend/apps/chat/task/llm.py index e758fa93..b0ec1cfb 100644 --- a/backend/apps/chat/task/llm.py +++ b/backend/apps/chat/task/llm.py @@ -439,6 +439,7 @@ class LLMService: _ds = self.out_ds_instance.get_ds(data['id']) self.ds = _ds self.chat_question.engine = _ds.type + self.chat_question.db_schema = self.out_ds_instance.get_db_schema(ds.id) _engine_type = self.chat_question.engine _chat.engine_type = _ds.type else: @@ -448,6 +449,7 @@ class LLMService: raise Exception(f"Datasource configuration with id {_datasource} not found") self.ds = CoreDatasource(**_ds.model_dump()) self.chat_question.engine = _ds.type_name if _ds.type != 'excel' else 'PostgreSQL' + self.chat_question.db_schema = get_table_schema(session=self.session, current_user=self.current_user, ds=self.ds) _engine_type = self.chat_question.engine _chat.engine_type = _ds.type_name # save chat diff --git a/backend/template.yaml b/backend/template.yaml index 60eb5a5b..0c86b1ce 100644 --- a/backend/template.yaml +++ b/backend/template.yaml @@ -54,13 +54,13 @@ template: ] ``` + ### 提供表结构如下: + {schema} + ### 响应, 请直接返回JSON结果: ```json user: | - ### 提供表结构如下: - {schema} - ### 问题: {question} From 788639276861927937006393a0be2b1d34c0d4af Mon Sep 17 00:00:00 2001 From: ulleo Date: Wed, 30 Jul 2025 15:17:02 +0800 Subject: [PATCH 02/17] fix: select_datasource id error --- backend/apps/chat/task/llm.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backend/apps/chat/task/llm.py b/backend/apps/chat/task/llm.py index b0ec1cfb..fcaf3bed 100644 --- a/backend/apps/chat/task/llm.py +++ b/backend/apps/chat/task/llm.py @@ -439,7 +439,7 @@ class LLMService: _ds = self.out_ds_instance.get_ds(data['id']) self.ds = _ds self.chat_question.engine = _ds.type - self.chat_question.db_schema = self.out_ds_instance.get_db_schema(ds.id) + self.chat_question.db_schema = self.out_ds_instance.get_db_schema(self.ds.id) _engine_type = self.chat_question.engine _chat.engine_type = _ds.type else: From c5ab4a8461e1b995d5c97c6b02a6abce05403960 Mon Sep 17 00:00:00 2001 From: fit2cloud-chenyw Date: Wed, 30 Jul 2025 15:39:26 +0800 Subject: [PATCH 03/17] perf: Disable model validate --- backend/apps/chat/task/llm.py | 11 +++++++++-- backend/common/core/config.py | 1 - frontend/src/views/system/model/Model.vue | 3 +++ 3 files changed, 12 insertions(+), 3 deletions(-) diff --git a/backend/apps/chat/task/llm.py b/backend/apps/chat/task/llm.py index fcaf3bed..895aea5e 100644 --- a/backend/apps/chat/task/llm.py +++ b/backend/apps/chat/task/llm.py @@ -836,7 +836,8 @@ class LLMService: self.ds.id) if self.out_ds_instance else get_table_schema(session=self.session, current_user=self.current_user, ds=self.ds) - + else: + self.validate_history_ds() # generate sql sql_res = self.generate_sql() full_sql_text = '' @@ -1025,7 +1026,13 @@ class LLMService: finally: # end pass - + + def validate_history_ds(self): + _invalid_ds = False + _ds = self.ds + _assistant = self.current_assistant + if _invalid_ds: + yield orjson.dumps({'content': 'ds is invalid', 'type': 'error'}).decode() + '\n\n' def execute_sql_with_db(db: SQLDatabase, sql: str) -> str: """Execute SQL query using SQLDatabase diff --git a/backend/common/core/config.py b/backend/common/core/config.py index 5d16c61a..9de1279b 100644 --- a/backend/common/core/config.py +++ b/backend/common/core/config.py @@ -9,7 +9,6 @@ from pydantic import ( ) from pydantic_core import MultiHostUrl from pydantic_settings import BaseSettings, SettingsConfigDict -from typing_extensions import Self def parse_cors(v: Any) -> list[str] | str: diff --git a/frontend/src/views/system/model/Model.vue b/frontend/src/views/system/model/Model.vue index 32a9ed2e..8c991f1a 100644 --- a/frontend/src/views/system/model/Model.vue +++ b/frontend/src/views/system/model/Model.vue @@ -71,6 +71,8 @@ const defaultModelListWithSearch = computed(() => { }) const modelCheckHandler = async (item: any) => { + console.log(item) + /** const response = await modelApi.check(item) const reader = response.body.getReader() const decoder = new TextDecoder() @@ -110,6 +112,7 @@ const modelCheckHandler = async (item: any) => { currentRef?.showErrorMask(checkMsg) } }) + */ } const duplicateName = async (item: any) => { const res = await modelApi.queryAll() From 0a3432fa9a9af1a698a2f77c52f853948b572a4f Mon Sep 17 00:00:00 2001 From: fit2cloud-chenyw Date: Wed, 30 Jul 2025 15:46:51 +0800 Subject: [PATCH 04/17] perf: Remove unused code --- frontend/src/views/system/model/Model.vue | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontend/src/views/system/model/Model.vue b/frontend/src/views/system/model/Model.vue index 8c991f1a..11415864 100644 --- a/frontend/src/views/system/model/Model.vue +++ b/frontend/src/views/system/model/Model.vue @@ -35,7 +35,7 @@ const activeName = ref('') const activeType = ref('') const modelFormRef = ref() const cardRefs = ref([]) -const showCardError = ref(true) // if you don`t want card mask error, just change this to false +// const showCardError = ref(true) // if you don`t want card mask error, just change this to false reactive({ form: { id: '', From 955f2d0878b52f4be4884d76b4d5615e5571ffb1 Mon Sep 17 00:00:00 2001 From: dataeaseShu Date: Wed, 30 Jul 2025 15:50:47 +0800 Subject: [PATCH 05/17] fix: bug fix --- frontend/src/views/ds/Datasource.vue | 6 +++++- frontend/src/views/ds/DatasourceForm.vue | 9 +++++---- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/frontend/src/views/ds/Datasource.vue b/frontend/src/views/ds/Datasource.vue index 0ad1aaa5..b6fbebd8 100644 --- a/frontend/src/views/ds/Datasource.vue +++ b/frontend/src/views/ds/Datasource.vue @@ -77,6 +77,10 @@ const handleDefaultDatasourceChange = (item: any) => { } } +const changeActiveStep = (val: number) => { + activeStep.value = val > 2 ? 2 : val +} + const formatKeywords = (item: string) => { if (!defaultDatasourceKeywords.value) return item return item.replaceAll( @@ -359,7 +363,7 @@ const back = () => { :active-type="activeType" @refresh="refresh" @close="beforeClose" - @change-active-step="(val: number) => (activeStep = val)" + @change-active-step="changeActiveStep" > diff --git a/frontend/src/views/ds/DatasourceForm.vue b/frontend/src/views/ds/DatasourceForm.vue index 0440699e..80bafdb0 100644 --- a/frontend/src/views/ds/DatasourceForm.vue +++ b/frontend/src/views/ds/DatasourceForm.vue @@ -9,6 +9,7 @@ import { ElMessage } from 'element-plus-secondary' import type { FormInstance, FormRules } from 'element-plus-secondary' import icon_form_outlined from '@/assets/svg/icon_form_outlined.svg' import FixedSizeList from 'element-plus-secondary/es/components/virtual-list/src/components/fixed-size-list.mjs' +import { debounce } from 'lodash-es' import { Plus } from '@element-plus/icons-vue' import { useCache } from '@/utils/useCache' import { haveSchema } from '@/views/ds/js/ds-type' @@ -339,7 +340,7 @@ const check = () => { onBeforeUnmount(() => (saveLoading.value = false)) -const next = async (formEl: FormInstance | undefined) => { +const next = debounce(async (formEl: FormInstance | undefined) => { if (!formEl) return await formEl.validate((valid) => { if (valid) { @@ -369,11 +370,11 @@ const next = async (formEl: FormInstance | undefined) => { } } }) -} +}, 300) -const preview = () => { +const preview = debounce(() => { emit('changeActiveStep', props.activeStep - 1) -} +}, 200) const beforeUpload = (rawFile: any) => { setFile(rawFile) From 1d4fe1fbb435970104d69e7deb9517a6ed0e1d1f Mon Sep 17 00:00:00 2001 From: fit2cloud-chenyw Date: Wed, 30 Jul 2025 15:56:57 +0800 Subject: [PATCH 06/17] perf: Chat validate ds --- backend/apps/chat/task/llm.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/backend/apps/chat/task/llm.py b/backend/apps/chat/task/llm.py index 895aea5e..c240a04b 100644 --- a/backend/apps/chat/task/llm.py +++ b/backend/apps/chat/task/llm.py @@ -1030,7 +1030,12 @@ class LLMService: def validate_history_ds(self): _invalid_ds = False _ds = self.ds - _assistant = self.current_assistant + if not self.current_assistant: + current_ds = self.session.exec(CoreDatasource, _ds.id) + _invalid_ds = not current_ds + else: + _ds_list: list[dict] = get_assistant_ds(session=self.session, llm_service=self) + _invalid_ds = any(item.get("id") == _ds.id for item in _ds_list) if _invalid_ds: yield orjson.dumps({'content': 'ds is invalid', 'type': 'error'}).decode() + '\n\n' From c23247edb3899f06b4102ae26f9c3281985b0a4c Mon Sep 17 00:00:00 2001 From: dataeaseShu Date: Wed, 30 Jul 2025 16:02:24 +0800 Subject: [PATCH 07/17] fix: bug fix --- frontend/src/views/ds/DatasourceForm.vue | 40 ++++++++++++++---------- 1 file changed, 24 insertions(+), 16 deletions(-) diff --git a/frontend/src/views/ds/DatasourceForm.vue b/frontend/src/views/ds/DatasourceForm.vue index 80bafdb0..e81db1b8 100644 --- a/frontend/src/views/ds/DatasourceForm.vue +++ b/frontend/src/views/ds/DatasourceForm.vue @@ -43,6 +43,7 @@ const tableList = ref([]) const excelUploadSuccess = ref(false) const tableListLoading = ref(false) const token = wsCache.get('user.token') +const checkLoading = ref(false) const request_key = computed(() => { // eslint-disable-next-line no-undef return LicenseGenerator.generate() @@ -350,23 +351,30 @@ const next = debounce(async (formEl: FormInstance | undefined) => { emit('changeActiveStep', props.activeStep + 1) } } else { + if (checkLoading.value) return // check status if success do next const requestObj = buildConf() - datasourceApi.check(requestObj).then((res: boolean) => { - if (res) { - emit('changeActiveStep', props.activeStep + 1) - // request tables - datasourceApi.getTablesByConf(requestObj).then((res: any) => { - tableList.value = res - }) - } else { - ElMessage({ - message: t('ds.form.connect.failed'), - type: 'error', - showClose: true, - }) - } - }) + checkLoading.value = true + datasourceApi + .check(requestObj) + .then((res: boolean) => { + if (res) { + emit('changeActiveStep', props.activeStep + 1) + // request tables + datasourceApi.getTablesByConf(requestObj).then((res: any) => { + tableList.value = res + }) + } else { + ElMessage({ + message: t('ds.form.connect.failed'), + type: 'error', + showClose: true, + }) + } + }) + .finally(() => { + checkLoading.value = false + }) } } }) @@ -480,7 +488,7 @@ defineExpose({