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',