@n8n/ai-workflow-builder 0.27.1 → 0.29.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (107) hide show
  1. package/dist/build.tsbuildinfo +1 -1
  2. package/dist/chains/prompt-categorization.d.ts +3 -0
  3. package/dist/chains/prompt-categorization.js +109 -0
  4. package/dist/chains/prompt-categorization.js.map +1 -0
  5. package/dist/chains/prompts/parameter-types/system-message.d.ts +1 -0
  6. package/dist/chains/prompts/parameter-types/system-message.js +75 -0
  7. package/dist/chains/prompts/parameter-types/system-message.js.map +1 -0
  8. package/dist/chains/prompts/prompt-builder.d.ts +1 -0
  9. package/dist/chains/prompts/prompt-builder.js +23 -1
  10. package/dist/chains/prompts/prompt-builder.js.map +1 -1
  11. package/dist/chains/test/integration/test-helpers.d.ts +3 -0
  12. package/dist/chains/test/integration/test-helpers.js +16 -0
  13. package/dist/chains/test/integration/test-helpers.js.map +1 -0
  14. package/dist/index.d.ts +1 -0
  15. package/dist/index.js +3 -0
  16. package/dist/index.js.map +1 -1
  17. package/dist/tools/best-practices/chatbot.d.ts +7 -0
  18. package/dist/tools/best-practices/chatbot.js +118 -0
  19. package/dist/tools/best-practices/chatbot.js.map +1 -0
  20. package/dist/tools/best-practices/content-generation.d.ts +7 -0
  21. package/dist/tools/best-practices/content-generation.js +79 -0
  22. package/dist/tools/best-practices/content-generation.js.map +1 -0
  23. package/dist/tools/best-practices/data-extraction.d.ts +7 -0
  24. package/dist/tools/best-practices/data-extraction.js +105 -0
  25. package/dist/tools/best-practices/data-extraction.js.map +1 -0
  26. package/dist/tools/best-practices/form-input.d.ts +7 -0
  27. package/dist/tools/best-practices/form-input.js +173 -0
  28. package/dist/tools/best-practices/form-input.js.map +1 -0
  29. package/dist/tools/best-practices/index.d.ts +3 -0
  30. package/dist/tools/best-practices/index.js +27 -0
  31. package/dist/tools/best-practices/index.js.map +1 -0
  32. package/dist/tools/best-practices/scraping-and-research.d.ts +7 -0
  33. package/dist/tools/best-practices/scraping-and-research.js +147 -0
  34. package/dist/tools/best-practices/scraping-and-research.js.map +1 -0
  35. package/dist/tools/builder-tools.js +9 -0
  36. package/dist/tools/builder-tools.js.map +1 -1
  37. package/dist/tools/categorize-prompt.tool.d.ts +5 -0
  38. package/dist/tools/categorize-prompt.tool.js +84 -0
  39. package/dist/tools/categorize-prompt.tool.js.map +1 -0
  40. package/dist/tools/engines/node-search-engine.d.ts +0 -9
  41. package/dist/tools/engines/node-search-engine.js +52 -72
  42. package/dist/tools/engines/node-search-engine.js.map +1 -1
  43. package/dist/tools/get-best-practices.tool.d.ts +33 -0
  44. package/dist/tools/get-best-practices.tool.js +94 -0
  45. package/dist/tools/get-best-practices.tool.js.map +1 -0
  46. package/dist/tools/prompts/main-agent.prompt.js +116 -5
  47. package/dist/tools/prompts/main-agent.prompt.js.map +1 -1
  48. package/dist/tools/validate-workflow.tool.d.ts +5 -0
  49. package/dist/tools/validate-workflow.tool.js +61 -0
  50. package/dist/tools/validate-workflow.tool.js.map +1 -0
  51. package/dist/types/best-practices.d.ts +6 -0
  52. package/dist/types/best-practices.js +3 -0
  53. package/dist/types/best-practices.js.map +1 -0
  54. package/dist/types/categorization.d.ts +23 -0
  55. package/dist/types/categorization.js +38 -0
  56. package/dist/types/categorization.js.map +1 -0
  57. package/dist/types/index.d.ts +2 -0
  58. package/dist/types/tools.d.ts +4 -0
  59. package/dist/utils/operations-processor.d.ts +2 -0
  60. package/dist/utils/operations-processor.js +1 -0
  61. package/dist/utils/operations-processor.js.map +1 -1
  62. package/dist/utils/stream-processor.d.ts +1 -0
  63. package/dist/utils/stream-processor.js +99 -59
  64. package/dist/utils/stream-processor.js.map +1 -1
  65. package/dist/utils/workflow-validation.d.ts +2 -0
  66. package/dist/utils/workflow-validation.js +36 -0
  67. package/dist/utils/workflow-validation.js.map +1 -0
  68. package/dist/validation/checks/agent-prompt.d.ts +3 -0
  69. package/dist/validation/checks/agent-prompt.js +45 -0
  70. package/dist/validation/checks/agent-prompt.js.map +1 -0
  71. package/dist/validation/checks/connections.d.ts +4 -0
  72. package/dist/validation/checks/connections.js +162 -0
  73. package/dist/validation/checks/connections.js.map +1 -0
  74. package/dist/validation/checks/from-ai.d.ts +4 -0
  75. package/dist/validation/checks/from-ai.js +59 -0
  76. package/dist/validation/checks/from-ai.js.map +1 -0
  77. package/dist/validation/checks/index.d.ts +5 -0
  78. package/dist/validation/checks/index.js +14 -0
  79. package/dist/validation/checks/index.js.map +1 -0
  80. package/dist/validation/checks/tools.d.ts +4 -0
  81. package/dist/validation/checks/tools.js +44 -0
  82. package/dist/validation/checks/tools.js.map +1 -0
  83. package/dist/validation/checks/trigger.d.ts +8 -0
  84. package/dist/validation/checks/trigger.js +35 -0
  85. package/dist/validation/checks/trigger.js.map +1 -0
  86. package/dist/validation/programmatic.d.ts +3 -0
  87. package/dist/validation/programmatic.js +20 -0
  88. package/dist/validation/programmatic.js.map +1 -0
  89. package/dist/validation/types.d.ts +41 -0
  90. package/dist/validation/types.js +3 -0
  91. package/dist/validation/types.js.map +1 -0
  92. package/dist/validation/utils/expressions.d.ts +3 -0
  93. package/dist/validation/utils/expressions.js +37 -0
  94. package/dist/validation/utils/expressions.js.map +1 -0
  95. package/dist/validation/utils/is-tool.d.ts +2 -0
  96. package/dist/validation/utils/is-tool.js +7 -0
  97. package/dist/validation/utils/is-tool.js.map +1 -0
  98. package/dist/validation/utils/resolve-connections.d.ts +8 -0
  99. package/dist/validation/utils/resolve-connections.js +64 -0
  100. package/dist/validation/utils/resolve-connections.js.map +1 -0
  101. package/dist/workflow-builder-agent.d.ts +2 -0
  102. package/dist/workflow-builder-agent.js +28 -25
  103. package/dist/workflow-builder-agent.js.map +1 -1
  104. package/dist/workflow-state.d.ts +3 -1
  105. package/dist/workflow-state.js +4 -0
  106. package/dist/workflow-state.js.map +1 -1
  107. package/package.json +12 -7
