Restore AI workflow design nodes

This commit is contained in:
2026-06-09 21:18:33 +08:00
parent fbd726ebdf
commit cb45c0a068
71 changed files with 22676 additions and 21 deletions
@@ -0,0 +1,205 @@
"""
应用设计节点
接收LLM生成的应用设计方案,展示给用户确认或编辑
"""
import json
import logging
from typing import Any, Dict, Optional
from ..base import BaseNode, NodeContext, NodeResult
from ..registry import NodeRegistry
logger = logging.getLogger(__name__)
@NodeRegistry.register
class AppDesignNode(BaseNode):
"""
应用设计节点
接收LLM生成的应用设计方案(Markdown格式),展示给用户确认或编辑
用户可以查看设计方案,编辑后确认继续
"""
node_type = 'app_design'
node_name = '应用设计'
node_category = 'application'
node_icon = 'layout'
node_description = '展示应用设计方案,支持用户确认或编辑'
inputs = [
{
'name': 'design_content',
'type': 'string',
'description': '设计方案内容(Markdown格式)',
'required': True,
},
{
'name': 'design_title',
'type': 'string',
'description': '设计方案标题',
'required': False,
},
]
outputs = [
{
'name': 'design_content',
'type': 'string',
'description': '确认后的设计方案内容',
},
{
'name': 'confirmed',
'type': 'boolean',
'description': '是否已确认',
},
]
def execute(self, context: NodeContext) -> NodeResult:
"""执行节点"""
try:
# 检查是否有用户编辑的数据(从设计预览面板提交)
user_input = context.variables.get('__user_input__')
if user_input:
edited_data = self._parse_user_edit(user_input)
if edited_data:
logger.info(f'AppDesignNode - 使用用户编辑的数据')
# 使用编辑后的数据,清除用户输入
context.variables.pop('__user_input__', None)
return self._build_result(edited_data, require_confirmation=False)
# 获取输入参数
design_content = context.resolve_template(self.config.get('design_content', ''))
design_title = context.resolve_template(self.config.get('design_title', '应用设计方案'))
logger.info(f'AppDesignNode - 输入参数: title={design_title}, content_length={len(design_content)}')
# 验证必填字段
if not design_content or not design_content.strip():
return NodeResult(
success=False,
error='设计方案内容不能为空',
)
design_content = design_content.strip()
design_title = design_title.strip() if design_title else '应用设计方案'
# 构建设计数据
design_data = {
'title': design_title,
'content': design_content,
}
logger.info(f'AppDesignNode - 输出设计方案: title={design_title}')
# 检查是否需要确认(支持布尔值、字符串模式和变量引用)
require_confirmation = self.resolve_require_confirmation(context, default=True)
return self._build_result(design_data, require_confirmation)
except Exception as e:
logger.exception(f'应用设计节点执行失败: {e}')
return NodeResult(
success=False,
error=f'节点执行失败: {str(e)}',
)
async def execute_async(self, context: NodeContext) -> NodeResult:
"""异步执行节点(直接调用同步方法)"""
return self.execute(context)
def _parse_user_edit(self, user_input: Any) -> Optional[Dict[str, Any]]:
"""解析用户编辑的数据"""
if isinstance(user_input, dict):
# 检查是否包含设计内容字段
if 'content' in user_input:
return user_input
return None
if isinstance(user_input, str):
try:
data = json.loads(user_input)
if isinstance(data, dict) and 'content' in data:
return data
except (json.JSONDecodeError, TypeError):
# 如果不是JSON,可能直接是编辑后的内容
return {'content': user_input, 'title': '应用设计方案'}
return None
def _build_result(self, design_data: Dict[str, Any], require_confirmation: bool = False) -> NodeResult:
"""构建节点结果"""
title = design_data.get('title', '应用设计方案')
content = design_data.get('content', '')
# 构建预览数据
preview_data = {
'type': 'app_design',
'title': title,
'data': design_data,
'editable': True,
} if require_confirmation else None
return NodeResult(
success=True,
output=design_data,
output_variables={
'design_content': content,
'design_title': title,
'confirmed': not require_confirmation,
},
preview=preview_data,
waiting_for_input=require_confirmation,
waiting_config={
'type': 'design_preview',
'preview_type': 'app_design',
'title': title,
'message': '请确认或编辑应用设计方案',
'data': design_data,
} if require_confirmation else {},
)
@classmethod
def get_config_schema(cls) -> Dict[str, Any]:
"""
获取节点配置 Schema(供前端表单渲染)
Returns:
配置 Schema
"""
return {
'type': 'object',
'properties': {
'design_content': {
'type': 'string',
'title': '设计方案内容',
'description': '设计方案内容(Markdown格式),支持变量引用如 {{llm_output}}',
'required': True,
'x-component': 'Textarea',
'x-component-props': {
'placeholder': '请输入设计方案内容或使用变量 {{llm_output}}',
'rows': 6,
},
},
'design_title': {
'type': 'string',
'title': '设计方案标题',
'description': '设计方案的标题,支持变量引用',
'required': False,
'default': '应用设计方案',
'x-component': 'Input',
'x-component-props': {
'placeholder': '请输入标题,默认为"应用设计方案"',
},
},
'require_confirmation': {
'type': 'boolean',
'title': '需要确认',
'description': '设计完成后是否暂停等待用户确认或编辑',
'default': True,
'x-component': 'Switch',
},
},
'required': ['design_content'],
}