From fc5b6077f353e4c030858b4e79cf561a9d80a2d4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E8=89=AF?= <841369634@qq.com> Date: Mon, 23 Mar 2026 17:02:55 +0800 Subject: [PATCH 01/14] perf: system prompt double-generating --- .../flow/step_node/ai_chat_step_node/impl/base_chat_node.py | 2 +- .../flow/step_node/question_node/impl/base_question_node.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) 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 53dfe7a0cd4..87735cae99e 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 @@ -377,7 +377,7 @@ def generate_prompt_question(self, prompt): def generate_message_list(self, system: str, prompt: str, history_message): if system is not None and len(system) > 0: - return [SystemMessage(self.workflow_manage.generate_prompt(system)), *history_message, + return [SystemMessage(system), *history_message, HumanMessage(self.workflow_manage.generate_prompt(prompt))] else: return [*history_message, HumanMessage(self.workflow_manage.generate_prompt(prompt))] diff --git a/apps/application/flow/step_node/question_node/impl/base_question_node.py b/apps/application/flow/step_node/question_node/impl/base_question_node.py index d2ccad823f0..84ea0ac0d84 100644 --- a/apps/application/flow/step_node/question_node/impl/base_question_node.py +++ b/apps/application/flow/step_node/question_node/impl/base_question_node.py @@ -126,7 +126,7 @@ def generate_prompt_question(self, prompt): def generate_message_list(self, system: str, prompt: str, history_message): if system is not None and len(system) > 0: - return [SystemMessage(self.workflow_manage.generate_prompt(system)), *history_message, + return [SystemMessage(system), *history_message, HumanMessage(self.workflow_manage.generate_prompt(prompt))] else: return [*history_message, HumanMessage(self.workflow_manage.generate_prompt(prompt))] From 75f239d1c62f39d63814d559465f996607c8f068 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E8=89=AF?= <841369634@qq.com> Date: Wed, 25 Mar 2026 13:12:39 +0800 Subject: [PATCH 02/14] fix: Fix some minor problem --- .../flow/step_node/tool_lib_node/impl/base_tool_lib_node.py | 3 +-- .../impl/base_variable_aggregation_node.py | 2 +- apps/application/serializers/application_chat_record.py | 1 - apps/chat/serializers/chat_record.py | 3 +-- apps/knowledge/serializers/paragraph.py | 1 - 5 files changed, 3 insertions(+), 7 deletions(-) diff --git a/apps/application/flow/step_node/tool_lib_node/impl/base_tool_lib_node.py b/apps/application/flow/step_node/tool_lib_node/impl/base_tool_lib_node.py index 4bc000f7236..e6995d356fe 100644 --- a/apps/application/flow/step_node/tool_lib_node/impl/base_tool_lib_node.py +++ b/apps/application/flow/step_node/tool_lib_node/impl/base_tool_lib_node.py @@ -250,6 +250,7 @@ def execute(self, tool_lib_id, input_field_list, **kwargs) -> NodeResult: def tool_exec_record(self, tool_lib, all_params): task_record_id = uuid.uuid7() start_time = time.time() + filtered_args = all_params try: # 过滤掉 tool_init_params 中的参数 tool_init_params = json.loads(rsa_long_decrypt(tool_lib.init_params)) if tool_lib.init_params else {} @@ -258,8 +259,6 @@ def tool_exec_record(self, tool_lib, all_params): k: v for k, v in all_params.items() if k not in tool_init_params } - else: - filtered_args = all_params ToolRecord( id=task_record_id, workspace_id=tool_lib.workspace_id, diff --git a/apps/application/flow/step_node/variable_aggregation_node/impl/base_variable_aggregation_node.py b/apps/application/flow/step_node/variable_aggregation_node/impl/base_variable_aggregation_node.py index fa1d6479e5c..341f2e0eab9 100644 --- a/apps/application/flow/step_node/variable_aggregation_node/impl/base_variable_aggregation_node.py +++ b/apps/application/flow/step_node/variable_aggregation_node/impl/base_variable_aggregation_node.py @@ -24,7 +24,7 @@ class BaseVariableAggregationNode(IVariableAggregation): def save_context(self, details, workflow_manage): for key, value in details.get('result').items(): - self.context['key'] = value + self.context[key] = value self.context['result'] = details.get('result') self.context['strategy'] = details.get('strategy') self.context['group_list'] = details.get('group_list') diff --git a/apps/application/serializers/application_chat_record.py b/apps/application/serializers/application_chat_record.py index 540d9310dd9..27e2d1112f7 100644 --- a/apps/application/serializers/application_chat_record.py +++ b/apps/application/serializers/application_chat_record.py @@ -104,7 +104,6 @@ def is_valid(self, *, raise_exception=False): def list(self, with_valid=True): if with_valid: self.is_valid(raise_exception=True) - QuerySet(ChatRecord).filter(chat_id=self.data.get('chat_id')) order_by = 'create_time' if self.data.get('order_asc') is None or self.data.get( 'order_asc') else '-create_time' return [ChatRecordSerializerModel(chat_record).data for chat_record in diff --git a/apps/chat/serializers/chat_record.py b/apps/chat/serializers/chat_record.py index d094216f53f..ee6d446dd57 100644 --- a/apps/chat/serializers/chat_record.py +++ b/apps/chat/serializers/chat_record.py @@ -75,8 +75,7 @@ def vote(self, instance: Dict, with_valid=True): chat_record_details_model.vote_status = VoteChoices.STAR chat_record_details_model.vote_reason = vote_reason chat_record_details_model.vote_other_content = vote_other_content - - if vote_status == VoteChoices.TRAMPLE: + elif vote_status == VoteChoices.TRAMPLE: # 点踩 chat_record_details_model.vote_status = VoteChoices.TRAMPLE chat_record_details_model.vote_reason = vote_reason diff --git a/apps/knowledge/serializers/paragraph.py b/apps/knowledge/serializers/paragraph.py index a1df1bd8100..c3a36c2b2ba 100644 --- a/apps/knowledge/serializers/paragraph.py +++ b/apps/knowledge/serializers/paragraph.py @@ -226,7 +226,6 @@ def edit(self, instance: Dict): return self.one(), instance, self.data.get('knowledge_id') def get_problem_list(self): - ProblemParagraphMapping(ProblemParagraphMapping) problem_paragraph_mapping = QuerySet(ProblemParagraphMapping).filter( paragraph_id=self.data.get("paragraph_id")) if len(problem_paragraph_mapping) > 0: From b9a02b192471618993311f948f5531708e0fd706 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E8=89=AF?= <841369634@qq.com> Date: Wed, 25 Mar 2026 13:31:09 +0800 Subject: [PATCH 03/14] fix --- .../impl/base_variable_assign_node.py | 8 +++++--- apps/application/serializers/application_chat_record.py | 2 +- apps/chat/serializers/chat.py | 8 ++++---- ui/src/locales/lang/en-US/workflow.ts | 2 +- 4 files changed, 11 insertions(+), 9 deletions(-) diff --git a/apps/application/flow/step_node/variable_assign_node/impl/base_variable_assign_node.py b/apps/application/flow/step_node/variable_assign_node/impl/base_variable_assign_node.py index f1711009a47..7d3cf751377 100644 --- a/apps/application/flow/step_node/variable_assign_node/impl/base_variable_assign_node.py +++ b/apps/application/flow/step_node/variable_assign_node/impl/base_variable_assign_node.py @@ -73,19 +73,21 @@ def execute(self, variable_list, **kwargs) -> NodeResult: for variable in variable_list: if 'fields' not in variable: continue + if 'global' == variable['fields'][0]: result = self.handle(variable, self.global_evaluation) result_list.append(result) - if 'chat' == variable['fields'][0]: + elif 'chat' == variable['fields'][0]: result = self.handle(variable, self.chat_evaluation) result_list.append(result) is_chat = True - if 'loop' == variable['fields'][0]: + elif 'loop' == variable['fields'][0]: result = self.handle(variable, self.loop_evaluation) result_list.append(result) - if 'output' == variable['fields'][0]: + elif 'output' == variable['fields'][0]: result = self.handle(variable, self.out_evaluation) result_list.append(result) + if is_chat: from application.flow.loop_workflow_manage import LoopWorkflowManage if isinstance(self.workflow_manage, LoopWorkflowManage): diff --git a/apps/application/serializers/application_chat_record.py b/apps/application/serializers/application_chat_record.py index 27e2d1112f7..92946bbdc01 100644 --- a/apps/application/serializers/application_chat_record.py +++ b/apps/application/serializers/application_chat_record.py @@ -168,7 +168,7 @@ def reset_chat_record(chat_record, show_source, show_exec): 'padding_problem_text': chat_record.details.get('problem_padding').get( 'padding_problem_text') if 'problem_padding' in chat_record.details else None, **(show_source_dict if show_source else {}), - **(show_exec_dict if show_exec else show_exec_dict) + **(show_exec_dict if show_exec else {}) } def page(self, current_page: int, page_size: int, with_valid=True, show_source=None, show_exec=None): diff --git a/apps/chat/serializers/chat.py b/apps/chat/serializers/chat.py index 076d7634178..79c3cd22379 100644 --- a/apps/chat/serializers/chat.py +++ b/apps/chat/serializers/chat.py @@ -382,10 +382,10 @@ def get_chat_record(chat_info, chat_record_id): str(chat_record.id) == str(chat_record_id)] if chat_record_list is not None and len(chat_record_list): return chat_record_list[-1] - chat_record = QuerySet(ChatRecord).filter(id=chat_record_id, chat_id=chat_info.chat_id).first() - if chat_record is None: - if not is_valid_uuid(chat_record_id): - raise ChatException(500, _("Conversation record does not exist")) + chat_record = QuerySet(ChatRecord).filter(id=chat_record_id, chat_id=chat_info.chat_id).first() + if chat_record is None: + if not is_valid_uuid(chat_record_id): + raise ChatException(500, _("Conversation record does not exist")) chat_record = QuerySet(ChatRecord).filter(id=chat_record_id).first() return chat_record diff --git a/ui/src/locales/lang/en-US/workflow.ts b/ui/src/locales/lang/en-US/workflow.ts index 74fa49f04b4..3b1ba0d740c 100644 --- a/ui/src/locales/lang/en-US/workflow.ts +++ b/ui/src/locales/lang/en-US/workflow.ts @@ -188,7 +188,7 @@ export default { result: 'Search Results', searchParam: 'Search Parameters', select_variable: 'Select Variable', - valueMessage: `Value or name `, + valueMessage: 'Value or name', searchQuestion: { label: 'Search Question', From 27fc513219b6e507f7ca97a73bc26047678c925a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E8=89=AF?= <841369634@qq.com> Date: Wed, 25 Mar 2026 17:56:32 +0800 Subject: [PATCH 04/14] =?UTF-8?q?=E5=B0=8F=E8=B0=83=E6=95=B4=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/knowledge/serializers/common.py | 11 +++++------ apps/knowledge/serializers/document.py | 2 +- 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/apps/knowledge/serializers/common.py b/apps/knowledge/serializers/common.py index 50d8b16275d..1ef66386cce 100644 --- a/apps/knowledge/serializers/common.py +++ b/apps/knowledge/serializers/common.py @@ -162,12 +162,11 @@ def get_embedding_model_id_by_knowledge_id_list(knowledge_id_list: List): def zip_dir(zip_path, output=None): output = output or os.path.basename(zip_path) + '.zip' - zip = zipfile.ZipFile(output, 'w', zipfile.ZIP_DEFLATED) - for root, dirs, files in os.walk(zip_path): - relative_root = '' if root == zip_path else root.replace(zip_path, '') + os.sep - for filename in files: - zip.write(os.path.join(root, filename), relative_root + filename) - zip.close() + with zipfile.ZipFile(output, 'w', zipfile.ZIP_DEFLATED) as zip: + for root, dirs, files in os.walk(zip_path): + relative_root = '' if root == zip_path else root.replace(zip_path, '') + os.sep + for filename in files: + zip.write(os.path.join(root, filename), relative_root + filename) def is_valid_uuid(s): diff --git a/apps/knowledge/serializers/document.py b/apps/knowledge/serializers/document.py index d8466663464..e52cf23bbd8 100644 --- a/apps/knowledge/serializers/document.py +++ b/apps/knowledge/serializers/document.py @@ -257,7 +257,7 @@ def table_export(self, with_valid=True): "rb") content = file.read() file.close() - return HttpResponse(content, status=200, headers={'Content-Type': 'text/cxv', + return HttpResponse(content, status=200, headers={'Content-Type': 'text/csv', 'Content-Disposition': 'attachment; filename="csv_template.csv"'}) elif self.data.get('type') == 'excel': file = open(os.path.join(PROJECT_DIR, "apps", "knowledge", 'template', From 46218ef8db464469dab808e3abe7efee4203da7d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E8=89=AF?= <841369634@qq.com> Date: Thu, 26 Mar 2026 09:57:43 +0800 Subject: [PATCH 05/14] =?UTF-8?q?=E6=96=87=E4=BB=B6=E5=A4=84=E7=90=86?= =?UTF-8?q?=EF=BC=8C=E4=BD=BF=E7=94=A8=20with=20...=20as=20file=20?= =?UTF-8?q?=E8=AF=AD=E6=B3=95=EF=BC=8C=E9=81=BF=E5=85=8D=E6=96=87=E4=BB=B6?= =?UTF-8?q?=E6=9C=AA=E5=85=B3=E9=97=AD=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/knowledge/serializers/document.py | 30 +++++++++++--------------- 1 file changed, 13 insertions(+), 17 deletions(-) diff --git a/apps/knowledge/serializers/document.py b/apps/knowledge/serializers/document.py index e52cf23bbd8..007ac8489d9 100644 --- a/apps/knowledge/serializers/document.py +++ b/apps/knowledge/serializers/document.py @@ -228,19 +228,17 @@ def export(self, with_valid=True): self.is_valid(raise_exception=True) language = get_language() if self.data.get('type') == 'csv': - file = open( + with open( os.path.join(PROJECT_DIR, "apps", "knowledge", 'template', f'csv_template_{to_locale(language)}.csv'), - "rb") - content = file.read() - file.close() + "rb") as file: + content = file.read() return HttpResponse(content, status=200, headers={'Content-Type': 'text/csv', 'Content-Disposition': 'attachment; filename="csv_template.csv"'}) elif self.data.get('type') == 'excel': - file = open(os.path.join(PROJECT_DIR, "apps", "knowledge", 'template', - f'excel_template_{to_locale(language)}.xlsx'), "rb") - content = file.read() - file.close() + with open(os.path.join(PROJECT_DIR, "apps", "knowledge", 'template', + f'excel_template_{to_locale(language)}.xlsx'), "rb") as file: + content = file.read() return HttpResponse(content, status=200, headers={'Content-Type': 'application/vnd.ms-excel', 'Content-Disposition': 'attachment; filename="excel_template.xlsx"'}) else: @@ -251,20 +249,18 @@ def table_export(self, with_valid=True): self.is_valid(raise_exception=True) language = get_language() if self.data.get('type') == 'csv': - file = open( + with open( os.path.join(PROJECT_DIR, "apps", "knowledge", 'template', f'table_template_{to_locale(language)}.csv'), - "rb") - content = file.read() - file.close() + "rb") as file: + content = file.read() return HttpResponse(content, status=200, headers={'Content-Type': 'text/csv', 'Content-Disposition': 'attachment; filename="csv_template.csv"'}) elif self.data.get('type') == 'excel': - file = open(os.path.join(PROJECT_DIR, "apps", "knowledge", 'template', - f'table_template_{to_locale(language)}.xlsx'), - "rb") - content = file.read() - file.close() + with open(os.path.join(PROJECT_DIR, "apps", "knowledge", 'template', + f'table_template_{to_locale(language)}.xlsx'), + "rb") as file: + content = file.read() return HttpResponse(content, status=200, headers={'Content-Type': 'application/vnd.ms-excel', 'Content-Disposition': 'attachment; filename="excel_template.xlsx"'}) else: From 2e8dced1b2b220eacebf4c62e52b8e2de40ef7be Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E8=89=AF?= <841369634@qq.com> Date: Thu, 26 Mar 2026 11:13:13 +0800 Subject: [PATCH 06/14] =?UTF-8?q?=E4=BF=AE=E6=AD=A3=E9=94=99=E8=AF=AF?= =?UTF-8?q?=E5=AD=97=E7=AC=A6=E4=B8=B2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/common/handle/impl/text/zip_split_handle.py | 4 ++-- .../impl/ollama_model_provider/ollama_model_provider.py | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/apps/common/handle/impl/text/zip_split_handle.py b/apps/common/handle/impl/text/zip_split_handle.py index d8365d5c285..498afbea848 100644 --- a/apps/common/handle/impl/text/zip_split_handle.py +++ b/apps/common/handle/impl/text/zip_split_handle.py @@ -83,7 +83,7 @@ def get_image_list(result_list: list, zip_files: List[str]): if not zip_files.__contains__(image_path): continue if image_path.startswith('oss/file/') or image_path.startswith('oss/image/'): - image_id = image_path.replace('oss/file/', '').replace('oss/file/', '') + image_id = image_path.replace('oss/file/', '').replace('oss/image/', '') if is_valid_uuid(image_id): image_file_list.append({'source_file': image_path, 'image_id': image_id}) @@ -115,7 +115,7 @@ def get_image_list_by_content(name: str, content: str, zip_files: List[str]): if not zip_files.__contains__(image_path): continue if image_path.startswith('oss/file/') or image_path.startswith('oss/image/'): - image_id = image_path.replace('oss/file/', '').replace('oss/file/', '') + image_id = image_path.replace('oss/file/', '').replace('oss/image/', '') if is_valid_uuid(image_id): image_file_list.append({'source_file': image_path, 'image_id': image_id}) diff --git a/apps/models_provider/impl/ollama_model_provider/ollama_model_provider.py b/apps/models_provider/impl/ollama_model_provider/ollama_model_provider.py index 2ad2107e1a2..5bb8a54049f 100644 --- a/apps/models_provider/impl/ollama_model_provider/ollama_model_provider.py +++ b/apps/models_provider/impl/ollama_model_provider/ollama_model_provider.py @@ -224,7 +224,7 @@ def convert_to_down_model_chunk(row_str: str, chunk_index: int): if row.get('status').__contains__("pulling"): progress = 0 status = DownModelChunkStatus.pulling - if 'total' in row and 'completed' in row: + if 'total' in row and 'completed' in row and row.get('total'): progress = (row.get('completed') / row.get('total') * 100) elif 'error' in row: status = DownModelChunkStatus.error From b3e7b6541e839e16bd946771b178806e96e6553c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E8=89=AF?= <841369634@qq.com> Date: Thu, 26 Mar 2026 11:38:34 +0800 Subject: [PATCH 07/14] fix bugs: invalid regex escape sequences, and resource leaks --- .../application_node/impl/base_application_node.py | 2 +- apps/common/handle/impl/common_handle.py | 8 ++++---- apps/common/handle/impl/qa/zip_parse_qa_handle.py | 2 +- apps/common/handle/impl/text/pdf_split_handle.py | 14 +++++++++++--- apps/common/handle/impl/text/zip_split_handle.py | 4 ++-- apps/common/utils/common.py | 4 ++-- apps/knowledge/serializers/common.py | 2 +- 7 files changed, 22 insertions(+), 14 deletions(-) diff --git a/apps/application/flow/step_node/application_node/impl/base_application_node.py b/apps/application/flow/step_node/application_node/impl/base_application_node.py index 7d033e08884..ca8aebb8b3d 100644 --- a/apps/application/flow/step_node/application_node/impl/base_application_node.py +++ b/apps/application/flow/step_node/application_node/impl/base_application_node.py @@ -130,7 +130,7 @@ def reset_application_node_dict(application_node_dict, runtime_node_id, node_dat application_node = application_node_dict[key] if application_node.get('runtime_node_id') == runtime_node_id: content: str = application_node.get('content') - match = re.search('.*?', content) + match = re.search(r'.*?', content) if match: form_setting_str = match.group().replace('', '').replace('', '') form_setting = json.loads(form_setting_str) diff --git a/apps/common/handle/impl/common_handle.py b/apps/common/handle/impl/common_handle.py index 16c647a9626..c143b727658 100644 --- a/apps/common/handle/impl/common_handle.py +++ b/apps/common/handle/impl/common_handle.py @@ -121,10 +121,10 @@ def xlsx_embed_cells_images(buffer) -> {}: continue if len(image_excel_id_list) > 0: image_excel_id = image_excel_id_list[-1] - f = archive.open(img.target) - img_byte = io.BytesIO() - im = PILImage.open(f).convert('RGB') - im.save(img_byte, format='JPEG') + with archive.open(img.target) as f: + img_byte = io.BytesIO() + im = PILImage.open(f).convert('RGB') + im.save(img_byte, format='JPEG') image = File(id=uuid.uuid7(), file_name=img.path, meta={'debug': False, 'content': img_byte.getvalue()}) result['=' + image_excel_id] = image archive.close() diff --git a/apps/common/handle/impl/qa/zip_parse_qa_handle.py b/apps/common/handle/impl/qa/zip_parse_qa_handle.py index cdf56ef1524..1bd6bf7be23 100644 --- a/apps/common/handle/impl/qa/zip_parse_qa_handle.py +++ b/apps/common/handle/impl/qa/zip_parse_qa_handle.py @@ -82,7 +82,7 @@ def get_image_list(result_list: list, zip_files: List[str]): content: str = p.get('content', '') image_list = parse_md_image(content) for image in image_list: - search = re.search("\(.*\)", image) + search = re.search(r"\(.*\)", image) if search: new_image_id = str(uuid.uuid7()) source_image_path = search.group().replace('(', '').replace(')', '') diff --git a/apps/common/handle/impl/text/pdf_split_handle.py b/apps/common/handle/impl/text/pdf_split_handle.py index f3172e29884..0ffafff61c0 100644 --- a/apps/common/handle/impl/text/pdf_split_handle.py +++ b/apps/common/handle/impl/text/pdf_split_handle.py @@ -49,8 +49,9 @@ def handle(self, file, pattern_list: List, with_filter: bool, limit: int, get_bu # 获取临时文件的路径 temp_file_path = temp_file.name - pdf_document = fitz.open(temp_file_path) + pdf_document = None try: + pdf_document = fitz.open(temp_file_path) if type(limit) is str: limit = int(limit) if type(with_filter) is str: @@ -79,7 +80,8 @@ def handle(self, file, pattern_list: List, with_filter: bool, limit: int, get_bu 'content': [] } finally: - pdf_document.close() + if pdf_document is not None: + pdf_document.close() # 处理完后可以删除临时文件 os.remove(temp_file_path) @@ -331,9 +333,15 @@ def get_content(self, file, save_image): # 获取临时文件的路径 temp_file_path = temp_file.name - pdf_document = fitz.open(temp_file_path) + pdf_document = None try: + pdf_document = fitz.open(temp_file_path) return self.handle_pdf_content(file, pdf_document) except BaseException as e: traceback.print_exception(e) return f'{e}' + finally: + if pdf_document is not None: + pdf_document.close() + # 处理完后可以删除临时文件 + os.remove(temp_file_path) diff --git a/apps/common/handle/impl/text/zip_split_handle.py b/apps/common/handle/impl/text/zip_split_handle.py index 498afbea848..a6569f23c02 100644 --- a/apps/common/handle/impl/text/zip_split_handle.py +++ b/apps/common/handle/impl/text/zip_split_handle.py @@ -73,7 +73,7 @@ def get_image_list(result_list: list, zip_files: List[str]): content: str = p.get('content', '') image_list = parse_md_image(content) for image in image_list: - search = re.search("\(.*\)", image) + search = re.search(r"\(.*\)", image) if search: new_image_id = str(uuid.uuid7()) source_image_path = search.group().replace('(', '').replace(')', '') @@ -105,7 +105,7 @@ def get_image_list_by_content(name: str, content: str, zip_files: List[str]): image_file_list = [] image_list = parse_md_image(content) for image in image_list: - search = re.search("\(.*\)", image) + search = re.search(r"\(.*\)", image) if search: new_image_id = str(uuid.uuid7()) source_image_path = search.group().replace('(', '').replace(')', '') diff --git a/apps/common/utils/common.py b/apps/common/utils/common.py index e2c6ace2721..9e035ac3531 100644 --- a/apps/common/utils/common.py +++ b/apps/common/utils/common.py @@ -272,7 +272,7 @@ def run(*args, **kwargs): def parse_md_image(content: str): - matches = re.finditer("!\[.*?\]\(.*?\)", content) + matches = re.finditer(r"!\[.*?\]\(.*?\)", content) image_list = [match.group() for match in matches] return image_list @@ -330,7 +330,7 @@ def flat_map(array: List[List]): def parse_image(content: str): - matches = re.finditer("!\[.*?\]\(\.\/oss\/(image|file)\/.*?\)", content) + matches = re.finditer(r"!\[.*?\]\(\.\/oss\/(image|file)\/.*?\)", content) image_list = [match.group() for match in matches] return image_list diff --git a/apps/knowledge/serializers/common.py b/apps/knowledge/serializers/common.py index 1ef66386cce..d5ef9a6ddc0 100644 --- a/apps/knowledge/serializers/common.py +++ b/apps/knowledge/serializers/common.py @@ -179,7 +179,7 @@ def is_valid_uuid(s): def write_image(zip_path: str, image_list: List[str]): for image in image_list: - search = re.search("\(.*\)", image) + search = re.search(r"\(.*\)", image) if search: text = search.group() if text.startswith('(./oss/file/'): From ad2aff24b844ecf0e1e9889a573e7ca4f7742acd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E8=89=AF?= <841369634@qq.com> Date: Thu, 26 Mar 2026 11:53:51 +0800 Subject: [PATCH 08/14] fix bugs: invalid regex escape sequences, and resource leaks --- .../step_node/ai_chat_step_node/impl/base_chat_node.py | 2 +- .../flow/step_node/intent_node/impl/base_intent_node.py | 2 +- .../step_node/question_node/impl/base_question_node.py | 2 +- apps/chat/serializers/chat_embed_serializers.py | 5 ++--- apps/maxkb/urls/web.py | 5 ++--- .../impl/aws_bedrock_model_provider/model/llm.py | 6 +++++- apps/users/serializers/user.py | 9 ++++----- 7 files changed, 16 insertions(+), 15 deletions(-) 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 6aa899bf286..cf72b20afd6 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 @@ -471,7 +471,7 @@ def get_history_message(history_chat_record, dialogue_number, dialogue_type, run range(start_index if start_index > 0 else 0, len(history_chat_record))], []) for message in history_message: if isinstance(message.content, str): - message.content = re.sub('[\d\D]*?<\/form_rander>', '', message.content) + message.content = re.sub(r'[\d\D]*?<\/form_rander>', '', message.content) return history_message def generate_prompt_question(self, prompt): diff --git a/apps/application/flow/step_node/intent_node/impl/base_intent_node.py b/apps/application/flow/step_node/intent_node/impl/base_intent_node.py index cdf8a769abf..8744d274d05 100644 --- a/apps/application/flow/step_node/intent_node/impl/base_intent_node.py +++ b/apps/application/flow/step_node/intent_node/impl/base_intent_node.py @@ -131,7 +131,7 @@ def get_history_message(history_chat_record, dialogue_number): for message in history_message: if isinstance(message.content, str): - message.content = re.sub('[\d\D]*?<\/form_rander>', '', message.content) + message.content = re.sub(r'[\d\D]*?<\/form_rander>', '', message.content) return history_message def build_system_prompt(self) -> str: diff --git a/apps/application/flow/step_node/question_node/impl/base_question_node.py b/apps/application/flow/step_node/question_node/impl/base_question_node.py index 07ba8cd7622..dc5771f0aa4 100644 --- a/apps/application/flow/step_node/question_node/impl/base_question_node.py +++ b/apps/application/flow/step_node/question_node/impl/base_question_node.py @@ -128,7 +128,7 @@ def get_history_message(history_chat_record, dialogue_number): range(start_index if start_index > 0 else 0, len(history_chat_record))], []) for message in history_message: if isinstance(message.content, str): - message.content = re.sub('[\d\D]*?<\/form_rander>', '', message.content) + message.content = re.sub(r'[\d\D]*?<\/form_rander>', '', message.content) return history_message def generate_prompt_question(self, prompt): diff --git a/apps/chat/serializers/chat_embed_serializers.py b/apps/chat/serializers/chat_embed_serializers.py index 7f330f93e94..5594e5b0abe 100644 --- a/apps/chat/serializers/chat_embed_serializers.py +++ b/apps/chat/serializers/chat_embed_serializers.py @@ -32,9 +32,8 @@ def get_embed(self, with_valid=True, params=None): if with_valid: self.is_valid(raise_exception=True) index_path = os.path.join(PROJECT_DIR, 'apps', "chat", 'template', 'embed.js') - file = open(index_path, "r", encoding='utf-8') - content = file.read() - file.close() + with open(index_path, "r", encoding='utf-8') as file: + content = file.read() application_access_token = QuerySet(ApplicationAccessToken).filter( access_token=self.data.get('token')).first() is_draggable = 'false' diff --git a/apps/maxkb/urls/web.py b/apps/maxkb/urls/web.py index fb043d56a64..1fee100f073 100644 --- a/apps/maxkb/urls/web.py +++ b/apps/maxkb/urls/web.py @@ -80,9 +80,8 @@ def pro(): def get_index_html(index_path): - file = open(index_path, "r", encoding='utf-8') - content = file.read() - file.close() + with open(index_path, "r", encoding='utf-8') as file: + content = file.read() return content diff --git a/apps/models_provider/impl/aws_bedrock_model_provider/model/llm.py b/apps/models_provider/impl/aws_bedrock_model_provider/model/llm.py index 50ee4abfe65..e5d32ab1c9d 100644 --- a/apps/models_provider/impl/aws_bedrock_model_provider/model/llm.py +++ b/apps/models_provider/impl/aws_bedrock_model_provider/model/llm.py @@ -92,7 +92,11 @@ def _update_aws_credentials(profile_name, access_key_id, secret_access_key): credentials_path = os.path.join(os.path.expanduser("~"), ".aws", "credentials") os.makedirs(os.path.dirname(credentials_path), exist_ok=True) - content = open(credentials_path, 'r').read() if os.path.exists(credentials_path) else '' + if os.path.exists(credentials_path): + with open(credentials_path, 'r') as f: + content = f.read() + else: + content = '' pattern = rf'\n*\[{profile_name}\]\n*(aws_access_key_id = .*)\n*(aws_secret_access_key = .*)\n*' content = re.sub(pattern, '', content, flags=re.DOTALL) diff --git a/apps/users/serializers/user.py b/apps/users/serializers/user.py index 45e55528c30..05cf370c16d 100644 --- a/apps/users/serializers/user.py +++ b/apps/users/serializers/user.py @@ -1071,11 +1071,10 @@ def send(self): ]), range(6)))) # 获取邮件模板 language = get_language() - file = open( - os.path.join(PROJECT_DIR, "apps", "common", 'template', f'email_template_{to_locale(language)}.html'), "r", - encoding='utf-8') - content = file.read() - file.close() + with open( + os.path.join(PROJECT_DIR, "apps", "common", 'template', f'email_template_{to_locale(language)}.html'), + "r", encoding='utf-8') as file: + content = file.read() code_cache_key = email + ":" + state code_cache_key_lock = code_cache_key + "_lock" # 设置缓存 From fbbdb70bcc843df4ffbad760cc2b127bc58c58f6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E8=89=AF?= <841369634@qq.com> Date: Thu, 26 Mar 2026 12:10:05 +0800 Subject: [PATCH 09/14] =?UTF-8?q?=E6=92=A4=E5=9B=9E=E5=AF=B9=E6=AD=A3?= =?UTF-8?q?=E5=88=99=E7=9A=84=E4=BF=AE=E6=AD=A3=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../flow/step_node/ai_chat_step_node/impl/base_chat_node.py | 2 +- .../step_node/application_node/impl/base_application_node.py | 2 +- .../flow/step_node/intent_node/impl/base_intent_node.py | 2 +- .../flow/step_node/question_node/impl/base_question_node.py | 2 +- apps/common/handle/impl/qa/zip_parse_qa_handle.py | 2 +- apps/common/handle/impl/text/zip_split_handle.py | 4 ++-- apps/common/utils/common.py | 4 ++-- apps/knowledge/serializers/common.py | 2 +- 8 files changed, 10 insertions(+), 10 deletions(-) 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 cf72b20afd6..6aa899bf286 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 @@ -471,7 +471,7 @@ def get_history_message(history_chat_record, dialogue_number, dialogue_type, run range(start_index if start_index > 0 else 0, len(history_chat_record))], []) for message in history_message: if isinstance(message.content, str): - message.content = re.sub(r'[\d\D]*?<\/form_rander>', '', message.content) + message.content = re.sub('[\d\D]*?<\/form_rander>', '', message.content) return history_message def generate_prompt_question(self, prompt): diff --git a/apps/application/flow/step_node/application_node/impl/base_application_node.py b/apps/application/flow/step_node/application_node/impl/base_application_node.py index ca8aebb8b3d..7d033e08884 100644 --- a/apps/application/flow/step_node/application_node/impl/base_application_node.py +++ b/apps/application/flow/step_node/application_node/impl/base_application_node.py @@ -130,7 +130,7 @@ def reset_application_node_dict(application_node_dict, runtime_node_id, node_dat application_node = application_node_dict[key] if application_node.get('runtime_node_id') == runtime_node_id: content: str = application_node.get('content') - match = re.search(r'.*?', content) + match = re.search('.*?', content) if match: form_setting_str = match.group().replace('', '').replace('', '') form_setting = json.loads(form_setting_str) diff --git a/apps/application/flow/step_node/intent_node/impl/base_intent_node.py b/apps/application/flow/step_node/intent_node/impl/base_intent_node.py index 8744d274d05..cdf8a769abf 100644 --- a/apps/application/flow/step_node/intent_node/impl/base_intent_node.py +++ b/apps/application/flow/step_node/intent_node/impl/base_intent_node.py @@ -131,7 +131,7 @@ def get_history_message(history_chat_record, dialogue_number): for message in history_message: if isinstance(message.content, str): - message.content = re.sub(r'[\d\D]*?<\/form_rander>', '', message.content) + message.content = re.sub('[\d\D]*?<\/form_rander>', '', message.content) return history_message def build_system_prompt(self) -> str: diff --git a/apps/application/flow/step_node/question_node/impl/base_question_node.py b/apps/application/flow/step_node/question_node/impl/base_question_node.py index dc5771f0aa4..07ba8cd7622 100644 --- a/apps/application/flow/step_node/question_node/impl/base_question_node.py +++ b/apps/application/flow/step_node/question_node/impl/base_question_node.py @@ -128,7 +128,7 @@ def get_history_message(history_chat_record, dialogue_number): range(start_index if start_index > 0 else 0, len(history_chat_record))], []) for message in history_message: if isinstance(message.content, str): - message.content = re.sub(r'[\d\D]*?<\/form_rander>', '', message.content) + message.content = re.sub('[\d\D]*?<\/form_rander>', '', message.content) return history_message def generate_prompt_question(self, prompt): diff --git a/apps/common/handle/impl/qa/zip_parse_qa_handle.py b/apps/common/handle/impl/qa/zip_parse_qa_handle.py index 1bd6bf7be23..cdf56ef1524 100644 --- a/apps/common/handle/impl/qa/zip_parse_qa_handle.py +++ b/apps/common/handle/impl/qa/zip_parse_qa_handle.py @@ -82,7 +82,7 @@ def get_image_list(result_list: list, zip_files: List[str]): content: str = p.get('content', '') image_list = parse_md_image(content) for image in image_list: - search = re.search(r"\(.*\)", image) + search = re.search("\(.*\)", image) if search: new_image_id = str(uuid.uuid7()) source_image_path = search.group().replace('(', '').replace(')', '') diff --git a/apps/common/handle/impl/text/zip_split_handle.py b/apps/common/handle/impl/text/zip_split_handle.py index a6569f23c02..498afbea848 100644 --- a/apps/common/handle/impl/text/zip_split_handle.py +++ b/apps/common/handle/impl/text/zip_split_handle.py @@ -73,7 +73,7 @@ def get_image_list(result_list: list, zip_files: List[str]): content: str = p.get('content', '') image_list = parse_md_image(content) for image in image_list: - search = re.search(r"\(.*\)", image) + search = re.search("\(.*\)", image) if search: new_image_id = str(uuid.uuid7()) source_image_path = search.group().replace('(', '').replace(')', '') @@ -105,7 +105,7 @@ def get_image_list_by_content(name: str, content: str, zip_files: List[str]): image_file_list = [] image_list = parse_md_image(content) for image in image_list: - search = re.search(r"\(.*\)", image) + search = re.search("\(.*\)", image) if search: new_image_id = str(uuid.uuid7()) source_image_path = search.group().replace('(', '').replace(')', '') diff --git a/apps/common/utils/common.py b/apps/common/utils/common.py index 9e035ac3531..e2c6ace2721 100644 --- a/apps/common/utils/common.py +++ b/apps/common/utils/common.py @@ -272,7 +272,7 @@ def run(*args, **kwargs): def parse_md_image(content: str): - matches = re.finditer(r"!\[.*?\]\(.*?\)", content) + matches = re.finditer("!\[.*?\]\(.*?\)", content) image_list = [match.group() for match in matches] return image_list @@ -330,7 +330,7 @@ def flat_map(array: List[List]): def parse_image(content: str): - matches = re.finditer(r"!\[.*?\]\(\.\/oss\/(image|file)\/.*?\)", content) + matches = re.finditer("!\[.*?\]\(\.\/oss\/(image|file)\/.*?\)", content) image_list = [match.group() for match in matches] return image_list diff --git a/apps/knowledge/serializers/common.py b/apps/knowledge/serializers/common.py index d5ef9a6ddc0..1ef66386cce 100644 --- a/apps/knowledge/serializers/common.py +++ b/apps/knowledge/serializers/common.py @@ -179,7 +179,7 @@ def is_valid_uuid(s): def write_image(zip_path: str, image_list: List[str]): for image in image_list: - search = re.search(r"\(.*\)", image) + search = re.search("\(.*\)", image) if search: text = search.group() if text.startswith('(./oss/file/'): From 66ccc3a7d46553ca6598b4bf2b442233cfac0577 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E8=89=AF?= <841369634@qq.com> Date: Fri, 27 Mar 2026 10:18:37 +0800 Subject: [PATCH 10/14] operation --- .../impl/base_variable_assign_node.py | 2 +- apps/common/handle/impl/common_handle.py | 81 +++++++++---------- .../handler/impl/trigger/event_trigger.py | 2 +- 3 files changed, 42 insertions(+), 43 deletions(-) diff --git a/apps/application/flow/step_node/variable_assign_node/impl/base_variable_assign_node.py b/apps/application/flow/step_node/variable_assign_node/impl/base_variable_assign_node.py index 7d3cf751377..152bda93abc 100644 --- a/apps/application/flow/step_node/variable_assign_node/impl/base_variable_assign_node.py +++ b/apps/application/flow/step_node/variable_assign_node/impl/base_variable_assign_node.py @@ -71,7 +71,7 @@ def execute(self, variable_list, **kwargs) -> NodeResult: result_list = [] is_chat = False for variable in variable_list: - if 'fields' not in variable: + if not variable.get('fields'): continue if 'global' == variable['fields'][0]: diff --git a/apps/common/handle/impl/common_handle.py b/apps/common/handle/impl/common_handle.py index c143b727658..98b7537926f 100644 --- a/apps/common/handle/impl/common_handle.py +++ b/apps/common/handle/impl/common_handle.py @@ -86,46 +86,45 @@ def handle_images(deps, archive: ZipFile) -> []: def xlsx_embed_cells_images(buffer) -> {}: - archive = ZipFile(buffer) - # 解析cellImage.xml文件 - deps = get_dependents(archive, get_rels_path("xl/cellimages.xml")) - image_rel = handle_images(deps=deps, archive=archive) - # 工作表及其中图片ID - sheet_list = {} - for item in archive.namelist(): - if not item.startswith('xl/worksheets/sheet'): - continue - key = item.split('/')[-1].split('.')[0].split('sheet')[-1] - sheet_list[key] = parse_element_sheet_xml(fromstring(archive.read(item))) - cell_images_xml = parse_element(fromstring(archive.read("xl/cellimages.xml"))) - cell_images_rel = {} - for image in image_rel: - cell_images_rel[image.embed] = image - for cnv, embed in cell_images_xml.items(): - cell_images_xml[cnv] = cell_images_rel.get(embed) - result = {} - for key, img in cell_images_xml.items(): - all_cells = [ - cell - for _sheet_id, sheet in sheet_list.items() - if sheet is not None - for cell in sheet or [] - ] + with ZipFile(buffer) as archive: + # 解析cellImage.xml文件 + deps = get_dependents(archive, get_rels_path("xl/cellimages.xml")) + image_rel = handle_images(deps=deps, archive=archive) + # 工作表及其中图片ID + sheet_list = {} + for item in archive.namelist(): + if not item.startswith('xl/worksheets/sheet'): + continue + key = item.split('/')[-1].split('.')[0].split('sheet')[-1] + sheet_list[key] = parse_element_sheet_xml(fromstring(archive.read(item))) + cell_images_xml = parse_element(fromstring(archive.read("xl/cellimages.xml"))) + cell_images_rel = {} + for image in image_rel: + cell_images_rel[image.embed] = image + for cnv, embed in cell_images_xml.items(): + cell_images_xml[cnv] = cell_images_rel.get(embed) + result = {} + for key, img in cell_images_xml.items(): + all_cells = [ + cell + for _sheet_id, sheet in sheet_list.items() + if sheet is not None + for cell in sheet or [] + ] - image_excel_id_list = [ - cell for cell in all_cells - if isinstance(cell, str) and key in cell - ] - # print(key, img) - if img is None: - continue - if len(image_excel_id_list) > 0: - image_excel_id = image_excel_id_list[-1] - with archive.open(img.target) as f: - img_byte = io.BytesIO() - im = PILImage.open(f).convert('RGB') - im.save(img_byte, format='JPEG') - image = File(id=uuid.uuid7(), file_name=img.path, meta={'debug': False, 'content': img_byte.getvalue()}) - result['=' + image_excel_id] = image - archive.close() + image_excel_id_list = [ + cell for cell in all_cells + if isinstance(cell, str) and key in cell + ] + # print(key, img) + if img is None: + continue + if len(image_excel_id_list) > 0: + image_excel_id = image_excel_id_list[-1] + with archive.open(img.target) as f: + img_byte = io.BytesIO() + im = PILImage.open(f).convert('RGB') + im.save(img_byte, format='JPEG') + image = File(id=uuid.uuid7(), file_name=img.path, meta={'debug': False, 'content': img_byte.getvalue()}) + result['=' + image_excel_id] = image return result diff --git a/apps/trigger/handler/impl/trigger/event_trigger.py b/apps/trigger/handler/impl/trigger/event_trigger.py index 6368cf58b13..cb3df4c26f4 100644 --- a/apps/trigger/handler/impl/trigger/event_trigger.py +++ b/apps/trigger/handler/impl/trigger/event_trigger.py @@ -119,7 +119,7 @@ def execute(trigger, request=None, **kwargs): trigger_setting = trigger.get('trigger_setting') if trigger_setting.get('token'): token = request.META.get('HTTP_AUTHORIZATION') - if trigger_setting.get('token') != token.replace('Bearer ', ''): + if not token or trigger_setting.get('token') != token.replace('Bearer ', ''): raise AppAuthenticationFailed(1002, _('Authentication information is incorrect')) is_active = trigger.get('is_active') if not is_active: From 8b94350315d137d91a58c65cba9c52265815b68c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E8=89=AF?= <841369634@qq.com> Date: Fri, 27 Mar 2026 15:12:51 +0800 Subject: [PATCH 11/14] =?UTF-8?q?=E5=B0=8F=E8=B0=83=E6=95=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../chat_pipeline/step/chat_step/impl/base_chat_step.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/application/chat_pipeline/step/chat_step/impl/base_chat_step.py b/apps/application/chat_pipeline/step/chat_step/impl/base_chat_step.py index 8a586eaf44f..501394ff584 100644 --- a/apps/application/chat_pipeline/step/chat_step/impl/base_chat_step.py +++ b/apps/application/chat_pipeline/step/chat_step/impl/base_chat_step.py @@ -183,7 +183,7 @@ def execute(self, message_list: List[BaseMessage], mcp_output_enable=True, **kwargs): chat_model = get_model_instance_by_model_workspace_id(model_id, workspace_id, - **model_params_setting) if model_id is not None else None + **(model_params_setting or {})) if model_id is not None else None if stream: return self.execute_stream(message_list, chat_id, problem_text, post_response_handler, chat_model, paragraph_list, From d4527dedf1f6190e3735630cea51b90eb31dce42 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E8=89=AF?= <841369634@qq.com> Date: Fri, 27 Mar 2026 15:31:34 +0800 Subject: [PATCH 12/14] =?UTF-8?q?=E5=B0=8F=E8=B0=83=E6=95=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../flow/step_node/ai_chat_step_node/impl/base_chat_node.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 6aa899bf286..4b60edfc0b9 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 @@ -453,7 +453,7 @@ def handle_variables(self, tool_params): tool_params[k] = self.workflow_manage.generate_prompt(tool_params[k]) if type(v) == dict: self.handle_variables(v) - if (type(v) == list) and (type(v[0]) == str): + if (type(v) == list) and len(v) > 0 and (type(v[0]) == str): tool_params[k] = self.get_reference_content(v) return tool_params From 2feaa9a3ce89d40deda33ac5fd94f449cf544c66 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E8=89=AF?= <841369634@qq.com> Date: Fri, 27 Mar 2026 16:27:27 +0800 Subject: [PATCH 13/14] =?UTF-8?q?=E5=B0=8F=E8=B0=83=E6=95=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../impl/base_variable_splitting_node.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/application/flow/step_node/variable_splitting_node/impl/base_variable_splitting_node.py b/apps/application/flow/step_node/variable_splitting_node/impl/base_variable_splitting_node.py index 90a47613a46..274604e2328 100644 --- a/apps/application/flow/step_node/variable_splitting_node/impl/base_variable_splitting_node.py +++ b/apps/application/flow/step_node/variable_splitting_node/impl/base_variable_splitting_node.py @@ -16,7 +16,7 @@ jsonpath_expr_cache = MemCache('parse_path', { 'TIMEOUT': 3600, # 缓存有效期为 1 小时 'OPTIONS': { - 'MAX_ENTRIES': 1000, # 最多缓存 500 个条目 + 'MAX_ENTRIES': 1000, # 最多缓存 1000 个条目 'CULL_FREQUENCY': 10, # 达到上限时,删除约 1/10 的缓存 }, }) From 5ae0a846035894da711118c58b67be0c36998dc4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E8=89=AF?= <841369634@qq.com> Date: Fri, 27 Mar 2026 16:31:35 +0800 Subject: [PATCH 14/14] revert --- ui/src/locales/lang/en-US/workflow.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ui/src/locales/lang/en-US/workflow.ts b/ui/src/locales/lang/en-US/workflow.ts index c46811dc1aa..d4268a6f242 100644 --- a/ui/src/locales/lang/en-US/workflow.ts +++ b/ui/src/locales/lang/en-US/workflow.ts @@ -188,7 +188,7 @@ export default { result: 'Search Results', searchParam: 'Search Parameters', select_variable: 'Select Variable', - valueMessage: 'Value or name', + valueMessage: `Value or name `, searchQuestion: { label: 'Search Question',