@@ -1,12 +1,6 @@
1
1
  import type { INodeTypeDescription, NodeConnectionType } from 'n8n-workflow';
2
2
  import type { NodeSearchResult } from '../../types/nodes';
3
3
  export declare const SCORE_WEIGHTS: {
4
- readonly NAME_CONTAINS: 10;
5
- readonly DISPLAY_NAME_CONTAINS: 8;
6
- readonly DESCRIPTION_CONTAINS: 5;
7
- readonly ALIAS_CONTAINS: 8;
8
- readonly NAME_EXACT: 20;
9
- readonly DISPLAY_NAME_EXACT: 15;
10
4
  readonly CONNECTION_EXACT: 100;
11
5
  readonly CONNECTION_IN_EXPRESSION: 50;
12
6
  };
@@ -16,10 +10,7 @@ export declare class NodeSearchEngine {
16
10
  searchByName(query: string, limit?: number): NodeSearchResult[];
17
11
  searchByConnectionType(connectionType: NodeConnectionType, limit?: number, nameFilter?: string): NodeSearchResult[];
18
12
  formatResult(result: NodeSearchResult): string;
19
- private calculateNameScore;
20
13
  private getConnectionScore;
21
- private createSearchResult;
22
- private sortAndLimit;
23
14
  static isAiConnectionType(connectionType: string): boolean;
24
15
  static getAiConnectionTypes(): NodeConnectionType[];
25
16
  }
@@ -1,14 +1,15 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.NodeSearchEngine = exports.SCORE_WEIGHTS = void 0;
4
+ const sublimeSearch_1 = require("@n8n/utils/dist/search/sublimeSearch");
4
5
  const n8n_workflow_1 = require("n8n-workflow");
6
+ const NODE_SEARCH_KEYS = [
7
+ { key: 'displayName', weight: 1.5 },
8
+ { key: 'name', weight: 1.3 },
9
+ { key: 'codex.alias', weight: 1.0 },
10
+ { key: 'description', weight: 0.7 },
11
+ ];
5
12
  exports.SCORE_WEIGHTS = {
6
- NAME_CONTAINS: 10,
7
- DISPLAY_NAME_CONTAINS: 8,
8
- DESCRIPTION_CONTAINS: 5,
9
- ALIAS_CONTAINS: 8,
10
- NAME_EXACT: 20,
11
- DISPLAY_NAME_EXACT: 15,
12
13
  CONNECTION_EXACT: 100,
13
14
  CONNECTION_IN_EXPRESSION: 50,
14
15
  };
@@ -18,40 +19,54 @@ class NodeSearchEngine {
18
19
  this.nodeTypes = nodeTypes;
19
20
  }
20
21
  searchByName(query, limit = 20) {
21
- const normalizedQuery = query.toLowerCase();
22
- const results = [];
23
- for (const nodeType of this.nodeTypes) {
24
- try {
25
- const score = this.calculateNameScore(nodeType, normalizedQuery);
26
- if (score > 0) {
27
- results.push(this.createSearchResult(nodeType, score));
28
- }
29
- }
30
- catch (error) {
31
- }
32
- }
33
- return this.sortAndLimit(results, limit);
22
+ const searchResults = (0, sublimeSearch_1.sublimeSearch)(query, this.nodeTypes, NODE_SEARCH_KEYS);
23
+ return searchResults
24
+ .slice(0, limit)
25
+ .map(({ item, score }) => ({
26
+ name: item.name,
27
+ displayName: item.displayName,
28
+ description: item.description ?? 'No description available',
29
+ inputs: item.inputs,
30
+ outputs: item.outputs,
31
+ score,
32
+ }));
34
33
  }
