From c0ffc0aaf518f68d634944320cc9cc15373af0d5 Mon Sep 17 00:00:00 2001 From: liqiang-fit2cloud Date: Wed, 9 Apr 2025 09:57:11 +0800 Subject: [PATCH 001/140] 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/140] 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/140] 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/140] 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/140] 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/140] 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/140] 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/140] 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/140] 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 b57455d0eec8caa80f3a096555597dad26920e5c Mon Sep 17 00:00:00 2001 From: wxg0103 <727495428@qq.com> Date: Tue, 19 Aug 2025 11:06:36 +0800 Subject: [PATCH 138/140] refactor: expand permissions for application access token MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --bug=1060032 --user=王孝刚 【桂物智慧】 api 调用客户端修改对话摘要接口,报错403,没有访问权限 https://www.tapd.cn/57709429/s/1757188 --- apps/application/views/chat_views.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/application/views/chat_views.py b/apps/application/views/chat_views.py index 77a087351ee..b0f42c020b9 100644 --- a/apps/application/views/chat_views.py +++ b/apps/application/views/chat_views.py @@ -241,7 +241,7 @@ def delete(self, request: Request, application_id: str, chat_id: str): request_body=ChatClientHistoryApi.Operate.ReAbstract.get_request_body_api(), tags=[_("Application/Conversation Log")]) @has_permissions(ViewPermission( - [RoleConstants.APPLICATION_ACCESS_TOKEN], + [RoleConstants.APPLICATION_ACCESS_TOKEN, RoleConstants.ADMIN, RoleConstants.USER], [lambda r, keywords: Permission(group=Group.APPLICATION, operate=Operate.USE, dynamic_tag=keywords.get('application_id'))], compare=CompareConstants.AND), From 847755b1c2bba658a2062e0f47dd97fa8ae37247 Mon Sep 17 00:00:00 2001 From: wxg0103 <727495428@qq.com> Date: Tue, 19 Aug 2025 15:15:46 +0800 Subject: [PATCH 139/140] feat: add response body schemas for various API endpoints --- .../swagger_api/application_api.py | 111 ++++++++++++++++++ apps/application/swagger_api/chat_api.py | 9 ++ apps/application/views/application_views.py | 8 +- apps/application/views/chat_views.py | 4 + apps/dataset/views/dataset.py | 1 + .../swagger_api/function_lib_api.py | 49 +++++++- apps/function_lib/views/function_lib_views.py | 4 + apps/function_lib/views/py_lint.py | 1 + apps/setting/serializers/team_serializers.py | 18 +++ apps/setting/views/Team.py | 4 + apps/setting/views/model.py | 12 +- apps/users/views/user.py | 4 +- 12 files changed, 216 insertions(+), 9 deletions(-) diff --git a/apps/application/swagger_api/application_api.py b/apps/application/swagger_api/application_api.py index 2c9cbd86bf4..a2f08f0eae8 100644 --- a/apps/application/swagger_api/application_api.py +++ b/apps/application/swagger_api/application_api.py @@ -38,6 +38,15 @@ def get_request_body_api(): } ) + @staticmethod + def get_response_body_api(): + return openapi.Schema( + type=openapi.TYPE_STRING, + title=_("Application authentication token"), + description=_("Application authentication token"), + default="token" + ) + @staticmethod def get_response_body_api(): return openapi.Schema( @@ -133,6 +142,27 @@ def get_request_body_api(): } ) + @staticmethod + def get_response_body_api(): + return openapi.Schema( + type=openapi.TYPE_OBJECT, + properties={ + 'id': openapi.Schema(type=openapi.TYPE_STRING, title=_("Primary key id"), + description=_("Primary key id")), + 'secret_key': openapi.Schema(type=openapi.TYPE_STRING, title=_("Secret key"), + description=_("Secret key")), + 'is_active': openapi.Schema(type=openapi.TYPE_BOOLEAN, title=_("Is activation"), + description=_("Is activation")), + 'application_id': openapi.Schema(type=openapi.TYPE_STRING, title=_("Application ID"), + description=_("Application ID")), + 'allow_cross_domain': openapi.Schema(type=openapi.TYPE_BOOLEAN, + title=_("Is cross-domain allowed"), + description=_("Is cross-domain allowed")), + 'cross_domain_list': openapi.Schema(type=openapi.TYPE_ARRAY, title=_('Cross-domain list'), + items=openapi.Schema(type=openapi.TYPE_STRING)) + } + ) + class AccessToken(ApiMixin): @staticmethod def get_request_params_api(): @@ -171,6 +201,37 @@ def get_request_body_api(): } ) + @staticmethod + def get_response_body_api(): + return openapi.Schema( + type=openapi.TYPE_OBJECT, + required=[], + properties={ + 'id': openapi.Schema(type=openapi.TYPE_STRING, title=_("Primary key id"), + description=_("Primary key id")), + 'access_token': openapi.Schema(type=openapi.TYPE_STRING, title=_("Access Token"), + description=_("Access Token")), + 'access_token_reset': openapi.Schema(type=openapi.TYPE_BOOLEAN, title=_("Reset Token"), + description=_("Reset Token")), + + 'is_active': openapi.Schema(type=openapi.TYPE_BOOLEAN, title=_("Is activation"), + description=_("Is activation")), + 'access_num': openapi.Schema(type=openapi.TYPE_NUMBER, title=_("Number of visits"), + description=_("Number of visits")), + 'white_active': openapi.Schema(type=openapi.TYPE_BOOLEAN, title=_("Whether to enable whitelist"), + description=_("Whether to enable whitelist")), + 'white_list': openapi.Schema(type=openapi.TYPE_ARRAY, + items=openapi.Schema(type=openapi.TYPE_STRING), title=_("Whitelist"), + description=_("Whitelist")), + 'show_source': openapi.Schema(type=openapi.TYPE_BOOLEAN, + title=_("Whether to display knowledge sources"), + description=_("Whether to display knowledge sources")), + 'language': openapi.Schema(type=openapi.TYPE_STRING, + title=_("language"), + description=_("language")) + } + ) + class Edit(ApiMixin): @staticmethod def get_request_body_api(): @@ -367,6 +428,56 @@ def get_request_body_api(): } ) + @staticmethod + def get_response_body_api(): + return openapi.Schema( + type=openapi.TYPE_OBJECT, + required=['id', 'name', 'desc', 'model_id', 'dialogue_number', 'dataset_setting', 'model_setting', + 'problem_optimization', 'stt_model_enable', 'stt_model_enable', 'tts_type', + 'work_flow'], + properties={ + 'id': openapi.Schema(type=openapi.TYPE_STRING, title=_("Primary key id"), + description=_("Primary key id")), + 'name': openapi.Schema(type=openapi.TYPE_STRING, title=_("Application Name"), + description=_("Application Name")), + 'desc': openapi.Schema(type=openapi.TYPE_STRING, title=_("Application Description"), + description=_("Application Description")), + 'model_id': openapi.Schema(type=openapi.TYPE_STRING, title=_("Model id"), + description=_("Model id")), + "dialogue_number": openapi.Schema(type=openapi.TYPE_NUMBER, + title=_("Number of multi-round conversations"), + description=_("Number of multi-round conversations")), + 'prologue': openapi.Schema(type=openapi.TYPE_STRING, title=_("Opening remarks"), + description=_("Opening remarks")), + 'dataset_id_list': openapi.Schema(type=openapi.TYPE_ARRAY, + items=openapi.Schema(type=openapi.TYPE_STRING), + title=_("List of associated knowledge base IDs"), + description=_("List of associated knowledge base IDs")), + 'dataset_setting': ApplicationApi.DatasetSetting.get_request_body_api(), + 'model_setting': ApplicationApi.ModelSetting.get_request_body_api(), + 'problem_optimization': openapi.Schema(type=openapi.TYPE_BOOLEAN, title=_("Problem Optimization"), + description=_("Problem Optimization"), default=True), + 'type': openapi.Schema(type=openapi.TYPE_STRING, title=_("Application Type"), + description=_("Application Type SIMPLE | WORK_FLOW")), + 'problem_optimization_prompt': openapi.Schema(type=openapi.TYPE_STRING, + title=_('Question optimization tips'), + description=_("Question optimization tips"), + default=_( + "() contains the user's question. Answer the guessed user's question based on the context ({question}) Requirement: Output a complete question and put it in the tag")), + 'tts_model_id': openapi.Schema(type=openapi.TYPE_STRING, title=_("Text-to-speech model ID"), + description=_("Text-to-speech model ID")), + 'stt_model_id': openapi.Schema(type=openapi.TYPE_STRING, title=_("Speech-to-text model id"), + description=_("Speech-to-text model id")), + 'stt_model_enable': openapi.Schema(type=openapi.TYPE_STRING, title=_("Is speech-to-text enabled"), + description=_("Is speech-to-text enabled")), + 'tts_model_enable': openapi.Schema(type=openapi.TYPE_STRING, title=_("Is text-to-speech enabled"), + description=_("Is text-to-speech enabled")), + 'tts_type': openapi.Schema(type=openapi.TYPE_STRING, title=_("Text-to-speech type"), + description=_("Text-to-speech type")), + 'work_flow': ApplicationApi.WorkFlow.get_request_body_api(), + } + ) + class Query(ApiMixin): @staticmethod def get_request_params_api(): diff --git a/apps/application/swagger_api/chat_api.py b/apps/application/swagger_api/chat_api.py index 54b5678f747..c5fa614c964 100644 --- a/apps/application/swagger_api/chat_api.py +++ b/apps/application/swagger_api/chat_api.py @@ -319,6 +319,15 @@ def get_request_body_api(): } ) + @staticmethod + def get_response_body_api(): + return openapi.Schema( + type=openapi.TYPE_STRING, + title=_("Conversation ID"), + description=_("Conversation ID"), + default="chat_id" + ) + @staticmethod def get_request_params_api(): return [openapi.Parameter(name='application_id', diff --git a/apps/application/views/application_views.py b/apps/application/views/application_views.py index f16041d1de3..2628644f1d1 100644 --- a/apps/application/views/application_views.py +++ b/apps/application/views/application_views.py @@ -373,7 +373,8 @@ class Operate(APIView): operation_id=_("Modify application API_KEY"), tags=[_('Application/API_KEY')], manual_parameters=ApplicationApi.ApiKey.Operate.get_request_params_api(), - request_body=ApplicationApi.ApiKey.Operate.get_request_body_api()) + request_body=ApplicationApi.ApiKey.Operate.get_request_body_api(), + responses=result.get_api_response(ApplicationApi.ApiKey.Operate.get_response_body_api())) @has_permissions(ViewPermission( [RoleConstants.ADMIN, RoleConstants.USER], [lambda r, keywords: Permission(group=Group.APPLICATION, operate=Operate.MANAGE, @@ -415,7 +416,8 @@ class AccessToken(APIView): operation_id=_("Modify Application AccessToken"), tags=[_('Application/Public Access')], manual_parameters=ApplicationApi.AccessToken.get_request_params_api(), - request_body=ApplicationApi.AccessToken.get_request_body_api()) + request_body=ApplicationApi.AccessToken.get_request_body_api(), + responses=result.get_api_response(ApplicationApi.AccessToken.get_response_body_api())) @has_permissions(ViewPermission( [RoleConstants.ADMIN, RoleConstants.USER], [lambda r, keywords: Permission(group=Group.APPLICATION, operate=Operate.MANAGE, @@ -455,6 +457,7 @@ def options(self, request, *args, **kwargs): @swagger_auto_schema(operation_summary=_("Application Certification"), operation_id=_("Application Certification"), request_body=ApplicationApi.Authentication.get_request_body_api(), + responses=result.get_api_response(ApplicationApi.Authentication.get_response_body_api()), tags=[_("Application/Certification")], security=[]) def post(self, request: Request): @@ -472,6 +475,7 @@ def post(self, request: Request): @swagger_auto_schema(operation_summary=_("Create an application"), operation_id=_("Create an application"), request_body=ApplicationApi.Create.get_request_body_api(), + responses=result.get_api_response(ApplicationApi.Create.get_response_body_api()), tags=[_('Application')]) @has_permissions(PermissionConstants.APPLICATION_CREATE, compare=CompareConstants.AND) @log(menu='Application', operate="Create an application", diff --git a/apps/application/views/chat_views.py b/apps/application/views/chat_views.py index b0f42c020b9..e8d402b9ae9 100644 --- a/apps/application/views/chat_views.py +++ b/apps/application/views/chat_views.py @@ -94,6 +94,7 @@ class OpenWorkFlowTemp(APIView): @swagger_auto_schema(operation_summary=_("Get the workflow temporary session id"), operation_id=_("Get the workflow temporary session id"), request_body=ChatApi.OpenWorkFlowTemp.get_request_body_api(), + responses=result.get_api_response(ChatApi.OpenTempChat.get_response_body_api()), tags=[_("Application/Chat")]) def post(self, request: Request): return result.success(ChatSerializers.OpenWorkFlowChat( @@ -106,6 +107,7 @@ class OpenTemp(APIView): @swagger_auto_schema(operation_summary=_("Get a temporary session id"), operation_id=_("Get a temporary session id"), request_body=ChatApi.OpenTempChat.get_request_body_api(), + responses=result.get_api_response(ChatApi.OpenTempChat.get_response_body_api()), tags=[_("Application/Chat")]) @has_permissions(RoleConstants.ADMIN, RoleConstants.USER) def post(self, request: Request): @@ -239,6 +241,7 @@ def delete(self, request: Request, application_id: str, chat_id: str): @swagger_auto_schema(operation_summary=_("Client modifies dialogue summary"), operation_id=_("Client modifies dialogue summary"), request_body=ChatClientHistoryApi.Operate.ReAbstract.get_request_body_api(), + responses=result.get_default_response(), tags=[_("Application/Conversation Log")]) @has_permissions(ViewPermission( [RoleConstants.APPLICATION_ACCESS_TOKEN, RoleConstants.ADMIN, RoleConstants.USER], @@ -418,6 +421,7 @@ def put(self, request: Request, application_id: str, chat_id: str, chat_record_i operation_id=_("Add to Knowledge Base"), manual_parameters=ImproveApi.get_request_params_api_post(), request_body=ImproveApi.get_request_body_api_post(), + responses=result.get_default_response(), tags=[_("Application/Conversation Log/Add to Knowledge Base")] ) @has_permissions( diff --git a/apps/dataset/views/dataset.py b/apps/dataset/views/dataset.py index bbb9e033980..40d9a0c6514 100644 --- a/apps/dataset/views/dataset.py +++ b/apps/dataset/views/dataset.py @@ -181,6 +181,7 @@ class GenerateRelated(APIView): @swagger_auto_schema(operation_summary=_('Generate related'), operation_id=_('Generate related'), manual_parameters=DataSetSerializers.Operate.get_request_params_api(), request_body=GenerateRelatedSerializer.get_request_body_api(), + responses=result.get_default_response(), tags=[_('Knowledge Base')] ) @log(menu='document', operate="Generate related documents", diff --git a/apps/function_lib/swagger_api/function_lib_api.py b/apps/function_lib/swagger_api/function_lib_api.py index 89b33b7acf3..f0d409efaf8 100644 --- a/apps/function_lib/swagger_api/function_lib_api.py +++ b/apps/function_lib/swagger_api/function_lib_api.py @@ -195,6 +195,53 @@ def get_request_body_api(): } ) + @staticmethod + def get_response_body_api(): + return openapi.Schema( + type=openapi.TYPE_OBJECT, + required=['id', 'name', 'code', 'input_field_list', 'permission_type'], + properties={ + 'id': openapi.Schema(type=openapi.TYPE_STRING, title="", description=_('ID')), + + 'name': openapi.Schema(type=openapi.TYPE_STRING, title=_('function name'), + description=_('function name')), + 'desc': openapi.Schema(type=openapi.TYPE_STRING, title=_('function description'), + description=_('function description')), + 'code': openapi.Schema(type=openapi.TYPE_STRING, title=_('function content'), + description=_('function content')), + 'permission_type': openapi.Schema(type=openapi.TYPE_STRING, title=_('permission'), + description=_('permission')), + 'is_active': openapi.Schema(type=openapi.TYPE_BOOLEAN, title=_('Is active'), + description=_('Is active')), + 'input_field_list': openapi.Schema(type=openapi.TYPE_ARRAY, + description=_('Input variable list'), + items=openapi.Schema(type=openapi.TYPE_OBJECT, + required=['name', 'is_required', 'source'], + properties={ + 'name': openapi.Schema( + type=openapi.TYPE_STRING, + title=_('variable name'), + description=_('variable name')), + 'is_required': openapi.Schema( + type=openapi.TYPE_BOOLEAN, + title=_('required'), + description=_('required')), + 'type': openapi.Schema( + type=openapi.TYPE_STRING, + title=_('type'), + description=_( + 'Field type string|int|dict|array|float') + ), + 'source': openapi.Schema( + type=openapi.TYPE_STRING, + title=_('source'), + description=_( + 'The source only supports custom|reference')), + + })) + } + ) + class Export(ApiMixin): @staticmethod def get_request_params_api(): @@ -214,4 +261,4 @@ def get_request_params_api(): type=openapi.TYPE_FILE, required=True, description=_('Upload image files')) - ] \ No newline at end of file + ] diff --git a/apps/function_lib/views/function_lib_views.py b/apps/function_lib/views/function_lib_views.py index 018c015d030..e865566e3be 100644 --- a/apps/function_lib/views/function_lib_views.py +++ b/apps/function_lib/views/function_lib_views.py @@ -44,6 +44,7 @@ def get(self, request: Request): @swagger_auto_schema(operation_summary=_('Create function'), operation_id=_('Create function'), request_body=FunctionLibApi.Create.get_request_body_api(), + responses=result.get_api_response(FunctionLibApi.Create.get_response_body_api()), tags=[_('Function')]) @has_permissions(RoleConstants.ADMIN, RoleConstants.USER) @log(menu='Function', operate="Create function", @@ -58,6 +59,7 @@ class Debug(APIView): @swagger_auto_schema(operation_summary=_('Debug function'), operation_id=_('Debug function'), request_body=FunctionLibApi.Debug.get_request_body_api(), + responses=result.get_default_response(), tags=[_('Function')]) @has_permissions(RoleConstants.ADMIN, RoleConstants.USER) def post(self, request: Request): @@ -72,6 +74,7 @@ class Operate(APIView): @swagger_auto_schema(operation_summary=_('Update function'), operation_id=_('Update function'), request_body=FunctionLibApi.Edit.get_request_body_api(), + responses=result.get_api_response(FunctionLibApi.Edit.get_request_body_api()), tags=[_('Function')]) @has_permissions(RoleConstants.ADMIN, RoleConstants.USER) @log(menu='Function', operate="Update function", @@ -84,6 +87,7 @@ def put(self, request: Request, function_lib_id: str): @action(methods=['DELETE'], detail=False) @swagger_auto_schema(operation_summary=_('Delete function'), operation_id=_('Delete function'), + responses=result.get_default_response(), tags=[_('Function')]) @has_permissions(RoleConstants.ADMIN, RoleConstants.USER) @log(menu='Function', operate="Delete function", diff --git a/apps/function_lib/views/py_lint.py b/apps/function_lib/views/py_lint.py index acfe8fcc6b2..a0bee2a4c02 100644 --- a/apps/function_lib/views/py_lint.py +++ b/apps/function_lib/views/py_lint.py @@ -26,6 +26,7 @@ class PyLintView(APIView): @swagger_auto_schema(operation_summary=_('Check code'), operation_id=_('Check code'), request_body=PyLintApi.get_request_body_api(), + responses=result.get_api_response(PyLintApi.get_request_body_api()), tags=[_('Function')]) @has_permissions(RoleConstants.ADMIN, RoleConstants.USER) def post(self, request: Request): diff --git a/apps/setting/serializers/team_serializers.py b/apps/setting/serializers/team_serializers.py index 5ee041022be..0b264e88b29 100644 --- a/apps/setting/serializers/team_serializers.py +++ b/apps/setting/serializers/team_serializers.py @@ -171,6 +171,24 @@ def get_request_body_api(): } ) + @staticmethod + def get_response_body_api(): + return openapi.Schema( + type=openapi.TYPE_OBJECT, + properties={ + 'id': openapi.Schema(type=openapi.TYPE_STRING, title=_('user id'), description=_('user id')), + 'username': openapi.Schema(type=openapi.TYPE_STRING, title=_('Username'), description=_('Username')), + 'email': openapi.Schema(type=openapi.TYPE_STRING, title=_('Email'), description=_('Email')), + 'role': openapi.Schema(type=openapi.TYPE_STRING, title=_('Role'), description=_('Role')), + 'is_active': openapi.Schema(type=openapi.TYPE_STRING, title=_('Is active'), + description=_('Is active')), + 'team_id': openapi.Schema(type=openapi.TYPE_STRING, title=_('team id'), description=_('team id')), + 'user_id': openapi.Schema(type=openapi.TYPE_STRING, title=_('user id'), description=_('user id')), + 'type': openapi.Schema(type=openapi.TYPE_STRING, title=_('member type'), + description=_('member type manage|member')), + } + ) + @transaction.atomic def batch_add_member(self, user_id_list: List[str], with_valid=True): """ diff --git a/apps/setting/views/Team.py b/apps/setting/views/Team.py index 4dff7e7332d..9c2ade72fbc 100644 --- a/apps/setting/views/Team.py +++ b/apps/setting/views/Team.py @@ -38,6 +38,7 @@ def get(self, request: Request): @swagger_auto_schema(operation_summary=_('Add member'), operation_id=_('Add member'), request_body=TeamMemberSerializer().get_request_body_api(), + responses=result.get_default_response(), tags=[_('Team')]) @has_permissions(PermissionConstants.TEAM_CREATE) @log(menu='Team', operate='Add member', @@ -53,6 +54,7 @@ class Batch(APIView): @swagger_auto_schema(operation_summary=_('Add members in batches'), operation_id=_('Add members in batches'), request_body=TeamMemberSerializer.get_bach_request_body_api(), + responses=result.get_api_array_response(TeamMemberSerializer.get_response_body_api()), tags=[_('Team')]) @has_permissions(PermissionConstants.TEAM_CREATE) @log(menu='Team', operate='Add members in batches', @@ -78,6 +80,7 @@ def get(self, request: Request, member_id: str): @swagger_auto_schema(operation_summary=_('Update team member permissions'), operation_id=_('Update team member permissions'), request_body=UpdateTeamMemberPermissionSerializer().get_request_body_api(), + responses=result.get_default_response(), manual_parameters=TeamMemberSerializer.Operate.get_request_params_api(), tags=[_('Team')] ) @@ -93,6 +96,7 @@ def put(self, request: Request, member_id: str): @swagger_auto_schema(operation_summary=_('Remove member'), operation_id=_('Remove member'), manual_parameters=TeamMemberSerializer.Operate.get_request_params_api(), + responses=result.get_default_response(), tags=[_('Team')] ) @has_permissions(PermissionConstants.TEAM_DELETE) diff --git a/apps/setting/views/model.py b/apps/setting/views/model.py index 7b926013b7e..4fe13d1d95f 100644 --- a/apps/setting/views/model.py +++ b/apps/setting/views/model.py @@ -31,7 +31,8 @@ class Model(APIView): @action(methods=['POST'], detail=False) @swagger_auto_schema(operation_summary=_('Create model'), operation_id=_('Create model'), - request_body=ModelCreateApi.get_request_body_api() + request_body=ModelCreateApi.get_request_body_api(), + manual_parameters=result.get_api_response(ModelCreateApi.get_request_body_api()) , tags=[_('model')]) @has_permissions(PermissionConstants.MODEL_CREATE) @log(menu='model', operate='Create model', @@ -45,7 +46,8 @@ def post(self, request: Request): @action(methods=['PUT'], detail=False) @swagger_auto_schema(operation_summary=_('Download model, trial only with Ollama platform'), operation_id=_('Download model, trial only with Ollama platform'), - request_body=ModelCreateApi.get_request_body_api() + request_body=ModelCreateApi.get_request_body_api(), + responses=result.get_api_response(ModelCreateApi.get_request_body_api()) , tags=[_('model')]) @has_permissions(PermissionConstants.MODEL_CREATE) def put(self, request: Request): @@ -123,7 +125,8 @@ class Operate(APIView): @action(methods=['PUT'], detail=False) @swagger_auto_schema(operation_summary=_('Update model'), operation_id=_('Update model'), - request_body=ModelEditApi.get_request_body_api() + request_body=ModelEditApi.get_request_body_api(), + responses=result.get_api_response(ModelEditApi.get_request_body_api()) , tags=[_('model')]) @has_permissions(PermissionConstants.MODEL_CREATE) @log(menu='model', operate='Update model', @@ -166,7 +169,8 @@ class Exec(APIView): @swagger_auto_schema(operation_summary=_('Call the supplier function to obtain form data'), operation_id=_('Call the supplier function to obtain form data'), manual_parameters=ProvideApi.get_request_params_api(), - request_body=ProvideApi.get_request_body_api() + request_body=ProvideApi.get_request_body_api(), + responses=result.get_api_response(ProvideApi.get_request_body_api()) , tags=[_('model')]) @has_permissions(PermissionConstants.MODEL_READ) @log(menu='model', operate='Call the supplier function to obtain form data') diff --git a/apps/users/views/user.py b/apps/users/views/user.py index 9e21daa4ee9..d4b9f8a6a41 100644 --- a/apps/users/views/user.py +++ b/apps/users/views/user.py @@ -84,7 +84,7 @@ class SwitchUserLanguageView(APIView): description=_("language")), } ), - responses=RePasswordSerializer().get_response_body_api(), + responses=result.get_default_response(), tags=[_("User management")]) @log(menu='User management', operate='Switch Language', get_operation_object=lambda r, k: {'name': r.user.username}) @@ -111,7 +111,7 @@ class ResetCurrentUserPasswordView(APIView): description=_("Password")) } ), - responses=RePasswordSerializer().get_response_body_api(), + responses=result.get_default_response(), tags=[_("User management")]) @log(menu='User management', operate='Modify current user password', get_operation_object=lambda r, k: {'name': r.user.username}, From fbb44d5231706ba52f08932d0dff098cfb46df21 Mon Sep 17 00:00:00 2001 From: simpleqt <89645338+simpleqt@users.noreply.github.com> Date: Sun, 23 Aug 2026 19:26:19 +0800 Subject: [PATCH 140/140] fix(i18n): correct broken keys and mistranslations in en-US/zh-Hant locales MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - workflow.ts (en-US, zh-Hant): the showCondition/hideCondition keys contained an invisible U+200C zero-width non-joiner, so lookups from Constructor.vue fell through and the Visibility Setting dialog rendered the raw key instead of 'Show Condition'/'Hide Condition' - common.ts (en-US): task status STARTED was translated as 'Padding'; zh-CN/zh-Hant say 执行中/執行中 (Running) - workflow.ts (en-US): 'Iniiator' -> 'Initiator'; stray trailing quote in 'Restore Previous Version"' rendered on three workflow pages; 'Wireless loop' -> 'Infinite loop' (无限循环), consistent with infiniteLoop elsewhere in the same file --- ui/src/locales/lang/en-US/common.ts | 10 +- ui/src/locales/lang/en-US/workflow.ts | 560 ++++++++++++++++++++++++ ui/src/locales/lang/zh-Hant/workflow.ts | 545 +++++++++++++++++++++++ 3 files changed, 1114 insertions(+), 1 deletion(-) create mode 100644 ui/src/locales/lang/en-US/workflow.ts create mode 100644 ui/src/locales/lang/zh-Hant/workflow.ts diff --git a/ui/src/locales/lang/en-US/common.ts b/ui/src/locales/lang/en-US/common.ts index 2fd0a30b32d..2384bd3701a 100644 --- a/ui/src/locales/lang/en-US/common.ts +++ b/ui/src/locales/lang/en-US/common.ts @@ -53,7 +53,15 @@ export default { status: { label: 'Status', enableSuccess: 'Successful', - disableSuccess: 'Successful' + disableSuccess: 'Successful', + published: 'Published', + unpublished: 'Unpublished', + success: 'Successful', + fail: 'Failed', + all: 'All', + STARTED: 'Running', + REVOKED: 'Cancelled', + REVOKE: 'Cancelling', }, param: { outputParam: 'Output Parameters', diff --git a/ui/src/locales/lang/en-US/workflow.ts b/ui/src/locales/lang/en-US/workflow.ts new file mode 100644 index 00000000000..a8f648368c2 --- /dev/null +++ b/ui/src/locales/lang/en-US/workflow.ts @@ -0,0 +1,560 @@ +export default { + node: 'Node', + nodeName: 'Node Name', + baseComponent: 'Basic', + nodeSetting: 'Node Settings', + workflow: 'Workflow', + knowledgeWorkflow: 'Knowledge Workflow', + info: { + previewVersion: 'Preview Version:', + saveTime: 'Last Saved:', + }, + operation: { + toImportDoc: 'Go to Import Documents', + importWorkflow: 'Import Workflow', + exportWorkflow: 'Export Workflow', + }, + setting: { + restoreVersion: 'Restore Previous Version', + restoreCurrentVersion: 'Restore to This Version', + addComponent: 'Add', + releaseHistory: 'Release History', + autoSave: 'Auto Save', + latestRelease: 'Latest Release', + copyParam: 'Copy Parameters', + debug: 'Run', + exit: 'Exit', + exitSave: 'Save & Exit', + templateCenter: 'Template Center', + }, + tip: { + noData: 'No related results found', + nameMessage: 'Name cannot be empty!', + onlyRight: 'Connections can only be made from the right anchor', + notRecyclable: 'Loop connections are not allowed', + onlyLeft: 'Connections can only be made to the left anchor', + applicationNodeError: 'This agent is unavailable', + toolNodeError: 'This tool node is unavailable', + repeatedNodeError: 'A node with this name already exists', + cannotCopy: 'Cannot be copied', + copyError: 'Node already copied', + paramErrorMessage: 'Parameter already exists: ', + saveMessage: 'Current changes have not been saved. Save before exiting?', + searchPlaceholder: 'Please enter node name', + disabled: 'The node has been disabled', + }, + delete: { + confirmTitle: 'Confirm to delete this node?', + deleteMessage: 'This node cannot be deleted', + }, + control: { + zoomOut: 'Zoom Out', + zoomIn: 'Zoom In', + fitView: 'Fit to Screen', + retract: 'Collapse All', + extend: 'Expand All', + beautify: 'Auto-Arrange', + }, + variable: { + global: 'Global Variable', + chat: 'Chat Variable', + Referencing: 'Referenced Variable', + ReferencingRequired: 'Referenced variable is required', + ReferencingError: 'Invalid referenced variable', + NoReferencing: 'Referenced variable does not exist', + placeholder_key: 'Enter key', + placeholder: 'Please select a variable', + inputPlaceholder: 'Please enter variable', + loop: 'Loop Variable', + }, + condition: { + title: 'Execution Condition', + front: 'Precondition', + AND: 'All', + OR: 'Any', + text: 'After the connected node is executed, execute the current node', + }, + validate: { + startNodeRequired: 'Start node is required', + startNodeOnly: 'Only one start node is allowed', + baseNodeRequired: 'Base information node is required', + baseNodeOnly: 'Only one base information node is allowed', + notInWorkFlowNode: 'Node not in workflow', + noNextNode: 'Next node does not exist', + nodeUnavailable: 'Node unavailable', + needConnect1: 'The branch of the node needs to be connected', + cannotEndNode: 'This node cannot be used as an end node', + loopNodeBreakNodeRequired: 'Infinite loop must have a Break node', + }, + nodes: { + toolWorlflowNode: { + label: 'Workflow Tool', + text: 'Workflow Tool', + }, + knowledgeWriteNode: { + label: 'Knowledge write', + text: 'Write the input paragraph list into the current knowledge base and complete vectorization processing', + }, + dataSourceWebNode: { + label: 'Web Site', + text: 'Input the root URL to automatically crawl web data (single link corresponds to a single document), output a list of documents with content', + field_label: 'Document list', + }, + dataSourceLocalNode: { + label: 'Local File', + text: 'Upload local documents, output document list (content not parsed, needs to be used with "Document Content Extraction" node to parse)', + fileList: 'File List', + fileFormat: { + label: 'Supported File Formats', + requiredMessage: 'Please select file formats', + }, + maxFileNumber: { + label: 'Maximum Number of Files per Upload', + }, + maxFileCountNumber: { + label: 'Maximum Size per File (MB)', + }, + }, + classify: { + aiCapability: 'AI capability', + businessLogic: 'Business logic', + dataProcessing: 'Data Processing', + }, + startNode: { + label: 'Start', + question: 'User Question', + currentTime: 'Current Time', + }, + baseNode: { + visibilitySetting: { + label: 'Visibility Setting', + showCondition: 'Show Condition', + hideCondition: 'Hide Condition', + }, + fileUpload: { + label: 'File Upload', + tooltip: 'When enabled, the Q&A page will display a file upload button.', + }, + FileUploadSetting: { + title: 'File Upload Settings', + maxFiles: 'Maximum number of files per upload', + fileLimit: 'Maximum size per file (MB)', + fileUploadType: { + label: 'File types allowed for upload', + documentText: 'Requires "Document Content Extraction" node to parse document content', + imageText: 'Requires "Image Understanding" node to parse image content', + videoText: 'Requires "Video Understanding" node to parse video content', + audioText: 'Requires "Speech-to-Text" node to parse audio content', + uploadMethod: 'Upload Method', + }, + }, + }, + KnowledgeBaseNode: { + DocumentSetting: 'Document Processing Setting', + }, + aiChatNode: { + label: 'AI Chat', + text: 'Chat with an AI model', + answer: 'AI Content', + vision: { + label: 'vision', + }, + returnContent: { + label: 'Return Content', + tooltip: `If turned off, the content of this node will not be output to the user. + If you want the user to see the output of this node, please turn on the switch.`, + }, + defaultPrompt: 'Known Information', + think: 'Thinking Process', + historyMessage: 'Historical chat records', + }, + searchKnowledgeNode: { + label: 'Knowledge Retrieval', + text: 'Allows you to query text content related to user questions from the Knowledge', + paragraph_list: 'List of retrieved segments', + is_hit_handling_method_list: 'List of segments that meet direct response criteria', + result: 'Search Result', + directly_return: 'Content of segments that meet direct response criteria', + searchParam: 'Retrieval Parameters', + showKnowledge: { + label: 'Results are displayed in the knowledge source', + requiredMessage: 'Please set parameters', + }, + searchQuestion: { + label: 'Question', + placeholder: 'Please select a search question', + requiredMessage: 'Please select a search question', + }, + }, + searchDocumentNode: { + label: 'Document Tag Retrieval', + text: 'Search for documents that meet the conditions based on the document label within the specified search scope', + selectKnowledge: 'Search Scope', + searchSetting: 'Search Settings', + custom: 'Manual', + customTooltip: 'Manually set tag filtering conditions', + auto: 'Automatic', + autoTooltip: 'Automatically filter setting tag conditions based on the search question', + documentList: 'Document List', + knowledgeList: 'Knowledge Base List', + result: 'Search Results', + searchParam: 'Search Parameters', + select_variable: 'Select Variable', + valueMessage: 'Value or name', + + searchQuestion: { + label: 'Search Question', + placeholder: 'Please select a search question', + requiredMessage: 'Please select a search question', + }, + }, + questionNode: { + label: 'Question Optimization', + text: 'Optimize and improve the current question based on historical chat records to better match knowledge segments', + result: 'Optimized Question Result', + systemDefault: `#Role +You are a master of problem optimization, adept at accurately inferring user intentions based on context and optimizing the questions raised by users. + +##Skills +###Skill 1: Optimizing Problems +2. Receive user input questions. +3. Carefully analyze the meaning of the problem based on the context. +4. Output optimized problems. + +##Limitations: +-Only return the optimized problem without any additional explanation or clarification. +-Ensure that the optimized problem accurately reflects the original problem intent and does not alter the original intention.`, + }, + conditionNode: { + label: 'Conditional Branch', + text: 'Trigger different nodes based on conditions', + branch_name: 'Branch Name', + conditions: { + label: 'Conditions', + info: 'Meets the following', + requiredMessage: 'Please select conditions', + }, + valueMessage: 'Please enter a value', + addCondition: 'Add Condition', + addBranch: 'Add Branch', + }, + replyNode: { + label: 'Specified Reply', + text: 'Specify reply content, referenced variables will be converted to strings for output', + replyContent: 'Reply Content', + }, + rerankerNode: { + label: 'Multi-path Recall', + text: 'Use a re-ranking model to refine retrieval results from multiple knowledge sources', + result_list: 'Re-ranked Results List', + result: 'Re-ranking Result', + rerankerContent: { + label: 'Re-ranking Content', + requiredMessage: 'Please select re-ranking content', + }, + higher: 'Higher', + ScoreTooltip: 'The higher the Score, the stronger the relevance.', + max_paragraph_char_number: 'Maximum Character', + reranker_model: { + label: 'Rerank', + placeholder: 'Please select a rerank', + }, + }, + formNode: { + label: 'Form Input', + text: 'Collect user input during Q&A and use it in subsequent processes', + form_content_format1: 'Hello, please fill out the form below:', + form_content_format2: 'Click the [Submit] button after filling it out.', + form_data: 'All Form Content', + formContent: { + label: 'Form Output Content', + requiredMessage: + 'Please set the output content of this node, { form } is a placeholder for the form.', + tooltip: 'Define the output content of this node. { form } is a placeholder for the form', + }, + formAllContent: 'All Form Content', + formSetting: 'Form Configuration', + }, + documentExtractNode: { + label: 'Document Content Extraction', + text: 'Parse input documents to output structured document content', + content: 'Document Content', + }, + documentSplitNode: { + label: 'Document Splitting', + text: 'Split input document content according to the segmentation strategy, output a list of segmented texts', + paragraphList: 'List of split segments', + splitStrategy: { + label: 'Splitting Strategy', + placeholder: 'Please select a splitting strategy', + requiredMessage: 'Please select a splitting strategy', + }, + chunk_length: { + label: 'Chunk length', + tooltip1: 'Core objective is to balance retrieval precision and recall efficiency', + tooltip2: + 'Avoid excessively short segmentation: A single segment <50 characters may lead to semantic fragmentation, potentially failing to match query intent during retrieval due to lack of context.', + tooltip3: + 'Avoid excessive segmentation: A single block exceeding 500 characters increases redundant information, reduces retrieval accuracy, and consumes more storage and computing resources.', + }, + title1: 'Segment title set as the associated question of the segment', + title2: 'Document name set as the associated question of the segment', + }, + imageUnderstandNode: { + label: 'Image Understanding', + text: 'Analyze images to identify objects, scenes, and provide answers', + answer: 'AI Content', + model: { + label: 'Vision Model', + requiredMessage: 'Please select a vision model', + }, + image: { + label: 'Select Image', + requiredMessage: 'Please select an image', + }, + }, + videoUnderstandNode: { + label: 'Video Understanding', + text: 'Identify objects, scenes, and other information in videos to answer user questions', + answer: 'AI Response Content', + model: { + label: 'Vision Model', + requiredMessage: 'Please select a vision model', + }, + video: { + label: 'Select Video', + requiredMessage: 'Please select a video', + }, + }, + variableAssignNode: { + label: 'Variable Assign', + text: 'Update the value of the global variable', + assign: 'Set Value', + }, + variableAggregationNode: { + label: 'Variable Aggregation', + text: 'Aggregate variables of each group according to the aggregation strategy', + Strategy: 'Aggregation Strategy', + placeholder: 'Return the first non-null value of each group', + placeholder1: 'Return the array of variables for each group', + placeholder2: 'Return the dict of variables for each group', + group: { + noneError: 'Name cannot be empty', + dupError: 'Name cannot be duplicated', + }, + addGroup: 'Add Group', + editGroup: 'Edit Group', + }, + mcpNode: { + label: 'MCP Call', + text: 'Call external MCP services to process data', + getToolsSuccess: 'Tools fetched successfully', + getTool: 'Fetch Tools', + toolParam: 'Tool Parameters', + mcpServerTip: 'Please enter MCP server configuration in JSON format', + mcpToolTip: 'Please select a tool', + configLabel: 'MCP Server Config (Only SSE/Streamable HTTP calls are supported)', + reference: 'Reference MCP', + }, + imageGenerateNode: { + label: 'Image Generation', + text: 'Generate images based on provided text content', + answer: 'AI Content', + model: { + label: 'Image Generation Model', + requiredMessage: 'Please select an image generation model', + }, + prompt: { + label: 'Positive Prompt', + tooltip: 'Describe elements and visual features you want in the generated image', + }, + negative_prompt: { + label: 'Negative Prompt', + tooltip: 'Describe elements you want to exclude from the generated image', + placeholder: + 'Please describe content you do not want to generate, such as color, bloody content', + }, + }, + textToVideoGenerate: { + label: 'Text-to-Video', + text: 'Generate video based on provided text content', + answer: 'AI Response Content', + model: { + label: 'Text-to-Video Model', + requiredMessage: 'Please select a text-to-video model', + }, + prompt: { + label: 'Prompt (Positive)', + tooltip: + 'Positive prompt, used to describe elements and visual features expected in the generated video', + }, + negative_prompt: { + label: 'Prompt (Negative)', + tooltip: + "Negative prompt, used to describe content you don't want to see in the video, which can restrict the video generation", + placeholder: + "Please describe video content you don't want to generate, such as: colors, bloody content", + }, + }, + imageToVideoGenerate: { + label: 'Image-to-Video', + text: 'Generate video based on provided images', + answer: 'AI Response Content', + model: { + label: 'Image-to-Video Model', + requiredMessage: 'Please select an image-to-video model', + }, + prompt: { + label: 'Prompt (Positive)', + tooltip: + 'Positive prompt, used to describe elements and visual features expected in the generated video', + }, + negative_prompt: { + label: 'Prompt (Negative)', + tooltip: + "Negative prompt, used to describe content you don't want to see in the video, which can restrict the video generation", + placeholder: + "Please describe video content you don't want to generate, such as: colors, bloody content", + }, + first_frame: { + label: 'First Frame Image', + requiredMessage: 'Please select the first frame image', + }, + last_frame: { + label: 'Last Frame Image', + requiredMessage: 'Please select the last frame image', + }, + }, + speechToTextNode: { + label: 'Speech2Text', + text: 'Convert audio to text through speech recognition model', + stt_model: { + label: 'Speech Recognition Model', + }, + audio: { + label: 'Select Audio File', + placeholder: 'Please select an audio file', + }, + }, + textToSpeechNode: { + label: 'TTS', + text: 'Convert text to audio through speech synthesis model', + tts_model: { + label: 'Speech Synthesis Model', + }, + content: { + label: 'Select Text Content', + }, + }, + toolNode: { + label: 'Custom Tool', + text: 'Execute custom scripts to achieve data processing', + }, + intentNode: { + label: 'IntentNode', + text: 'Match user questions with user-defined intent classifications', + error2: 'Repeated intent', + placeholder: 'Please choose a classification option', + classify: { + label: 'Intent classify', + }, + input: { + label: 'Input', + }, + }, + applicationNode: { + label: 'Agent Node', + }, + loopNode: { + label: 'Loop', + text: 'Repeat a series of tasks by setting the number of loops and logic', + loopType: { + label: 'Loop Type', + requiredMessage: 'Please select a loop type', + arrayLoop: 'Array Loop', + numberLoop: 'Loop for Specified Times', + infiniteLoop: 'Infinite Loop', + }, + loopNumber: { + label: 'Loop Number', + requiredMessage: 'Please enter the number of loops', + }, + loopArray: { + label: 'Circular Array', + requiredMessage: 'Circular Array is required', + placeholder: 'Please select a circular array', + }, + loopSetting: 'Loop Settings', + loopDetail: 'Loop Details', + }, + loopStartNode: { + label: 'Loop Start', + loopIndex: 'Index', + loopItem: 'Loop Element', + }, + loopBodyNode: { + label: 'Loop Body', + text: 'Loop Body', + }, + loopContinueNode: { + label: 'Continue', + text: 'Used to terminate the current loop and proceed to the next one.', + isContinue: 'Continue', + }, + loopBreakNode: { + label: 'Break', + text: 'Terminate the current loop and exit the loop body', + isBreak: 'Break', + }, + variableSplittingNode: { + label: 'Variable Splitting', + text: 'By configuring JSON Path expressions, parse and split the input JSON format variable', + result: 'Result', + splitVariables: 'Split Variables', + inputVariables: 'Input Variable', + addVariables: 'Add Variables', + editVariables: 'Edit Variables', + variableListPlaceholder: 'Please add split variables', + expression: { + label: 'Expression', + placeholder: 'Please enter expression', + tooltip: + 'Please use JSON Path expressions to split variables, e.g.: $.store.book Click for details ➜ pypi.org', + }, + }, + parameterExtractionNode: { + label: 'Parameter Extraction', + text: 'Use AI models to extract structured parameters', + extractParameters: { + label: 'Extract Parameters', + variableListPlaceholder: 'Please add extraction parameters', + parameterType: 'Parameter Type', + }, + }, + }, + compare: { + is_null: 'Is null', + is_not_null: 'Is not null', + contain: 'Contains', + not_contain: 'Does not contain', + eq: 'Equal to', + not_eq: 'Not equal to', + ge: 'Greater than or equal to', + gt: 'Greater than', + le: 'Less than or equal to', + lt: 'Less than', + len_eq: 'Length equal to', + len_ge: 'Length greater than or equal to', + len_gt: 'Length greater than', + len_le: 'Length less than or equal to', + len_lt: 'Length less than', + is_true: 'Is true', + is_not_true: 'Is not true', + regex: 'Regex matching', + wildcard: 'Wildcard matching', + }, + SystemPromptPlaceholder: 'System Prompt, can reference variables in the system, such as', + UserPromptPlaceholder: 'User Prompt, can reference variables in the system, such as', + initiator: 'Initiator', + abnormalInformation: 'Abnormal Information', +} diff --git a/ui/src/locales/lang/zh-Hant/workflow.ts b/ui/src/locales/lang/zh-Hant/workflow.ts new file mode 100644 index 00000000000..d6448b1a3c2 --- /dev/null +++ b/ui/src/locales/lang/zh-Hant/workflow.ts @@ -0,0 +1,545 @@ +export default { + node: '節點', + nodeName: '節點名稱', + baseComponent: '基礎組件', + nodeSetting: '節點設置', + workflow: '工作流', + knowledgeWorkflow: '知識庫工作流', + info: { + previewVersion: '預覽版本:', + saveTime: '保存時間:', + }, + operation: { + toImportDoc: '去導入文檔', + importWorkflow: '導入工作流', + exportWorkflow: '導出工作流', + }, + setting: { + restoreVersion: '恢復版本', + restoreCurrentVersion: '恢復此版本', + addComponent: '添加組件', + releaseHistory: '發布歷史', + autoSave: '自動保存', + latestRelease: '最近發布', + copyParam: '複製參數', + exit: '直接退出', + exitSave: '保存並退出', + templateCenter: '模板中心', + }, + tip: { + noData: '沒有找到相關結果', + nameMessage: '名字不能為空!', + onlyRight: '只允許從右邊的錨點連出', + notRecyclable: '不可循環連線', + onlyLeft: '只允許連接左邊的錨點', + applicationNodeError: '該智能體不可用', + toolNodeError: '該函數不可用', + repeatedNodeError: '節點名稱已存在!', + cannotCopy: '不能被複製', + copyError: '已複製節點', + paramErrorMessage: '參數已存在: ', + saveMessage: '當前修改未保存,是否保存後退出?', + searchPlaceholder: '請輸入節點名稱', + disabled: '该节点已被禁用', + }, + delete: { + confirmTitle: '確定刪除該節點?', + deleteMessage: '節點不允許刪除', + }, + control: { + zoomOut: '縮小', + zoomIn: '放大', + fitView: '適應', + retract: '收起全部節點', + extend: '展開全部節點', + beautify: '一鍵美化', + }, + variable: { + global: '全局變量', + chat: '會話變量', + Referencing: '引用變量', + ReferencingRequired: '引用變量必填', + ReferencingError: '引用變量錯誤', + NoReferencing: '不存在的引用變量', + placeholder_key: '請輸入鍵名', + placeholder: '請選擇變量', + inputPlaceholder: '請輸入變量', + loop: '循環變量', + }, + condition: { + title: '執行條件', + front: '前置', + AND: '所有', + OR: '任一', + text: '連線節點執行完,執行當前節點', + }, + validate: { + startNodeRequired: '開始節點必填', + startNodeOnly: '開始節點只能有一個', + baseNodeRequired: '基本信息節點必填', + baseNodeOnly: '基本信息節點只能有一個', + notInWorkFlowNode: '未在流程中的節點', + noNextNode: '不存在的下一個節點', + nodeUnavailable: '節點不可用', + needConnect1: '節點的', + needConnect2: '分支需要連接', + cannotEndNode: '節點不能當做結束節點', + loopNodeBreakNodeRequired: '無限循環必須存在 Break 節點', + }, + nodes: { + toolWorlflowNode: { + label: '工作流工具', + text: '工作流工具', + }, + knowledgeWriteNode: { + label: '知識庫寫入', + text: '將輸入的分段列表寫入當前知識庫,並完成向量化處理', + }, + dataSourceWebNode: { + label: 'Web 網站', + text: '輸入根地址自動抓取Web數據(單鏈接對應單文檔),輸出含內容的文檔列表', + field_label: '文件列表', + }, + dataSourceLocalNode: { + label: '本地文件', + text: '上傳本地文件,輸出文件列表(不解析內容,需配合 “文檔內容提取” 節點解析)', + fileList: '文件列表', + fileFormat: { + label: '支持的文件格式', + requiredMessage: '請選擇文件格式', + }, + maxFileNumber: { + label: '每次上傳最大文件數', + }, + maxFileCountNumber: { + label: '上傳的每個文檔最大(MB)', + }, + }, + classify: { + aiCapability: 'AI 能力', + businessLogic: '業務邏輯', + dataProcessing: '數據處理', + }, + startNode: { + label: '開始', + question: '用戶問題', + currentTime: '當前時間', + }, + baseNode: { + visibilitySetting: { + label: '顯隱設置', + showCondition: '顯示條件', + hideCondition: '隱藏條件', + }, + fileUpload: { + label: '文件上傳', + tooltip: '開啟後,問答頁面會顯示上傳文件的按鈕。', + }, + FileUploadSetting: { + title: '文件上傳設置', + maxFiles: '單次上傳最多文件數', + fileLimit: '每個文件最大(MB)', + fileUploadType: { + label: '上傳的文件類型', + documentText: '需要使用「文檔內容提取」節點解析文檔內容', + imageText: '需要使用「圖片理解」節點解析圖片內容', + videoText: '需要使用「視頻理解」節點解析視頻內容', + audioText: '需要使用「語音轉文本」節點解析音頻內容', + uploadMethod: '上傳方式', + }, + }, + }, + KnowledgeBaseNode: { + DocumentSetting: '文檔處理設置', + }, + aiChatNode: { + label: 'AI 對話', + text: '與 AI 大模型進行對話', + answer: 'AI 回答內容', + vision: { + label: '視覺', + }, + returnContent: { + label: '返回內容', + tooltip: `關閉後該節點的內容則不輸出給用戶。 + 如果你想讓用戶看到該節點的輸出內容,請打開開關。`, + }, + defaultPrompt: '已知信息', + think: '思考過程', + historyMessage: '歷史聊天記錄', + }, + searchKnowledgeNode: { + label: '知識庫檢索', + text: '關聯知識庫,查找與問題相關的分段', + paragraph_list: '檢索結果的分段列表', + is_hit_handling_method_list: '滿足直接回答的分段列表', + result: '檢索結果', + directly_return: '滿足直接回答的分段內容', + searchParam: '檢索參數', + showKnowledge: { + label: '結果顯示在知識來源', + requiredMessage: '請設定參數', + }, + searchQuestion: { + label: '檢索問題', + placeholder: '請選擇檢索問題', + requiredMessage: '請選擇檢索問題', + }, + }, + searchDocumentNode: { + label: '文檔標籤檢索', + text: '從設定的檢索範圍中,根據文檔標籤檢索出符合條件的文檔', + selectKnowledge: '檢索範圍', + searchSetting: '檢索設定', + custom: '手動', + customTooltip: '手動設置標籤過濾條件', + auto: '自動', + autoTooltip: '根據檢索問題自動匹配文檔標簽', + documentList: '文檔列表', + knowledgeList: '知識庫列表', + result: '檢索結果', + searchParam: '檢索參數', + select_variable: '選擇變數', + valueMessage: `值或變量`, + + searchQuestion: { + label: '檢索問題', + placeholder: '請選擇檢索問題', + requiredMessage: '請選擇檢索問題', + }, + }, + questionNode: { + label: '問題優化', + text: '根據歷史聊天記錄優化完善當前問題,更利於匹配知識庫分段', + result: '問題優化結果', + systemDefault: `# 角色 +妳是壹位問題優化大師,擅長根據上下文精準揣測用戶意圖,並對用戶提出的問題進行優化。 + +## 技能 +### 技能 1: 優化問題 +2. 接收用戶輸入的問題。 +3. 依據上下文仔細分析問題含義。 +4. 輸出優化後的問題。 + +## 限制: +- 僅返回優化後的問題,不進行額外解釋或說明。 +- 確保優化後的問題準確反映原始問題意圖,不得改變原意。`, + }, + conditionNode: { + label: '判斷器', + text: '根據不同條件執行不同的節點', + branch_name: '分支名稱', + conditions: { + label: '條件', + info: '符合以下', + requiredMessage: '請選擇條件', + }, + valueMessage: '請輸入值', + addCondition: '添加條件', + addBranch: '添加分支', + }, + replyNode: { + label: '指定回覆', + text: '指定回覆內容,引用變量會轉換為字符串進行輸出', + replyContent: '回覆內容', + }, + rerankerNode: { + label: '多路召回', + text: '使用重排模型對多個知識庫的檢索結果進行二次召回', + result_list: '重排結果列表', + result: '重排結果', + rerankerContent: { + label: '重排內容', + requiredMessage: '請選擇重排內容', + }, + higher: '高於', + ScoreTooltip: 'Score 越高相關性越強。', + max_paragraph_char_number: '最大引用字符數', + reranker_model: { + label: '重排模型', + placeholder: '請選擇重排模型', + }, + }, + formNode: { + label: '表單收集', + text: '在問答過程中用於收集用戶信息,可以根據收集到表單數據執行後續流程', + form_content_format1: '你好,請先填寫下面表單內容:', + form_content_format2: '填寫後請點擊【提交】按鈕進行提交。', + form_data: '表單全部內容', + formContent: { + label: '表單輸出內容', + requiredMessage: '請表單輸出內容', + tooltip: '設置執行該節點輸出的內容,{ form } 為表單的佔位符。', + }, + formAllContent: '表單全部內容', + formSetting: '表單配置', + }, + documentExtractNode: { + label: '文檔內容提取', + text: '解析輸入文檔,輸出結構化文檔內容', + content: '文檔內容', + }, + documentSplitNode: { + label: '文檔拆分', + text: '按分段策略拆分輸入文檔內容,輸出分段文本列表', + paragraphList: '分段列表', + splitStrategy: { + label: '分段策略', + placeholder: '請選擇分段策略', + requiredMessage: '請選擇分段策略', + }, + chunk_length: { + label: '子分塊長度', + tooltip1: '核心目標是平衡檢索精度與召回效率', + tooltip2: + '避免過短拆分:單塊<50 字易導致語義碎片化,檢索時可能因缺少上下文無法匹配查詢意圖', + tooltip3: + '避免過長拆分:單塊>500 字會增加冗餘信息,降低檢索精准度,且佔用更多存儲和計算資源', + }, + title1: '分段標題設置為分段的關聯問題', + title2: '文檔名稱設置為分段的關聯問題', + }, + videoUnderstandNode: { + label: '视频理解', + text: '识别出视频中的对象、场景等信息回答用户问题', + answer: 'AI 回答内容', + model: { + label: '视觉模型', + requiredMessage: '请选择视觉模型', + }, + video: { + label: '选择视频', + requiredMessage: '请选择视频', + }, + }, + imageUnderstandNode: { + label: '圖片理解', + text: '識別出圖片中的物件、場景等信息回答用戶問題', + answer: 'AI 回答內容', + model: { + label: '視覺模型', + requiredMessage: '請選擇視覺模型', + }, + image: { + label: '選擇圖片', + requiredMessage: '請選擇圖片', + }, + }, + variableAssignNode: { + label: '變數賦值', + text: '更新全域變數的值', + assign: '賦值', + }, + variableAggregationNode: { + label: '變量聚合', + text: '按聚合策略聚合每組的變量', + Strategy: '聚合策略', + placeholder: '返回每組的第一個非空值', + placeholder1: '返回每組變量的數組(Array)', + placeholder2: '返回每組變量的字典(Dict)', + group: { + noneError: '名稱不能為空', + dupError: '名稱不能重複', + }, + addGroup: '添加分組', + editGroup: '編輯分組', + }, + mcpNode: { + label: 'MCP 調用', + text: '通過 SSE/Streamable HTTP 方式執行 MCP 服務中的工具', + getToolsSuccess: '獲取工具成功', + getTool: '獲取工具', + toolParam: '工具參數', + mcpServerTip: '請輸入 JSON 格式的 MCP 服務器配置', + mcpToolTip: '請選擇工具', + configLabel: 'MCP Server Config (僅支持SSE/Streamable HTTP 調用方式)', + reference: '引用MCP', + }, + imageGenerateNode: { + label: '圖片生成', + text: '根據提供的文本內容生成圖片', + answer: 'AI 回答內容', + model: { + label: '圖片生成模型', + requiredMessage: '請選擇圖片生成模型', + }, + prompt: { + label: '提示詞(正向)', + tooltip: '正向提示詞,用來描述生成圖像中期望包含的元素和視覺特點', + }, + negative_prompt: { + label: '提示詞(負向)', + tooltip: '反向提示詞,用來描述不希望在畫面中看到的內容,可以對畫面進行限制。', + placeholder: '請描述不想生成的圖片內容,比如:顏色、血腥內容', + }, + }, + textToVideoGenerate: { + label: '文生影片', + text: '根據提供的文字內容生成影片', + answer: 'AI 回答內容', + model: { + label: '文生影片模型', + requiredMessage: '請選擇文生影片模型', + }, + prompt: { + label: '提示詞(正向)', + tooltip: '正向提示詞,用來描述生成影片中期望包含的元素和視覺特點', + }, + negative_prompt: { + label: '提示詞(負向)', + tooltip: '反向提示詞,用來描述不希望在影片中看到的內容,可以對影片進行限制。', + placeholder: '請描述不想生成的影片內容,例如:顏色、血腥內容', + }, + }, + imageToVideoGenerate: { + label: '圖生影片', + text: '根據提供的圖片生成影片', + answer: 'AI 回答內容', + model: { + label: '圖生影片模型', + requiredMessage: '請選擇圖生影片模型', + }, + prompt: { + label: '提示詞(正向)', + tooltip: '正向提示詞,用來描述生成影片中期望包含的元素和視覺特點', + }, + negative_prompt: { + label: '提示詞(負向)', + tooltip: '反向提示詞,用來描述不希望在影片中看到的內容,可以對影片進行限制。', + placeholder: '請描述不想生成的影片內容,例如:顏色、血腥內容', + }, + first_frame: { + label: '首幀圖片', + requiredMessage: '請選擇首幀圖片', + }, + last_frame: { + label: '尾幀圖片', + requiredMessage: '請選擇尾幀圖片', + }, + }, + speechToTextNode: { + label: '語音轉文本', + text: '將音頻通過語音識別模型轉換為文本', + stt_model: { + label: '語音識別模型', + }, + audio: { + label: '選擇語音文件', + placeholder: '請選擇語音文件', + }, + }, + textToSpeechNode: { + label: '文本轉語音', + text: '將文本通過語音合成模型轉換為音頻', + tts_model: { + label: '語音合成模型', + }, + content: { + label: '選擇文本內容', + }, + }, + toolNode: { + label: '自定義工具', + text: '通過執行自定義腳本,實現數據處理', + }, + intentNode: { + label: '意圖識別', + text: '將用戶問題與用戶預設的意圖分類進行匹配', + error2: '意圖重複', + placeholder: '請選擇分類項', + classify: { + label: '意圖分類', + }, + input: { + label: '輸入', + }, + }, + applicationNode: { + label: '智能體節點', + }, + loopNode: { + label: '循環節點', + text: '通過設置循環次數和邏輯,重複執行一系列任務', + loopType: { + label: '循環類型', + requiredMessage: '請選擇循環類型', + arrayLoop: '數組循環', + numberLoop: '指定次數循環', + infiniteLoop: '無限循環', + }, + loopNumber: { + label: '循環次數', + requiredMessage: '請填寫循環次數', + }, + loopArray: { + label: '循環數組', + requiredMessage: '循環數組必填', + placeholder: '請選擇循環數組', + }, + loopSetting: '循環設置', + loopDetail: '循環詳情', + }, + loopStartNode: { + label: '循環開始', + loopIndex: '下標', + loopItem: '循環元素', + }, + loopBodyNode: { label: '循環體', text: '循環體' }, + loopContinueNode: { + label: 'Continue', + text: '用於終止當前循環,執行下次循環', + isContinue: 'Continue', + }, + loopBreakNode: { label: 'Break', text: '終止當前循環,跳出循環體', isBreak: 'Break' }, + variableSplittingNode: { + label: '變量拆分', + text: '通過配置 JSON Path 表達式,對輸入的 JSON 格式變量進行解析和拆分', + result: '結果', + splitVariables: '拆分變量', + inputVariables: '輸入變量', + addVariables: '添加變量', + editVariables: '編輯變量', + variableListPlaceholder: '請添加折開變數', + expression: { + label: '表達式', + placeholder: '請輸入表達式', + tooltip: + '請使用 JSON Path 表達式拆分變量,例如:$.store.book 點擊查看詳情 ➜ pypi.org', + }, + }, + parameterExtractionNode: { + label: '參數提取', + text: '利用 AI 模型提取結構化參數', + extractParameters: { + label: '提取參數', + variableListPlaceholder: '請添加選取參數', + parameterType: '參數類型', + }, + }, + }, + compare: { + is_null: '為空', + is_not_null: '不為空', + contain: '包含', + not_contain: '不包含', + eq: '等於', + not_eq: '不等於', + ge: '大於等於', + gt: '大於', + le: '小於等於', + lt: '小於', + len_eq: '長度等於', + len_ge: '長度大於等於', + len_gt: '長度大於', + len_le: '長度小於等於', + len_lt: '長度小於', + is_true: '為真', + is_not_true: '不為真', + regex: '正則匹配', + wildcard: '通配符匹配', + }, + SystemPromptPlaceholder: '系統提示詞,可以引用系統中的變量:如', + UserPromptPlaceholder: '用戶提示詞,可以引用系統中的變量:如', + initiator: '發起人', + abnormalInformation: '異常信息', +}

Feature