From c15c770acb08b8c0edc00e36ff1f47d284cbfc61 Mon Sep 17 00:00:00 2001 From: agenthaulk Date: Sat, 4 Apr 2026 22:03:25 -0700 Subject: [PATCH 1/4] refactor(services): convert AppMode if/elif to match/case in service files (#30001) --- .../advanced_prompt_template_service.py | 84 ++++++++++-------- api/services/app_model_config_service.py | 17 ++-- api/services/workflow/workflow_converter.py | 88 +++++++++++-------- api/services/workflow_service.py | 21 ++--- 4 files changed, 117 insertions(+), 93 deletions(-) diff --git a/api/services/advanced_prompt_template_service.py b/api/services/advanced_prompt_template_service.py index f2ffa3b170c304..4a521bd9a501d0 100644 --- a/api/services/advanced_prompt_template_service.py +++ b/api/services/advanced_prompt_template_service.py @@ -32,22 +32,27 @@ def get_prompt(cls, args: dict): def get_common_prompt(cls, app_mode: str, model_mode: str, has_context: str): context_prompt = copy.deepcopy(CONTEXT) - if app_mode == AppMode.CHAT: - if model_mode == "completion": - return cls.get_completion_prompt( - copy.deepcopy(CHAT_APP_COMPLETION_PROMPT_CONFIG), has_context, context_prompt - ) - elif model_mode == "chat": - return cls.get_chat_prompt(copy.deepcopy(CHAT_APP_CHAT_PROMPT_CONFIG), has_context, context_prompt) - elif app_mode == AppMode.COMPLETION: - if model_mode == "completion": - return cls.get_completion_prompt( - copy.deepcopy(COMPLETION_APP_COMPLETION_PROMPT_CONFIG), has_context, context_prompt - ) - elif model_mode == "chat": - return cls.get_chat_prompt( - copy.deepcopy(COMPLETION_APP_CHAT_PROMPT_CONFIG), has_context, context_prompt - ) + match app_mode: + case AppMode.CHAT: + match model_mode: + case "completion": + return cls.get_completion_prompt( + copy.deepcopy(CHAT_APP_COMPLETION_PROMPT_CONFIG), has_context, context_prompt + ) + case "chat": + return cls.get_chat_prompt( + copy.deepcopy(CHAT_APP_CHAT_PROMPT_CONFIG), has_context, context_prompt + ) + case AppMode.COMPLETION: + match model_mode: + case "completion": + return cls.get_completion_prompt( + copy.deepcopy(COMPLETION_APP_COMPLETION_PROMPT_CONFIG), has_context, context_prompt + ) + case "chat": + return cls.get_chat_prompt( + copy.deepcopy(COMPLETION_APP_CHAT_PROMPT_CONFIG), has_context, context_prompt + ) # default return empty dict return {} @@ -73,25 +78,32 @@ def get_chat_prompt(cls, prompt_template: dict, has_context: str, context: str): def get_baichuan_prompt(cls, app_mode: str, model_mode: str, has_context: str): baichuan_context_prompt = copy.deepcopy(BAICHUAN_CONTEXT) - if app_mode == AppMode.CHAT: - if model_mode == "completion": - return cls.get_completion_prompt( - copy.deepcopy(BAICHUAN_CHAT_APP_COMPLETION_PROMPT_CONFIG), has_context, baichuan_context_prompt - ) - elif model_mode == "chat": - return cls.get_chat_prompt( - copy.deepcopy(BAICHUAN_CHAT_APP_CHAT_PROMPT_CONFIG), has_context, baichuan_context_prompt - ) - elif app_mode == AppMode.COMPLETION: - if model_mode == "completion": - return cls.get_completion_prompt( - copy.deepcopy(BAICHUAN_COMPLETION_APP_COMPLETION_PROMPT_CONFIG), - has_context, - baichuan_context_prompt, - ) - elif model_mode == "chat": - return cls.get_chat_prompt( - copy.deepcopy(BAICHUAN_COMPLETION_APP_CHAT_PROMPT_CONFIG), has_context, baichuan_context_prompt - ) + match app_mode: + case AppMode.CHAT: + match model_mode: + case "completion": + return cls.get_completion_prompt( + copy.deepcopy(BAICHUAN_CHAT_APP_COMPLETION_PROMPT_CONFIG), + has_context, + baichuan_context_prompt, + ) + case "chat": + return cls.get_chat_prompt( + copy.deepcopy(BAICHUAN_CHAT_APP_CHAT_PROMPT_CONFIG), has_context, baichuan_context_prompt + ) + case AppMode.COMPLETION: + match model_mode: + case "completion": + return cls.get_completion_prompt( + copy.deepcopy(BAICHUAN_COMPLETION_APP_COMPLETION_PROMPT_CONFIG), + has_context, + baichuan_context_prompt, + ) + case "chat": + return cls.get_chat_prompt( + copy.deepcopy(BAICHUAN_COMPLETION_APP_CHAT_PROMPT_CONFIG), + has_context, + baichuan_context_prompt, + ) # default return empty dict return {} diff --git a/api/services/app_model_config_service.py b/api/services/app_model_config_service.py index 3bc30cb323276f..2013c869afd7be 100644 --- a/api/services/app_model_config_service.py +++ b/api/services/app_model_config_service.py @@ -7,11 +7,12 @@ class AppModelConfigService: @classmethod def validate_configuration(cls, tenant_id: str, config: dict, app_mode: AppMode) -> AppModelConfigDict: - if app_mode == AppMode.CHAT: - return ChatAppConfigManager.config_validate(tenant_id, config) - elif app_mode == AppMode.AGENT_CHAT: - return AgentChatAppConfigManager.config_validate(tenant_id, config) - elif app_mode == AppMode.COMPLETION: - return CompletionAppConfigManager.config_validate(tenant_id, config) - else: - raise ValueError(f"Invalid app mode: {app_mode}") + match app_mode: + case AppMode.CHAT: + return ChatAppConfigManager.config_validate(tenant_id, config) + case AppMode.AGENT_CHAT: + return AgentChatAppConfigManager.config_validate(tenant_id, config) + case AppMode.COMPLETION: + return CompletionAppConfigManager.config_validate(tenant_id, config) + case AppMode.WORKFLOW | AppMode.ADVANCED_CHAT | AppMode.CHANNEL | AppMode.RAG_PIPELINE: + raise ValueError(f"Invalid app mode: {app_mode}") diff --git a/api/services/workflow/workflow_converter.py b/api/services/workflow/workflow_converter.py index c1ad3f33ad04af..f3b590557cf9ef 100644 --- a/api/services/workflow/workflow_converter.py +++ b/api/services/workflow/workflow_converter.py @@ -170,34 +170,38 @@ def convert_app_model_config_to_workflow(self, app_model: App, app_model_config: graph = self._append_node(graph, llm_node) - if new_app_mode == AppMode.WORKFLOW: - # convert to end node by app mode - end_node = self._convert_to_end_node() - graph = self._append_node(graph, end_node) - else: - answer_node = self._convert_to_answer_node() - graph = self._append_node(graph, answer_node) - app_model_config_dict = app_config.app_model_config_dict - # features - if new_app_mode == AppMode.ADVANCED_CHAT: - features = { - "opening_statement": app_model_config_dict.get("opening_statement"), - "suggested_questions": app_model_config_dict.get("suggested_questions"), - "suggested_questions_after_answer": app_model_config_dict.get("suggested_questions_after_answer"), - "speech_to_text": app_model_config_dict.get("speech_to_text"), - "text_to_speech": app_model_config_dict.get("text_to_speech"), - "file_upload": app_model_config_dict.get("file_upload"), - "sensitive_word_avoidance": app_model_config_dict.get("sensitive_word_avoidance"), - "retriever_resource": app_model_config_dict.get("retriever_resource"), - } - else: - features = { - "text_to_speech": app_model_config_dict.get("text_to_speech"), - "file_upload": app_model_config_dict.get("file_upload"), - "sensitive_word_avoidance": app_model_config_dict.get("sensitive_word_avoidance"), - } + match new_app_mode: + case AppMode.WORKFLOW: + end_node = self._convert_to_end_node() + graph = self._append_node(graph, end_node) + features = { + "text_to_speech": app_model_config_dict.get("text_to_speech"), + "file_upload": app_model_config_dict.get("file_upload"), + "sensitive_word_avoidance": app_model_config_dict.get("sensitive_word_avoidance"), + } + case AppMode.ADVANCED_CHAT: + answer_node = self._convert_to_answer_node() + graph = self._append_node(graph, answer_node) + features = { + "opening_statement": app_model_config_dict.get("opening_statement"), + "suggested_questions": app_model_config_dict.get("suggested_questions"), + "suggested_questions_after_answer": app_model_config_dict.get("suggested_questions_after_answer"), + "speech_to_text": app_model_config_dict.get("speech_to_text"), + "text_to_speech": app_model_config_dict.get("text_to_speech"), + "file_upload": app_model_config_dict.get("file_upload"), + "sensitive_word_avoidance": app_model_config_dict.get("sensitive_word_avoidance"), + "retriever_resource": app_model_config_dict.get("retriever_resource"), + } + case _: + answer_node = self._convert_to_answer_node() + graph = self._append_node(graph, answer_node) + features = { + "text_to_speech": app_model_config_dict.get("text_to_speech"), + "file_upload": app_model_config_dict.get("file_upload"), + "sensitive_word_avoidance": app_model_config_dict.get("sensitive_word_avoidance"), + } # create workflow record workflow = Workflow( @@ -220,19 +224,25 @@ def convert_app_model_config_to_workflow(self, app_model: App, app_model_config: def _convert_to_app_config(self, app_model: App, app_model_config: AppModelConfig) -> EasyUIBasedAppConfig: app_mode_enum = AppMode.value_of(app_model.mode) app_config: EasyUIBasedAppConfig - if app_mode_enum == AppMode.AGENT_CHAT or app_model.is_agent: - app_model.mode = AppMode.AGENT_CHAT - app_config = AgentChatAppConfigManager.get_app_config( - app_model=app_model, app_model_config=app_model_config - ) - elif app_mode_enum == AppMode.CHAT: - app_config = ChatAppConfigManager.get_app_config(app_model=app_model, app_model_config=app_model_config) - elif app_mode_enum == AppMode.COMPLETION: - app_config = CompletionAppConfigManager.get_app_config( - app_model=app_model, app_model_config=app_model_config - ) - else: - raise ValueError("Invalid app mode") + effective_mode = ( + AppMode.AGENT_CHAT if app_model.is_agent and app_mode_enum != AppMode.AGENT_CHAT else app_mode_enum + ) + match effective_mode: + case AppMode.AGENT_CHAT: + app_model.mode = AppMode.AGENT_CHAT + app_config = AgentChatAppConfigManager.get_app_config( + app_model=app_model, app_model_config=app_model_config + ) + case AppMode.CHAT: + app_config = ChatAppConfigManager.get_app_config( + app_model=app_model, app_model_config=app_model_config + ) + case AppMode.COMPLETION: + app_config = CompletionAppConfigManager.get_app_config( + app_model=app_model, app_model_config=app_model_config + ) + case _: + raise ValueError("Invalid app mode") return app_config diff --git a/api/services/workflow_service.py b/api/services/workflow_service.py index 8f365c7c51f741..662e0410f96442 100644 --- a/api/services/workflow_service.py +++ b/api/services/workflow_service.py @@ -1417,16 +1417,17 @@ def validate_graph_structure(self, graph: Mapping[str, Any]): self._validate_human_input_node_data(node_data) def validate_features_structure(self, app_model: App, features: dict): - if app_model.mode == AppMode.ADVANCED_CHAT: - return AdvancedChatAppConfigManager.config_validate( - tenant_id=app_model.tenant_id, config=features, only_structure_validate=True - ) - elif app_model.mode == AppMode.WORKFLOW: - return WorkflowAppConfigManager.config_validate( - tenant_id=app_model.tenant_id, config=features, only_structure_validate=True - ) - else: - raise ValueError(f"Invalid app mode: {app_model.mode}") + match app_model.mode: + case AppMode.ADVANCED_CHAT: + return AdvancedChatAppConfigManager.config_validate( + tenant_id=app_model.tenant_id, config=features, only_structure_validate=True + ) + case AppMode.WORKFLOW: + return WorkflowAppConfigManager.config_validate( + tenant_id=app_model.tenant_id, config=features, only_structure_validate=True + ) + case _: + raise ValueError(f"Invalid app mode: {app_model.mode}") def _validate_human_input_node_data(self, node_data: dict) -> None: """ From 17114312b29ba3098bb82fc97638f0a44947daf9 Mon Sep 17 00:00:00 2001 From: agenthaulk Date: Sun, 5 Apr 2026 00:39:20 -0700 Subject: [PATCH 2/4] fix: add case _ pass to model_mode match statements for pyrefly exhaustive check (#30001) --- api/services/advanced_prompt_template_service.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/api/services/advanced_prompt_template_service.py b/api/services/advanced_prompt_template_service.py index 4a521bd9a501d0..b7cb5cd4878545 100644 --- a/api/services/advanced_prompt_template_service.py +++ b/api/services/advanced_prompt_template_service.py @@ -43,6 +43,8 @@ def get_common_prompt(cls, app_mode: str, model_mode: str, has_context: str): return cls.get_chat_prompt( copy.deepcopy(CHAT_APP_CHAT_PROMPT_CONFIG), has_context, context_prompt ) + case _: + pass case AppMode.COMPLETION: match model_mode: case "completion": @@ -53,6 +55,8 @@ def get_common_prompt(cls, app_mode: str, model_mode: str, has_context: str): return cls.get_chat_prompt( copy.deepcopy(COMPLETION_APP_CHAT_PROMPT_CONFIG), has_context, context_prompt ) + case _: + pass # default return empty dict return {} @@ -91,6 +95,8 @@ def get_baichuan_prompt(cls, app_mode: str, model_mode: str, has_context: str): return cls.get_chat_prompt( copy.deepcopy(BAICHUAN_CHAT_APP_CHAT_PROMPT_CONFIG), has_context, baichuan_context_prompt ) + case _: + pass case AppMode.COMPLETION: match model_mode: case "completion": @@ -105,5 +111,7 @@ def get_baichuan_prompt(cls, app_mode: str, model_mode: str, has_context: str): has_context, baichuan_context_prompt, ) + case _: + pass # default return empty dict return {} From f0879fd5f4111bcf8f2dfdcc37ca099c82756140 Mon Sep 17 00:00:00 2001 From: agenthaulk Date: Sun, 5 Apr 2026 00:47:49 -0700 Subject: [PATCH 3/4] fix: add outer case _ for app_mode match in get_common_prompt and get_baichuan_prompt (#30001) --- api/services/advanced_prompt_template_service.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/api/services/advanced_prompt_template_service.py b/api/services/advanced_prompt_template_service.py index b7cb5cd4878545..a6e6b1bae70672 100644 --- a/api/services/advanced_prompt_template_service.py +++ b/api/services/advanced_prompt_template_service.py @@ -57,6 +57,8 @@ def get_common_prompt(cls, app_mode: str, model_mode: str, has_context: str): ) case _: pass + case _: + pass # default return empty dict return {} @@ -113,5 +115,7 @@ def get_baichuan_prompt(cls, app_mode: str, model_mode: str, has_context: str): ) case _: pass + case _: + pass # default return empty dict return {} From 4de8c227cc5cc2751baa3adfb1522c520e4c40c7 Mon Sep 17 00:00:00 2001 From: "autofix-ci[bot]" <114827586+autofix-ci[bot]@users.noreply.github.com> Date: Sun, 5 Apr 2026 09:13:52 +0000 Subject: [PATCH 4/4] [autofix.ci] apply automated fixes --- api/services/workflow/workflow_converter.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/api/services/workflow/workflow_converter.py b/api/services/workflow/workflow_converter.py index f3b590557cf9ef..1582bcd46cd192 100644 --- a/api/services/workflow/workflow_converter.py +++ b/api/services/workflow/workflow_converter.py @@ -234,9 +234,7 @@ def _convert_to_app_config(self, app_model: App, app_model_config: AppModelConfi app_model=app_model, app_model_config=app_model_config ) case AppMode.CHAT: - app_config = ChatAppConfigManager.get_app_config( - app_model=app_model, app_model_config=app_model_config - ) + app_config = ChatAppConfigManager.get_app_config(app_model=app_model, app_model_config=app_model_config) case AppMode.COMPLETION: app_config = CompletionAppConfigManager.get_app_config( app_model=app_model, app_model_config=app_model_config