Skip to content

Commit e662998

Browse files
authored
fix(Anthropic Chat Model Node): Fix LmChatAnthropic node to work when both thinking is enabled and tools used (#16010)
1 parent 0bea193 commit e662998

File tree

7 files changed

+176
-140
lines changed

7 files changed

+176
-140
lines changed

packages/@n8n/nodes-langchain/nodes/ToolExecutor/ToolExecutor.node.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -75,8 +75,8 @@ export class ToolExecutor implements INodeType {
7575
}
7676
} else {
7777
// Handle single tool
78-
if (!toolName || toolName === (tool as Tool).name) {
79-
const result = await executeTool(tool as Tool, parsedQuery);
78+
if (!toolName || toolName === tool.name) {
79+
const result = await executeTool(tool, parsedQuery);
8080
resultData.push(result);
8181
}
8282
}

packages/@n8n/nodes-langchain/nodes/ToolExecutor/utils/executeTool.ts

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,9 @@
1-
import type { StructuredTool } from 'langchain/tools';
1+
import type { Tool } from '@langchain/core/tools';
22
import { type IDataObject, type INodeExecutionData } from 'n8n-workflow';
33

44
import { convertObjectBySchema } from './convertToSchema';
55

6-
export async function executeTool(
7-
tool: StructuredTool,
8-
query: string | object,
9-
): Promise<INodeExecutionData> {
6+
export async function executeTool(tool: Tool, query: string | object): Promise<INodeExecutionData> {
107
let convertedQuery: string | object = query;
118
if ('schema' in tool && tool.schema) {
129
convertedQuery = convertObjectBySchema(query, tool.schema);

packages/@n8n/nodes-langchain/nodes/agents/OpenAiAssistant/utils.ts

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,18 @@
1-
import type { StructuredTool } from '@langchain/core/tools';
1+
import type { Tool } from '@langchain/core/tools';
22
import type { OpenAIClient } from '@langchain/openai';
33
import { zodToJsonSchema } from 'zod-to-json-schema';
44

55
// Copied from langchain(`langchain/src/tools/convert_to_openai.ts`)
66
// since these functions are not exported
77

88
/**
9-
* Formats a `StructuredTool` instance into a format that is compatible
9+
* Formats a `Tool` instance into a format that is compatible
1010
* with OpenAI's ChatCompletionFunctions. It uses the `zodToJsonSchema`
11-
* function to convert the schema of the `StructuredTool` into a JSON
11+
* function to convert the schema of the tool into a JSON
1212
* schema, which is then used as the parameters for the OpenAI function.
1313
*/
1414
export function formatToOpenAIFunction(
15-
tool: StructuredTool,
15+
tool: Tool,
1616
): OpenAIClient.Chat.ChatCompletionCreateParams.Function {
1717
return {
1818
name: tool.name,
@@ -21,7 +21,7 @@ export function formatToOpenAIFunction(
2121
};
2222
}
2323

24-
export function formatToOpenAITool(tool: StructuredTool): OpenAIClient.Chat.ChatCompletionTool {
24+
export function formatToOpenAITool(tool: Tool): OpenAIClient.Chat.ChatCompletionTool {
2525
const schema = zodToJsonSchema(tool.schema);
2626
return {
2727
type: 'function',
@@ -33,7 +33,7 @@ export function formatToOpenAITool(tool: StructuredTool): OpenAIClient.Chat.Chat
3333
};
3434
}
3535

36-
export function formatToOpenAIAssistantTool(tool: StructuredTool): OpenAIClient.Beta.AssistantTool {
36+
export function formatToOpenAIAssistantTool(tool: Tool): OpenAIClient.Beta.AssistantTool {
3737
return {
3838
type: 'function',
3939
function: {

packages/@n8n/nodes-langchain/nodes/mcp/McpClientTool/utils.ts

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,16 @@
1+
import { DynamicStructuredTool, type DynamicStructuredToolInput } from '@langchain/core/tools';
12
import { Client } from '@modelcontextprotocol/sdk/client/index.js';
23
import { SSEClientTransport } from '@modelcontextprotocol/sdk/client/sse.js';
34
import { CompatibilityCallToolResultSchema } from '@modelcontextprotocol/sdk/types.js';
45
import { Toolkit } from 'langchain/agents';
5-
import { DynamicStructuredTool, type DynamicStructuredToolInput } from 'langchain/tools';
66
import {
77
createResultError,
88
createResultOk,
99
type IDataObject,
1010
type IExecuteFunctions,
1111
type Result,
1212
} from 'n8n-workflow';
13-
import { type ZodTypeAny } from 'zod';
13+
import { z } from 'zod';
1414

1515
import { convertJsonSchemaToZod } from '@utils/schemaParsing';
1616

@@ -99,18 +99,24 @@ export const createCallTool =
9999
export function mcpToolToDynamicTool(
100100
tool: McpTool,
101101
onCallTool: DynamicStructuredToolInput['func'],
102-
) {
102+
): DynamicStructuredTool<z.ZodObject<any, any, any, any>> {
103+
const rawSchema = convertJsonSchemaToZod(tool.inputSchema);
104+
105+
// Ensure we always have an object schema for structured tools
106+
const objectSchema =
107+
rawSchema instanceof z.ZodObject ? rawSchema : z.object({ value: rawSchema });
108+
103109
return new DynamicStructuredTool({
104110
name: tool.name,
105111
description: tool.description ?? '',
106-
schema: convertJsonSchemaToZod(tool.inputSchema),
112+
schema: objectSchema,
107113
func: onCallTool,
108114
metadata: { isFromToolkit: true },
109115
});
110116
}
111117

112118
export class McpToolkit extends Toolkit {
113-
constructor(public tools: Array<DynamicStructuredTool<ZodTypeAny>>) {
119+
constructor(public tools: Array<DynamicStructuredTool<z.ZodObject<any, any, any, any>>>) {
114120
super();
115121
}
116122
}

packages/@n8n/nodes-langchain/nodes/vendors/OpenAi/helpers/utils.ts

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import type { BaseMessage } from '@langchain/core/messages';
2-
import type { StructuredTool } from '@langchain/core/tools';
2+
import type { Tool } from '@langchain/core/tools';
33
import type { OpenAIClient } from '@langchain/openai';
44
import type { BufferWindowMemory } from 'langchain/memory';
55
import { zodToJsonSchema } from 'zod-to-json-schema';
@@ -8,13 +8,13 @@ import { zodToJsonSchema } from 'zod-to-json-schema';
88
// since these functions are not exported
99

1010
/**
11-
* Formats a `StructuredTool` instance into a format that is compatible
11+
* Formats a `Tool` instance into a format that is compatible
1212
* with OpenAI's ChatCompletionFunctions. It uses the `zodToJsonSchema`
13-
* function to convert the schema of the `StructuredTool` into a JSON
13+
* function to convert the schema of the tool into a JSON
1414
* schema, which is then used as the parameters for the OpenAI function.
1515
*/
1616
export function formatToOpenAIFunction(
17-
tool: StructuredTool,
17+
tool: Tool,
1818
): OpenAIClient.Chat.ChatCompletionCreateParams.Function {
1919
return {
2020
name: tool.name,
@@ -23,7 +23,7 @@ export function formatToOpenAIFunction(
2323
};
2424
}
2525

26-
export function formatToOpenAITool(tool: StructuredTool): OpenAIClient.Chat.ChatCompletionTool {
26+
export function formatToOpenAITool(tool: Tool): OpenAIClient.Chat.ChatCompletionTool {
2727
const schema = zodToJsonSchema(tool.schema);
2828
return {
2929
type: 'function',
@@ -35,7 +35,7 @@ export function formatToOpenAITool(tool: StructuredTool): OpenAIClient.Chat.Chat
3535
};
3636
}
3737

38-
export function formatToOpenAIAssistantTool(tool: StructuredTool): OpenAIClient.Beta.AssistantTool {
38+
export function formatToOpenAIAssistantTool(tool: Tool): OpenAIClient.Beta.AssistantTool {
3939
return {
4040
type: 'function',
4141
function: {

0 commit comments

Comments
 (0)