fix(workflow): fix Dify compatibility issues

This commit is contained in:
Eternity
2026-03-06 16:58:36 +08:00
parent ccc67df8df
commit f53633a8b8
5 changed files with 33 additions and 25 deletions

View File

@@ -129,11 +129,11 @@ class DifyConverter(BaseConverter):
@staticmethod @staticmethod
def _convert_file(var): def _convert_file(var):
pass return None
@staticmethod @staticmethod
def _convert_array_file(var): def _convert_array_file(var):
pass return []
@staticmethod @staticmethod
def variable_type_map(source_type) -> VariableType | None: def variable_type_map(source_type) -> VariableType | None:
@@ -198,7 +198,7 @@ class DifyConverter(BaseConverter):
"over-write": AssignmentOperator.COVER, "over-write": AssignmentOperator.COVER,
"remove-last": AssignmentOperator.REMOVE_LAST, "remove-last": AssignmentOperator.REMOVE_LAST,
"remove-first": AssignmentOperator.REMOVE_FIRST, "remove-first": AssignmentOperator.REMOVE_FIRST,
"set": AssignmentOperator.ASSIGN,
} }
return operator_map.get(operator, operator) return operator_map.get(operator, operator)
@@ -267,10 +267,10 @@ class DifyConverter(BaseConverter):
type=var_type, type=var_type,
required=var["required"], required=var["required"],
default=self.convert_variable_type( default=self.convert_variable_type(
var_type, var["default"] var_type, var.get("default")
), ),
description=var["label"], description=var["label"],
max_length=var.get("max_length"), max_length=var.get("max_length", 50),
) )
start_vars.append(var_def) start_vars.append(var_def)
result = StartNodeConfig.model_construct( result = StartNodeConfig.model_construct(
@@ -333,7 +333,7 @@ class DifyConverter(BaseConverter):
MessageConfig( MessageConfig(
role="user", role="user",
content=self.trans_variable_format( content=self.trans_variable_format(
node_data["memory"].get("query_prompt_template", "{{#sys.query#}}") node_data["memory"].get("query_prompt_template") or "{{#sys.query#}}"
) )
) )
) )
@@ -612,7 +612,7 @@ class DifyConverter(BaseConverter):
), ),
headers=headers, headers=headers,
params=params, params=params,
verify_ssl=node_data["ssl_verify"], verify_ssl=node_data.get("ssl_verify", False),
timeouts=HttpTimeOutConfig.model_construct( timeouts=HttpTimeOutConfig.model_construct(
connect_timeout=node_data["timeout"]["max_connect_timeout"] or 5, connect_timeout=node_data["timeout"]["max_connect_timeout"] or 5,
read_timeout=node_data["timeout"]["max_read_timeout"] or 5, read_timeout=node_data["timeout"]["max_read_timeout"] or 5,
@@ -696,7 +696,7 @@ class DifyConverter(BaseConverter):
group_variables = {} group_variables = {}
group_type = {} group_type = {}
if not advanced_settings or not advanced_settings["group_enabled"]: if not advanced_settings or not advanced_settings["group_enabled"]:
group_variables["output"] = [ group_variables = [
self._process_list_variable_litearl(variable) self._process_list_variable_litearl(variable)
for variable in node_data["variables"] for variable in node_data["variables"]
] ]

View File

@@ -83,6 +83,12 @@ class DifyAdapter(BasePlatformAdapter, DifyConverter):
require_fields = frozenset({'app', 'kind', 'version', 'workflow'}) require_fields = frozenset({'app', 'kind', 'version', 'workflow'})
if not all(field in self.config for field in require_fields): if not all(field in self.config for field in require_fields):
return False return False
if self.config.get("app",{}).get("mode") == "workflow":
self.errors.append(ExceptionDefineition(
type=ExceptionType.PLATFORM,
detail="workflow mode is not supported"
))
return False
for node in self.origin_nodes: for node in self.origin_nodes:
if not self._valid_nodes(node): if not self._valid_nodes(node):
@@ -134,6 +140,8 @@ class DifyAdapter(BasePlatformAdapter, DifyConverter):
for node in self.origin_nodes: for node in self.origin_nodes:
if self.map_node_type(node["data"]["type"]) == NodeType.LLM: if self.map_node_type(node["data"]["type"]) == NodeType.LLM:
self.node_output_map[f"{node['id']}.text"] = f"{node['id']}.output" self.node_output_map[f"{node['id']}.text"] = f"{node['id']}.output"
elif self.map_node_type(node["data"]["type"]) == NodeType.KNOWLEDGE_RETRIEVAL:
self.node_output_map[f"{node['id']}.result"] = f"{node['id']}.output"
def _convert_cycle_node_position(self, node_id: str, position: dict): def _convert_cycle_node_position(self, node_id: str, position: dict):
for node in self.origin_nodes: for node in self.origin_nodes:
@@ -184,7 +192,7 @@ class DifyAdapter(BasePlatformAdapter, DifyConverter):
type=ExceptionType.NODE, type=ExceptionType.NODE,
node_id=node["id"], node_id=node["id"],
node_name=node["data"]["title"], node_name=node["data"]["title"],
detail=f"node type {node_type} is unsupported", detail=f"node type {node_type if node_type else 'notes'} is unsupported",
)) ))
return converter(node) return converter(node)
except Exception as e: except Exception as e:

View File

@@ -320,7 +320,7 @@ class GraphBuilder:
# Used later to determine which branch to take based on the node's output # Used later to determine which branch to take based on the node's output
# Assumes node output `node.<node_id>.output` matches the edge's label # Assumes node output `node.<node_id>.output` matches the edge's label
# For example, if node.123.output == 'CASE1', take the branch labeled 'CASE1' # For example, if node.123.output == 'CASE1', take the branch labeled 'CASE1'
related_edge[idx]['condition'] = f"node.{node_id}.output == '{related_edge[idx]['label']}'" related_edge[idx]['condition'] = f"node['{node_id}']['output'] == '{related_edge[idx]['label']}'"
if node_instance: if node_instance:
# Wrap node's run method to avoid closure issues # Wrap node's run method to avoid closure issues

View File

@@ -85,20 +85,20 @@ class BaseNodeConfig(BaseModel):
- tags: 节点标签(用于分类和搜索) - tags: 节点标签(用于分类和搜索)
""" """
name: str | None = Field( # name: str | None = Field(
default=None, # default=None,
description="节点名称(显示名称),如果不设置则使用节点 ID" # description="节点名称(显示名称),如果不设置则使用节点 ID"
) # )
#
description: str | None = Field( # description: str | None = Field(
default=None, # default=None,
description="节点描述,说明节点的作用" # description="节点描述,说明节点的作用"
) # )
#
tags: list[str] = Field( # tags: list[str] = Field(
default_factory=list, # default_factory=list,
description="节点标签,用于分类和搜索" # description="节点标签,用于分类和搜索"
) # )
class Config: class Config:
"""Pydantic 配置""" """Pydantic 配置"""

View File

@@ -56,7 +56,7 @@ class WorkflowImportService:
success=False, success=False,
temp_id=None, temp_id=None,
workflow_id=None, workflow_id=None,
errors=[InvalidConfiguration()] errors=[InvalidConfiguration()] + adapter.errors
) )
workflow_config = adapter.parse_workflow() workflow_config = adapter.parse_workflow()