diff --git a/backend-fastapi/ai_platform/services/workflow_service.py b/backend-fastapi/ai_platform/services/workflow_service.py index 061b5bc..37b97dc 100644 --- a/backend-fastapi/ai_platform/services/workflow_service.py +++ b/backend-fastapi/ai_platform/services/workflow_service.py @@ -217,6 +217,7 @@ def _make_execution_log_entry( node_type: str, **extra: Any, ) -> dict: + extra.setdefault('timestamp', datetime.now().isoformat()) metadata = dict(extra.pop('metadata', {}) or {}) collaboration = _node_collaboration_metadata(node_map, node_id, node_type) branch_id = extra.get('branch') or extra.get('branch_id') @@ -238,6 +239,7 @@ def _make_execution_log_entry( output=extra.get('output'), error=extra.get('error'), ) + metadata['communication']['timestamp'] = extra.get('timestamp') return { 'node_id': node_id, 'node_type': node_type, @@ -982,9 +984,18 @@ class AIWorkflowService: current_id = next_nodes[0] if next_nodes else None continue - # 执行节点(异步) + node_inputs = _snapshot_node_inputs(branch_context) + + # 执行节点(异步)。并行分支不能共享同一个 AsyncSession,否则模型/Provider 查询会并发抢占连接。 start_time = time.time() - result = await node_instance.execute_async(branch_context) + if context.db_session is not None: + from app.database import AsyncSessionLocal + + async with AsyncSessionLocal() as branch_db: + branch_context.db_session = branch_db + result = await node_instance.execute_async(branch_context) + else: + result = await node_instance.execute_async(branch_context) elapsed = int((time.time() - start_time) * 1000) target_node_id = _resolve_handoff_target( current_id, @@ -1004,6 +1015,7 @@ class AIWorkflowService: elapsed_time=elapsed, tokens_used=result.tokens_used, metadata=_node_result_metadata(result), + inputs=copy.deepcopy(node_inputs), branch=branch_id, branch_label=branch_labels.get(branch_id, branch_id), target_node_id=target_node_id, @@ -1027,6 +1039,12 @@ class AIWorkflowService: branch_context.variables.update(result.output_variables) branch_context.previous_output = result.output branch_output = result.output + + # 支持分支内后续节点使用 {{node_id.output_variable}} 引用当前节点输出。 + branch_context.variables[f'_node_{current_id}'] = { + 'output': result.output, + **result.output_variables, + } # 下一个节点 if result.next_node_id: diff --git a/web/apps/web-ele/src/api/ai-platform/ai-platform.ts b/web/apps/web-ele/src/api/ai-platform/ai-platform.ts index 7318a08..806e206 100644 --- a/web/apps/web-ele/src/api/ai-platform/ai-platform.ts +++ b/web/apps/web-ele/src/api/ai-platform/ai-platform.ts @@ -281,6 +281,7 @@ export interface ExecutionLogEntry { error?: string; elapsed_time?: number; tokens_used?: number; + timestamp?: string; branch?: string; branch_label?: string; metadata?: Record; diff --git a/web/apps/web-ele/src/router/prefetch.ts b/web/apps/web-ele/src/router/prefetch.ts index d32c330..97127df 100644 --- a/web/apps/web-ele/src/router/prefetch.ts +++ b/web/apps/web-ele/src/router/prefetch.ts @@ -13,11 +13,16 @@ type WindowWithIdleCallback = Window & { let prefetched = false; -const prefetchTasks = [ - () => import('#/views/ai-platform/agent/index.vue'), +const criticalPrefetchTasks = [ () => import('#/views/_core/agent-chat/index.vue'), - () => import('#/views/ai-platform/workflow/index.vue'), () => import('#/views/ai-platform/workflow-runs/index.vue'), + () => import('#/components/ai-chat-panel/AiChatPanel.vue'), + () => import('#/views/ai-platform/workflow-runs/modules/detail-dialog.vue'), +]; + +const deferredPrefetchTasks = [ + () => import('#/views/ai-platform/agent/index.vue'), + () => import('#/views/ai-platform/workflow/index.vue'), () => import('#/views/ai-platform/model/index.vue'), () => import('#/views/ai-platform/knowledge/index.vue'), ]; @@ -39,8 +44,11 @@ function prefetchAiPlatformPages() { } prefetched = true; + window.setTimeout(() => { + void Promise.allSettled(criticalPrefetchTasks.map((task) => task())); + }, 300); scheduleIdle(() => { - void Promise.allSettled(prefetchTasks.map((task) => task())); + void Promise.allSettled(deferredPrefetchTasks.map((task) => task())); }); } diff --git a/web/apps/web-ele/src/views/_core/agent-chat/index.vue b/web/apps/web-ele/src/views/_core/agent-chat/index.vue index b23b3ea..6c70792 100644 --- a/web/apps/web-ele/src/views/_core/agent-chat/index.vue +++ b/web/apps/web-ele/src/views/_core/agent-chat/index.vue @@ -104,16 +104,27 @@ onMounted(() => {