From 231e4eff57efe2a9ff11f4e5bcbd36c252e8006f Mon Sep 17 00:00:00 2001 From: Michael Drury Date: Fri, 21 Nov 2025 09:01:25 +0000 Subject: [PATCH] fix(Agent Node): Thinking model issue - undefined `.map` error (#22046) --- .../agents/Agent/agents/ToolsAgent/common.ts | 29 +++++++++--- .../Agent/test/ToolsAgent/commons.test.ts | 45 +++++++++++++++++++ 2 files changed, 68 insertions(+), 6 deletions(-) diff --git a/packages/@n8n/nodes-langchain/nodes/agents/Agent/agents/ToolsAgent/common.ts b/packages/@n8n/nodes-langchain/nodes/agents/Agent/agents/ToolsAgent/common.ts index 88d1d4ad4d8..5f43ba958fc 100644 --- a/packages/@n8n/nodes-langchain/nodes/agents/Agent/agents/ToolsAgent/common.ts +++ b/packages/@n8n/nodes-langchain/nodes/agents/Agent/agents/ToolsAgent/common.ts @@ -206,18 +206,35 @@ export function handleAgentFinishOutput( if (agentFinishSteps.returnValues) { const isMultiOutput = Array.isArray(agentFinishSteps.returnValues?.output); if (isMultiOutput) { - // If all items in the multi-output array are of type 'text', merge them into a single string const multiOutputSteps = agentFinishSteps.returnValues.output as Array<{ index: number; type: string; - text: string; + text?: string; + thinking?: string; }>; - const isTextOnly = multiOutputSteps.every((output) => 'text' in output); - if (isTextOnly) { - agentFinishSteps.returnValues.output = multiOutputSteps - .map((output) => output.text) + + // Filter out thinking blocks and join text blocks + const textOutputs = multiOutputSteps + .filter((output) => output.type === 'text' && output.text) + .map((output) => output.text) + .join('\n') + .trim(); + + if (textOutputs) { + agentFinishSteps.returnValues.output = textOutputs; + } else { + const thinkingOutputs = multiOutputSteps + .filter((output) => output.type === 'thinking' && output.thinking) + .map((output) => output.thinking) .join('\n') .trim(); + + if (thinkingOutputs) { + agentFinishSteps.returnValues.output = thinkingOutputs; + } else { + // no output was found + agentFinishSteps.returnValues.output = ''; + } } return agentFinishSteps; } diff --git a/packages/@n8n/nodes-langchain/nodes/agents/Agent/test/ToolsAgent/commons.test.ts b/packages/@n8n/nodes-langchain/nodes/agents/Agent/test/ToolsAgent/commons.test.ts index a6a6977577d..f953f45e24d 100644 --- a/packages/@n8n/nodes-langchain/nodes/agents/Agent/test/ToolsAgent/commons.test.ts +++ b/packages/@n8n/nodes-langchain/nodes/agents/Agent/test/ToolsAgent/commons.test.ts @@ -831,4 +831,49 @@ describe('handleAgentFinishOutput', () => { expect(result).toEqual(steps); }); + + it('should filter out thinking blocks and return only text blocks', () => { + const steps: AgentFinish = { + returnValues: { + output: [ + { index: 0, type: 'thinking', thinking: 'Internal reasoning...' }, + { index: 1, type: 'text', text: 'User-facing output' }, + ], + }, + log: '', + }; + + const result = handleAgentFinishOutput(steps) as AgentFinish; + + expect(result.returnValues.output).toBe('User-facing output'); + }); + + it('should return thinking content when no text blocks exist', () => { + const steps: AgentFinish = { + returnValues: { + output: [ + { index: 0, type: 'thinking', thinking: 'Only thinking content' }, + { index: 1, type: 'thinking', thinking: 'More thinking' }, + ], + }, + log: '', + }; + + const result = handleAgentFinishOutput(steps) as AgentFinish; + + expect(result.returnValues.output).toBe('Only thinking content\nMore thinking'); + }); + + it('should return empty string when no text or thinking blocks exist', () => { + const steps: AgentFinish = { + returnValues: { + output: [{ index: 0, type: 'unknown' }], + }, + log: '', + }; + + const result = handleAgentFinishOutput(steps) as AgentFinish; + + expect(result.returnValues.output).toBe(''); + }); });