diff --git a/api/core/repositories/sqlalchemy_workflow_node_execution_repository.py b/api/core/repositories/sqlalchemy_workflow_node_execution_repository.py index 79b0c702e0..0a3189f398 100644 --- a/api/core/repositories/sqlalchemy_workflow_node_execution_repository.py +++ b/api/core/repositories/sqlalchemy_workflow_node_execution_repository.py @@ -480,9 +480,10 @@ class SQLAlchemyWorkflowNodeExecutionRepository(WorkflowNodeExecutionRepository) if reasoning_content: # reasoning_content could be a string or already a list if isinstance(reasoning_content, str): - reasoning_list = [reasoning_content] if reasoning_content else [] + reasoning_list = [reasoning_content] if reasoning_content.strip() else [] elif isinstance(reasoning_content, list): - reasoning_list = reasoning_content + # Filter out empty or whitespace-only strings + reasoning_list = [r.strip() for r in reasoning_content if isinstance(r, str) and r.strip()] # Extract tool_calls from metadata.agent_log tool_calls_list: list[dict] = [] @@ -491,16 +492,25 @@ class SQLAlchemyWorkflowNodeExecutionRepository(WorkflowNodeExecutionRepository) for log in agent_log: # Each log entry has label, data, status, etc. log_data = log.data if hasattr(log, "data") else log.get("data", {}) - if log_data.get("tool_name"): + tool_name = log_data.get("tool_name") + # Only include tool calls with valid tool_name + if tool_name and str(tool_name).strip(): tool_calls_list.append( { "id": log_data.get("tool_call_id", ""), - "name": log_data.get("tool_name", ""), + "name": tool_name, "arguments": json.dumps(log_data.get("tool_args", {})), "result": str(log_data.get("output", "")), } ) + # Only save if there's meaningful generation detail (reasoning or tool calls) + has_valid_reasoning = bool(reasoning_list) + has_valid_tool_calls = bool(tool_calls_list) + + if not has_valid_reasoning and not has_valid_tool_calls: + return + # Build sequence based on content, reasoning, and tool_calls sequence: list[dict] = [] text = outputs.get("text", "") @@ -514,10 +524,6 @@ class SQLAlchemyWorkflowNodeExecutionRepository(WorkflowNodeExecutionRepository) for i in range(len(tool_calls_list)): sequence.append({"type": "tool_call", "index": i}) - # Only save if there's meaningful generation detail - if not reasoning_list and not tool_calls_list: - return - # Check if generation detail already exists for this node execution existing = ( session.query(LLMGenerationDetail) diff --git a/api/core/workflow/nodes/llm/node.py b/api/core/workflow/nodes/llm/node.py index e14dfebe64..4acbe25ae3 100644 --- a/api/core/workflow/nodes/llm/node.py +++ b/api/core/workflow/nodes/llm/node.py @@ -1680,9 +1680,6 @@ class LLMNode(Node[LLMNodeData]): "content": text, }, }, - metadata={ - WorkflowNodeExecutionMetadataKey.LLM_CONTENT_SEQUENCE: [], - }, inputs={ **node_inputs, "tools": [