import time from datetime import datetime from typing import Any from sqlalchemy.ext.asyncio import AsyncSession from app.models import Agent, Workflow, WorkflowRun from app.services.llm import LLMService class WorkflowService: def __init__(self, db: AsyncSession): self.db = db self.llm = LLMService(db) async def run(self, workflow: Workflow, inputs: dict[str, Any]) -> WorkflowRun: started = time.time() definition = workflow.published_definition or workflow.definition or {} run = WorkflowRun( workflow_id=workflow.id, status="running", inputs=inputs, outputs={}, execution_log=[], started_at=datetime.utcnow(), ) self.db.add(run) await self.db.flush() variables: dict[str, Any] = dict(inputs) log: list[dict[str, Any]] = [] try: nodes = definition.get("nodes") or [] for node in nodes: node_type = node.get("type", "unknown") node_id = node.get("id", node_type) data = node.get("data") or {} entry = {"node_id": node_id, "node_type": node_type, "status": "completed"} if node_type == "start": entry["output"] = variables elif node_type == "llm": agent_id = data.get("agent_id") prompt = data.get("prompt") or inputs.get("task") or inputs.get("message") or "" agent = await self.db.get(Agent, agent_id) if agent_id else None if agent: result = await self.llm.complete(agent, prompt) else: result = f"LLM 节点占位输出:{prompt}" variables[node_id] = result entry["output"] = result elif node_type == "agent": agent_id = data.get("agent_id") agent = await self.db.get(Agent, agent_id) if agent_id else None task = data.get("task") or inputs.get("task") or inputs.get("message") or "" result = await self.llm.complete(agent, task) if agent else f"Agent 节点占位输出:{task}" variables[node_id] = result entry["output"] = result elif node_type == "condition": entry["output"] = {"matched": True} elif node_type in {"parallel", "merge", "tool", "http"}: entry["output"] = f"{node_type} 节点已执行最小占位逻辑" elif node_type == "end": entry["output"] = variables else: entry["status"] = "skipped" entry["output"] = "未知节点类型,已跳过" log.append(entry) run.status = "completed" run.outputs = {"result": variables} run.execution_log = log workflow.run_count = (workflow.run_count or 0) + 1 except Exception as exc: run.status = "failed" run.error_message = str(exc) run.execution_log = log finally: run.elapsed_time = int((time.time() - started) * 1000) run.completed_at = datetime.utcnow() await self.db.commit() await self.db.refresh(run) return run