From c0ffc0aaf518f68d634944320cc9cc15373af0d5 Mon Sep 17 00:00:00 2001 From: liqiang-fit2cloud Date: Wed, 9 Apr 2025 09:57:11 +0800 Subject: [PATCH 001/215] security: fix reverse shell vulnerability in function library. --- apps/common/util/function_code.py | 2 +- installer/Dockerfile | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/common/util/function_code.py b/apps/common/util/function_code.py index 31797a9f425..30ce3a33d20 100644 --- a/apps/common/util/function_code.py +++ b/apps/common/util/function_code.py @@ -88,7 +88,7 @@ def _exec_sandbox(self, _code, _id): os.system(f"chown {self.user}:{self.user} {exec_python_file}") kwargs = {'cwd': BASE_DIR} subprocess_result = subprocess.run( - ['su', '-c', python_directory + ' ' + exec_python_file, self.user], + ['su', '-s', python_directory, '-c', "exec(open('" + exec_python_file + "').read())", self.user], text=True, capture_output=True, **kwargs) os.remove(exec_python_file) diff --git a/installer/Dockerfile b/installer/Dockerfile index a2dc3f66264..d2c1eefb6fa 100644 --- a/installer/Dockerfile +++ b/installer/Dockerfile @@ -70,7 +70,7 @@ RUN chmod 755 /opt/maxkb/app/installer/run-maxkb.sh && \ useradd --no-create-home --home /opt/maxkb/app/sandbox sandbox -g root && \ chown -R sandbox:root /opt/maxkb/app/sandbox && \ chmod g-x /usr/local/bin/* /usr/bin/* /bin/* /usr/sbin/* /sbin/* /usr/lib/postgresql/15/bin/* && \ - chmod g+x /usr/local/bin/python* /bin/sh + chmod g+x /usr/local/bin/python* EXPOSE 8080 From 0b60a03e5df917b91b153227f8cf8d6f7510f292 Mon Sep 17 00:00:00 2001 From: ivy <188476399@qq.com> Date: Fri, 11 Apr 2025 16:56:41 +0800 Subject: [PATCH 002/215] perf: refine copywriting --- ui/src/locales/lang/en-US/views/system.ts | 1 + ui/src/locales/lang/zh-CN/views/system.ts | 3 ++- ui/src/locales/lang/zh-Hant/views/system.ts | 3 ++- ui/src/router/modules/setting.ts | 2 +- 4 files changed, 6 insertions(+), 3 deletions(-) diff --git a/ui/src/locales/lang/en-US/views/system.ts b/ui/src/locales/lang/en-US/views/system.ts index 303d1175dcf..6488ed6b5ae 100644 --- a/ui/src/locales/lang/en-US/views/system.ts +++ b/ui/src/locales/lang/en-US/views/system.ts @@ -1,5 +1,6 @@ export default { title: 'System', + subTitle: 'Setting', test: 'Test Connection', testSuccess: 'Successful', testFailed: 'Test connection failed', diff --git a/ui/src/locales/lang/zh-CN/views/system.ts b/ui/src/locales/lang/zh-CN/views/system.ts index 9ce23d90d86..1b72e1e01e1 100644 --- a/ui/src/locales/lang/zh-CN/views/system.ts +++ b/ui/src/locales/lang/zh-CN/views/system.ts @@ -1,5 +1,6 @@ export default { - title: '系统设置', + title: '系统管理', + subTitle: '系统设置', test: '测试连接', testSuccess: '测试连接成功', testFailed: '测试连接失败', diff --git a/ui/src/locales/lang/zh-Hant/views/system.ts b/ui/src/locales/lang/zh-Hant/views/system.ts index 10259390be1..e27e6c1228c 100644 --- a/ui/src/locales/lang/zh-Hant/views/system.ts +++ b/ui/src/locales/lang/zh-Hant/views/system.ts @@ -1,5 +1,6 @@ export default { - title: '系統設置', + title: '系統管理', + subTitle: '系統設置', test: '測試連線', testSuccess: '測試連線成功', testFailed: '測試連線失敗', diff --git a/ui/src/router/modules/setting.ts b/ui/src/router/modules/setting.ts index e97a658b02b..eaedb6a5f50 100644 --- a/ui/src/router/modules/setting.ts +++ b/ui/src/router/modules/setting.ts @@ -59,7 +59,7 @@ const settingRouter = { meta: { icon: 'app-setting', iconActive: 'app-setting-active', - title: 'common.setting', + title: 'views.system.subTitle', activeMenu: '/setting', parentPath: '/setting', parentName: 'setting', From 3b24373cd076e17842fbf374b06531f49cac4795 Mon Sep 17 00:00:00 2001 From: CaptainB Date: Mon, 14 Apr 2025 14:19:31 +0800 Subject: [PATCH 003/215] fix: handle line breaks in cell content for markdown table formatting MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --bug=1054683 --user=刘瑞斌 【github#2831】知识库上传excel、应用编排文档内容提取节点中上传excel,单元格中有换行,导入后没有在一个单元格里显示 https://www.tapd.cn/57709429/s/1685274 --- apps/common/handle/impl/table/xls_parse_table_handle.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/apps/common/handle/impl/table/xls_parse_table_handle.py b/apps/common/handle/impl/table/xls_parse_table_handle.py index 5609e3e8835..897e347e8a8 100644 --- a/apps/common/handle/impl/table/xls_parse_table_handle.py +++ b/apps/common/handle/impl/table/xls_parse_table_handle.py @@ -82,7 +82,10 @@ def get_content(self, file, save_image): for row in data: # 将每个单元格中的内容替换换行符为
以保留原始格式 md_table += '| ' + ' | '.join( - [str(cell).replace('\n', '
') if cell else '' for cell in row]) + ' |\n' + [str(cell) + .replace('\r\n', '
') + .replace('\n', '
') + if cell else '' for cell in row]) + ' |\n' md_tables += md_table + '\n\n' return md_tables From c781c11d268395f591f2046822a49987002cb3cf Mon Sep 17 00:00:00 2001 From: wangdan-fit2cloud <79562285+wangdan-fit2cloud@users.noreply.github.com> Date: Mon, 14 Apr 2025 15:11:55 +0800 Subject: [PATCH 004/215] fix: Application chat page style issue (#2866) --- ui/src/views/chat/base/index.vue | 20 -------------------- 1 file changed, 20 deletions(-) diff --git a/ui/src/views/chat/base/index.vue b/ui/src/views/chat/base/index.vue index 27be286f25a..7156f7d894a 100644 --- a/ui/src/views/chat/base/index.vue +++ b/ui/src/views/chat/base/index.vue @@ -42,7 +42,6 @@ - diff --git a/ui/src/views/login/reset-password/index.vue b/ui/src/views/login/reset-password/index.vue index 2c2ff02576e..576e6f340a6 100644 --- a/ui/src/views/login/reset-password/index.vue +++ b/ui/src/views/login/reset-password/index.vue @@ -1,6 +1,10 @@ - + From b62c79fda69f42fd528cba96a33878cc4155d86e Mon Sep 17 00:00:00 2001 From: wangdan-fit2cloud Date: Thu, 10 Jul 2025 11:36:16 +0800 Subject: [PATCH 133/215] fix: text bug --- .../lang/zh-CN/views/application-workflow.ts | 2 +- .../views/application/ApplicationAccess.vue | 49 +------------------ 2 files changed, 2 insertions(+), 49 deletions(-) diff --git a/ui/src/locales/lang/zh-CN/views/application-workflow.ts b/ui/src/locales/lang/zh-CN/views/application-workflow.ts index 1495316b836..c7c6038cc5f 100644 --- a/ui/src/locales/lang/zh-CN/views/application-workflow.ts +++ b/ui/src/locales/lang/zh-CN/views/application-workflow.ts @@ -266,7 +266,7 @@ export default { label: '文本转语音', text: '将文本通过语音合成模型转换为音频', tts_model: { - label: '语音识别模型' + label: '语音合成模型' }, content: { label: '选择文本内容' diff --git a/ui/src/views/application/ApplicationAccess.vue b/ui/src/views/application/ApplicationAccess.vue index ce2fe6aab82..8e1bf03b7e6 100644 --- a/ui/src/views/application/ApplicationAccess.vue +++ b/ui/src/views/application/ApplicationAccess.vue @@ -135,51 +135,4 @@ onMounted(() => { }) - + From e1ada3ffe24e5f11962f16dad7c3495d12518bdf Mon Sep 17 00:00:00 2001 From: liqiang-fit2cloud Date: Thu, 10 Jul 2025 17:37:21 +0800 Subject: [PATCH 134/215] Update build-and-push.yml --- .github/workflows/build-and-push.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build-and-push.yml b/.github/workflows/build-and-push.yml index 2c873cd36ee..1e1daf2696c 100644 --- a/.github/workflows/build-and-push.yml +++ b/.github/workflows/build-and-push.yml @@ -64,7 +64,7 @@ jobs: TAG_NAME=${{ github.event.inputs.dockerImageTag }} TAG_NAME_WITH_LATEST=${{ github.event.inputs.dockerImageTagWithLatest }} if [[ ${TAG_NAME_WITH_LATEST} == 'true' ]]; then - DOCKER_IMAGE_TAGS="--tag ${DOCKER_IMAGE}:${TAG_NAME} --tag ${DOCKER_IMAGE}:latest" + DOCKER_IMAGE_TAGS="--tag ${DOCKER_IMAGE}:${TAG_NAME} --tag ${DOCKER_IMAGE}:${TAG_NAME%%.*}" else DOCKER_IMAGE_TAGS="--tag ${DOCKER_IMAGE}:${TAG_NAME}" fi @@ -122,7 +122,7 @@ jobs: TAG_NAME=${{ github.event.inputs.dockerImageTag }} TAG_NAME_WITH_LATEST=${{ github.event.inputs.dockerImageTagWithLatest }} if [[ ${TAG_NAME_WITH_LATEST} == 'true' ]]; then - DOCKER_IMAGE_TAGS="--tag ${DOCKER_IMAGE}:${TAG_NAME} --tag ${DOCKER_IMAGE}:latest" + DOCKER_IMAGE_TAGS="--tag ${DOCKER_IMAGE}:${TAG_NAME} --tag ${DOCKER_IMAGE}:${TAG_NAME%%.*}" else DOCKER_IMAGE_TAGS="--tag ${DOCKER_IMAGE}:${TAG_NAME}" fi From 90c64d77dde7058a084e65f45c9112bda139943f Mon Sep 17 00:00:00 2001 From: maninhill <41712985+maninhill@users.noreply.github.com> Date: Mon, 14 Jul 2025 17:27:02 +0800 Subject: [PATCH 135/215] chore: Update README.md (#3584) --- README.md | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 06025c069c3..b4ef070847f 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@

MaxKB

-

An Open-Source AI Assistant for Enterprise

+

Open-source platform for building enterprise-grade agents

1Panel-dev%2FMaxKB | Trendshift

License: GPL v3 @@ -10,7 +10,7 @@


-MaxKB = Max Knowledge Brain, it is a powerful and easy-to-use AI assistant that integrates Retrieval-Augmented Generation (RAG) pipelines, supports robust workflows, and provides advanced MCP tool-use capabilities. MaxKB is widely applied in scenarios such as intelligent customer service, corporate internal knowledge bases, academic research, and education. +MaxKB = Max Knowledge Brain, it is an open-source platform for building enterprise-grade agents. MaxKB integrates Retrieval-Augmented Generation (RAG) pipelines, supports robust workflows, and provides advanced MCP tool-use capabilities. MaxKB is widely applied in scenarios such as intelligent customer service, corporate internal knowledge bases, academic research, and education. - **RAG Pipeline**: Supports direct uploading of documents / automatic crawling of online documents, with features for automatic text splitting, vectorization. This effectively reduces hallucinations in large models, providing a superior smart Q&A interaction experience. - **Agentic Workflow**: Equipped with a powerful workflow engine, function library and MCP tool-use, enabling the orchestration of AI processes to meet the needs of complex business scenarios. @@ -55,8 +55,6 @@ Access MaxKB web interface at `http://your_server_ip:8080` with default admin cr ## Feature Comparison -MaxKB is positioned as an Ready-to-use RAG (Retrieval-Augmented Generation) intelligent Q&A application, rather than a middleware platform for building large model applications. The following table is merely a comparison from a functional perspective. - From d47699331c4f67bbf055394f76ba1ff4caad38da Mon Sep 17 00:00:00 2001 From: maninhill <41712985+maninhill@users.noreply.github.com> Date: Mon, 14 Jul 2025 17:28:34 +0800 Subject: [PATCH 136/215] chore: Update README_CN.md (#3585) --- README_CN.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README_CN.md b/README_CN.md index 11c0df23b14..aec9379eea8 100644 --- a/README_CN.md +++ b/README_CN.md @@ -1,5 +1,5 @@

MaxKB

-

强大易用的企业级 AI 助手

+

强大易用的企业级智能体平台

1Panel-dev%2FMaxKB | Trendshift

@@ -14,7 +14,7 @@


-MaxKB = Max Knowledge Brain,是一款强大易用的企业级 AI 助手,支持 RAG 检索增强生成、工作流编排、MCP 工具调用能力。MaxKB 支持对接各种主流大语言模型,广泛应用于智能客服、企业内部知识库问答、员工助手、学术研究与教育等场景。 +MaxKB = Max Knowledge Brain,是一款强大易用的企业级智能体平台,支持 RAG 检索增强生成、工作流编排、MCP 工具调用能力。MaxKB 支持对接各种主流大语言模型,广泛应用于智能客服、企业内部知识库问答、员工助手、学术研究与教育等场景。 - **RAG 检索增强生成**:高效搭建本地 AI 知识库,支持直接上传文档 / 自动爬取在线文档,支持文本自动拆分、向量化,有效减少大模型幻觉,提升问答效果; - **灵活编排**:内置强大的工作流引擎、函数库和 MCP 工具调用能力,支持编排 AI 工作过程,满足复杂业务场景下的需求; From 2a257edff93c4a3602f084578675d7460c8a282c Mon Sep 17 00:00:00 2001 From: maninhill <41712985+maninhill@users.noreply.github.com> Date: Mon, 14 Jul 2025 17:49:32 +0800 Subject: [PATCH 137/215] chore: Update README.md (#3587) --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index b4ef070847f..7acd92c539c 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,6 @@

MaxKB

Open-source platform for building enterprise-grade agents

+

强大易用的企业级智能体平台

1Panel-dev%2FMaxKB | Trendshift

License: GPL v3 From efa196c58b1fc0ed8afe4611f50d7801b4c84938 Mon Sep 17 00:00:00 2001 From: liqiang-fit2cloud Date: Tue, 15 Jul 2025 16:23:46 +0800 Subject: [PATCH 138/215] docs: Update README.md --- README.md | 2 +- README_CN.md | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 7acd92c539c..40320976bfb 100644 --- a/README.md +++ b/README.md @@ -24,7 +24,7 @@ MaxKB = Max Knowledge Brain, it is an open-source platform for building enterpri Execute the script below to start a MaxKB container using Docker: ```bash -docker run -d --name=maxkb --restart=always -p 8080:8080 -v ~/.maxkb:/var/lib/postgresql/data -v ~/.python-packages:/opt/maxkb/app/sandbox/python-packages 1panel/maxkb +docker run -d --name=maxkb --restart=always -p 8080:8080 -v ~/.maxkb:/var/lib/postgresql/data -v ~/.python-packages:/opt/maxkb/app/sandbox/python-packages 1panel/maxkb:v1 ``` Access MaxKB web interface at `http://your_server_ip:8080` with default admin credentials: diff --git a/README_CN.md b/README_CN.md index aec9379eea8..631fda832aa 100644 --- a/README_CN.md +++ b/README_CN.md @@ -27,10 +27,10 @@ MaxKB 三分钟视频介绍:https://www.bilibili.com/video/BV18JypYeEkj/ ``` # Linux 机器 -docker run -d --name=maxkb --restart=always -p 8080:8080 -v ~/.maxkb:/var/lib/postgresql/data -v ~/.python-packages:/opt/maxkb/app/sandbox/python-packages registry.fit2cloud.com/maxkb/maxkb +docker run -d --name=maxkb --restart=always -p 8080:8080 -v ~/.maxkb:/var/lib/postgresql/data -v ~/.python-packages:/opt/maxkb/app/sandbox/python-packages registry.fit2cloud.com/maxkb/maxkb:v1 # Windows 机器 -docker run -d --name=maxkb --restart=always -p 8080:8080 -v C:/maxkb:/var/lib/postgresql/data -v C:/python-packages:/opt/maxkb/app/sandbox/python-packages registry.fit2cloud.com/maxkb/maxkb +docker run -d --name=maxkb --restart=always -p 8080:8080 -v C:/maxkb:/var/lib/postgresql/data -v C:/python-packages:/opt/maxkb/app/sandbox/python-packages registry.fit2cloud.com/maxkb/maxkb:v1 # 用户名: admin # 密码: MaxKB@123.. From f01a65f5079d2080f04e4482983cf704992506da Mon Sep 17 00:00:00 2001 From: liqiang-fit2cloud Date: Tue, 15 Jul 2025 16:26:03 +0800 Subject: [PATCH 139/215] docs: Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 40320976bfb..b4a925edb64 100644 --- a/README.md +++ b/README.md @@ -32,7 +32,7 @@ Access MaxKB web interface at `http://your_server_ip:8080` with default admin cr - username: admin - password: MaxKB@123.. -中国用户如遇到 Docker 镜像 Pull 失败问题,请参照该 [离线安装文档](https://maxkb.cn/docs/installation/offline_installtion/) 进行安装。 +中国用户如遇到 Docker 镜像 Pull 失败问题,请参照该 [离线安装文档](https://maxkb.cn/docs/v1/installation/offline_installtion/) 进行安装。 ## Screenshots From 1268b2043ad439381e94cd55aee58a375709411b Mon Sep 17 00:00:00 2001 From: maninhill <41712985+maninhill@users.noreply.github.com> Date: Tue, 15 Jul 2025 21:35:03 +0800 Subject: [PATCH 140/215] chore: Update README_CN.md (#3619) --- README_CN.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README_CN.md b/README_CN.md index 631fda832aa..37a80ffa991 100644 --- a/README_CN.md +++ b/README_CN.md @@ -14,7 +14,7 @@


-MaxKB = Max Knowledge Brain,是一款强大易用的企业级智能体平台,支持 RAG 检索增强生成、工作流编排、MCP 工具调用能力。MaxKB 支持对接各种主流大语言模型,广泛应用于智能客服、企业内部知识库问答、员工助手、学术研究与教育等场景。 +MaxKB = Max Knowledge Brain,是一个强大易用的企业级智能体平台,致力于解决企业 AI 落地面临的技术门槛高、部署成本高、迭代周期长等问题,助力企业在人工智能时代赢得先机。秉承“开箱即用,伴随成长”的设计理念,MaxKB 支持企业快速接入主流大模型,高效构建专属知识库,并提供从基础问答(RAG)、复杂流程自动化(工作流)到智能体(Agent)的渐进式升级路径,全面赋能智能客服、智能办公助手等多种应用场景。 - **RAG 检索增强生成**:高效搭建本地 AI 知识库,支持直接上传文档 / 自动爬取在线文档,支持文本自动拆分、向量化,有效减少大模型幻觉,提升问答效果; - **灵活编排**:内置强大的工作流引擎、函数库和 MCP 工具调用能力,支持编排 AI 工作过程,满足复杂业务场景下的需求; @@ -39,7 +39,7 @@ docker run -d --name=maxkb --restart=always -p 8080:8080 -v C:/maxkb:/var/lib/po - 你也可以通过 [1Panel 应用商店](https://apps.fit2cloud.com/1panel) 快速部署 MaxKB; - 如果是内网环境,推荐使用 [离线安装包](https://community.fit2cloud.com/#/products/maxkb/downloads) 进行安装部署; - MaxKB 产品版本分为社区版和专业版,详情请参见:[MaxKB 产品版本对比](https://maxkb.cn/pricing.html); -- 如果您需要向团队介绍 MaxKB,可以使用这个 [官方 PPT 材料](https://maxkb.cn/download/introduce-maxkb_202503.pdf)。 +- 如果您需要向团队介绍 MaxKB,可以使用这个 [官方 PPT 材料](https://maxkb.cn/download/introduce-maxkb_202507.pdf)。 如你有更多问题,可以查看使用手册,或者通过论坛与我们交流。 From ee83139b9679aab9201322a079b6c5ba12dabd5c Mon Sep 17 00:00:00 2001 From: maninhill <41712985+maninhill@users.noreply.github.com> Date: Tue, 15 Jul 2025 21:56:48 +0800 Subject: [PATCH 141/215] chore: Update README_CN.md (#3621) --- README_CN.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README_CN.md b/README_CN.md index 37a80ffa991..c1d64fb3f6f 100644 --- a/README_CN.md +++ b/README_CN.md @@ -19,7 +19,7 @@ MaxKB = Max Knowledge Brain,是一个强大易用的企业级智能体平台 - **RAG 检索增强生成**:高效搭建本地 AI 知识库,支持直接上传文档 / 自动爬取在线文档,支持文本自动拆分、向量化,有效减少大模型幻觉,提升问答效果; - **灵活编排**:内置强大的工作流引擎、函数库和 MCP 工具调用能力,支持编排 AI 工作过程,满足复杂业务场景下的需求; - **无缝嵌入**:支持零编码快速嵌入到第三方业务系统,让已有系统快速拥有智能问答能力,提高用户满意度; -- **模型中立**:支持对接各种大模型,包括本地私有大模型(DeepSeek R1 / Llama 3 / Qwen 2 等)、国内公共大模型(通义千问 / 腾讯混元 / 字节豆包 / 百度千帆 / 智谱 AI / Kimi 等)和国外公共大模型(OpenAI / Claude / Gemini 等)。 +- **模型中立**:支持对接各种大模型,包括本地私有大模型(DeepSeek R1 / Qwen 3 等)、国内公共大模型(通义千问 / 腾讯混元 / 字节豆包 / 百度千帆 / 智谱 AI / Kimi 等)和国外公共大模型(OpenAI / Claude / Gemini 等)。 MaxKB 三分钟视频介绍:https://www.bilibili.com/video/BV18JypYeEkj/ @@ -38,7 +38,7 @@ docker run -d --name=maxkb --restart=always -p 8080:8080 -v C:/maxkb:/var/lib/po - 你也可以通过 [1Panel 应用商店](https://apps.fit2cloud.com/1panel) 快速部署 MaxKB; - 如果是内网环境,推荐使用 [离线安装包](https://community.fit2cloud.com/#/products/maxkb/downloads) 进行安装部署; -- MaxKB 产品版本分为社区版和专业版,详情请参见:[MaxKB 产品版本对比](https://maxkb.cn/pricing.html); +- MaxKB 不同产品产品版本的对比请参见:[MaxKB 产品版本对比](https://maxkb.cn/price); - 如果您需要向团队介绍 MaxKB,可以使用这个 [官方 PPT 材料](https://maxkb.cn/download/introduce-maxkb_202507.pdf)。 如你有更多问题,可以查看使用手册,或者通过论坛与我们交流。 From 30ddab322f74480fac77b330aa4e2b578bd07235 Mon Sep 17 00:00:00 2001 From: liqiang-fit2cloud Date: Wed, 16 Jul 2025 10:30:40 +0800 Subject: [PATCH 142/215] Update README_CN.md --- README_CN.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README_CN.md b/README_CN.md index c1d64fb3f6f..07fa00ea4e6 100644 --- a/README_CN.md +++ b/README_CN.md @@ -39,7 +39,7 @@ docker run -d --name=maxkb --restart=always -p 8080:8080 -v C:/maxkb:/var/lib/po - 你也可以通过 [1Panel 应用商店](https://apps.fit2cloud.com/1panel) 快速部署 MaxKB; - 如果是内网环境,推荐使用 [离线安装包](https://community.fit2cloud.com/#/products/maxkb/downloads) 进行安装部署; - MaxKB 不同产品产品版本的对比请参见:[MaxKB 产品版本对比](https://maxkb.cn/price); -- 如果您需要向团队介绍 MaxKB,可以使用这个 [官方 PPT 材料](https://maxkb.cn/download/introduce-maxkb_202507.pdf)。 +- 如果您需要向团队介绍 MaxKB,可以使用这个 [官方 PPT 材料](https://fit2cloud.com/maxkb/download/introduce-maxkb_202507.pdf)。 如你有更多问题,可以查看使用手册,或者通过论坛与我们交流。 From 90ee3c4d21c173e9c77b9d4f46171d3124be7165 Mon Sep 17 00:00:00 2001 From: wxg0103 <727495428@qq.com> Date: Mon, 21 Jul 2025 11:05:48 +0800 Subject: [PATCH 143/215] refactor: improve formatting in chat_serializers.py MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --bug=1059060 --user=王孝刚 【github#3392】【应用】对话日志使用自定义时间段导出报错 https://www.tapd.cn/57709429/s/1736692 --- apps/application/serializers/chat_serializers.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/apps/application/serializers/chat_serializers.py b/apps/application/serializers/chat_serializers.py index ea43c6c5793..6eb429ac07e 100644 --- a/apps/application/serializers/chat_serializers.py +++ b/apps/application/serializers/chat_serializers.py @@ -222,7 +222,8 @@ def to_row(row: Dict): reference_paragraph, "\n".join([ f"{improve_paragraph_list[index].get('title')}\n{improve_paragraph_list[index].get('content')}" - for index in range(len(improve_paragraph_list))]), + for index in range(len(improve_paragraph_list)) + ]) if improve_paragraph_list is not None else "", row.get('asker').get('user_name'), row.get('message_tokens') + row.get('answer_tokens'), row.get('run_time'), str(row.get('create_time').astimezone(pytz.timezone(TIME_ZONE)).strftime('%Y-%m-%d %H:%M:%S') From 93d1958fef133d42bb6de13b45edeb81ef8b1d43 Mon Sep 17 00:00:00 2001 From: CaptainB Date: Mon, 21 Jul 2025 11:21:27 +0800 Subject: [PATCH 144/215] fix: validate transport type in MCP server configuration MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --bug=1056812 --user=刘瑞斌 【github##3232】【应用编排】mcp节点的transport配置填写http,错误提示不对 https://www.tapd.cn/57709429/s/1736690 --- apps/application/serializers/application_serializers.py | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/apps/application/serializers/application_serializers.py b/apps/application/serializers/application_serializers.py index 9cd06bf2b92..d25a6c95271 100644 --- a/apps/application/serializers/application_serializers.py +++ b/apps/application/serializers/application_serializers.py @@ -16,6 +16,7 @@ import uuid from functools import reduce from typing import Dict, List + from django.contrib.postgres.fields import ArrayField from django.core import cache, validators from django.core import signing @@ -24,8 +25,8 @@ from django.db.models.expressions import RawSQL from django.http import HttpResponse from django.template import Template, Context +from django.utils.translation import gettext_lazy as _, get_language, to_locale from langchain_mcp_adapters.client import MultiServerMCPClient -from mcp.client.sse import sse_client from rest_framework import serializers, status from rest_framework.utils.formatting import lazy_format @@ -38,7 +39,7 @@ from common.constants.authentication_type import AuthenticationType from common.db.search import get_dynamics_model, native_search, native_page_search from common.db.sql_execute import select_list -from common.exception.app_exception import AppApiException, NotFound404, AppUnauthorizedFailed, ChatException +from common.exception.app_exception import AppApiException, NotFound404, AppUnauthorizedFailed from common.field.common import UploadedImageField, UploadedFileField from common.models.db_model_manage import DBModelManage from common.response import result @@ -57,7 +58,6 @@ from setting.serializers.provider_serializers import ModelSerializer from smartdoc.conf import PROJECT_DIR from users.models import User -from django.utils.translation import gettext_lazy as _, get_language, to_locale chat_cache = cache.caches['chat_cache'] @@ -1328,6 +1328,9 @@ def get_mcp_servers(self, with_valid=True): if '"stdio"' in self.data.get('mcp_servers'): raise AppApiException(500, _('stdio is not supported')) servers = json.loads(self.data.get('mcp_servers')) + for server, config in servers.items(): + if config.get('transport') not in ['sse', 'streamable_http']: + raise AppApiException(500, _('Only support transport=sse or transport=streamable_http')) async def get_mcp_tools(servers): async with MultiServerMCPClient(servers) as client: From f568c6800ffaeb7b00e312d4af6a355c8714f47d Mon Sep 17 00:00:00 2001 From: wxg0103 <727495428@qq.com> Date: Mon, 21 Jul 2025 11:31:03 +0800 Subject: [PATCH 145/215] refactor: add early return for invalid document type in document_serializers.py MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --bug=1057562 --user=王孝刚 【知识库】飞书知识库对接,设置命中处理方式保存报错 https://www.tapd.cn/57709429/s/1736833 --- apps/dataset/serializers/document_serializers.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/apps/dataset/serializers/document_serializers.py b/apps/dataset/serializers/document_serializers.py index 3b92a7e60fa..ff70486608d 100644 --- a/apps/dataset/serializers/document_serializers.py +++ b/apps/dataset/serializers/document_serializers.py @@ -141,6 +141,8 @@ def is_valid(self, *, document: Document = None): if 'meta' in self.data and self.data.get('meta') is not None: dataset_meta_valid_map = self.get_meta_valid_map() valid_class = dataset_meta_valid_map.get(document.type) + if valid_class is None: + return valid_class(data=self.data.get('meta')).is_valid(raise_exception=True) From 622a8e525c7b4cbaee6085837ea53095673fedde Mon Sep 17 00:00:00 2001 From: wxg0103 <727495428@qq.com> Date: Mon, 21 Jul 2025 11:32:26 +0800 Subject: [PATCH 146/215] refactor: add early return for invalid document type in document_serializers.py MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --bug=1057562 --user=王孝刚 【知识库】飞书知识库对接,设置命中处理方式保存报错 https://www.tapd.cn/57709429/s/1736833 --- apps/dataset/serializers/document_serializers.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/apps/dataset/serializers/document_serializers.py b/apps/dataset/serializers/document_serializers.py index ff70486608d..b34ca626527 100644 --- a/apps/dataset/serializers/document_serializers.py +++ b/apps/dataset/serializers/document_serializers.py @@ -141,9 +141,8 @@ def is_valid(self, *, document: Document = None): if 'meta' in self.data and self.data.get('meta') is not None: dataset_meta_valid_map = self.get_meta_valid_map() valid_class = dataset_meta_valid_map.get(document.type) - if valid_class is None: - return - valid_class(data=self.data.get('meta')).is_valid(raise_exception=True) + if valid_class is not None: + valid_class(data=self.data.get('meta')).is_valid(raise_exception=True) class DocumentWebInstanceSerializer(ApiMixin, serializers.Serializer): From bca56af7883d7ae0ba862b6b562956c513fa3c09 Mon Sep 17 00:00:00 2001 From: shaohuzhang1 <80892890+shaohuzhang1@users.noreply.github.com> Date: Mon, 21 Jul 2025 11:38:41 +0800 Subject: [PATCH 147/215] fix: Interface permission verification error #3343 (#3683) --- .../serializers/function_lib_serializer.py | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/apps/function_lib/serializers/function_lib_serializer.py b/apps/function_lib/serializers/function_lib_serializer.py index 440eb22c786..ad7ff3cce61 100644 --- a/apps/function_lib/serializers/function_lib_serializer.py +++ b/apps/function_lib/serializers/function_lib_serializer.py @@ -33,11 +33,13 @@ function_executor = FunctionExecutor(CONFIG.get('SANDBOX')) + class FlibInstance: def __init__(self, function_lib: dict, version: str): self.function_lib = function_lib self.version = version + def encryption(message: str): """ 加密敏感字段数据 加密方式是 如果密码是 1234567890 那么给前端则是 123******890 @@ -68,7 +70,8 @@ def encryption(message: str): class FunctionLibModelSerializer(serializers.ModelSerializer): class Meta: model = FunctionLib - fields = ['id', 'name', 'icon', 'desc', 'code', 'input_field_list','init_field_list', 'init_params', 'permission_type', 'is_active', 'user_id', 'template_id', + fields = ['id', 'name', 'icon', 'desc', 'code', 'input_field_list', 'init_field_list', 'init_params', + 'permission_type', 'is_active', 'user_id', 'template_id', 'create_time', 'update_time'] @@ -148,7 +151,6 @@ class Query(serializers.Serializer): select_user_id = serializers.CharField(required=False, allow_null=True, allow_blank=True) function_type = serializers.CharField(required=False, allow_null=True, allow_blank=True) - def get_query_set(self): query_set = QuerySet(FunctionLib).filter( (Q(user_id=self.data.get('user_id')) | Q(permission_type='PUBLIC'))) @@ -269,7 +271,7 @@ class Operate(serializers.Serializer): def is_valid(self, *, raise_exception=False): super().is_valid(raise_exception=True) - if not QuerySet(FunctionLib).filter(id=self.data.get('id')).exists(): + if not QuerySet(FunctionLib).filter(user_id=self.data.get('user_id'), id=self.data.get('id')).exists(): raise AppApiException(500, _('Function does not exist')) def delete(self, with_valid=True): @@ -285,7 +287,8 @@ def edit(self, instance, with_valid=True): if with_valid: self.is_valid(raise_exception=True) EditFunctionLib(data=instance).is_valid(raise_exception=True) - edit_field_list = ['name', 'desc', 'code', 'icon', 'input_field_list', 'init_field_list', 'init_params', 'permission_type', 'is_active'] + edit_field_list = ['name', 'desc', 'code', 'icon', 'input_field_list', 'init_field_list', 'init_params', + 'permission_type', 'is_active'] edit_dict = {field: instance.get(field) for field in edit_field_list if ( field in instance and instance.get(field) is not None)} @@ -317,7 +320,8 @@ def one(self, with_valid=True): if function_lib.init_params: function_lib.init_params = json.loads(rsa_long_decrypt(function_lib.init_params)) if function_lib.init_field_list: - password_fields = [i["field"] for i in function_lib.init_field_list if i.get("input_type") == "PasswordInput"] + password_fields = [i["field"] for i in function_lib.init_field_list if + i.get("input_type") == "PasswordInput"] if function_lib.init_params: for k in function_lib.init_params: if k in password_fields and function_lib.init_params[k]: From b7ba9fdf67f9082c78db0f1e795c109fd691bb8d Mon Sep 17 00:00:00 2001 From: CaptainB Date: Mon, 21 Jul 2025 12:05:55 +0800 Subject: [PATCH 148/215] fix: change HitTest action methods from GET to PUT in API views --- apps/application/views/application_views.py | 38 ++++++++++----------- apps/dataset/views/dataset.py | 22 ++++++------ ui/src/api/application.ts | 2 +- ui/src/api/dataset.ts | 2 +- 4 files changed, 31 insertions(+), 33 deletions(-) diff --git a/apps/application/views/application_views.py b/apps/application/views/application_views.py index f16041d1de3..8c3e8059bcb 100644 --- a/apps/application/views/application_views.py +++ b/apps/application/views/application_views.py @@ -7,16 +7,6 @@ @desc: """ -from django.core import cache -from django.http import HttpResponse -from django.utils.translation import gettext_lazy as _, gettext -from drf_yasg.utils import swagger_auto_schema -from langchain_core.prompts import PromptTemplate -from rest_framework.decorators import action -from rest_framework.parsers import MultiPartParser -from rest_framework.request import Request -from rest_framework.views import APIView - from application.serializers.application_serializers import ApplicationSerializer from application.serializers.application_statistics_serializers import ApplicationStatisticsSerializer from application.swagger_api.application_api import ApplicationApi @@ -31,6 +21,14 @@ from common.swagger_api.common_api import CommonApi from common.util.common import query_params_to_single_dict from dataset.serializers.dataset_serializers import DataSetSerializers +from django.core import cache +from django.http import HttpResponse +from django.utils.translation import gettext_lazy as _ +from drf_yasg.utils import swagger_auto_schema +from rest_framework.decorators import action +from rest_framework.parsers import MultiPartParser +from rest_framework.request import Request +from rest_framework.views import APIView chat_cache = cache.caches['chat_cache'] @@ -494,7 +492,7 @@ def get(self, request: Request): class HitTest(APIView): authentication_classes = [TokenAuth] - @action(methods="GET", detail=False) + @action(methods="PUT", detail=False) @swagger_auto_schema(operation_summary=_("Hit Test List"), operation_id=_("Hit Test List"), manual_parameters=CommonApi.HitTestApi.get_request_params_api(), responses=result.get_api_array_response(CommonApi.HitTestApi.get_response_body_api()), @@ -505,15 +503,15 @@ class HitTest(APIView): [lambda r, keywords: Permission(group=Group.APPLICATION, operate=Operate.USE, dynamic_tag=keywords.get('application_id'))], compare=CompareConstants.AND)) - def get(self, request: Request, application_id: str): - return result.success( - ApplicationSerializer.HitTest(data={'id': application_id, 'user_id': request.user.id, - "query_text": request.query_params.get("query_text"), - "top_number": request.query_params.get("top_number"), - 'similarity': request.query_params.get('similarity'), - 'search_mode': request.query_params.get( - 'search_mode')}).hit_test( - )) + def put(self, request: Request, application_id: str): + return result.success(ApplicationSerializer.HitTest(data={ + 'id': application_id, + 'user_id': request.user.id, + "query_text": request.data.get("query_text"), + "top_number": request.data.get("top_number"), + 'similarity': request.data.get('similarity'), + 'search_mode': request.data.get('search_mode')} + ).hit_test()) class Publish(APIView): authentication_classes = [TokenAuth] diff --git a/apps/dataset/views/dataset.py b/apps/dataset/views/dataset.py index bbb9e033980..ad28bc1984e 100644 --- a/apps/dataset/views/dataset.py +++ b/apps/dataset/views/dataset.py @@ -7,13 +7,13 @@ @desc: """ +from django.utils.translation import gettext_lazy as _ from drf_yasg.utils import swagger_auto_schema from rest_framework.decorators import action from rest_framework.parsers import MultiPartParser from rest_framework.views import APIView from rest_framework.views import Request -import dataset.models from common.auth import TokenAuth, has_permissions from common.constants.permission_constants import PermissionConstants, CompareConstants, Permission, Group, Operate, \ ViewPermission, RoleConstants @@ -25,7 +25,6 @@ from dataset.serializers.dataset_serializers import DataSetSerializers from dataset.views.common import get_dataset_operation_object from setting.serializers.provider_serializers import ModelSerializer -from django.utils.translation import gettext_lazy as _ class Dataset(APIView): @@ -141,21 +140,22 @@ def post(self, request: Request): class HitTest(APIView): authentication_classes = [TokenAuth] - @action(methods="GET", detail=False) + @action(methods="PUT", detail=False) @swagger_auto_schema(operation_summary=_('Hit test list'), operation_id=_('Hit test list'), manual_parameters=CommonApi.HitTestApi.get_request_params_api(), responses=result.get_api_array_response(CommonApi.HitTestApi.get_response_body_api()), tags=[_('Knowledge Base')]) @has_permissions(lambda r, keywords: Permission(group=Group.DATASET, operate=Operate.USE, dynamic_tag=keywords.get('dataset_id'))) - def get(self, request: Request, dataset_id: str): - return result.success( - DataSetSerializers.HitTest(data={'id': dataset_id, 'user_id': request.user.id, - "query_text": request.query_params.get("query_text"), - "top_number": request.query_params.get("top_number"), - 'similarity': request.query_params.get('similarity'), - 'search_mode': request.query_params.get('search_mode')}).hit_test( - )) + def put(self, request: Request, dataset_id: str): + return result.success(DataSetSerializers.HitTest(data={ + 'id': dataset_id, + 'user_id': request.user.id, + "query_text": request.data.get("query_text"), + "top_number": request.data.get("top_number"), + 'similarity': request.data.get('similarity'), + 'search_mode': request.data.get('search_mode')} + ).hit_test()) class Embedding(APIView): authentication_classes = [TokenAuth] diff --git a/ui/src/api/application.ts b/ui/src/api/application.ts index efd4a4985a8..bc903c957eb 100644 --- a/ui/src/api/application.ts +++ b/ui/src/api/application.ts @@ -227,7 +227,7 @@ const getApplicationHitTest: ( data: any, loading?: Ref ) => Promise>> = (application_id, data, loading) => { - return get(`${prefix}/${application_id}/hit_test`, data, loading) + return put(`${prefix}/${application_id}/hit_test`, data, undefined, loading) } /** diff --git a/ui/src/api/dataset.ts b/ui/src/api/dataset.ts index a5a663b03c7..83de865b3bc 100644 --- a/ui/src/api/dataset.ts +++ b/ui/src/api/dataset.ts @@ -186,7 +186,7 @@ const getDatasetHitTest: ( data: any, loading?: Ref ) => Promise>> = (dataset_id, data, loading) => { - return get(`${prefix}/${dataset_id}/hit_test`, data, loading) + return put(`${prefix}/${dataset_id}/hit_test`, data, undefined, loading) } /** From abe51dc30c91e15d0b193af0658cbd930c7e8403 Mon Sep 17 00:00:00 2001 From: shaohuzhang1 <80892890+shaohuzhang1@users.noreply.github.com> Date: Mon, 21 Jul 2025 12:34:14 +0800 Subject: [PATCH 149/215] fix: Quick question in the opening statement, English word breaks.(#3158) Co-authored-by: wangdan-fit2cloud --- ui/src/components/markdown/MdRenderer.vue | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ui/src/components/markdown/MdRenderer.vue b/ui/src/components/markdown/MdRenderer.vue index e2fc4ee903e..eb991477a43 100644 --- a/ui/src/components/markdown/MdRenderer.vue +++ b/ui/src/components/markdown/MdRenderer.vue @@ -9,7 +9,7 @@ class="problem-button mt-4 mb-4 flex" :class="sendMessage ? 'cursor' : 'disabled'" > - + {{ item.content }} @@ -237,7 +237,7 @@ const split_form_rander_ = (source: string, type: string) => { padding: 12px; box-sizing: border-box; color: var(--el-text-color-regular); - word-break: break-all; + word-break: break-word; &:hover { background: var(--el-color-primary-light-9); From 8ecf5b52ed1e35e0719261601c33af55f02364d1 Mon Sep 17 00:00:00 2001 From: shaohuzhang1 <80892890+shaohuzhang1@users.noreply.github.com> Date: Mon, 21 Jul 2025 15:18:40 +0800 Subject: [PATCH 150/215] fix: Interface permission verification error #3309 (#3687) --- apps/application/flow/workflow_manage.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/application/flow/workflow_manage.py b/apps/application/flow/workflow_manage.py index 0f7bc9c7576..0922f5cd515 100644 --- a/apps/application/flow/workflow_manage.py +++ b/apps/application/flow/workflow_manage.py @@ -298,8 +298,8 @@ def init_fields(self): if global_fields is not None: for global_field in global_fields: global_field_list.append({**global_field, 'node_id': node_id, 'node_name': node_name}) - field_list.sort(key=lambda f: len(f.get('node_name')), reverse=True) - global_field_list.sort(key=lambda f: len(f.get('node_name')), reverse=True) + field_list.sort(key=lambda f: len(f.get('node_name') + f.get('label')), reverse=True) + global_field_list.sort(key=lambda f: len(f.get('node_name') + f.get('label')), reverse=True) self.field_list = field_list self.global_field_list = global_field_list From 40be71d765c788f672a4ea313c30b11e516d9c9b Mon Sep 17 00:00:00 2001 From: shaohuzhang1 <80892890+shaohuzhang1@users.noreply.github.com> Date: Mon, 21 Jul 2025 15:24:49 +0800 Subject: [PATCH 151/215] fix: Create document prompt error #3527 (#3688) --- apps/dataset/serializers/document_serializers.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/dataset/serializers/document_serializers.py b/apps/dataset/serializers/document_serializers.py index b34ca626527..caae7a78dae 100644 --- a/apps/dataset/serializers/document_serializers.py +++ b/apps/dataset/serializers/document_serializers.py @@ -856,7 +856,7 @@ def get_request_body_api(): class Create(ApiMixin, serializers.Serializer): dataset_id = serializers.UUIDField(required=True, error_messages=ErrMessage.char( - _('document id'))) + _('dataset id'))) def is_valid(self, *, raise_exception=False): super().is_valid(raise_exception=True) From 4013606a93adc72a8e30f810d7665b527913c7f9 Mon Sep 17 00:00:00 2001 From: shaohuzhang1 <80892890+shaohuzhang1@users.noreply.github.com> Date: Mon, 21 Jul 2025 16:12:47 +0800 Subject: [PATCH 152/215] fix: The password rule prompt is unclear #3547 (#3689) --- apps/locales/en_US/LC_MESSAGES/django.po | 2 +- apps/locales/zh_CN/LC_MESSAGES/django.po | 3 ++- apps/locales/zh_Hant/LC_MESSAGES/django.po | 2 +- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/apps/locales/en_US/LC_MESSAGES/django.po b/apps/locales/en_US/LC_MESSAGES/django.po index e068ff410a0..ad642d8747d 100644 --- a/apps/locales/en_US/LC_MESSAGES/django.po +++ b/apps/locales/en_US/LC_MESSAGES/django.po @@ -7238,7 +7238,7 @@ msgstr "" msgid "" "The confirmation password must be 6-20 characters long and must be a " "combination of letters, numbers, and special characters." -msgstr "" +msgstr "The confirmation password must be 6-20 characters long and must be a combination of letters, numbers, and special characters.(Special character support:_、!、@、#、$、%、(、) ……)" #: community/apps/users/serializers/user_serializers.py:380 #, python-brace-format diff --git a/apps/locales/zh_CN/LC_MESSAGES/django.po b/apps/locales/zh_CN/LC_MESSAGES/django.po index 346fd5e47ad..55f71fe5031 100644 --- a/apps/locales/zh_CN/LC_MESSAGES/django.po +++ b/apps/locales/zh_CN/LC_MESSAGES/django.po @@ -7395,7 +7395,8 @@ msgstr "语言只支持:" msgid "" "The confirmation password must be 6-20 characters long and must be a " "combination of letters, numbers, and special characters." -msgstr "确认密码长度6-20个字符,必须字母、数字、特殊字符组合" +_!@#$%^&*`~()-+= +msgstr "确认密码长度6-20个字符,必须字母、数字、特殊字符组合(特殊字符支持:_、!、@、#、$、%、(、) ……)" #: community/apps/users/serializers/user_serializers.py:380 #, python-brace-format diff --git a/apps/locales/zh_Hant/LC_MESSAGES/django.po b/apps/locales/zh_Hant/LC_MESSAGES/django.po index 8bf746a89c8..3feacf1778d 100644 --- a/apps/locales/zh_Hant/LC_MESSAGES/django.po +++ b/apps/locales/zh_Hant/LC_MESSAGES/django.po @@ -7405,7 +7405,7 @@ msgstr "語言只支持:" msgid "" "The confirmation password must be 6-20 characters long and must be a " "combination of letters, numbers, and special characters." -msgstr "確認密碼長度6-20個字符,必須字母、數字、特殊字符組合" +msgstr "確認密碼長度6-20個字符,必須字母、數字、特殊字符組合(特殊字元支持:_、!、@、#、$、%、(、) ……)" #: community/apps/users/serializers/user_serializers.py:380 #, python-brace-format From 8d3b3f8121484d507620371668c45a043631600f Mon Sep 17 00:00:00 2001 From: shaohuzhang1 <80892890+shaohuzhang1@users.noreply.github.com> Date: Mon, 21 Jul 2025 16:20:38 +0800 Subject: [PATCH 153/215] fix: Quick question in the opening statement, English word breaks.(#3158) Co-authored-by: wangdan-fit2cloud From 02d6239a711f8b7b65d06b2ab3b68d4418e47863 Mon Sep 17 00:00:00 2001 From: wangdan-fit2cloud Date: Mon, 21 Jul 2025 16:44:13 +0800 Subject: [PATCH 154/215] fix: Quick question in the opening statement, English word breaks.(#3158) --- ui/src/components/ai-chat/index.vue | 4 ++-- ui/src/views/application-workflow/index.vue | 5 ++--- ui/src/views/chat/embed/index.vue | 4 +++- ui/src/views/chat/mobile/index.vue | 4 +++- ui/src/views/chat/pc/index.vue | 4 +++- 5 files changed, 13 insertions(+), 8 deletions(-) diff --git a/ui/src/components/ai-chat/index.vue b/ui/src/components/ai-chat/index.vue index a3e3d3d36cf..bbc95010255 100644 --- a/ui/src/components/ai-chat/index.vue +++ b/ui/src/components/ai-chat/index.vue @@ -163,13 +163,13 @@ const initialApiFormData = ref({}) const isUserInput = computed( () => props.applicationDetails.work_flow?.nodes?.filter((v: any) => v.id === 'base-node')[0] - .properties.user_input_field_list.length > 0 + ?.properties.user_input_field_list.length > 0 ) const isAPIInput = computed( () => props.type === 'debug-ai-chat' && props.applicationDetails.work_flow?.nodes?.filter((v: any) => v.id === 'base-node')[0] - .properties.api_input_field_list.length > 0 + ?.properties.api_input_field_list.length > 0 ) const showUserInputContent = computed(() => { return ( diff --git a/ui/src/views/application-workflow/index.vue b/ui/src/views/application-workflow/index.vue index f9a30983943..d623968a946 100644 --- a/ui/src/views/application-workflow/index.vue +++ b/ui/src/views/application-workflow/index.vue @@ -3,7 +3,7 @@
-

{{ detail?.name }}

+

{{ detail?.name }}

{{ $t('views.applicationWorkflow.info.previewVersion') }} @@ -101,7 +101,7 @@ />
-

+

{{ detail?.name || $t('views.application.applicationForm.form.appName.label') }}

@@ -279,7 +279,6 @@ async function publicHandle() { return } applicationApi.putPublishApplication(id as String, obj, loading).then(() => { - application.asyncGetApplicationDetail(id, loading).then((res: any) => { detail.value.name = res.data.name MsgSuccess(t('views.applicationWorkflow.tip.publicSuccess')) diff --git a/ui/src/views/chat/embed/index.vue b/ui/src/views/chat/embed/index.vue index 34063439fb4..806e6622e09 100644 --- a/ui/src/views/chat/embed/index.vue +++ b/ui/src/views/chat/embed/index.vue @@ -28,7 +28,9 @@ />
-

{{ applicationDetail?.name }}

+

+ {{ applicationDetail?.name }} +

diff --git a/ui/src/views/chat/mobile/index.vue b/ui/src/views/chat/mobile/index.vue index 3748dd1b728..820634f9e65 100644 --- a/ui/src/views/chat/mobile/index.vue +++ b/ui/src/views/chat/mobile/index.vue @@ -27,7 +27,9 @@ />
-

{{ applicationDetail?.name }}

+

+ {{ applicationDetail?.name }} +

diff --git a/ui/src/views/chat/pc/index.vue b/ui/src/views/chat/pc/index.vue index 30fd2fb6bf1..e51a2b9df83 100644 --- a/ui/src/views/chat/pc/index.vue +++ b/ui/src/views/chat/pc/index.vue @@ -27,7 +27,9 @@ :size="32" />
-

{{ applicationDetail?.name }}

+

+ {{ applicationDetail?.name }} +

From 0ba9b97752998eabc7e3083b45d71202aa04f27f Mon Sep 17 00:00:00 2001 From: CaptainB Date: Mon, 21 Jul 2025 17:45:20 +0800 Subject: [PATCH 155/215] feat: add MySQL and PostgreSQL query templates with JSON serialization --- .../0004_functionlib_decimal_date.py | 127 ++++++++++++++++++ 1 file changed, 127 insertions(+) create mode 100644 apps/function_lib/migrations/0004_functionlib_decimal_date.py diff --git a/apps/function_lib/migrations/0004_functionlib_decimal_date.py b/apps/function_lib/migrations/0004_functionlib_decimal_date.py new file mode 100644 index 00000000000..82e4a6d029a --- /dev/null +++ b/apps/function_lib/migrations/0004_functionlib_decimal_date.py @@ -0,0 +1,127 @@ +# Generated by Django 4.2.15 on 2025-03-13 07:21 + +from django.db import migrations +from django.db.models import Q + +mysql_template = """ +def query_mysql(host,port, user, password, database, sql): + import pymysql + import json + from pymysql.cursors import DictCursor + from datetime import datetime, date + + def default_serializer(obj): + from decimal import Decimal + if isinstance(obj, (datetime, date)): + return obj.isoformat() # 将 datetime/date 转换为 ISO 格式字符串 + elif isinstance(obj, Decimal): + return float(obj) # 将 Decimal 转换为 float + raise TypeError(f"Type {type(obj)} not serializable") + + try: + # 创建连接 + db = pymysql.connect( + host=host, + port=int(port), + user=user, + password=password, + database=database, + cursorclass=DictCursor # 使用字典游标 + ) + + # 使用 cursor() 方法创建一个游标对象 cursor + cursor = db.cursor() + + # 使用 execute() 方法执行 SQL 查询 + cursor.execute(sql) + + # 使用 fetchall() 方法获取所有数据 + data = cursor.fetchall() + + # 处理 bytes 类型的数据 + for row in data: + for key, value in row.items(): + if isinstance(value, bytes): + row[key] = value.decode("utf-8") # 转换为字符串 + + # 将数据序列化为 JSON + json_data = json.dumps(data, default=default_serializer, ensure_ascii=False) + return json_data + + # 关闭数据库连接 + db.close() + + except Exception as e: + print(f"Error while connecting to MySQL: {e}") + raise e +""" + +pgsql_template = """ +def queryPgSQL(database, user, password, host, port, query): + import psycopg2 + import json + from datetime import datetime + + # 自定义 JSON 序列化函数 + def default_serializer(obj): + from decimal import Decimal + if isinstance(obj, datetime): + return obj.isoformat() # 将 datetime 转换为 ISO 格式字符串 + elif isinstance(obj, Decimal): + return float(obj) # 将 Decimal 转换为 float + raise TypeError(f"Type {type(obj)} not serializable") + + # 数据库连接信息 + conn_params = { + "dbname": database, + "user": user, + "password": password, + "host": host, + "port": port + } + try: + # 建立连接 + conn = psycopg2.connect(**conn_params) + print("连接成功!") + # 创建游标对象 + cursor = conn.cursor() + # 执行查询语句 + cursor.execute(query) + # 获取查询结果 + rows = cursor.fetchall() + # 处理 bytes 类型的数据 + columns = [desc[0] for desc in cursor.description] + result = [dict(zip(columns, row)) for row in rows] + # 转换为 JSON 格式 + json_result = json.dumps(result, default=default_serializer, ensure_ascii=False) + return json_result + except Exception as e: + print(f"发生错误:{e}") + raise e + finally: + # 关闭游标和连接 + if cursor: + cursor.close() + if conn: + conn.close() +""" + + +def fix_type(apps, schema_editor): + FunctionLib = apps.get_model('function_lib', 'FunctionLib') + FunctionLib.objects.filter( + Q(id='22c21b76-0308-11f0-9694-5618c4394482') | Q(template_id='22c21b76-0308-11f0-9694-5618c4394482') + ).update(code=mysql_template) + FunctionLib.objects.filter( + Q(id='bd1e8b88-0302-11f0-87bb-5618c4394482') | Q(template_id='bd1e8b88-0302-11f0-87bb-5618c4394482') + ).update(code=pgsql_template) + + +class Migration(migrations.Migration): + dependencies = [ + ('function_lib', '0003_functionlib_function_type_functionlib_icon_and_more'), + ] + + operations = [ + migrations.RunPython(fix_type) + ] From 1ee0eac4550092f014927a0f95458e4d8c8341f6 Mon Sep 17 00:00:00 2001 From: shaohuzhang1 <80892890+shaohuzhang1@users.noreply.github.com> Date: Tue, 22 Jul 2025 10:20:46 +0800 Subject: [PATCH 156/215] build: locales (#3696) --- apps/locales/zh_CN/LC_MESSAGES/django.po | 1 - 1 file changed, 1 deletion(-) diff --git a/apps/locales/zh_CN/LC_MESSAGES/django.po b/apps/locales/zh_CN/LC_MESSAGES/django.po index 55f71fe5031..4b38c171bc2 100644 --- a/apps/locales/zh_CN/LC_MESSAGES/django.po +++ b/apps/locales/zh_CN/LC_MESSAGES/django.po @@ -7395,7 +7395,6 @@ msgstr "语言只支持:" msgid "" "The confirmation password must be 6-20 characters long and must be a " "combination of letters, numbers, and special characters." -_!@#$%^&*`~()-+= msgstr "确认密码长度6-20个字符,必须字母、数字、特殊字符组合(特殊字符支持:_、!、@、#、$、%、(、) ……)" #: community/apps/users/serializers/user_serializers.py:380 From 0531a6ecc8adde8406973d31cc95bd495cdc67eb Mon Sep 17 00:00:00 2001 From: shaohuzhang1 <80892890+shaohuzhang1@users.noreply.github.com> Date: Tue, 22 Jul 2025 10:35:20 +0800 Subject: [PATCH 157/215] feat: Support session_timeout parameter (#3697) --- apps/common/auth/handle/impl/user_token.py | 10 +++++----- apps/smartdoc/conf.py | 4 ++++ apps/users/views/user.py | 4 ++-- 3 files changed, 11 insertions(+), 7 deletions(-) diff --git a/apps/common/auth/handle/impl/user_token.py b/apps/common/auth/handle/impl/user_token.py index dbb6bd2b51a..bdb041f9f79 100644 --- a/apps/common/auth/handle/impl/user_token.py +++ b/apps/common/auth/handle/impl/user_token.py @@ -6,18 +6,18 @@ @date:2024/3/14 03:02 @desc: 用户认证 """ +from django.core import cache from django.db.models import QuerySet +from django.utils.translation import gettext_lazy as _ from common.auth.handle.auth_base_handle import AuthBaseHandle from common.constants.authentication_type import AuthenticationType from common.constants.permission_constants import RoleConstants, get_permission_list_by_role, Auth from common.exception.app_exception import AppAuthenticationFailed -from smartdoc.settings import JWT_AUTH +from smartdoc.const import CONFIG from users.models import User -from django.core import cache - from users.models.user import get_user_dynamics_permission -from django.utils.translation import gettext_lazy as _ + token_cache = cache.caches['token_cache'] @@ -35,7 +35,7 @@ def handle(self, request, token: str, get_token_details): auth_details = get_token_details() user = QuerySet(User).get(id=auth_details['id']) # 续期 - token_cache.touch(token, timeout=JWT_AUTH['JWT_EXPIRATION_DELTA'].total_seconds()) + token_cache.touch(token, timeout=CONFIG.get_session_timeout()) rule = RoleConstants[user.role] permission_list = get_permission_list_by_role(RoleConstants[user.role]) # 获取用户的应用和知识库的权限 diff --git a/apps/smartdoc/conf.py b/apps/smartdoc/conf.py index 8da97883ca9..21deebf55cf 100644 --- a/apps/smartdoc/conf.py +++ b/apps/smartdoc/conf.py @@ -7,6 +7,7 @@ 2. 程序需要, 用户不需要更改的写到settings中 3. 程序需要, 用户需要更改的写到本config中 """ +import datetime import errno import logging import os @@ -119,6 +120,9 @@ def get_db_setting(self) -> dict: } } + def get_session_timeout(self): + return datetime.timedelta(seconds=self.get('SESSION_TIMEOUT', 28800)) + def get_language_code(self): return self.get('LANGUAGE_CODE', 'zh-CN') diff --git a/apps/users/views/user.py b/apps/users/views/user.py index 9e21daa4ee9..3ca8b395f91 100644 --- a/apps/users/views/user.py +++ b/apps/users/views/user.py @@ -22,7 +22,7 @@ from common.log.log import log from common.response import result from common.util.common import encryption -from smartdoc.settings import JWT_AUTH +from smartdoc.const import CONFIG from users.serializers.user_serializers import RegisterSerializer, LoginSerializer, CheckCodeSerializer, \ RePasswordSerializer, \ SendEmailSerializer, UserProfile, UserSerializer, UserManageSerializer, UserInstanceSerializer, SystemSerializer, \ @@ -199,7 +199,7 @@ def post(self, request: Request): # 校验请求参数 user = login_request.is_valid(raise_exception=True) token = login_request.get_user_token() - token_cache.set(token, user, timeout=JWT_AUTH['JWT_EXPIRATION_DELTA']) + token_cache.set(token, user, timeout=CONFIG.get_session_timeout()) return result.success(token) From 55a7d73f985c7fae87e84e61e08847b18af27f95 Mon Sep 17 00:00:00 2001 From: shaohuzhang1 <80892890+shaohuzhang1@users.noreply.github.com> Date: Tue, 22 Jul 2025 11:26:52 +0800 Subject: [PATCH 158/215] fix: The thinking process information of AI dialogue nodes is lost (#3698) --- .../flow/step_node/ai_chat_step_node/impl/base_chat_node.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/apps/application/flow/step_node/ai_chat_step_node/impl/base_chat_node.py b/apps/application/flow/step_node/ai_chat_step_node/impl/base_chat_node.py index 56efa4e54ef..00871a8dc4d 100644 --- a/apps/application/flow/step_node/ai_chat_step_node/impl/base_chat_node.py +++ b/apps/application/flow/step_node/ai_chat_step_node/impl/base_chat_node.py @@ -188,6 +188,7 @@ def save_context(self, details, workflow_manage): self.context['answer'] = details.get('answer') self.context['question'] = details.get('question') self.context['reasoning_content'] = details.get('reasoning_content') + self.context['model_setting'] = details.get('model_setting') if self.node_params.get('is_result', False): self.answer_text = details.get('answer') @@ -274,6 +275,7 @@ def get_details(self, index: int, **kwargs): "index": index, 'run_time': self.context.get('run_time'), 'system': self.context.get('system'), + 'model_setting': self.context.get('model_setting'), 'history_message': [{'content': message.content, 'role': message.type} for message in (self.context.get('history_message') if self.context.get( 'history_message') is not None else [])], From ae30052daea89f133776c304e791d133fe45fb9f Mon Sep 17 00:00:00 2001 From: shaohuzhang1 <80892890+shaohuzhang1@users.noreply.github.com> Date: Tue, 22 Jul 2025 11:52:04 +0800 Subject: [PATCH 159/215] docs: Delete the conversation log history_day parameter #3159 (#3699) --- apps/application/swagger_api/chat_api.py | 5 ----- 1 file changed, 5 deletions(-) diff --git a/apps/application/swagger_api/chat_api.py b/apps/application/swagger_api/chat_api.py index 54b5678f747..f27a19c200e 100644 --- a/apps/application/swagger_api/chat_api.py +++ b/apps/application/swagger_api/chat_api.py @@ -326,11 +326,6 @@ def get_request_params_api(): type=openapi.TYPE_STRING, required=True, description=_('Application ID')), - openapi.Parameter(name='history_day', - in_=openapi.IN_QUERY, - type=openapi.TYPE_NUMBER, - required=True, - description=_('Historical days')), openapi.Parameter(name='abstract', in_=openapi.IN_QUERY, type=openapi.TYPE_STRING, required=False, description=_("abstract")), openapi.Parameter(name='min_star', in_=openapi.IN_QUERY, type=openapi.TYPE_INTEGER, required=False, From 01075166b8048b3a7e6d0f141dd79dacfbf5b772 Mon Sep 17 00:00:00 2001 From: shaohuzhang1 <80892890+shaohuzhang1@users.noreply.github.com> Date: Tue, 22 Jul 2025 12:05:24 +0800 Subject: [PATCH 160/215] docs: Missing thinking process related parameters in model_setting #3134 (#3700) --- apps/application/swagger_api/application_api.py | 14 +++++++++++++- apps/locales/en_US/LC_MESSAGES/django.po | 9 +++++++++ apps/locales/zh_CN/LC_MESSAGES/django.po | 11 ++++++++++- apps/locales/zh_Hant/LC_MESSAGES/django.po | 11 ++++++++++- 4 files changed, 42 insertions(+), 3 deletions(-) diff --git a/apps/application/swagger_api/application_api.py b/apps/application/swagger_api/application_api.py index 2c9cbd86bf4..4e47ab32619 100644 --- a/apps/application/swagger_api/application_api.py +++ b/apps/application/swagger_api/application_api.py @@ -302,7 +302,19 @@ def get_request_body_api(): 'no_references_prompt': openapi.Schema(type=openapi.TYPE_STRING, title=_("No citation segmentation prompt"), default="{question}", - description=_("No citation segmentation prompt")) + description=_("No citation segmentation prompt")), + 'reasoning_content_enable': openapi.Schema(type=openapi.TYPE_BOOLEAN, + title=_("Reasoning enable"), + default=False, + description=_("Reasoning enable")), + 'reasoning_content_end': openapi.Schema(type=openapi.TYPE_STRING, + title=_("Reasoning end tag"), + default="", + description=_("Reasoning end tag")), + "reasoning_content_start": openapi.Schema(type=openapi.TYPE_STRING, + title=_("Reasoning start tag"), + default="", + description=_("Reasoning start tag")) } ) diff --git a/apps/locales/en_US/LC_MESSAGES/django.po b/apps/locales/en_US/LC_MESSAGES/django.po index ad642d8747d..a7917f9741e 100644 --- a/apps/locales/en_US/LC_MESSAGES/django.po +++ b/apps/locales/en_US/LC_MESSAGES/django.po @@ -7499,4 +7499,13 @@ msgid "Captcha code error or expiration" msgstr "" msgid "captcha" +msgstr "" + +msgid "Reasoning enable" +msgstr "" + +msgid "Reasoning start tag" +msgstr "" + +msgid "Reasoning end tag" msgstr "" \ No newline at end of file diff --git a/apps/locales/zh_CN/LC_MESSAGES/django.po b/apps/locales/zh_CN/LC_MESSAGES/django.po index 4b38c171bc2..1674cf1d8ea 100644 --- a/apps/locales/zh_CN/LC_MESSAGES/django.po +++ b/apps/locales/zh_CN/LC_MESSAGES/django.po @@ -7662,4 +7662,13 @@ msgid "Captcha code error or expiration" msgstr "验证码错误或过期" msgid "captcha" -msgstr "验证码" \ No newline at end of file +msgstr "验证码" + +msgid "Reasoning enable" +msgstr "开启思考过程" + +msgid "Reasoning start tag" +msgstr "思考过程开始标签" + +msgid "Reasoning end tag" +msgstr "思考过程结束标签" \ No newline at end of file diff --git a/apps/locales/zh_Hant/LC_MESSAGES/django.po b/apps/locales/zh_Hant/LC_MESSAGES/django.po index 3feacf1778d..c00975d5a15 100644 --- a/apps/locales/zh_Hant/LC_MESSAGES/django.po +++ b/apps/locales/zh_Hant/LC_MESSAGES/django.po @@ -7672,4 +7672,13 @@ msgid "Captcha code error or expiration" msgstr "驗證碼錯誤或過期" msgid "captcha" -msgstr "驗證碼" \ No newline at end of file +msgstr "驗證碼" + +msgid "Reasoning enable" +msgstr "開啟思考過程" + +msgid "Reasoning start tag" +msgstr "思考過程開始標籤" + +msgid "Reasoning end tag" +msgstr "思考過程結束標籤" \ No newline at end of file From a0b6aaa5686b9ed5293b0375af0a6665765c8e61 Mon Sep 17 00:00:00 2001 From: shaohuzhang1 <80892890+shaohuzhang1@users.noreply.github.com> Date: Tue, 22 Jul 2025 15:49:59 +0800 Subject: [PATCH 161/215] fix: Specifying a specific form parameter for the reply output will result in an error #3309 (#3703) --- apps/application/flow/workflow_manage.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/application/flow/workflow_manage.py b/apps/application/flow/workflow_manage.py index 0922f5cd515..7496e01fe8b 100644 --- a/apps/application/flow/workflow_manage.py +++ b/apps/application/flow/workflow_manage.py @@ -298,8 +298,8 @@ def init_fields(self): if global_fields is not None: for global_field in global_fields: global_field_list.append({**global_field, 'node_id': node_id, 'node_name': node_name}) - field_list.sort(key=lambda f: len(f.get('node_name') + f.get('label')), reverse=True) - global_field_list.sort(key=lambda f: len(f.get('node_name') + f.get('label')), reverse=True) + field_list.sort(key=lambda f: len(f.get('node_name') + f.get('value')), reverse=True) + global_field_list.sort(key=lambda f: len(f.get('node_name') + f.get('value')), reverse=True) self.field_list = field_list self.global_field_list = global_field_list From 2adb872cdff6f59ee68553b81c89109c2c5716bc Mon Sep 17 00:00:00 2001 From: wangdan-fit2cloud Date: Tue, 22 Jul 2025 14:20:45 +0800 Subject: [PATCH 162/215] fix: Application dialogue history error(#3223) --- ui/src/views/chat/embed/index.vue | 2 +- ui/src/views/chat/mobile/index.vue | 2 +- ui/src/views/chat/pc/index.vue | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/ui/src/views/chat/embed/index.vue b/ui/src/views/chat/embed/index.vue index 806e6622e09..7cd5911c44a 100644 --- a/ui/src/views/chat/embed/index.vue +++ b/ui/src/views/chat/embed/index.vue @@ -265,7 +265,7 @@ function getChatRecord() { currentChatId.value, paginationConfig, loading, - false + true ) .then((res: any) => { paginationConfig.total = res.data.total diff --git a/ui/src/views/chat/mobile/index.vue b/ui/src/views/chat/mobile/index.vue index 820634f9e65..e2e9c7cb52f 100644 --- a/ui/src/views/chat/mobile/index.vue +++ b/ui/src/views/chat/mobile/index.vue @@ -261,7 +261,7 @@ function getChatRecord() { currentChatId.value, paginationConfig, loading, - false + true ) .then((res: any) => { paginationConfig.total = res.data.total diff --git a/ui/src/views/chat/pc/index.vue b/ui/src/views/chat/pc/index.vue index e51a2b9df83..f4340c0d773 100644 --- a/ui/src/views/chat/pc/index.vue +++ b/ui/src/views/chat/pc/index.vue @@ -315,7 +315,7 @@ function getChatRecord() { currentChatId.value, paginationConfig.value, loading, - false + true ) .then((res: any) => { paginationConfig.value.total = res.data.total From 33762f26bf1d9a8da18009d1ea815c0d0ae8c2b4 Mon Sep 17 00:00:00 2001 From: shaohuzhang1 <80892890+shaohuzhang1@users.noreply.github.com> Date: Tue, 22 Jul 2025 16:23:15 +0800 Subject: [PATCH 163/215] fix: Password change prompt (#3705) --- apps/locales/en_US/LC_MESSAGES/django.po | 2 +- apps/locales/zh_CN/LC_MESSAGES/django.po | 2 +- apps/locales/zh_Hant/LC_MESSAGES/django.po | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/apps/locales/en_US/LC_MESSAGES/django.po b/apps/locales/en_US/LC_MESSAGES/django.po index a7917f9741e..9b83be9686d 100644 --- a/apps/locales/en_US/LC_MESSAGES/django.po +++ b/apps/locales/en_US/LC_MESSAGES/django.po @@ -7238,7 +7238,7 @@ msgstr "" msgid "" "The confirmation password must be 6-20 characters long and must be a " "combination of letters, numbers, and special characters." -msgstr "The confirmation password must be 6-20 characters long and must be a combination of letters, numbers, and special characters.(Special character support:_、!、@、#、$、%、(、) ……)" +msgstr "The confirmation password must be 6-20 characters long and must be a combination of letters, numbers, and special characters.(Special character support:_、!、@、#、$、(、) ……)" #: community/apps/users/serializers/user_serializers.py:380 #, python-brace-format diff --git a/apps/locales/zh_CN/LC_MESSAGES/django.po b/apps/locales/zh_CN/LC_MESSAGES/django.po index 1674cf1d8ea..9500103c702 100644 --- a/apps/locales/zh_CN/LC_MESSAGES/django.po +++ b/apps/locales/zh_CN/LC_MESSAGES/django.po @@ -7395,7 +7395,7 @@ msgstr "语言只支持:" msgid "" "The confirmation password must be 6-20 characters long and must be a " "combination of letters, numbers, and special characters." -msgstr "确认密码长度6-20个字符,必须字母、数字、特殊字符组合(特殊字符支持:_、!、@、#、$、%、(、) ……)" +msgstr "确认密码长度6-20个字符,必须字母、数字、特殊字符组合(特殊字符支持:_、!、@、#、$、(、) ……)" #: community/apps/users/serializers/user_serializers.py:380 #, python-brace-format diff --git a/apps/locales/zh_Hant/LC_MESSAGES/django.po b/apps/locales/zh_Hant/LC_MESSAGES/django.po index c00975d5a15..6993cdd2161 100644 --- a/apps/locales/zh_Hant/LC_MESSAGES/django.po +++ b/apps/locales/zh_Hant/LC_MESSAGES/django.po @@ -7405,7 +7405,7 @@ msgstr "語言只支持:" msgid "" "The confirmation password must be 6-20 characters long and must be a " "combination of letters, numbers, and special characters." -msgstr "確認密碼長度6-20個字符,必須字母、數字、特殊字符組合(特殊字元支持:_、!、@、#、$、%、(、) ……)" +msgstr "確認密碼長度6-20個字符,必須字母、數字、特殊字符組合(特殊字元支持:_、!、@、#、$、(、) ……)" #: community/apps/users/serializers/user_serializers.py:380 #, python-brace-format From 8e3e46a96d4c82ebb59eb4aac3a2c14fc3c7a47e Mon Sep 17 00:00:00 2001 From: shaohuzhang1 <80892890+shaohuzhang1@users.noreply.github.com> Date: Tue, 22 Jul 2025 17:08:57 +0800 Subject: [PATCH 164/215] fix: Replace replaceAll with the replace function (#3706) #3656 --- .../component/chat-input-operate/index.vue | 53 +++---------------- .../component/prologue-content/index.vue | 2 +- 2 files changed, 7 insertions(+), 48 deletions(-) diff --git a/ui/src/components/ai-chat/component/chat-input-operate/index.vue b/ui/src/components/ai-chat/component/chat-input-operate/index.vue index 666a3b7eebc..de3c86b8849 100644 --- a/ui/src/components/ai-chat/component/chat-input-operate/index.vue +++ b/ui/src/components/ai-chat/component/chat-input-operate/index.vue @@ -287,7 +287,7 @@
From 6f69c8beb839eed02a60845e94121bccca65d5bf Mon Sep 17 00:00:00 2001 From: CaptainB Date: Mon, 18 Aug 2025 17:10:36 +0800 Subject: [PATCH 194/215] fix: add existence check for ProblemParagraphMapping association --- apps/dataset/serializers/paragraph_serializers.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/apps/dataset/serializers/paragraph_serializers.py b/apps/dataset/serializers/paragraph_serializers.py index 3a63fd95cd0..9b6e096ba00 100644 --- a/apps/dataset/serializers/paragraph_serializers.py +++ b/apps/dataset/serializers/paragraph_serializers.py @@ -226,6 +226,14 @@ def is_valid(self, *, raise_exception=True): def association(self, with_valid=True, with_embedding=True): if with_valid: self.is_valid(raise_exception=True) + # 已关联则直接返回 + if QuerySet(ProblemParagraphMapping).filter( + dataset_id=self.data.get('dataset_id'), + document_id=self.data.get('document_id'), + paragraph_id=self.data.get('paragraph_id'), + problem_id=self.data.get('problem_id') + ).exists(): + return True problem = QuerySet(Problem).filter(id=self.data.get("problem_id")).first() problem_paragraph_mapping = ProblemParagraphMapping(id=uuid.uuid1(), document_id=self.data.get('document_id'), From a10991ad6d9dd57d8725b6716a8555a1794dd522 Mon Sep 17 00:00:00 2001 From: CaptainB Date: Tue, 19 Aug 2025 12:40:05 +0800 Subject: [PATCH 195/215] fix: update pypdf version to 6.0.0 --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 52ea56180cd..3f6afe3ed90 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -39,7 +39,7 @@ html2text = "2024.2.26" django-ipware = "6.0.5" django-apscheduler = "0.6.2" pymupdf = "1.24.9" -pypdf = "4.3.1" +pypdf = "6.0.0" rapidocr-onnxruntime = "1.3.24" python-docx = "1.1.2" xlwt = "1.3.0" From 0e1ae663b137494a1aab5eadb30b5679d96cfc0e Mon Sep 17 00:00:00 2001 From: CaptainB Date: Tue, 19 Aug 2025 13:55:10 +0800 Subject: [PATCH 196/215] fix: add migration to refresh collation and reindex database --- .../0011_refresh_collation_reindex.py | 26 +++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 apps/setting/migrations/0011_refresh_collation_reindex.py diff --git a/apps/setting/migrations/0011_refresh_collation_reindex.py b/apps/setting/migrations/0011_refresh_collation_reindex.py new file mode 100644 index 00000000000..cfef5f1131d --- /dev/null +++ b/apps/setting/migrations/0011_refresh_collation_reindex.py @@ -0,0 +1,26 @@ +from django.db import migrations + + +def refresh_collation_and_reindex(apps, schema_editor): + # 获取当前数据库名 + db_name = schema_editor.connection.settings_dict["NAME"] + with schema_editor.connection.cursor() as cursor: + cursor.execute(f'ALTER DATABASE "{db_name}" REFRESH COLLATION VERSION;') + cursor.execute(f'REINDEX DATABASE "{db_name}";') + + +def noop(apps, schema_editor): + # 不可逆操作,留空 + pass + + +class Migration(migrations.Migration): + atomic = False # ALTER DATABASE/REINDEX 需在事务外执行 + + dependencies = [ + ('setting', '0010_log'), + ] + + operations = [ + migrations.RunPython(refresh_collation_and_reindex, reverse_code=noop), + ] \ No newline at end of file From 87eb5c37896ce40c5145cc49cfe3cf3662291168 Mon Sep 17 00:00:00 2001 From: CaptainB Date: Tue, 19 Aug 2025 14:05:12 +0800 Subject: [PATCH 197/215] fix: update Docker images to use latest versions and adjust permissions --- .github/workflows/build-and-push-python-pg.yml | 2 +- installer/Dockerfile | 1 + installer/Dockerfile-python-pg | 4 ++-- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/.github/workflows/build-and-push-python-pg.yml b/.github/workflows/build-and-push-python-pg.yml index 7bb843e3dfb..4640f5edbd0 100644 --- a/.github/workflows/build-and-push-python-pg.yml +++ b/.github/workflows/build-and-push-python-pg.yml @@ -39,7 +39,7 @@ jobs: run: | DOCKER_IMAGE=ghcr.io/1panel-dev/maxkb-python-pg DOCKER_PLATFORMS=${{ github.event.inputs.architecture }} - TAG_NAME=python3.11-pg15.8 + TAG_NAME=python3.11-pg15.14 DOCKER_IMAGE_TAGS="--tag ${DOCKER_IMAGE}:${TAG_NAME} --tag ${DOCKER_IMAGE}:latest" echo ::set-output name=docker_image::${DOCKER_IMAGE} echo ::set-output name=version::${TAG_NAME} diff --git a/installer/Dockerfile b/installer/Dockerfile index 796e8535ef3..7aa5eb9f794 100644 --- a/installer/Dockerfile +++ b/installer/Dockerfile @@ -70,6 +70,7 @@ RUN chmod 755 /opt/maxkb/app/installer/run-maxkb.sh && \ useradd --no-create-home --home /opt/maxkb/app/sandbox sandbox -g root && \ chown -R sandbox:root /opt/maxkb/app/sandbox && \ chmod g-x /usr/local/bin/* /usr/bin/* /bin/* /usr/sbin/* /sbin/* /usr/lib/postgresql/15/bin/* && \ + chmod g+xr /usr/bin/ld.so && \ chmod g+x /usr/local/bin/python* && \ find /etc/ -type f ! -path '/etc/resolv.conf' ! -path '/etc/hosts' | xargs chmod g-rx diff --git a/installer/Dockerfile-python-pg b/installer/Dockerfile-python-pg index 05bfce27a28..eb52eec17fe 100644 --- a/installer/Dockerfile-python-pg +++ b/installer/Dockerfile-python-pg @@ -1,5 +1,5 @@ -FROM python:3.11-slim-bookworm AS python-stage -FROM postgres:15.14-bookworm +FROM python:3.11-slim-trixie AS python-stage +FROM postgres:15.14-trixie ARG DEPENDENCIES=" \ libexpat1-dev \ From 886c45fb1d7d5caa04434b4c7c48cc0e625218ce Mon Sep 17 00:00:00 2001 From: CaptainB Date: Tue, 19 Aug 2025 14:06:48 +0800 Subject: [PATCH 198/215] fix: update Dockerfile to use Python 3.11 and PostgreSQL 15.14 images --- installer/Dockerfile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/installer/Dockerfile b/installer/Dockerfile index 7aa5eb9f794..81db7241543 100644 --- a/installer/Dockerfile +++ b/installer/Dockerfile @@ -5,7 +5,7 @@ RUN cd ui && \ npm install && \ npm run build && \ rm -rf ./node_modules -FROM ghcr.io/1panel-dev/maxkb-python-pg:python3.11-pg15.8 AS stage-build +FROM ghcr.io/1panel-dev/maxkb-python-pg:python3.11-pg15.14 AS stage-build ARG DEPENDENCIES=" \ python3-pip" @@ -29,7 +29,7 @@ RUN python3 -m venv /opt/py3 && \ poetry install && \ export MAXKB_CONFIG_TYPE=ENV && python3 /opt/maxkb/app/apps/manage.py compilemessages -FROM ghcr.io/1panel-dev/maxkb-python-pg:python3.11-pg15.8 +FROM ghcr.io/1panel-dev/maxkb-python-pg:python3.11-pg15.14 ARG DOCKER_IMAGE_TAG=dev \ BUILD_AT \ GITHUB_COMMIT From b9762738769f2fc01352d9212daff7897146f8fc Mon Sep 17 00:00:00 2001 From: CaptainB Date: Tue, 19 Aug 2025 14:40:27 +0800 Subject: [PATCH 199/215] fix: update API request handling to use request body schema instead of query parameters --- apps/common/swagger_api/common_api.py | 42 ++++++++++----------------- apps/dataset/views/dataset.py | 2 +- 2 files changed, 16 insertions(+), 28 deletions(-) diff --git a/apps/common/swagger_api/common_api.py b/apps/common/swagger_api/common_api.py index 3134db0d083..9e7d1976298 100644 --- a/apps/common/swagger_api/common_api.py +++ b/apps/common/swagger_api/common_api.py @@ -15,33 +15,21 @@ class CommonApi: class HitTestApi(ApiMixin): @staticmethod - def get_request_params_api(): - return [ - openapi.Parameter(name='query_text', - in_=openapi.IN_QUERY, - type=openapi.TYPE_STRING, - required=True, - description=_('query text')), - openapi.Parameter(name='top_number', - in_=openapi.IN_QUERY, - type=openapi.TYPE_NUMBER, - default=10, - required=True, - description='topN'), - openapi.Parameter(name='similarity', - in_=openapi.IN_QUERY, - type=openapi.TYPE_NUMBER, - default=0.6, - required=True, - description=_('similarity')), - openapi.Parameter(name='search_mode', - in_=openapi.IN_QUERY, - type=openapi.TYPE_STRING, - default="embedding", - required=True, - description=_('Retrieval pattern embedding|keywords|blend') - ) - ] + def get_request_body_api(): + return openapi.Schema( + type=openapi.TYPE_OBJECT, + required=['query_text', 'top_number', 'similarity', 'search_mode'], + properties={ + 'query_text': openapi.Schema(type=openapi.TYPE_STRING, title=_('query text'), + description=_('query text')), + 'top_number': openapi.Schema(type=openapi.TYPE_NUMBER, title=_('top number'), + description=_('top number')), + 'similarity': openapi.Schema(type=openapi.TYPE_NUMBER, title=_('similarity'), + description=_('similarity')), + 'search_mode': openapi.Schema(type=openapi.TYPE_STRING, title=_('search mode'), + description=_('search mode')) + } + ) @staticmethod def get_response_body_api(): diff --git a/apps/dataset/views/dataset.py b/apps/dataset/views/dataset.py index ad28bc1984e..aeb1af28932 100644 --- a/apps/dataset/views/dataset.py +++ b/apps/dataset/views/dataset.py @@ -142,7 +142,7 @@ class HitTest(APIView): @action(methods="PUT", detail=False) @swagger_auto_schema(operation_summary=_('Hit test list'), operation_id=_('Hit test list'), - manual_parameters=CommonApi.HitTestApi.get_request_params_api(), + request_body=CommonApi.HitTestApi.get_request_body_api(), responses=result.get_api_array_response(CommonApi.HitTestApi.get_response_body_api()), tags=[_('Knowledge Base')]) @has_permissions(lambda r, keywords: Permission(group=Group.DATASET, operate=Operate.USE, From a3b14cb562301eecd0c432a1e7b1e7a3f1c0d925 Mon Sep 17 00:00:00 2001 From: shaohuzhang1 <80892890+shaohuzhang1@users.noreply.github.com> Date: Tue, 19 Aug 2025 14:54:05 +0800 Subject: [PATCH 200/215] fix: The issue of prologue in the conversation log (#3880) Co-authored-by: wangdan-fit2cloud --- .../ai-chat/component/prologue-content/index.vue | 1 + ui/src/components/markdown/MdRenderer.vue | 7 +++++-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/ui/src/components/ai-chat/component/prologue-content/index.vue b/ui/src/components/ai-chat/component/prologue-content/index.vue index ddf9cde219b..3494673c4e3 100644 --- a/ui/src/components/ai-chat/component/prologue-content/index.vue +++ b/ui/src/components/ai-chat/component/prologue-content/index.vue @@ -17,6 +17,7 @@ :source="prologue" :send-message="sendMessage" reasoning_content="" + :type="type" > diff --git a/ui/src/components/markdown/MdRenderer.vue b/ui/src/components/markdown/MdRenderer.vue index eb991477a43..4fa7ed6ae6b 100644 --- a/ui/src/components/markdown/MdRenderer.vue +++ b/ui/src/components/markdown/MdRenderer.vue @@ -5,9 +5,11 @@
Feature