Files
alighasami 3d5eaf9445
Security: Sync from Public / sync-from-public (push) Has been cancelled
Test: Benchmark Nightly / build (push) Has been cancelled
Test: Benchmark Nightly / Notify Cats on failure (push) Has been cancelled
CI: Python / Checks (push) Has been cancelled
Test: Evals Python / Workflow Comparison Python (push) Has been cancelled
Util: Check Docs URLs / check-docs-urls (push) Has been cancelled
Test: Visual Storybook / Cloudflare Pages (push) Has been cancelled
Test: E2E Performance / build-and-test-performance (push) Has been cancelled
Test: Workflows Nightly / Run Workflow Tests (push) Has been cancelled
Util: Cleanup CI Docker Images / Delete stale CI images (push) Has been cancelled
Test: Benchmark Destroy Env / build (push) Has been cancelled
Util: Update Node Popularity / update-popularity (push) Has been cancelled
Test: E2E Coverage Weekly / Coverage Tests (push) Has been cancelled
first commit
2026-03-17 16:22:57 +03:30

113 lines
2.8 KiB
TypeScript

import { DynamicTool } from '@langchain/classic/tools';
import {
type IExecuteFunctions,
NodeConnectionTypes,
nodeNameToToolName,
type INodeType,
type INodeTypeDescription,
type ISupplyDataFunctions,
type SupplyData,
type INodeExecutionData,
} from 'n8n-workflow';
import { logWrapper, getConnectionHintNoticeField } from '@n8n/ai-utilities';
async function getTool(
ctx: ISupplyDataFunctions | IExecuteFunctions,
itemIndex: number,
): Promise<DynamicTool> {
const node = ctx.getNode();
const { typeVersion } = node;
const name = typeVersion === 1 ? 'thinking_tool' : nodeNameToToolName(node);
const description = ctx.getNodeParameter('description', itemIndex) as string;
return new DynamicTool({
name,
description,
func: async (subject: string) => {
return subject;
},
});
}
// A thinking tool, see https://www.anthropic.com/engineering/claude-think-tool
const defaultToolDescription =
'Use the tool to think about something. It will not obtain new information or change the database, but just append the thought to the log. Use it when complex reasoning or some cache memory is needed.';
export class ToolThink implements INodeType {
description: INodeTypeDescription = {
displayName: 'Think Tool',
name: 'toolThink',
icon: 'fa:brain',
iconColor: 'black',
group: ['transform'],
version: [1, 1.1],
description: 'Invite the AI agent to do some thinking',
defaults: {
name: 'Think',
},
codex: {
categories: ['AI'],
subcategories: {
AI: ['Tools'],
Tools: ['Other Tools'],
},
resources: {
primaryDocumentation: [
{
url: 'https://docs.n8n.io/integrations/builtin/cluster-nodes/sub-nodes/n8n-nodes-langchain.toolthink/',
},
],
},
},
inputs: [],
outputs: [NodeConnectionTypes.AiTool],
outputNames: ['Tool'],
properties: [
getConnectionHintNoticeField([NodeConnectionTypes.AiAgent]),
{
displayName: 'Think Tool Description',
name: 'description',
type: 'string',
default: defaultToolDescription,
placeholder: '[Describe your thinking tool here, explaining how it will help the AI think]',
description: "The thinking tool's description",
typeOptions: {
rows: 3,
},
required: true,
},
],
};
async supplyData(this: ISupplyDataFunctions, itemIndex: number): Promise<SupplyData> {
const tool = await getTool(this, itemIndex);
return {
response: logWrapper(tool, this),
};
}
async execute(this: IExecuteFunctions): Promise<INodeExecutionData[][]> {
const input = this.getInputData();
const response: INodeExecutionData[] = [];
for (let i = 0; i < input.length; i++) {
const inputItem = input[i];
const tool = await getTool(this, i);
const result = await tool.invoke(inputItem.json);
response.push({
json: {
response: result,
},
pairedItem: {
item: i,
},
});
}
return [response];
}
}