fix(nodes-langchain): emit ai-tool-called log streaming event for ToolWorkflow, ToolCode, and ToolHttpRequest#28599
Open
octo-patch wants to merge 1 commit inton8n-io:masterfrom
Conversation
… ToolCode, and ToolHttpRequest
These three tools use a manual logging pattern (manualLogging=true) that
calls addInputData/addOutputData directly, bypassing the logWrapper proxy
which normally emits the ai-tool-called event for LangChain-native tools.
As a result, log streaming subscribers never received n8n.ai.tool.called
events when these tools executed, creating an observability blind spot for
the most commonly used AI agent tools.
Fix: call logAiEvent('ai-tool-called', ...) in the success branch of each
tool handler function, consistent with the pattern used by logWrapper.
Fixes n8n-io#28532
|
octo-patch seems not to be a GitHub user. You need a GitHub account to be able to sign the CLA. If you have already a GitHub account, please add the email address used for this commit to your account. You have signed the CLA already but the status is still pending? Let us recheck it. |
Contributor
There was a problem hiding this comment.
1 issue found across 4 files
Prompt for AI agents (unresolved issues)
Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.
<file name="packages/@n8n/nodes-langchain/nodes/tools/ToolWorkflow/v2/ToolWorkflowV2.test.ts">
<violation number="1" location="packages/@n8n/nodes-langchain/nodes/tools/ToolWorkflow/v2/ToolWorkflowV2.test.ts:1017">
P3: The positive-path telemetry test should also assert the logged `response` payload; currently it only checks the query, so it would miss regressions where `ai-tool-called` is emitted with the wrong or missing response data.</violation>
</file>
Architecture diagram
sequenceDiagram
participant Agent as AI Agent (LangChain)
participant Tool as Tool (Workflow / Code / HTTP)
participant Ctx as Node Execution Context
participant AIUtils as @n8n/ai-utilities
participant Stream as Log Streaming / Observability
Note over Agent,Stream: AI Tool Execution Flow (Manual Logging Path)
Agent->>Tool: call(query)
Tool->>Tool: Execute internal logic (JS Code, Sub-workflow, or HTTP Request)
alt Success Branch
Tool->>Ctx: addOutputData(NodeConnectionTypes.AiTool, index, response)
Note over Tool,AIUtils: NEW: Manual emission for tools bypassing logWrapper
Tool->>AIUtils: NEW: logAiEvent(ctx, 'ai-tool-called', { query, response })
AIUtils-->>Stream: Push log entry to external listeners
Tool-->>Agent: return response
else Error Branch
Tool->>Ctx: addOutputData(NodeConnectionTypes.AiTool, index, executionError)
Note right of Tool: Log event is NOT emitted on failure in this flow
Tool-->>Agent: return response
end
Note over Tool,Ctx: NOTE: If manualLogging is false (Engine-called),<br/>standard logWrapper proxy handles the event emission instead.
Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review, or fix all with cubic.
| expect(mockLogAiEvent).toHaveBeenCalledWith( | ||
| expect.anything(), | ||
| 'ai-tool-called', | ||
| expect.objectContaining({ query: 'test query' }), |
Contributor
There was a problem hiding this comment.
P3: The positive-path telemetry test should also assert the logged response payload; currently it only checks the query, so it would miss regressions where ai-tool-called is emitted with the wrong or missing response data.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At packages/@n8n/nodes-langchain/nodes/tools/ToolWorkflow/v2/ToolWorkflowV2.test.ts, line 1017:
<comment>The positive-path telemetry test should also assert the logged `response` payload; currently it only checks the query, so it would miss regressions where `ai-tool-called` is emitted with the wrong or missing response data.</comment>
<file context>
@@ -971,4 +978,71 @@ describe('WorkflowTool::WorkflowToolService', () => {
+ expect(mockLogAiEvent).toHaveBeenCalledWith(
+ expect.anything(),
+ 'ai-tool-called',
+ expect.objectContaining({ query: 'test query' }),
+ );
+ });
</file context>
Suggested change
| expect.objectContaining({ query: 'test query' }), | |
| expect.objectContaining({ | |
| query: 'test query', | |
| response: JSON.stringify(TEST_RESPONSE, null, 2), | |
| }), |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #28532
Problem
When an AI agent uses the Call n8n Sub-Workflow Tool (
toolWorkflow), HTTP Request Tool (toolHttpRequest), or Code Tool (toolCode) as tools, then8n.ai.tool.calledlog streaming event is never emitted. External observability systems subscribed to this event receive no signal that these tools were invoked.Root cause: These three tool types use a manual logging execution pattern where they call
addInputData/addOutputDatadirectly. This bypasses thelogWrapperproxy from@n8n/ai-utilities, which normally intercepts the LangChain_callmethod and emitsai-tool-calledvialogAiEvent. Because these tools never go throughlogWrapper,logAiEventis never called.Solution
Call
logAiEvent(ctx, 'ai-tool-called', { query, response })in the success branch of each tool's handler, consistent with the pattern used bylogWrapperfor LangChain-native tools:WorkflowToolService.ts(ToolWorkflow v2): added afteraddOutputDatain themanualLoggingsuccess branchToolCode.node.ts: added afteraddOutputDatain theelse if (log)success branchToolHttpRequest/utils.ts(configureToolFunction): added afteraddOutputDatain theelsesuccess branchTesting
Added unit tests in
ToolWorkflowV2.test.tsverifying:logAiEventis called with'ai-tool-called'and the correct query/response data whenmanualLogging=truelogAiEventis NOT called whenmanualLogging=false(engine-called path)