feat: analyze_missing_connections 回滚

This commit is contained in:
ai-business-hql
2025-08-14 16:31:04 +08:00
parent dd58d89d12
commit c88a98ea3a
+1 -179
View File
@@ -10,184 +10,6 @@ from ..service.database import get_workflow_data, save_workflow_data
from ..utils.comfy_gateway import get_object_info
from ..utils.logger import log
# @function_tool
# async def analyze_missing_connections() -> str:
# """
# 分析工作流中缺失的连接,枚举所有可能的连接选项和所需的新节点。
# 返回格式说明:
# - missing_connections: 缺失连接的详细列表,包含节点ID、输入名称、需要的数据类型等(仅包含required且非universal的输入)
# 每个missing_connection包含connectable_outputs字段,列出所有可连接的输出端口信息
# - universal_inputs: 类型为*的required输入端口,可以接受任意输出类型
# - optional_unconnected_inputs: 未连接的可选输入列表,包含节点ID、输入名称、配置信息等
# - required_new_nodes: 需要创建的新节点类型列表
# - connection_summary: 连接分析的统计摘要(包含optional输入的统计)
# """
# try:
# session_id = get_session_id()
# if not session_id:
# log.error("analyze_missing_connections: No session_id found in context")
# return json.dumps({"error": "No session_id found in context"})
# workflow_data = get_workflow_data(session_id)
# if not workflow_data:
# return json.dumps({"error": "No workflow data found for this session"})
# object_info = await get_object_info()
# analysis_result = {
# "missing_connections": [],
# "universal_inputs": [], # 可以连接任意输出的输入端口
# "optional_unconnected_inputs": [], # 未连接的optional输入
# "required_new_nodes": [],
# "connection_summary": {
# "total_missing": 0,
# "auto_fixable": 0,
# "requires_new_nodes": 0,
# "universal_inputs_count": 0,
# "optional_unconnected_count": 0
# }
# }
# # 构建现有节点的输出映射
# available_outputs = {}
# for node_id, node_data in workflow_data.items():
# node_class = node_data.get("class_type")
# if node_class in object_info and "output" in object_info[node_class]:
# outputs = object_info[node_class]["output"]
# available_outputs[node_id] = {
# "class_type": node_class,
# "outputs": [(i, output_type) for i, output_type in enumerate(outputs)]
# }
# # 分析每个节点的缺失连接
# for node_id, node_data in workflow_data.items():
# node_class = node_data.get("class_type")
# if node_class not in object_info:
# continue
# node_info = object_info[node_class]
# if "input" not in node_info:
# continue
# required_inputs = node_info["input"].get("required", {})
# current_inputs = node_data.get("inputs", {})
# # 检查每个required input
# for input_name, input_config in required_inputs.items():
# if input_name not in current_inputs:
# # 发现缺失的连接
# missing_connection = {
# "node_id": node_id,
# "node_class": node_class,
# "input_name": input_name,
# "input_config": input_config,
# "required": True
# }
# # 分析输入类型
# if isinstance(input_config, (list, tuple)) and len(input_config) > 0:
# expected_types = input_config[0] if isinstance(input_config[0], list) else [input_config[0]]
# missing_connection["expected_types"] = expected_types
# # 检查是否是通用输入(input类型为*)
# is_universal_input = expected_types == ["*"]
# if is_universal_input:
# # 这是一个通用输入端口,可以连接任意输出
# universal_input = {
# "node_id": node_id,
# "node_class": node_class,
# "input_name": input_name,
# "input_config": input_config,
# "can_connect_any_output": True
# }
# analysis_result["universal_inputs"].append(universal_input)
# analysis_result["connection_summary"]["universal_inputs_count"] += 1
# # 通用输入不加入missing_connections
# continue
# else:
# # 查找具体类型匹配的连接
# matching_outputs = []
# for source_node_id, source_info in available_outputs.items():
# if source_node_id == node_id: # 不能连接自己
# continue
# for output_index, output_type in source_info["outputs"]:
# # 检查类型匹配:expected_types相等 或 output类型为*
# type_match = (output_type in expected_types or output_type == "*")
# if type_match:
# matching_outputs.append({
# "source_node_id": source_node_id,
# "source_class": source_info["class_type"],
# "output_index": output_index,
# "output_type": output_type,
# "connection": [source_node_id, output_index]
# })
# # 添加匹配的输出信息到missing_connection
# missing_connection["connectable_outputs"] = matching_outputs
# if matching_outputs:
# # 有匹配的输出,标记为可自动修复
# analysis_result["connection_summary"]["auto_fixable"] += 1
# else:
# # 没有匹配的输出,需要新节点
# analysis_result["connection_summary"]["requires_new_nodes"] += 1
# # 分析需要什么类型的节点
# required_node_types = analyze_required_node_types(expected_types, object_info)
# analysis_result["required_new_nodes"].extend([{
# "for_node": node_id,
# "for_input": input_name,
# "expected_types": expected_types,
# "suggested_node_types": required_node_types
# }])
# # 只有非universal的input才加入missing_connections
# analysis_result["missing_connections"].append(missing_connection)
# # 检查optional inputs (未连接的可选输入)
# optional_inputs = node_info["input"].get("optional", {})
# for input_name, input_config in optional_inputs.items():
# if input_name not in current_inputs:
# # 发现未连接的optional输入
# optional_unconnected = {
# "node_id": node_id,
# "node_class": node_class,
# "input_name": input_name,
# "input_config": input_config,
# "required": False
# }
# # 分析输入类型
# if isinstance(input_config, (list, tuple)) and len(input_config) > 0:
# expected_types = input_config[0] if isinstance(input_config[0], list) else [input_config[0]]
# else:
# expected_types = ["*"] # 默认为通用类型
# optional_unconnected["expected_types"] = expected_types
# # 检查是否是通用输入(input类型为*)
# is_universal_input = expected_types == ["*"]
# optional_unconnected["is_universal"] = is_universal_input
# analysis_result["optional_unconnected_inputs"].append(optional_unconnected)
# # 更新统计信息
# analysis_result["connection_summary"]["total_missing"] = len(analysis_result["missing_connections"])
# analysis_result["connection_summary"]["optional_unconnected_count"] = len(analysis_result["optional_unconnected_inputs"])
# log.info(f"analysis_link_result: {json.dumps(analysis_result, ensure_ascii=False)}")
# return json.dumps(analysis_result)
# except Exception as e:
# return json.dumps({"error": f"Failed to analyze missing connections: {str(e)}"})
@function_tool
async def analyze_missing_connections() -> str:
"""
@@ -379,7 +201,7 @@ async def analyze_missing_connections() -> str:
except Exception as e:
return json.dumps({"error": f"Failed to analyze missing connections: {str(e)}"})
def analyze_required_node_types(expected_types: List[str], object_info: Dict) -> List[Dict]:
"""分析需要什么类型的节点来提供指定的输出类型"""
suggested_nodes = []