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 cd27c0bb918..53d39174d37 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 @@ -205,8 +205,7 @@ def execute( model_params_setting = reference_data.get("model_params_setting") elif model_id_type == "default": default_setting = self.workflow_manage.get_default_model_setting("LLM") - if default_setting.get("model_id"): - model_id = default_setting.get("model_id") + model_id = default_setting.get("model_id") model_params_setting = default_setting.get("model_params_setting", model_params_setting) if model_id is None or model_id == "": raise Exception(_("Model is not allowed to be empty")) diff --git a/apps/application/flow/step_node/image_generate_step_node/impl/base_image_generate_node.py b/apps/application/flow/step_node/image_generate_step_node/impl/base_image_generate_node.py index db2f723511d..d415a2acfae 100644 --- a/apps/application/flow/step_node/image_generate_step_node/impl/base_image_generate_node.py +++ b/apps/application/flow/step_node/image_generate_step_node/impl/base_image_generate_node.py @@ -38,8 +38,7 @@ def execute(self, model_id, prompt, negative_prompt, dialogue_number, dialogue_t model_params_setting = reference_data.get('model_params_setting') elif model_id_type == 'default': default_setting = self.workflow_manage.get_default_model_setting('TTI') - if default_setting.get('model_id'): - model_id = default_setting.get('model_id') + model_id = default_setting.get('model_id') model_params_setting = default_setting.get('model_params_setting', model_params_setting) if model_id is None or model_id == '': diff --git a/apps/application/flow/step_node/image_to_video_step_node/impl/base_image_to_video_node.py b/apps/application/flow/step_node/image_to_video_step_node/impl/base_image_to_video_node.py index 08cb0f0ad55..b58f463e6e5 100644 --- a/apps/application/flow/step_node/image_to_video_step_node/impl/base_image_to_video_node.py +++ b/apps/application/flow/step_node/image_to_video_step_node/impl/base_image_to_video_node.py @@ -41,8 +41,7 @@ def execute(self, model_id, prompt, negative_prompt, dialogue_number, dialogue_t model_params_setting = reference_data.get('model_params_setting') elif model_id_type == 'default': default_setting = self.workflow_manage.get_default_model_setting('ITV') - if default_setting.get('model_id'): - model_id = default_setting.get('model_id') + model_id = default_setting.get('model_id') model_params_setting = default_setting.get('model_params_setting', model_params_setting) if model_id is None or model_id == '': raise Exception(_('Model is not allowed to be empty')) diff --git a/apps/application/flow/step_node/image_understand_step_node/impl/base_image_understand_node.py b/apps/application/flow/step_node/image_understand_step_node/impl/base_image_understand_node.py index f6680c3764d..a577fb435df 100644 --- a/apps/application/flow/step_node/image_understand_step_node/impl/base_image_understand_node.py +++ b/apps/application/flow/step_node/image_understand_step_node/impl/base_image_understand_node.py @@ -154,8 +154,7 @@ def execute(self, model_id, system, prompt, dialogue_number, dialogue_type, hist model_params_setting = reference_data.get('model_params_setting') elif model_id_type == 'default': default_setting = self.workflow_manage.get_default_model_setting('IMAGE') - if default_setting.get('model_id'): - model_id = default_setting.get('model_id') + model_id = default_setting.get('model_id') model_params_setting = default_setting.get('model_params_setting', model_params_setting) if model_id is None or model_id == '': 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 f8c3f6c84d7..b516ec0ab9d 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 @@ -66,8 +66,7 @@ def execute(self, model_id, dialogue_number, history_chat_record, user_input, br model_params_setting = reference_data.get('model_params_setting') elif model_id_type == 'default': default_setting = self.workflow_manage.get_default_model_setting('LLM') - if default_setting.get('model_id'): - model_id = default_setting.get('model_id') + model_id = default_setting.get('model_id') model_params_setting = default_setting.get('model_params_setting', model_params_setting) if not model_id: raise Exception(_('Model is not allowed to be empty')) diff --git a/apps/application/flow/step_node/parameter_extraction_node/i_parameter_extraction_node.py b/apps/application/flow/step_node/parameter_extraction_node/i_parameter_extraction_node.py index c1c3667b055..2b68fd53c67 100644 --- a/apps/application/flow/step_node/parameter_extraction_node/i_parameter_extraction_node.py +++ b/apps/application/flow/step_node/parameter_extraction_node/i_parameter_extraction_node.py @@ -49,8 +49,7 @@ def _run(self): model_params_setting = reference_data.get('model_params_setting') elif model_id_type == 'default': default_setting = self.workflow_manage.get_default_model_setting('LLM') - if default_setting.get('model_id'): - model_id = default_setting.get('model_id') + model_id = default_setting.get('model_id') model_params_setting = default_setting.get('model_params_setting', model_params_setting) input_variable = self.workflow_manage.get_reference_field( 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 c984373d574..f62266f7f63 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 @@ -97,8 +97,7 @@ def execute(self, model_id, system, prompt, dialogue_number, history_chat_record model_params_setting = reference_data.get('model_params_setting') elif model_id_type == 'default': default_setting = self.workflow_manage.get_default_model_setting('LLM') - if default_setting.get('model_id'): - model_id = default_setting.get('model_id') + model_id = default_setting.get('model_id') model_params_setting = default_setting.get('model_params_setting', model_params_setting) if not model_id: raise Exception(_('Model is not allowed to be empty')) diff --git a/apps/application/flow/step_node/reranker_node/i_reranker_node.py b/apps/application/flow/step_node/reranker_node/i_reranker_node.py index 216cc0afaa0..d91bd515785 100644 --- a/apps/application/flow/step_node/reranker_node/i_reranker_node.py +++ b/apps/application/flow/step_node/reranker_node/i_reranker_node.py @@ -75,8 +75,7 @@ def _run(self): reference_data.get('model_id', reranker_model_id)) elif reranker_model_id_type == 'default': default_setting = self.workflow_manage.get_default_model_setting('RERANKER') - if default_setting.get('model_id'): - reranker_model_id = default_setting.get('model_id') + reranker_model_id = default_setting.get('model_id') if reranker_model_id is None or reranker_model_id == '': raise Exception(_('Model is not allowed to be empty')) diff --git a/apps/application/flow/step_node/speech_to_text_step_node/impl/base_speech_to_text_node.py b/apps/application/flow/step_node/speech_to_text_step_node/impl/base_speech_to_text_node.py index 371bc2bcba6..a91f176e5a1 100644 --- a/apps/application/flow/step_node/speech_to_text_step_node/impl/base_speech_to_text_node.py +++ b/apps/application/flow/step_node/speech_to_text_step_node/impl/base_speech_to_text_node.py @@ -34,8 +34,7 @@ def execute(self, stt_model_id, audio, model_params_setting=None, stt_model_id_t model_params_setting = reference_data.get('model_params_setting') elif stt_model_id_type == 'default': default_setting = self.workflow_manage.get_default_model_setting('STT') - if default_setting.get('model_id'): - stt_model_id = default_setting.get('model_id') + stt_model_id = default_setting.get('model_id') model_params_setting = default_setting.get('model_params_setting', model_params_setting) from django.utils.translation import gettext_lazy as _ diff --git a/apps/application/flow/step_node/text_to_speech_step_node/impl/base_text_to_speech_node.py b/apps/application/flow/step_node/text_to_speech_step_node/impl/base_text_to_speech_node.py index 1ba9c0bb801..6282e9f4dad 100644 --- a/apps/application/flow/step_node/text_to_speech_step_node/impl/base_text_to_speech_node.py +++ b/apps/application/flow/step_node/text_to_speech_step_node/impl/base_text_to_speech_node.py @@ -58,8 +58,7 @@ def execute(self, tts_model_id, model_params_setting = reference_data.get('model_params_setting') elif tts_model_id_type == 'default': default_setting = self.workflow_manage.get_default_model_setting('TTS') - if default_setting.get('model_id'): - tts_model_id = default_setting.get('model_id') + tts_model_id = default_setting.get('model_id') model_params_setting = default_setting.get('model_params_setting', model_params_setting) from django.utils.translation import gettext_lazy as _ diff --git a/apps/application/flow/step_node/text_to_video_step_node/impl/base_text_to_video_node.py b/apps/application/flow/step_node/text_to_video_step_node/impl/base_text_to_video_node.py index dedcd138acf..4f690779381 100644 --- a/apps/application/flow/step_node/text_to_video_step_node/impl/base_text_to_video_node.py +++ b/apps/application/flow/step_node/text_to_video_step_node/impl/base_text_to_video_node.py @@ -39,8 +39,7 @@ def execute(self, model_id, prompt, negative_prompt, dialogue_number, dialogue_t model_params_setting = reference_data.get('model_params_setting') elif model_id_type == 'default': default_setting = self.workflow_manage.get_default_model_setting('TTV') - if default_setting.get('model_id'): - model_id = default_setting.get('model_id') + model_id = default_setting.get('model_id') model_params_setting = default_setting.get('model_params_setting', model_params_setting) if model_id is None or model_id == '': diff --git a/apps/application/flow/step_node/video_understand_step_node/impl/base_video_understand_node.py b/apps/application/flow/step_node/video_understand_step_node/impl/base_video_understand_node.py index f819e82d286..12ea746a365 100644 --- a/apps/application/flow/step_node/video_understand_step_node/impl/base_video_understand_node.py +++ b/apps/application/flow/step_node/video_understand_step_node/impl/base_video_understand_node.py @@ -149,8 +149,7 @@ def execute(self, model_id, system, prompt, dialogue_number, dialogue_type, hist model_params_setting = reference_data.get('model_params_setting') elif model_id_type == 'default': default_setting = self.workflow_manage.get_default_model_setting('IMAGE') - if default_setting.get('model_id'): - model_id = default_setting.get('model_id') + model_id = default_setting.get('model_id') model_params_setting = default_setting.get('model_params_setting', model_params_setting) from django.utils.translation import gettext_lazy as _ diff --git a/apps/application/serializers/application.py b/apps/application/serializers/application.py index 157aaa5abe1..321300c45a8 100644 --- a/apps/application/serializers/application.py +++ b/apps/application/serializers/application.py @@ -54,6 +54,7 @@ from langchain_mcp_adapters.client import MultiServerMCPClient from maxkb.conf import PROJECT_DIR from maxkb.const import CONFIG +from models_provider.base_model_provider import ModelTypeConst from models_provider.models import Model from models_provider.tools import get_model_instance_by_model_workspace_id from rest_framework import serializers, status @@ -97,6 +98,17 @@ def _walk_workflow_nodes(work_flow, collector): } +def _default_model_not_configured_message(node_name: str, model_type: str) -> str: + """节点选了默认模型但该类别默认模型未配置时的报错,与前端「{节点名称}节点,{模型类别}的默认模型未配置」文案一致。""" + try: + model_type_label = str(ModelTypeConst[model_type].value['message']) + except Exception: + model_type_label = model_type + return _( + "{node_name} Node, the default model for {model_type_label} is not configured" + ).format(node_name=node_name, model_type_label=model_type_label) + + def validate_workflow_default_models(work_flow, default_model_setting): """发布前校验:节点选择「默认模型」但对应类别默认模型未配置时,禁止发布并定位。""" if not work_flow: @@ -117,10 +129,7 @@ def validate_workflow_default_models(work_flow, default_model_setting): and not ((default_model_setting or {}).get(default_model_type, {}) or {}).get('model_id')): raise AppApiException( 500, - _( - "{node_name} selected the default model, but the default model " - "of this type is not configured." - ).format(node_name=node_name), + _default_model_not_configured_message(node_name, default_model_type), ) if model_type is not None: # 取该节点实际使用的 model_id_type 字段(custom/reference/default) @@ -142,10 +151,7 @@ def validate_workflow_default_models(work_flow, default_model_setting): ).get("model_id"): raise AppApiException( 500, - _( - "{node_name} selected the default model, but the default model " - "of this type is not configured." - ).format(node_name=node_name), + _default_model_not_configured_message(node_name, model_type), ) if node_type == "loop-node": validate_workflow_default_models(node_data.get("loop_body"), default_model_setting) @@ -465,6 +471,7 @@ class WorkflowRequest(serializers.Serializer): required=False, allow_null=True, allow_blank=True, max_length=102400, label=_("Opening remarks") ) folder_id = serializers.CharField(required=True, label=_("folder id")) + default_model_setting = serializers.DictField(required=False, label=_("Default model settings")) @staticmethod def to_application_model(user_id: str, workspace_id: str, application: Dict): @@ -497,6 +504,7 @@ def to_application_model(user_id: str, workspace_id: str, application: Dict): file_upload_enable=application.get("file_upload_enable", False), file_upload_setting=application.get("file_upload_setting", {}), work_flow=default_workflow, + default_model_setting=application.get("default_model_setting") or {}, ) class SimplateRequest(serializers.Serializer): diff --git a/apps/locales/en_US/LC_MESSAGES/django.po b/apps/locales/en_US/LC_MESSAGES/django.po index 9eebebaa08b..78c598020ba 100644 --- a/apps/locales/en_US/LC_MESSAGES/django.po +++ b/apps/locales/en_US/LC_MESSAGES/django.po @@ -8691,6 +8691,9 @@ msgstr "" msgid "{node_name} selected the default model, but the default model of this type is not configured." msgstr "" +msgid "{node_name} Node, the default model for {model_type_label} is not configured" +msgstr "" + msgid "Authentication failed. Please verify that the parameters are correct" msgstr "" diff --git a/apps/locales/zh_CN/LC_MESSAGES/django.po b/apps/locales/zh_CN/LC_MESSAGES/django.po index ff4bfeb6a8f..8131866a881 100644 --- a/apps/locales/zh_CN/LC_MESSAGES/django.po +++ b/apps/locales/zh_CN/LC_MESSAGES/django.po @@ -8815,6 +8815,9 @@ msgstr "图生视频" msgid "{node_name} selected the default model, but the default model of this type is not configured." msgstr "{node_name}选择了默认模型,但未配置该类默认模型" +msgid "{node_name} Node, the default model for {model_type_label} is not configured" +msgstr "{node_name} 节点,{model_type_label}的默认模型未配置" + msgid "Authentication failed. Please verify that the parameters are correct" msgstr "认证失败,请检查参数是否正确" diff --git a/apps/locales/zh_Hant/LC_MESSAGES/django.po b/apps/locales/zh_Hant/LC_MESSAGES/django.po index 3d69eeaa926..54ca6ac533a 100644 --- a/apps/locales/zh_Hant/LC_MESSAGES/django.po +++ b/apps/locales/zh_Hant/LC_MESSAGES/django.po @@ -8815,6 +8815,9 @@ msgstr "圖生視頻" msgid "{node_name} selected the default model, but the default model of this type is not configured." msgstr "{node_name}選擇了預設模型,但未配置該類預設模型" +msgid "{node_name} Node, the default model for {model_type_label} is not configured" +msgstr "{node_name} 節點,{model_type_label}的預設模型未配置" + msgid "Authentication failed. Please verify that the parameters are correct" msgstr "認證失敗,請檢查參數是否正確" diff --git a/apps/tools/serializers/tool.py b/apps/tools/serializers/tool.py index 04deecc87c4..5f7773af812 100644 --- a/apps/tools/serializers/tool.py +++ b/apps/tools/serializers/tool.py @@ -524,7 +524,12 @@ def insert(self, instance, with_valid=True): } ).auth_resource(str(tool_id)) if instance.get("tool_type") == ToolType.WORKFLOW: - ToolWorkflow(id=uuid.uuid7(), tool_id=tool_id, work_flow=instance.get("work_flow", {})).save() + ToolWorkflow( + id=uuid.uuid7(), + tool_id=tool_id, + work_flow=instance.get("work_flow", {}), + default_model_setting=instance.get("default_model_setting") or {}, + ).save() # 如果是SKILL类型的工具,修改file表中对应的记录 if instance.get("tool_type") == ToolType.SKILL: file_id = instance.get("code") diff --git a/ui/src/components/workflow-dropdown-menu/default-model-setting/index.vue b/ui/src/components/workflow-dropdown-menu/default-model-setting/index.vue index 6932fc07ba5..a02099e2dc3 100644 --- a/ui/src/components/workflow-dropdown-menu/default-model-setting/index.vue +++ b/ui/src/components/workflow-dropdown-menu/default-model-setting/index.vue @@ -1,6 +1,6 @@