35
34
  searchByConnectionType(connectionType, limit = 20, nameFilter) {
36
- const results = [];
37
- const normalizedFilter = nameFilter?.toLowerCase();
38
- for (const nodeType of this.nodeTypes) {
39
- try {
40
- const connectionScore = this.getConnectionScore(nodeType, connectionType);
41
- if (connectionScore > 0) {
42
- const nameScore = normalizedFilter
43
- ? this.calculateNameScore(nodeType, normalizedFilter)
44
- : 0;
45
- if (!normalizedFilter || nameScore > 0) {
46
- const totalScore = connectionScore + nameScore;
47
- results.push(this.createSearchResult(nodeType, totalScore));
48
- }
49
- }
50
- }
51
- catch (error) {
52
- }
35
+ const nodesWithConnectionType = this.nodeTypes
36
+ .map((nodeType) => {
37
+ const connectionScore = this.getConnectionScore(nodeType, connectionType);
38
+ return connectionScore > 0 ? { nodeType, connectionScore } : null;
39
+ })
40
+ .filter((result) => Boolean(result));
41
+ if (!nameFilter) {
42
+ return nodesWithConnectionType
43
+ .sort((a, b) => b.connectionScore - a.connectionScore)
44
+ .slice(0, limit)
45
+ .map(({ nodeType, connectionScore }) => ({
46
+ name: nodeType.name,
47
+ displayName: nodeType.displayName,
48
+ description: nodeType.description ?? 'No description available',
49
+ inputs: nodeType.inputs,
50
+ outputs: nodeType.outputs,
51
+ score: connectionScore,
52
+ }));
53
53
  }
54
- return this.sortAndLimit(results, limit);
54
+ const nodeTypesOnly = nodesWithConnectionType.map((result) => result.nodeType);
55
+ const nameFilteredResults = (0, sublimeSearch_1.sublimeSearch)(nameFilter, nodeTypesOnly, NODE_SEARCH_KEYS);
56
+ return nameFilteredResults
57
+ .slice(0, limit)
58
+ .map(({ item, score: nameScore }) => {
59
+ const connectionResult = nodesWithConnectionType.find((result) => result.nodeType.name === item.name);
60
+ const connectionScore = connectionResult?.connectionScore ?? 0;
61
+ return {
62
+ name: item.name,
63
+ displayName: item.displayName,
64
+ description: item.description ?? 'No description available',
65
+ inputs: item.inputs,
66
+ outputs: item.outputs,
67
+ score: connectionScore + nameScore,
68
+ };
69
+ });
55
70
  }
56
71
  formatResult(result) {
57
72
  return `
@@ -62,28 +77,6 @@ class NodeSearchEngine {
62
77
  <node_outputs>${typeof result.outputs === 'object' ? JSON.stringify(result.outputs) : result.outputs}</node_outputs>
63
78
  </node>`;
64
79
  }
65
- calculateNameScore(nodeType, normalizedQuery) {
66
- let score = 0;
67
- if (nodeType.name.toLowerCase().includes(normalizedQuery)) {
68
- score += exports.SCORE_WEIGHTS.NAME_CONTAINS;
69
- }
70
- if (nodeType.displayName.toLowerCase().includes(normalizedQuery)) {
71
- score += exports.SCORE_WEIGHTS.DISPLAY_NAME_CONTAINS;
72
- }
73
- if (nodeType.description?.toLowerCase().includes(normalizedQuery)) {
74
- score += exports.SCORE_WEIGHTS.DESCRIPTION_CONTAINS;
75
- }
76
- if (nodeType.codex?.alias?.some((alias) => alias.toLowerCase().includes(normalizedQuery))) {
77
- score += exports.SCORE_WEIGHTS.ALIAS_CONTAINS;
78
- }
79
- if (nodeType.name.toLowerCase() === normalizedQuery) {
80
- score += exports.SCORE_WEIGHTS.NAME_EXACT;
81
- }
82
- if (nodeType.displayName.toLowerCase() === normalizedQuery) {
83
- score += exports.SCORE_WEIGHTS.DISPLAY_NAME_EXACT;
84
- }
85
- return score;
86
- }
87
80
  getConnectionScore(nodeType, connectionType) {
88
81
  const outputs = nodeType.outputs;
89
82
  if (Array.isArray(outputs)) {
@@ -98,19 +91,6 @@ class NodeSearchEngine {
98
91
  }
99
92
  return 0;
100
93
  }
101
- createSearchResult(nodeType, score) {
102
- return {
103
- name: nodeType.name,
104
- displayName: nodeType.displayName,
105
- description: nodeType.description ?? 'No description available',
106
- inputs: nodeType.inputs,
107
- outputs: nodeType.outputs,
108
- score,
109
- };
110
- }
111
- sortAndLimit(results, limit) {
112
- return results.sort((a, b) => b.score - a.score).slice(0, limit);
113
- }
114
94
  static isAiConnectionType(connectionType) {
115
95
  return connectionType.startsWith('ai_');
116
96
  }
@@ -1 +1 @@
1
- {"version":3,"file":"node-search-engine.js","sourceRoot":"","sources":["../../../src/tools/engines/node-search-engine.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"node-search-engine.js","sourceRoot":"","sources":["../../../src/tools/engines/node-search-engine.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,33 @@
1
+ import { z } from 'zod';
2
+ import type { BuilderToolBase } from '../utils/stream-processor';
3
+ export declare const GET_BEST_PRACTICES_TOOL: BuilderToolBase;
4
+ export declare function createGetBestPracticesTool(): {
5
+ toolName: string;
6
+ displayTitle: string;
7
+ getCustomDisplayTitle?: (values: Record<string, unknown>) => string;
8
+ tool: import("@langchain/core/tools").DynamicStructuredTool<z.ZodObject<{
9
+ techniques: z.ZodArray<z.ZodNativeEnum<{
10
+ readonly SCHEDULING: "scheduling";
11
+ readonly CHATBOT: "chatbot";
12
+ readonly FORM_INPUT: "form_input";
13
+ readonly SCRAPING_AND_RESEARCH: "scraping_and_research";
14
+ readonly MONITORING: "monitoring";
15
+ readonly ENRICHMENT: "enrichment";
16
+ readonly TRIAGE: "triage";
17
+ readonly CONTENT_GENERATION: "content_generation";
18
+ readonly DOCUMENT_PROCESSING: "document_processing";
19
+ readonly DATA_EXTRACTION: "data_extraction";
20
+ readonly DATA_ANALYSIS: "data_analysis";
21
+ readonly DATA_TRANSFORMATION: "data_transformation";
22
+ readonly NOTIFICATION: "notification";
23
+ readonly KNOWLEDGE_BASE: "knowledge_base";
24
+ readonly HUMAN_IN_THE_LOOP: "human_in_the_loop";
25
+ }>, "many">;
26
+ }, "strip", z.ZodTypeAny, {
27
+ techniques: ("scheduling" | "chatbot" | "form_input" | "scraping_and_research" | "monitoring" | "enrichment" | "triage" | "content_generation" | "document_processing" | "data_extraction" | "data_analysis" | "data_transformation" | "notification" | "knowledge_base" | "human_in_the_loop")[];
28
+ }, {
29
+ techniques: ("scheduling" | "chatbot" | "form_input" | "scraping_and_research" | "monitoring" | "enrichment" | "triage" | "content_generation" | "document_processing" | "data_extraction" | "data_analysis" | "data_transformation" | "notification" | "knowledge_base" | "human_in_the_loop")[];
30
+ }>, unknown, {
31
+ techniques: ("scheduling" | "chatbot" | "form_input" | "scraping_and_research" | "monitoring" | "enrichment" | "triage" | "content_generation" | "document_processing" | "data_extraction" | "data_analysis" | "data_transformation" | "notification" | "knowledge_base" | "human_in_the_loop")[];
32
+ }, import("@langchain/langgraph").Command<unknown>>;
33
+ };
@@ -0,0 +1,94 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.GET_BEST_PRACTICES_TOOL = void 0;
4
+ exports.createGetBestPracticesTool = createGetBestPracticesTool;
5
+ const tools_1 = require("@langchain/core/tools");
6
+ const zod_1 = require("zod");
7
+ const errors_1 = require("../errors");
8
+ const best_practices_1 = require("../tools/best-practices");
9
+ const progress_1 = require("../tools/helpers/progress");
10
+ const response_1 = require("../tools/helpers/response");
11
+ const categorization_1 = require("../types/categorization");
12
+ const getBestPracticesSchema = zod_1.z.object({
13
+ techniques: zod_1.z
14
+ .array(zod_1.z.nativeEnum(categorization_1.WorkflowTechnique))
15
+ .min(1)
16
+ .describe('List of workflow techniques to retrieve best practices for'),
17
+ });
18
+ function formatBestPractices(techniques) {
19
+ const parts = [];
20
+ const foundDocs = [];
21
+ for (const technique of techniques) {
22
+ const doc = best_practices_1.documentation[technique];
23
+ if (doc) {
24
+ foundDocs.push(doc.getDocumentation());
25
+ }
26
+ }
27
+ if (foundDocs.length > 0) {
28
+ parts.push('<best_practices>');
29
+ parts.push(foundDocs.join('\n---\n'));
30
+ parts.push('</best_practices>');
31
+ }
32
+ return parts.join('\n');
33
+ }
34
+ exports.GET_BEST_PRACTICES_TOOL = {
35
+ toolName: 'get_best_practices',
36
+ displayTitle: 'Getting best practices',
37
+ };
38
+ function createGetBestPracticesTool() {
39
+ const dynamicTool = (0, tools_1.tool)((input, config) => {
40
+ const reporter = (0, progress_1.createProgressReporter)(config, exports.GET_BEST_PRACTICES_TOOL.toolName, exports.GET_BEST_PRACTICES_TOOL.displayTitle);
41
+ try {
42
+ const validatedInput = getBestPracticesSchema.parse(input);
43
+ const { techniques } = validatedInput;
44
+ reporter.start(validatedInput);
45
+ reporter.progress(`Retrieving best practices for ${techniques.length} technique(s)...`);
46
+ const availableDocs = techniques.filter((technique) => best_practices_1.documentation[technique]);
47
+ if (availableDocs.length === 0) {
48
+ const message = `No best practices documentation available for the requested techniques: ${techniques.join(', ')}`;
49
+ reporter.complete({ techniques, found: 0 });
50
+ return (0, response_1.createSuccessResponse)(config, message);
51
+ }
52
+ const message = formatBestPractices(techniques);
53
+ reporter.complete({
54
+ techniques,
55
+ found: availableDocs.length,
56
+ missing: techniques.length - availableDocs.length,
57
+ });
58
+ return (0, response_1.createSuccessResponse)(config, message);
59
+ }
60
+ catch (error) {
61
+ if (error instanceof zod_1.z.ZodError) {
62
+ const validationError = new errors_1.ValidationError('Invalid input parameters', {
63
+ extra: { errors: error.errors },
64
+ });
65
+ reporter.error(validationError);
66
+ return (0, response_1.createErrorResponse)(config, validationError);
67
+ }
68
+ const toolError = new errors_1.ToolExecutionError(error instanceof Error ? error.message : 'Unknown error occurred', {
69
+ toolName: exports.GET_BEST_PRACTICES_TOOL.toolName,
70
+ cause: error instanceof Error ? error : undefined,
71
+ });
72
+ reporter.error(toolError);
73
+ return (0, response_1.createErrorResponse)(config, toolError);
74
+ }
75
+ }, {
76
+ name: exports.GET_BEST_PRACTICES_TOOL.toolName,
77
+ description: `Retrieve best practices documentation for specific workflow techniques.
78
+
79
+ Use this tool after categorizing a user's prompt to get relevant guidance on:
80
+ - Recommended nodes and their purposes
81
+ - Common pitfalls to avoid
82
+ - Performance and resource management tips
83
+ - Implementation patterns and best practices
84
+ - General tips on building workflows that utilise the provided techniques
85
+
86
+ This helps build better workflows by applying proven patterns and avoiding common mistakes.`,
87
+ schema: getBestPracticesSchema,
88
+ });
89
+ return {
90
+ tool: dynamicTool,
91
+ ...exports.GET_BEST_PRACTICES_TOOL,
92
+ };
93
+ }
94
+ //# sourceMappingURL=get-best-practices.tool.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"get-best-practices.tool.js","sourceRoot":"","sources":["../../src/tools/get-best-practices.tool.ts"],"names":[],"mappings":"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"}
@@ -33,24 +33,28 @@ The system's operations processor ensures state consistency across all parallel
33
33
  <workflow_creation_sequence>
34
34
  Follow this proven sequence for creating robust workflows:
35
35
 
36
- 1. **Discovery Phase** (parallel execution)
36
+ 1. **Categorization Phase** - MANDATORY
37
+ - Categorize the prompt and search for best practices documentation based on the techniques found
38
+ - Why: Best practices help to inform which nodes to search for and use to build the workflow plus mistakes to avoid
39
+
40
+ 2. **Discovery Phase** (parallel execution)
37
41
  - Search for all required node types simultaneously
38
42
  - Why: Ensures you work with actual available nodes, not assumptions
39
43
 
40
- 2. **Analysis Phase** (parallel execution)
44
+ 3. **Analysis Phase** (parallel execution)
41
45
  - Get details for ALL nodes before proceeding
42
46
  - Why: Understanding inputs/outputs prevents connection errors and ensures proper parameter configuration
43
47
 
44
- 3. **Creation Phase** (parallel execution)
48
+ 4. **Creation Phase** (parallel execution)
45
49
  - Add nodes individually by calling add_nodes for each node
46
50
  - Execute multiple add_nodes calls in parallel for efficiency
47
51
  - Why: Each node addition is independent, parallel execution is faster, and the operations processor ensures consistency
48
52
 
49
- 4. **Connection Phase** (parallel execution)
53
+ 5. **Connection Phase** (parallel execution)
50
54
  - Connect all nodes based on discovered input/output structure
51
55
  - Why: Parallel connections are safe and faster
52
56
 
53
- 5. **Configuration Phase** (parallel execution) - MANDATORY
57
+ 6. **Configuration Phase** (parallel execution) - MANDATORY
54
58
  - ALWAYS configure nodes using update_node_parameters
55
59
  - Even for "simple" nodes like HTTP Request, Set, etc.
56
60
  - Configure all nodes in parallel for efficiency
@@ -58,6 +62,23 @@ Follow this proven sequence for creating robust workflows:
58
62
  - Pay special attention to parameters that control node behavior (dataType, mode, operation)
59
63
  - Why: Unconfigured nodes will fail at runtime, defaults are unreliable
60
64
 
65
+ 6. **Validation Phase** (tool call) - MANDATORY
66
+ - Run validate_workflow after applying changes to refresh the workflow validation report
67
+ - Review <workflow_validation_report> and resolve any violations before finalizing
68
+ - Why: Ensures structural issues are surfaced early; rerun validation after major updates
69
+
70
+ <best_practices_compliance>
71
+ Enforcing best practice compliance is MANDATORY
72
+
73
+ You MUST enforce best practices even when the user doesn't explicitly request them. Best practices document CRITICAL requirements that prevent production failures.
74
+
75
+ When you retrieve best practices and see CRITICAL requirements:
76
+ 1. Identify all MUST-HAVE nodes and configurations
77
+ 2. Add them to your workflow plan
78
+ 3. Include them in the workflow even if user didn't explicitly ask
79
+ 4. Mention them in your setup response so user understands why they're there
80
+ </best_practices_compliance>
81
+
61
82
  <parallel_node_creation_example>
62
83
  Example: Creating and configuring a workflow (complete process):
63
84
 
@@ -71,6 +92,10 @@ Step 2 - Connect nodes:
71
92
  Step 3 - Configure ALL nodes in parallel (MANDATORY):
72
93
  - update_node_parameters({{ nodeId: "Fetch Data", instructions: ["Set URL to https://api.example.com/users", "Set method to GET"] }})
73
94
  - update_node_parameters({{ nodeId: "Transform Data", instructions: ["Add field status with value 'processed'", "Add field timestamp with current date"] }})
95
+
96
+ Step 4 - Validate workflow:
97
+ - validate_workflow()
98
+ - If there are validation errors or warnings, address them by returning to the appropriate phase.
74
99
  </parallel_node_creation_example>
75
100
  </workflow_creation_sequence>
76
101
 
@@ -83,6 +108,7 @@ Always determine connectionParametersReasoning before setting connectionParamete
83
108
  - Does this node have dynamic inputs/outputs?
84
109
  - Which parameters affect the connection structure?
85
110
  - What mode or operation changes the available connections?
111
+ - Are there best practices which provide recommendations for connections?
86
112
  </reasoning_first>
87
113
 
88
114
  <parameter_examples>
@@ -232,6 +258,90 @@ Configure multiple nodes in parallel:
232
258
  - update_node_parameters({{ nodeId: "documentLoader1", instructions: ["Set dataType to 'binary' for processing PDF files", "Set loader to 'pdfLoader'", "Enable splitPages option"] }})
233
259
 
234
260
  Why: Unconfigured nodes WILL fail at runtime
261
+
262
+ <system_message_configuration>
263
+ CRITICAL: For AI nodes (AI Agent, LLM Chain, Anthropic, OpenAI, etc.), you MUST separate system-level instructions from user context.
264
+
265
+ **System Message vs User Prompt:**
266
+ - **System Message** = AI's ROLE, CAPABILITIES, TASK DESCRIPTION, and BEHAVIORAL INSTRUCTIONS
267
+ - **User Message/Text** = DYNAMIC USER INPUT, CONTEXT VARIABLES, and DATA REFERENCES
268
+
269
+ **Node-specific field names:**
270
+ - AI Agent: system message goes in options.systemMessage, user context in text
271
+ - LLM Chain: system message in messages.messageValues[] with system role, user context in text
272
+ - Anthropic: system message in options.system, user context in messages.values[]
273
+ - OpenAI: system message in messages.values[] with role "system", user in messages.values[] with role "user"
274
+
275
+ **System Message** should contain:
276
+ - AI identity and role ("You are a...")
277
+ - Task description ("Your task is to...")
278
+ - Step-by-step instructions
279
+ - Behavioral guidelines
280
+ - Expected output format
281
+ - Coordination instructions
282
+
283
+ **User Message/Text** should contain:
284
+ - Dynamic data from workflow (expressions like {{ $json.field }})
285
+ - User input references ({{ $json.chatInput }})
286
+ - Context variables from previous nodes
287
+ - Minimal instruction (just what varies per execution)
288
+
289
+ **WRONG - Everything in text/user message field:**
290
+ ❌ text: "=You are an orchestrator that coordinates specialized AI tasks. Your task is to: 1) Call Research Tool 2) Call Fact-Check Tool 3) Return HTML. The research topic is: {{ $json.researchTopic }}"
291
+
292
+ **RIGHT - Properly separated:**
293
+ ✅ text: "=The research topic is: {{ $json.researchTopic }}"
294
+ ✅ System message: "You are an orchestrator that coordinates specialized AI tasks.\n\nYour task is to:\n1. Call the Research Agent Tool to gather information\n2. Call the Fact-Check Agent Tool to verify findings\n3. Call the Report Writer Agent Tool to create a report\n4. Return ONLY the final result"
295
+
296
+ **Configuration Examples:**
297
+
298
+ Example 1 - AI Agent with orchestration:
299
+ update_node_parameters({{
300
+ nodeId: "orchestratorAgent",
301
+ instructions: [
302
+ "Set text to '=The research topic is: {{ $json.researchTopic }}'",
303
+ "Set system message to 'You are an orchestrator coordinating AI tasks to research topics and generate reports.\\n\\nYour task is to:\\n1. Call the Research Agent Tool to gather information\\n2. Call the Fact-Check Agent Tool to verify findings (require 2+ sources)\\n3. Call the Report Writer Agent Tool to create a report under 1,000 words\\n4. Call the HTML Editor Agent Tool to format as HTML\\n5. Return ONLY the final HTML content'"
304
+ ]
305
+ }})
306
+
307
+ Example 2 - AI Agent Tool (sub-agent):
308
+ update_node_parameters({{
309
+ nodeId: "subAgentTool",
310
+ instructions: [
311
+ "Set text to '=Process this input: {{ $fromAI(\\'input\\') }}'",
312
+ "Set system message to 'You are a specialized assistant. Process the provided input and return the results in the requested format.'"
313
+ ]
314
+ }})
315
+
316
+ CRITICAL: AI Agent Tools MUST have BOTH system message AND text field configured:
317
+ - System message: Define the tool's role and capabilities
318
+ - Text field: Pass the context/input using $fromAI() to receive parameters from the parent agent
319
+ - Never leave text field empty - the tool needs to know what to process
320
+
321
+ Example 3 - Chat-based AI node:
322
+ update_node_parameters({{
323
+ nodeId: "chatAssistant",
324
+ instructions: [
325
+ "Set text to '=User question: {{ $json.chatInput }}'",
326
+ "Set system message to 'You are a helpful customer service assistant. Answer questions clearly and concisely. If you don\\'t know the answer, say so and offer to escalate to a human.'"
327
+ ]
328
+ }})
329
+
330
+ Example 4 - Data processing AI:
331
+ update_node_parameters({{
332
+ nodeId: "analysisNode",
333
+ instructions: [
334
+ "Set text to '=Analyze this data: {{ $json.data }}'",
335
+ "Set system message to 'You are a data analysis assistant. Examine the provided data and:\\n1. Identify key patterns and trends\\n2. Calculate relevant statistics\\n3. Highlight anomalies or outliers\\n4. Provide actionable insights\\n\\nReturn your analysis in structured JSON format.'"
336
+ ]
337
+ }})
338
+
339
+ **Why this matters:**
340
+ - Keeps AI behavior consistent (system message) while allowing dynamic context (user message)
341
+ - Makes workflows more maintainable and reusable
342
+ - Follows AI best practices for prompt engineering
343
+ - Prevents mixing static instructions with dynamic data
344
+ </system_message_configuration>
235
345
  </configuration_requirements>
236
346
 
237
347
  <data_parsing_strategy>
@@ -342,6 +452,7 @@ When modifying existing nodes:
342
452
  <handling_uncertainty>
343
453
  When unsure about specific values:
344
454
  - Add nodes and connections confidently
455
+ - investigate best practices to see if there are recommendations on how to proceed
345
456
  - For uncertain parameters, use update_node_parameters with placeholders formatted exactly as "<__PLACEHOLDER_VALUE__VALUE_LABEL__>"
346
457
  - Make VALUE_LABEL descriptive (e.g., "API endpoint URL", "Auth token header") so users know what to supply
347
458
  - For tool nodes with dynamic values, use $fromAI expressions instead of placeholders
@@ -1 +1 @@
1
- {"version":3,"file":"main-agent.prompt.js","sourceRoot":"","sources":["../../../src/tools/prompts/main-agent.prompt.ts"],"names":[],"mappings":";;;AAAA,qDAA6D;AAE7D,oEAAsE;AAEtE,MAAM,YAAY,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAwWpB,CAAC;AAEF,MAAM,gBAAgB,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAuCxB,CAAC;AAEF,MAAM,2BAA2B,GAAG;;;oBAGhB,CAAC;AAER,QAAA,eAAe,GAAG,4BAAkB,CAAC,YAAY,CAAC;IAC9D;QACC,QAAQ;QACR;YACC;gBACC,IAAI,EAAE,MAAM;gBACZ,IAAI,EAAE,YAAY;aAClB;YACD;gBACC,IAAI,EAAE,MAAM;gBACZ,IAAI,EAAE,gCAAiB;aACvB;YACD;gBACC,IAAI,EAAE,MAAM;gBACZ,IAAI,EAAE,gBAAgB;aACtB;YACD;gBACC,IAAI,EAAE,MAAM;gBACZ,IAAI,EAAE,2BAA2B;gBACjC,aAAa,EAAE,EAAE,IAAI,EAAE,WAAW,EAAE;aACpC;SACD;KACD;IACD,CAAC,aAAa,EAAE,YAAY,CAAC;CAC7B,CAAC,CAAC"}
1
+ {"version":3,"file":"main-agent.prompt.js","sourceRoot":"","sources":["../../../src/tools/prompts/main-agent.prompt.ts"],"names":[],"mappings":";;;AAAA,qDAA6D;AAE7D,oEAAsE;AAEtE,MAAM,YAAY,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAudpB,CAAC;AAEF,MAAM,gBAAgB,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAuCxB,CAAC;AAEF,MAAM,2BAA2B,GAAG;;;oBAGhB,CAAC;AAER,QAAA,eAAe,GAAG,4BAAkB,CAAC,YAAY,CAAC;IAC9D;QACC,QAAQ;QACR;YACC;gBACC,IAAI,EAAE,MAAM;gBACZ,IAAI,EAAE,YAAY;aAClB;YACD;gBACC,IAAI,EAAE,MAAM;gBACZ,IAAI,EAAE,gCAAiB;aACvB;YACD;gBACC,IAAI,EAAE,MAAM;gBACZ,IAAI,EAAE,gBAAgB;aACtB;YACD;gBACC,IAAI,EAAE,MAAM;gBACZ,IAAI,EAAE,2BAA2B;gBACjC,aAAa,EAAE,EAAE,IAAI,EAAE,WAAW,EAAE;aACpC;SACD;KACD;IACD,CAAC,aAAa,EAAE,YAAY,CAAC;CAC7B,CAAC,CAAC"}
@@ -0,0 +1,5 @@
1
+ import type { Logger } from '@n8n/backend-common';
2
+ import type { INodeTypeDescription } from 'n8n-workflow';
3
+ import type { BuilderTool, BuilderToolBase } from '../utils/stream-processor';
4
+ export declare const VALIDATE_WORKFLOW_TOOL: BuilderToolBase;
5
+ export declare function createValidateWorkflowTool(parsedNodeTypes: INodeTypeDescription[], logger?: Logger): BuilderTool;
@@ -0,0 +1,61 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.VALIDATE_WORKFLOW_TOOL = void 0;
4
+ exports.createValidateWorkflowTool = createValidateWorkflowTool;
5
+ const tools_1 = require("@langchain/core/tools");
6
+ const zod_1 = require("zod");
7
+ const programmatic_1 = require("../validation/programmatic");
8
+ const errors_1 = require("../errors");
9
+ const workflow_validation_1 = require("../utils/workflow-validation");
10
+ const progress_1 = require("./helpers/progress");
11
+ const response_1 = require("./helpers/response");
12
+ const state_1 = require("./helpers/state");
13
+ const validateWorkflowSchema = zod_1.z.object({}).strict().default({});
14
+ exports.VALIDATE_WORKFLOW_TOOL = {
15
+ toolName: 'validate_workflow',
16
+ displayTitle: 'Validating workflow',
17
+ };
18
+ function createValidateWorkflowTool(parsedNodeTypes, logger) {
19
+ const dynamicTool = (0, tools_1.tool)(async (input, config) => {
20
+ const reporter = (0, progress_1.createProgressReporter)(config, exports.VALIDATE_WORKFLOW_TOOL.toolName, exports.VALIDATE_WORKFLOW_TOOL.displayTitle);
21
+ try {
22
+ const validatedInput = validateWorkflowSchema.parse(input ?? {});
23
+ reporter.start(validatedInput);
24
+ const state = (0, state_1.getWorkflowState)();
25
+ (0, progress_1.reportProgress)(reporter, 'Running programmatic checks');
26
+ const violations = (0, programmatic_1.programmaticValidation)({
27
+ generatedWorkflow: state.workflowJSON,
28
+ }, parsedNodeTypes);
29
+ const message = (0, workflow_validation_1.formatWorkflowValidation)(violations);
30
+ reporter.complete({ message });
31
+ return (0, response_1.createSuccessResponse)(config, message, {
32
+ workflowValidation: violations,
33
+ });
34
+ }
35
+ catch (error) {
36
+ if (error instanceof zod_1.z.ZodError) {
37
+ const validationError = new errors_1.ValidationError('Invalid input parameters', {
38
+ extra: { errors: error.errors },
39
+ });
40
+ reporter.error(validationError);
41
+ return (0, response_1.createErrorResponse)(config, validationError);
42
+ }
43
+ const toolError = new errors_1.ToolExecutionError(error instanceof Error ? error.message : 'Failed to validate workflow', {
44
+ toolName: exports.VALIDATE_WORKFLOW_TOOL.toolName,
45
+ cause: error instanceof Error ? error : undefined,
46
+ });
47
+ logger?.warn('validate_workflow tool failed', { error: toolError });
48
+ reporter.error(toolError);
49
+ return (0, response_1.createErrorResponse)(config, toolError);
50
+ }
51
+ }, {
52
+ name: exports.VALIDATE_WORKFLOW_TOOL.toolName,
53
+ description: 'Run validation checks against the current workflow. Call this after making changes to ensure the workflow is valid.',
54
+ schema: validateWorkflowSchema,
55
+ });
56
+ return {
57
+ tool: dynamicTool,
58
+ ...exports.VALIDATE_WORKFLOW_TOOL,
59
+ };
60
+ }
61
+ //# sourceMappingURL=validate-workflow.tool.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validate-workflow.tool.js","sourceRoot":"","sources":["../../src/tools/validate-workflow.tool.ts"],"names":[],"mappings":";;;AAqBA,gEAoEC;AAzFD,iDAA6C;AAG7C,6BAAwB;AAGxB,4DAAmE;AAEnE,sCAAgE;AAChE,sEAAwE;AACxE,iDAA4E;AAC5E,iDAAgF;AAChF,2CAAmD;AAEnD,MAAM,sBAAsB,GAAG,OAAC,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;AAEpD,QAAA,sBAAsB,GAAoB;IACtD,QAAQ,EAAE,mBAAmB;IAC7B,YAAY,EAAE,qBAAqB;CACnC,CAAC;AAEF,SAAgB,0BAA0B,CACzC,eAAuC,EACvC,MAAe;IAEf,MAAM,WAAW,GAAG,IAAA,YAAI,EACvB,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE;QACvB,MAAM,QAAQ,GAAG,IAAA,iCAAsB,EACtC,MAAM,EACN,8BAAsB,CAAC,QAAQ,EAC/B,8BAAsB,CAAC,YAAY,CACnC,CAAC;QAEF,IAAI,CAAC;YACJ,MAAM,cAAc,GAAG,sBAAsB,CAAC,KAAK,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC;YACjE,QAAQ,CAAC,KAAK,CAAC,cAAc,CAAC,CAAC;YAE/B,MAAM,KAAK,GAAG,IAAA,wBAAgB,GAAE,CAAC;YACjC,IAAA,yBAAc,EAAC,QAAQ,EAAE,6BAA6B,CAAC,CAAC;YAExD,MAAM,UAAU,GAAG,IAAA,qCAAsB,EACxC;gBACC,iBAAiB,EAAE,KAAK,CAAC,YAAY;aACrC,EACD,eAAe,CACf,CAAC;YAEF,MAAM,OAAO,GAAG,IAAA,8CAAwB,EAAC,UAAU,CAAC,CAAC;YAErD,QAAQ,CAAC,QAAQ,CAAC,EAAE,OAAO,EAAE,CAAC,CAAC;YAE/B,OAAO,IAAA,gCAAqB,EAAC,MAAM,EAAE,OAAO,EAAE;gBAC7C,kBAAkB,EAAE,UAAU;aAC9B,CAAC,CAAC;QACJ,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YAChB,IAAI,KAAK,YAAY,OAAC,CAAC,QAAQ,EAAE,CAAC;gBACjC,MAAM,eAAe,GAAG,IAAI,wBAAe,CAAC,0BAA0B,EAAE;oBACvE,KAAK,EAAE,EAAE,MAAM,EAAE,KAAK,CAAC,MAAM,EAAE;iBAC/B,CAAC,CAAC;gBACH,QAAQ,CAAC,KAAK,CAAC,eAAe,CAAC,CAAC;gBAChC,OAAO,IAAA,8BAAmB,EAAC,MAAM,EAAE,eAAe,CAAC,CAAC;YACrD,CAAC;YAED,MAAM,SAAS,GAAG,IAAI,2BAAkB,CACvC,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,6BAA6B,EACtE;gBACC,QAAQ,EAAE,8BAAsB,CAAC,QAAQ;gBACzC,KAAK,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS;aACjD,CACD,CAAC;YAEF,MAAM,EAAE,IAAI,CAAC,+BAA+B,EAAE,EAAE,KAAK,EAAE,SAAS,EAAE,CAAC,CAAC;YAEpE,QAAQ,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC;YAC1B,OAAO,IAAA,8BAAmB,EAAC,MAAM,EAAE,SAAS,CAAC,CAAC;QAC/C,CAAC;IACF,CAAC,EACD;QACC,IAAI,EAAE,8BAAsB,CAAC,QAAQ;QACrC,WAAW,EACV,qHAAqH;QACtH,MAAM,EAAE,sBAAsB;KAC9B,CACD,CAAC;IAEF,OAAO;QACN,IAAI,EAAE,WAAW;QACjB,GAAG,8BAAsB;KACzB,CAAC;AACH,CAAC"}
@@ -0,0 +1,6 @@
1
+ import type { WorkflowTechniqueType } from './categorization';
2
+ export interface BestPracticesDocument {
3
+ readonly technique: WorkflowTechniqueType;
4
+ readonly version: string;
5
+ getDocumentation(): string;
6
+ }
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ //# sourceMappingURL=best-practices.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"best-practices.js","sourceRoot":"","sources":["../../src/types/best-practices.ts"],"names":[],"mappings":""}