From 5f3b4502f6fcaf75a5f1bdefa9ca18ff686a62a5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?cls=5F=E5=AE=81=E6=B3=A2=E6=9C=AC=E6=9C=BA?= <908705107@qq.com> Date: Sat, 13 Jun 2026 12:16:48 +0800 Subject: [PATCH] fix: map agent workflow inputs --- .../nodes/builtin/template_node.py | 18 ++++++ .../ai_platform/services/agent_service.py | 57 ++++++++++++++----- .../ai_platform/services/workflow_service.py | 1 + 3 files changed, 62 insertions(+), 14 deletions(-) diff --git a/backend-fastapi/ai_platform/nodes/builtin/template_node.py b/backend-fastapi/ai_platform/nodes/builtin/template_node.py index 220a55d..419488c 100644 --- a/backend-fastapi/ai_platform/nodes/builtin/template_node.py +++ b/backend-fastapi/ai_platform/nodes/builtin/template_node.py @@ -91,6 +91,8 @@ class TemplateNode(BaseNode): return NodeResult(success=False, error=f'智能体不存在或未发布: {agent_code}') model_id = self.config.get('model_id') or agent.model_id + if not model_id: + model_id = await self._resolve_default_chat_model_id(context) if not model_id: return NodeResult(success=False, error=f'智能体未配置模型: {agent.name}({agent.code})') @@ -148,6 +150,22 @@ class TemplateNode(BaseNode): elapsed_time=int((time.time() - start_time) * 1000), ) + @staticmethod + async def _resolve_default_chat_model_id(context: NodeContext) -> str: + from ai_platform.models import LLMModel + + result = await context.db_session.execute( + select(LLMModel) + .where( + LLMModel.is_deleted == False, + LLMModel.is_active == True, + LLMModel.model_type == 'chat', + ) + .order_by(LLMModel.sort.desc(), LLMModel.sys_create_datetime.desc()) + ) + model = result.scalars().first() + return str(model.id) if model else '' + @staticmethod def _build_agent_system_prompt(agent: Any) -> str: base_prompt = agent.system_prompt or '' diff --git a/backend-fastapi/ai_platform/services/agent_service.py b/backend-fastapi/ai_platform/services/agent_service.py index 60b885e..e58b4ca 100644 --- a/backend-fastapi/ai_platform/services/agent_service.py +++ b/backend-fastapi/ai_platform/services/agent_service.py @@ -9,7 +9,7 @@ from sqlalchemy import select from sqlalchemy.ext.asyncio import AsyncSession from ai_platform.models import ( - Agent, AgentConversation, AgentMessage, LLMModel, + Agent, AgentConversation, AgentMessage, AIWorkflow, LLMModel, ) from .llm_service import LLMService @@ -433,16 +433,16 @@ class AgentService: if accumulated: final_content = accumulated elif event_type == 'node_complete': - node_type = event.get('node_type') - if node_type == 'llm': - outputs = event.get('outputs', {}) - output = outputs.get('output', '') - if output: - final_content = output + output = (event.get('outputs') or {}).get('output', '') + if output: + final_content = output elif event_type == 'waiting_input': is_waiting = True elif event_type == 'complete': total_tokens = event.get('total_tokens', 0) + output = (event.get('outputs') or {}).get('output', '') + if output: + final_content = output yield event else: @@ -465,7 +465,7 @@ class AgentService: if attachment_texts: enhanced_user_input = user_message + '\n' + '\n'.join(attachment_texts) - workflow_inputs = {'user_input': enhanced_user_input} + workflow_inputs = await self._build_workflow_inputs(agent, enhanced_user_input) if application_id: workflow_inputs['application_id'] = application_id if form_code: @@ -495,12 +495,9 @@ class AgentService: if accumulated: final_content = accumulated elif event_type == 'node_complete': - node_type = event.get('node_type') - if node_type == 'llm': - outputs = event.get('outputs', {}) - output = outputs.get('output', '') - if output: - final_content = output + output = (event.get('outputs') or {}).get('output', '') + if output: + final_content = output elif event_type == 'waiting_input': is_waiting = True # 保存工作流运行 ID 到对话元数据 @@ -509,6 +506,9 @@ class AgentService: conversation.extra_data['workflow_run_id'] = current_run_id elif event_type == 'complete': total_tokens = event.get('total_tokens', 0) + output = (event.get('outputs') or {}).get('output', '') + if output: + final_content = output yield event @@ -552,6 +552,35 @@ class AgentService: 'type': 'error', 'content': str(e), } + + async def _build_workflow_inputs(self, agent: Agent, user_input: str) -> Dict[str, Any]: + workflow_inputs: Dict[str, Any] = {'user_input': user_input} + if not self._db or not agent.workflow_id: + return workflow_inputs + + result = await self._db.execute( + select(AIWorkflow).where( + AIWorkflow.id == agent.workflow_id, + AIWorkflow.is_deleted == False, + ) + ) + workflow = result.scalar_one_or_none() + if not workflow: + return workflow_inputs + + input_variables = workflow.input_variables or [] + if any((item or {}).get('name') == 'request' for item in input_variables): + workflow_inputs.setdefault('request', user_input) + if any((item or {}).get('name') == 'issue_id' for item in input_variables): + workflow_inputs.setdefault('issue_id', self._extract_issue_id(user_input)) + return workflow_inputs + + @staticmethod + def _extract_issue_id(text: str) -> str: + import re + + match = re.search(r'\b[A-Z][A-Z0-9]+-\d+\b', text or '', re.IGNORECASE) + return match.group(0).upper() if match else 'MANUAL-1' def _build_system_prompt_simple(self, agent: Agent) -> str: """构建简化的系统提示词""" diff --git a/backend-fastapi/ai_platform/services/workflow_service.py b/backend-fastapi/ai_platform/services/workflow_service.py index 635f4ec..f37694e 100644 --- a/backend-fastapi/ai_platform/services/workflow_service.py +++ b/backend-fastapi/ai_platform/services/workflow_service.py @@ -1594,6 +1594,7 @@ class AIWorkflowService: node_type, status='completed', output=result.output, + metadata=_node_result_metadata(result), inputs=copy.deepcopy(node_inputs), )) yield {