@n8n/ai-workflow-builder 0.13.0 → 0.14.1

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 (189) hide show
  1. package/dist/ai-workflow-builder-agent.service.d.ts +28 -0
  2. package/dist/ai-workflow-builder-agent.service.js +160 -0
  3. package/dist/ai-workflow-builder-agent.service.js.map +1 -0
  4. package/dist/build.tsbuildinfo +1 -1
  5. package/dist/chains/conversation-compact.d.ts +8 -0
  6. package/dist/chains/conversation-compact.js +56 -0
  7. package/dist/chains/conversation-compact.js.map +1 -0
  8. package/dist/chains/parameter-updater.d.ts +16 -0
  9. package/dist/chains/parameter-updater.js +94 -0
  10. package/dist/chains/parameter-updater.js.map +1 -0
  11. package/dist/chains/planner.js +2 -2
  12. package/dist/chains/planner.js.map +1 -1
  13. package/dist/chains/prompts/base/common-patterns.d.ts +1 -0
  14. package/dist/chains/prompts/base/common-patterns.js +13 -0
  15. package/dist/chains/prompts/base/common-patterns.js.map +1 -0
  16. package/dist/chains/prompts/base/core-instructions.d.ts +1 -0
  17. package/dist/chains/prompts/base/core-instructions.js +28 -0
  18. package/dist/chains/prompts/base/core-instructions.js.map +1 -0
  19. package/dist/chains/prompts/base/expression-rules.d.ts +1 -0
  20. package/dist/chains/prompts/base/expression-rules.js +15 -0
  21. package/dist/chains/prompts/base/expression-rules.js.map +1 -0
  22. package/dist/chains/prompts/base/output-format.d.ts +1 -0
  23. package/dist/chains/prompts/base/output-format.js +7 -0
  24. package/dist/chains/prompts/base/output-format.js.map +1 -0
  25. package/dist/chains/prompts/examples/advanced/resource-locator-examples.d.ts +1 -0
  26. package/dist/chains/prompts/examples/advanced/resource-locator-examples.js +79 -0
  27. package/dist/chains/prompts/examples/advanced/resource-locator-examples.js.map +1 -0
  28. package/dist/chains/prompts/examples/advanced/tool-node-examples.d.ts +1 -0
  29. package/dist/chains/prompts/examples/advanced/tool-node-examples.js +71 -0
  30. package/dist/chains/prompts/examples/advanced/tool-node-examples.js.map +1 -0
  31. package/dist/chains/prompts/examples/basic/if-node-examples.d.ts +1 -0
  32. package/dist/chains/prompts/examples/basic/if-node-examples.js +138 -0
  33. package/dist/chains/prompts/examples/basic/if-node-examples.js.map +1 -0
  34. package/dist/chains/prompts/examples/basic/set-node-examples.d.ts +1 -0
  35. package/dist/chains/prompts/examples/basic/set-node-examples.js +148 -0
  36. package/dist/chains/prompts/examples/basic/set-node-examples.js.map +1 -0
  37. package/dist/chains/prompts/examples/basic/simple-updates.d.ts +1 -0
  38. package/dist/chains/prompts/examples/basic/simple-updates.js +51 -0
  39. package/dist/chains/prompts/examples/basic/simple-updates.js.map +1 -0
  40. package/dist/chains/prompts/node-types/http-request.d.ts +1 -0
  41. package/dist/chains/prompts/node-types/http-request.js +113 -0
  42. package/dist/chains/prompts/node-types/http-request.js.map +1 -0
  43. package/dist/chains/prompts/node-types/if-node.d.ts +1 -0
  44. package/dist/chains/prompts/node-types/if-node.js +158 -0
  45. package/dist/chains/prompts/node-types/if-node.js.map +1 -0
  46. package/dist/chains/prompts/node-types/set-node.d.ts +1 -0
  47. package/dist/chains/prompts/node-types/set-node.js +91 -0
  48. package/dist/chains/prompts/node-types/set-node.js.map +1 -0
  49. package/dist/chains/prompts/node-types/tool-nodes.d.ts +1 -0
  50. package/dist/chains/prompts/node-types/tool-nodes.js +73 -0
  51. package/dist/chains/prompts/node-types/tool-nodes.js.map +1 -0
  52. package/dist/chains/prompts/parameter-types/resource-locator.d.ts +1 -0
  53. package/dist/chains/prompts/parameter-types/resource-locator.js +95 -0
  54. package/dist/chains/prompts/parameter-types/resource-locator.js.map +1 -0
  55. package/dist/chains/prompts/parameter-types/text-fields.d.ts +1 -0
  56. package/dist/chains/prompts/parameter-types/text-fields.js +22 -0
  57. package/dist/chains/prompts/parameter-types/text-fields.js.map +1 -0
  58. package/dist/chains/prompts/prompt-builder.d.ts +14 -0
  59. package/dist/chains/prompts/prompt-builder.js +118 -0
  60. package/dist/chains/prompts/prompt-builder.js.map +1 -0
  61. package/dist/chains/prompts/prompt-config.d.ts +5 -0
  62. package/dist/chains/prompts/prompt-config.js +52 -0
  63. package/dist/chains/prompts/prompt-config.js.map +1 -0
  64. package/dist/errors/index.d.ts +45 -0
  65. package/dist/errors/index.js +122 -0
  66. package/dist/errors/index.js.map +1 -0
  67. package/dist/index.d.ts +1 -1
  68. package/dist/index.js +1 -1
  69. package/dist/index.js.map +1 -1
  70. package/dist/llm-config.d.ts +6 -5
  71. package/dist/llm-config.js +19 -4
  72. package/dist/llm-config.js.map +1 -1
  73. package/dist/tools/add-node.tool.d.ts +56 -0
  74. package/dist/tools/add-node.tool.js +136 -0
  75. package/dist/tools/add-node.tool.js.map +1 -0
  76. package/dist/tools/connect-nodes.tool.d.ts +45 -0
  77. package/dist/tools/connect-nodes.tool.js +223 -0
  78. package/dist/tools/connect-nodes.tool.js.map +1 -0
  79. package/dist/tools/engines/node-search-engine.d.ts +25 -0
  80. package/dist/tools/engines/node-search-engine.js +121 -0
  81. package/dist/tools/engines/node-search-engine.js.map +1 -0
  82. package/dist/tools/helpers/index.d.ts +4 -0
  83. package/dist/tools/helpers/index.js +21 -0
  84. package/dist/tools/helpers/index.js.map +1 -0
  85. package/dist/tools/helpers/progress.d.ts +9 -0
  86. package/dist/tools/helpers/progress.js +114 -0
  87. package/dist/tools/helpers/progress.js.map +1 -0
  88. package/dist/tools/helpers/response.d.ts +7 -0
  89. package/dist/tools/helpers/response.js +31 -0
  90. package/dist/tools/helpers/response.js.map +1 -0
  91. package/dist/tools/helpers/state.d.ts +13 -0
  92. package/dist/tools/helpers/state.js +70 -0
  93. package/dist/tools/helpers/state.js.map +1 -0
  94. package/dist/tools/helpers/validation.d.ts +12 -0
  95. package/dist/tools/helpers/validation.js +69 -0
  96. package/dist/tools/helpers/validation.js.map +1 -0
  97. package/dist/tools/node-details.tool.d.ts +19 -0
  98. package/dist/tools/node-details.tool.js +133 -0
  99. package/dist/tools/node-details.tool.js.map +1 -0
  100. package/dist/tools/node-search.tool.d.ts +49 -0
  101. package/dist/tools/node-search.tool.js +146 -0
  102. package/dist/tools/node-search.tool.js.map +1 -0
  103. package/dist/tools/prompts/main-agent.prompt.d.ts +2 -0
  104. package/dist/tools/prompts/main-agent.prompt.js +390 -0
  105. package/dist/tools/prompts/main-agent.prompt.js.map +1 -0
  106. package/dist/tools/remove-node.tool.d.ts +13 -0
  107. package/dist/tools/remove-node.tool.js +97 -0
  108. package/dist/tools/remove-node.tool.js.map +1 -0
  109. package/dist/tools/update-node-parameters.tool.d.ts +19 -0
  110. package/dist/tools/update-node-parameters.tool.js +131 -0
  111. package/dist/tools/update-node-parameters.tool.js.map +1 -0
  112. package/dist/tools/utils/connection-parameters.utils.d.ts +8 -0
  113. package/dist/tools/utils/connection-parameters.utils.js +47 -0
  114. package/dist/tools/utils/connection-parameters.utils.js.map +1 -0
  115. package/dist/tools/utils/connection.utils.d.ts +15 -0
  116. package/dist/tools/utils/connection.utils.js +321 -0
  117. package/dist/tools/utils/connection.utils.js.map +1 -0
  118. package/dist/tools/utils/node-creation.utils.d.ts +8 -0
  119. package/dist/tools/utils/node-creation.utils.js +52 -0
  120. package/dist/tools/utils/node-creation.utils.js.map +1 -0
  121. package/dist/tools/utils/node-positioning.utils.d.ts +17 -0
  122. package/dist/tools/utils/node-positioning.utils.js +87 -0
  123. package/dist/tools/utils/node-positioning.utils.js.map +1 -0
  124. package/dist/tools/utils/parameter-update.utils.d.ts +6 -0
  125. package/dist/tools/utils/parameter-update.utils.js +75 -0
  126. package/dist/tools/utils/parameter-update.utils.js.map +1 -0
  127. package/dist/types/config.d.ts +53 -0
  128. package/dist/types/config.js +3 -0
  129. package/dist/types/config.js.map +1 -0
  130. package/dist/types/connections.d.ts +30 -0
  131. package/dist/types/connections.js +3 -0
  132. package/dist/types/connections.js.map +1 -0
  133. package/dist/types/index.d.ts +8 -0
  134. package/dist/types/index.js +25 -0
  135. package/dist/types/index.js.map +1 -0
  136. package/dist/types/messages.d.ts +38 -0
  137. package/dist/types/messages.js +3 -0
  138. package/dist/types/messages.js.map +1 -0
  139. package/dist/types/nodes.d.ts +26 -0
  140. package/dist/{types.js → types/nodes.js} +1 -1
  141. package/dist/types/nodes.js.map +1 -0
  142. package/dist/types/streaming.d.ts +33 -0
  143. package/dist/types/streaming.js +3 -0
  144. package/dist/types/streaming.js.map +1 -0
  145. package/dist/types/tools.d.ts +76 -0
  146. package/dist/types/tools.js +3 -0
  147. package/dist/types/tools.js.map +1 -0
  148. package/dist/types/utils.d.ts +2 -0
  149. package/dist/types/utils.js +3 -0
  150. package/dist/types/utils.js.map +1 -0
  151. package/dist/types/workflow.d.ts +21 -0
  152. package/dist/types/workflow.js +3 -0
  153. package/dist/types/workflow.js.map +1 -0
  154. package/dist/utils/node-helpers.d.ts +2 -0
  155. package/dist/utils/node-helpers.js +54 -0
  156. package/dist/utils/node-helpers.js.map +1 -0
  157. package/dist/utils/operations-processor.d.ts +10 -0
  158. package/dist/utils/operations-processor.js +114 -0
  159. package/dist/utils/operations-processor.js.map +1 -0
  160. package/dist/utils/stream-processor.d.ts +6 -0
  161. package/dist/utils/stream-processor.js +153 -0
  162. package/dist/utils/stream-processor.js.map +1 -0
  163. package/dist/utils/tool-executor.d.ts +3 -0
  164. package/dist/utils/tool-executor.js +86 -0
  165. package/dist/utils/tool-executor.js.map +1 -0
  166. package/dist/workflow-builder-agent.d.ts +41 -0
  167. package/dist/workflow-builder-agent.js +205 -0
  168. package/dist/workflow-builder-agent.js.map +1 -0
  169. package/dist/workflow-state.d.ts +12 -7
  170. package/dist/workflow-state.js +26 -7
  171. package/dist/workflow-state.js.map +1 -1
  172. package/package.json +24 -5
  173. package/dist/ai-workflow-builder.service.d.ts +0 -21
  174. package/dist/ai-workflow-builder.service.js +0 -294
  175. package/dist/ai-workflow-builder.service.js.map +0 -1
  176. package/dist/chains/connection-composer.d.ts +0 -10
  177. package/dist/chains/connection-composer.js +0 -135
  178. package/dist/chains/connection-composer.js.map +0 -1
  179. package/dist/chains/node-selector.d.ts +0 -8
  180. package/dist/chains/node-selector.js +0 -90
  181. package/dist/chains/node-selector.js.map +0 -1
  182. package/dist/chains/nodes-composer.d.ts +0 -8
  183. package/dist/chains/nodes-composer.js +0 -451
  184. package/dist/chains/nodes-composer.js.map +0 -1
  185. package/dist/chains/validator.d.ts +0 -2
  186. package/dist/chains/validator.js +0 -67
  187. package/dist/chains/validator.js.map +0 -1
  188. package/dist/types.d.ts +0 -87
  189. package/dist/types.js.map +0 -1
@@ -1,90 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.nodesSelectionChain = exports.nodeSelectorPrompt = void 0;
4
- const messages_1 = require("@langchain/core/messages");
5
- const prompts_1 = require("@langchain/core/prompts");
6
- const tools_1 = require("@langchain/core/tools");
7
- const n8n_workflow_1 = require("n8n-workflow");
8
- const zod_1 = require("zod");
9
- exports.nodeSelectorPrompt = new messages_1.SystemMessage(`You are an expert in n8n workflows who selects the optimal n8n nodes to implement workflow steps.
10
-
11
- ## Your Task
12
- For each workflow step, recommend the most appropriate n8n nodes from the allowed list.
13
-
14
- ## Input Information
15
- - <user_request>: Original user workflow request
16
- - <steps>: List of workflow steps to implement
17
- - <allowed_n8n_nodes>: List of available n8n nodes with descriptions
18
-
19
- ## CRITICAL REQUIREMENTS
20
- - ONLY recommend nodes that EXACTLY match names from the <allowed_n8n_nodes> list
21
- - NEVER suggest nodes that are not explicitly defined in <allowed_n8n_nodes>
22
- - ALWAYS use the COMPLETE node name as it appears in <node_name> tags (e.g., "Gmail" is NOT sufficient if the node name is "n8n-nodes-base.gmail")
23
- - VERIFY each recommended node exists in the allowed list before including it
24
-
25
- ## Selection Criteria
26
- 1. Functionality - Node must be able to perform the required action
27
- 2. Integration - Prefer nodes that integrate directly with services mentioned in the user request
28
- 3. Efficiency - Prefer nodes that accomplish the task with minimal configuration
29
-
30
- ## Output Requirements
31
- For the planned workflow steps, provider:
32
- 1. List of all possibly useful nodes in order of preference
33
- 2. Concise reasoning for why each node is suitable
34
- 3. Use EXACT, FULL node names from <node_name> tags
35
- 4. Pay attention to case sensitivity, e.g. "n8n-nodes-base.msql" is NOT "n8n-nodes-base.mySql"!
36
-
37
- Remember: ONLY use nodes from the <allowed_n8n_nodes> list and ALWAYS use their FULL names exactly as provided.`);
38
- const nodeSelectorSchema = zod_1.z.object({
39
- recommended_nodes: zod_1.z
40
- .array(zod_1.z.object({
41
- score: zod_1.z.number().describe('Matching score of the node for all the workflows steps'),
42
- node: zod_1.z
43
- .string()
44
- .describe('The full node type identifier (e.g., "n8n-nodes-base.if") from <allowed_n8n_nodes> list'),
45
- reasoning: zod_1.z
46
- .string()
47
- .describe('Very short explanation of why this node might be used to implement the workflow step'),
48
- }))
49
- .min(1)
50
- .max(20)
51
- .describe('Recommended n8n nodes for implementing any of the workflow steps, in order of descending preference. ONLY use nodes from the <allowed_n8n_nodes> list with EXACT full names from <node_name> tags.'),
52
- });
53
- const nodeSelectorTool = new tools_1.DynamicStructuredTool({
54
- name: 'select_n8n_nodes',
55
- description: 'Match each workflow step with the most appropriate n8n nodes from the allowed list, ensuring they can implement the required functionality.',
56
- schema: nodeSelectorSchema,
57
- func: async ({ recommended_nodes }) => {
58
- return { recommended_nodes };
59
- },
60
- });
61
- const humanTemplate = `
62
- <user_request>
63
- {prompt}
64
- </user_request>
65
- <steps>
66
- {steps}
67
- </steps>
68
- <allowed_n8n_nodes>
69
- {allowedNodes}
70
- </allowed_n8n_nodes>
71
- `;
72
- const chatPrompt = prompts_1.ChatPromptTemplate.fromMessages([
73
- exports.nodeSelectorPrompt,
74
- prompts_1.HumanMessagePromptTemplate.fromTemplate(humanTemplate),
75
- ]);
76
- const nodesSelectionChain = (llm) => {
77
- if (!llm.bindTools) {
78
- throw new n8n_workflow_1.OperationalError("LLM doesn't support binding tools");
79
- }
80
- return chatPrompt
81
- .pipe(llm.bindTools([nodeSelectorTool], {
82
- tool_choice: nodeSelectorTool.name,
83
- }))
84
- .pipe((x) => {
85
- const toolCall = x.tool_calls?.[0];
86
- return (toolCall?.args).recommended_nodes;
87
- });
88
- };
89
- exports.nodesSelectionChain = nodesSelectionChain;
90
- //# sourceMappingURL=node-selector.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"node-selector.js","sourceRoot":"","sources":["../../src/chains/node-selector.ts"],"names":[],"mappings":";;;AAEA,uDAAyD;AACzD,qDAAyF;AACzF,iDAA8D;AAC9D,+CAAgD;AAChD,6BAAwB;AAEX,QAAA,kBAAkB,GAAG,IAAI,wBAAa,CAClD;;;;;;;;;;;;;;;;;;;;;;;;;;;;gHA4B+G,CAC/G,CAAC;AACF,MAAM,kBAAkB,GAAG,OAAC,CAAC,MAAM,CAAC;IACnC,iBAAiB,EAAE,OAAC;SAClB,KAAK,CACL,OAAC,CAAC,MAAM,CAAC;QACR,KAAK,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,wDAAwD,CAAC;QACpF,IAAI,EAAE,OAAC;aACL,MAAM,EAAE;aACR,QAAQ,CACR,yFAAyF,CACzF;QACF,SAAS,EAAE,OAAC;aACV,MAAM,EAAE;aACR,QAAQ,CACR,sFAAsF,CACtF;KACF,CAAC,CACF;SACA,GAAG,CAAC,CAAC,CAAC;SACN,GAAG,CAAC,EAAE,CAAC;SACP,QAAQ,CACR,oMAAoM,CACpM;CACF,CAAC,CAAC;AAEH,MAAM,gBAAgB,GAAG,IAAI,6BAAqB,CAAC;IAClD,IAAI,EAAE,kBAAkB;IACxB,WAAW,EACV,6IAA6I;IAC9I,MAAM,EAAE,kBAAkB;IAC1B,IAAI,EAAE,KAAK,EAAE,EAAE,iBAAiB,EAAE,EAAE,EAAE;QACrC,OAAO,EAAE,iBAAiB,EAAE,CAAC;IAC9B,CAAC;CACD,CAAC,CAAC;AAEH,MAAM,aAAa,GAAG;;;;;;;;;;CAUrB,CAAC;AAEF,MAAM,UAAU,GAAG,4BAAkB,CAAC,YAAY,CAAC;IAClD,0BAAkB;IAClB,oCAA0B,CAAC,YAAY,CAAC,aAAa,CAAC;CACtD,CAAC,CAAC;AAEI,MAAM,mBAAmB,GAAG,CAAC,GAAkB,EAAE,EAAE;IACzD,IAAI,CAAC,GAAG,CAAC,SAAS,EAAE,CAAC;QACpB,MAAM,IAAI,+BAAgB,CAAC,mCAAmC,CAAC,CAAC;IACjE,CAAC;IAED,OAAO,UAAU;SACf,IAAI,CACJ,GAAG,CAAC,SAAS,CAAC,CAAC,gBAAgB,CAAC,EAAE;QACjC,WAAW,EAAE,gBAAgB,CAAC,IAAI;KAClC,CAAC,CACF;SACA,IAAI,CAAC,CAAC,CAAiB,EAAE,EAAE;QAC3B,MAAM,QAAQ,GAAG,CAAC,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC,CAAC;QACnC,OAAO,CAAC,QAAQ,EAAE,IAA2C,CAAA,CAAC,iBAAiB,CAAC;IACjF,CAAC,CAAC,CAAC;AACL,CAAC,CAAC;AAfW,QAAA,mBAAmB,uBAe9B"}
@@ -1,8 +0,0 @@
1
- import type { BaseChatModel } from '@langchain/core/language_models/chat_models';
2
- import { ChatPromptTemplate } from '@langchain/core/prompts';
3
- export declare const nodesComposerPrompt: ChatPromptTemplate<any, any>;
4
- export declare const nodesComposerChain: (llm: BaseChatModel) => import("@langchain/core/runnables").Runnable<any, {
5
- type: string;
6
- parameters: Record<string, any>;
7
- name: string;
8
- }[], import("@langchain/core/runnables").RunnableConfig<Record<string, any>>>;
@@ -1,451 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.nodesComposerChain = exports.nodesComposerPrompt = void 0;
4
- const messages_1 = require("@langchain/core/messages");
5
- const prompts_1 = require("@langchain/core/prompts");
6
- const tools_1 = require("@langchain/core/tools");
7
- const n8n_workflow_1 = require("n8n-workflow");
8
- const zod_1 = require("zod");
9
- const systemPrompt = new messages_1.SystemMessage(`You are an expert n8n workflow architect who creates complete node configurations for complex workflows.
10
-
11
- ## Your Task
12
- Generate fully-formed n8n node configurations with properly structured parameters for each selected node.
13
-
14
- ## Reference Information
15
- You will receive:
16
- 1. The original user workflow request
17
- 2. A list of selected n8n nodes with their descriptions and parameters
18
-
19
- ## Node Configuration Guidelines
20
- 1. CREATE PROPER STRUCTURE: Include all required fields (parameters, name, type)
21
- 2. USE DESCRIPTIVE NAMES: Each node name should clearly describe its function
22
- 3. POPULATE KEY PARAMETERS: Set values for essential parameters based on node type
23
- 4. MAINTAIN LOGICAL FLOW: Node parameters should enable proper data flow
24
- 5. FOLLOW NODE PATTERNS: Use the correct structure for each node type
25
- 6. ADD DOCUMENTATION: Include at least one sticky note, explaining the workflow. Include additional sticky notes for complex parts of the workflow.
26
-
27
- ## CRITICAL: Correctly Formatting n8n Expressions
28
- When using expressions to reference data from other nodes:
29
- - ALWAYS use the format: \`={{ $('Node Name').item.json.field }}\`
30
- - NEVER omit the equals sign before the double curly braces
31
- - ALWAYS use DOUBLE curly braces, never single
32
- - NEVER use emojis or special characters inside expressions as they will break the expression
33
- - INCORRECT: \`{ $('Node Name').item.json.field }\` (missing =, single braces)
34
- - INCORRECT: \`{{ $('Node Name').item.json.field }}\` (missing =)
35
- - INCORRECT: \`={{ $('👍 Node').item.json.field }}\` (contains emoji)
36
- - CORRECT: \`={{ $('Previous Node').item.json.field }}\`
37
-
38
- This format is essential for n8n to properly process the expression.
39
-
40
- ## IF Node Configuration (CRITICAL)
41
- The IF node allows conditional branching based on comparing values. It has two outputs:
42
- - Output 0: TRUE branch (when conditions are met)
43
- - Output 1: FALSE branch (when conditions are NOT met)
44
-
45
- ### Key Points for IF Node:
46
- 1. MATCH OPERATOR TYPE TO DATA TYPE - Use the correct operator type that matches your data:
47
- - For string values: use "type": "string" with operations like "equals", "contains", "exists"
48
- - For number values: use "type": "number" with operations like "equals", "gt", "lt"
49
- - For boolean values: use "type": "boolean" with operations like "equals", "true", "false"
50
- - For arrays: use "type": "array" with operations like "empty", "contains"
51
- - For objects: use "type": "object" with operations like "exists", "empty"
52
- - For dates: use "type": "dateTime" with operations like "before", "after"
53
-
54
- 2. USE SINGLE VALUE OPERATORS CORRECTLY:
55
- - Some operators like "exists", "notExists", "empty" don't need a right value
56
- - For these operators, include "singleValue": true in the operator object
57
- - Example: Checking if a string exists: "operator": { "type": "string", "operation": "exists", "singleValue": true }
58
-
59
- 3. USE CORRECT DATA TYPES FOR RIGHT VALUES:
60
- - Number comparisons: use actual numbers (without quotes) like 5, not "5"
61
- - Boolean comparisons: use true or false (without quotes), not "true" or "false"
62
- - String comparisons: use quoted strings like "text"
63
- - When using expressions for the right value, include the proper format: "={{ expression }}"
64
-
65
- ### IF Node Examples
66
- #### Example 1: Check if a number is greater than 5
67
- \`\`\`json
68
- {
69
- "parameters": {
70
- "conditions": {
71
- "options": {
72
- "caseSensitive": false,
73
- "leftValue": "",
74
- "typeValidation": "loose"
75
- },
76
- "conditions": [
77
- {
78
- "leftValue": "={{ $('Previous Node').item.json.amount }}",
79
- "rightValue": 5,
80
- "operator": {
81
- "type": "number",
82
- "operation": "gt"
83
- }
84
- }
85
- ],
86
- "combinator": "and"
87
- },
88
- "options": {
89
- "ignoreCase": true,
90
- "looseTypeValidation": true
91
- }
92
- }
93
- }
94
- \`\`\`
95
-
96
- #### Example 2: Check if a string exists
97
- \`\`\`json
98
- {
99
- "parameters": {
100
- "conditions": {
101
- "options": {
102
- "caseSensitive": false,
103
- "leftValue": "",
104
- "typeValidation": "loose"
105
- },
106
- "conditions": [
107
- {
108
- "leftValue": "={{ $('Previous Node').item.json.email }}",
109
- "rightValue": "",
110
- "operator": {
111
- "type": "string",
112
- "operation": "exists",
113
- "singleValue": true
114
- }
115
- }
116
- ],
117
- "combinator": "and"
118
- },
119
- "options": {
120
- "ignoreCase": true,
121
- "looseTypeValidation": true
122
- }
123
- }
124
- }
125
- \`\`\`
126
-
127
- #### Example 3: Check if a boolean is true
128
- \`\`\`json
129
- {
130
- "parameters": {
131
- "conditions": {
132
- "options": {
133
- "caseSensitive": false,
134
- "leftValue": "",
135
- "typeValidation": "loose"
136
- },
137
- "conditions": [
138
- {
139
- "leftValue": "={{ $('Previous Node').item.json.isActive }}",
140
- "rightValue": "",
141
- "operator": {
142
- "type": "boolean",
143
- "operation": "true",
144
- "singleValue": true
145
- }
146
- }
147
- ],
148
- "combinator": "and"
149
- },
150
- "options": {
151
- "ignoreCase": true,
152
- "looseTypeValidation": true
153
- }
154
- }
155
- }
156
- \`\`\`
157
-
158
- #### Example 4: Compare string value
159
- \`\`\`json
160
- {
161
- "parameters": {
162
- "conditions": {
163
- "options": {
164
- "caseSensitive": false,
165
- "leftValue": "",
166
- "typeValidation": "loose"
167
- },
168
- "conditions": [
169
- {
170
- "leftValue": "={{ $('Previous Node').item.json.status }}",
171
- "rightValue": "active",
172
- "operator": {
173
- "type": "string",
174
- "operation": "equals"
175
- }
176
- }
177
- ],
178
- "combinator": "and"
179
- },
180
- "options": {
181
- "ignoreCase": true,
182
- "looseTypeValidation": true
183
- }
184
- }
185
- }
186
- \`\`\`
187
-
188
- #### Example 5: Compare boolean value
189
- \`\`\`json
190
- {
191
- "parameters": {
192
- "conditions": {
193
- "options": {
194
- "caseSensitive": false,
195
- "leftValue": "",
196
- "typeValidation": "loose"
197
- },
198
- "conditions": [
199
- {
200
- "leftValue": "={{ $('Previous Node').item.json.isVerified }}",
201
- "rightValue": true,
202
- "operator": {
203
- "type": "boolean",
204
- "operation": "equals"
205
- }
206
- }
207
- ],
208
- "combinator": "and"
209
- },
210
- "options": {
211
- "ignoreCase": true,
212
- "looseTypeValidation": true
213
- }
214
- }
215
- }
216
- \`\`\`
217
-
218
- ### Common Operator Types and Operations
219
-
220
- #### String Operators:
221
- - "exists", "notExists", "empty", "notEmpty" (use with "singleValue": true)
222
- - "equals", "notEquals", "contains", "notContains", "startsWith", "endsWith", "regex"
223
-
224
- #### Number Operators:
225
- - "exists", "notExists" (use with "singleValue": true)
226
- - "equals", "notEquals", "gt" (greater than), "lt" (less than), "gte" (greater than or equal), "lte" (less than or equal)
227
-
228
- #### Boolean Operators:
229
- - "exists", "notExists" (use with "singleValue": true)
230
- - "true", "false" (use with "singleValue": true)
231
- - "equals", "notEquals"
232
-
233
- #### Array Operators:
234
- - "exists", "notExists", "empty", "notEmpty" (use with "singleValue": true)
235
- - "contains", "notContains", "lengthEquals", "lengthNotEquals"
236
-
237
- ## Other Important Node Structures
238
-
239
- ### Set Node Structure
240
- \`\`\`json
241
- {
242
- "parameters": {
243
- "assignments": {
244
- "assignments": [
245
- {
246
- "id": "unique-id-1",
247
- "name": "property_name_1",
248
- "value": "property_value_1",
249
- "type": "string"
250
- }
251
- ]
252
- },
253
- "options": {}
254
- }
255
- }
256
- \`\`\`
257
-
258
- ### HTTP Request Node Structures
259
-
260
- #### GET Request
261
- \`\`\`json
262
- {
263
- "parameters": {
264
- "url": "https://example.com",
265
- "sendHeaders": true,
266
- "headerParameters": {
267
- "parameters": [
268
- {
269
- "name": "header-name",
270
- "value": "header-value"
271
- }
272
- ]
273
- },
274
- "options": {}
275
- }
276
- }
277
- \`\`\`
278
-
279
- #### POST Request
280
- \`\`\`json
281
- {
282
- "parameters": {
283
- "method": "POST",
284
- "url": "https://example.com",
285
- "sendHeaders": true,
286
- "headerParameters": {
287
- "parameters": [
288
- {
289
- "name": "header-name",
290
- "value": "header-value"
291
- }
292
- ]
293
- },
294
- "sendBody": true,
295
- "bodyParameters": {
296
- "parameters": [
297
- {
298
- "name": "field-name",
299
- "value": "field-value"
300
- }
301
- ]
302
- },
303
- "options": {}
304
- }
305
- }
306
- \`\`\`
307
-
308
- ### Sticky Note Structure
309
- \`\`\`json
310
- {
311
- "parameters": {
312
- "content": "Note content here"
313
- },
314
- "name": "Descriptive Name",
315
- "type": "n8n-nodes-base.stickyNote",
316
- "notes": true
317
- }
318
- \`\`\`
319
-
320
- ## Expression Examples
321
- 1. Reference a field from another node:
322
- \`\`\`
323
- "value": "={{ $('Previous Node').item.json.fieldName }}"
324
- \`\`\`
325
-
326
- 2. Use an expression with string concatenation:
327
- \`\`\`
328
- "value": "={{ 'Hello ' + $('User Input').item.json.name }}"
329
- \`\`\`
330
-
331
- 3. Access an array item:
332
- \`\`\`
333
- "value": "={{ $('Data Node').item.json.items[0].id }}"
334
- \`\`\`
335
-
336
- 4. IMPORTANT: How to properly format text fields with expressions
337
-
338
- ### PREFERRED METHOD: Embedding expressions directly within text
339
- \`\`\`
340
- "text": "=ALERT: It is currently raining in {{ $('Weather Node').item.json.city }}! Temperature: {{ $('Weather Node').item.json.main.temp }}°C"
341
- \`\`\`
342
-
343
- ### Alternative method: Using string concatenation (use only when needed for complex operations)
344
- \`\`\`
345
- "text": "={{ 'ALERT: It is currently raining in ' + $('Weather Node').item.json.city + '! Temperature: ' + $('Weather Node').item.json.temp + '°C' }}"
346
- \`\`\`
347
-
348
- ## CRITICAL: Formatting Text Fields with Expressions
349
-
350
- ### KEY RULES FOR THE PREFERRED METHOD (Embedding expressions in text):
351
- - Start the string with just "=" (not "={{")
352
- - Place each expression inside {{ }} without the = prefix
353
- - MOST READABLE and RECOMMENDED approach
354
- - Example: "text": "=Status: {{ $('Node').item.json.status }} at {{ $('Node').item.json.time }}"
355
-
356
- ### KEY RULES FOR THE ALTERNATIVE METHOD (String concatenation):
357
- - Only use when you need complex operations not possible with embedded expressions
358
- - Enclose the entire text in a single expression with "={{ }}"
359
- - Put all static text in quotes and connect with + operators
360
- - Example: "text": "={{ 'Status: ' + $('Node').item.json.status + ' at ' + $('Node').item.json.time }}"
361
-
362
- ### EXAMPLES OF PREFERRED USAGE:
363
-
364
- 1. Slack message (PREFERRED):
365
- \`\`\`json
366
- "text": "=ALERT: It is currently raining in {{ $('Weather Node').item.json.city }}! Temperature: {{ $('Weather Node').item.json.main.temp }}°C"
367
- \`\`\`
368
-
369
- 2. Email subject (PREFERRED):
370
- \`\`\`json
371
- "subject": "=Order #{{ $('Order Node').item.json.orderId }} Status Update"
372
- \`\`\`
373
-
374
- 3. Image prompt (PREFERRED):
375
- \`\`\`json
376
- "prompt": "=Create an image of {{ $('Location Node').item.json.city }} during {{ $('Weather Node').item.json.weather[0].description }}"
377
- \`\`\`
378
-
379
- 4. Slack message with multiple data points (PREFERRED):
380
- \`\`\`json
381
- "text": "=Customer {{ $('Customer Data').item.json.name }} has placed order #{{ $('Order Data').item.json.id }} for {{ $('Order Data').item.json.amount }}€"
382
- \`\`\`
383
-
384
- 5. HTTP request URL (PREFERRED):
385
- \`\`\`json
386
- "url": "=https://api.example.com/users/{{ $('User Data').item.json.id }}/orders?status={{ $('Filter').item.json.status }}"
387
- \`\`\`
388
-
389
- ### COMMON MISTAKES TO AVOID:
390
- - INCORRECT: "text": "ALERT: Temperature is {{ $('Weather Node').item.json.temp }}°C" (missing = prefix)
391
- - INCORRECT: "text": "={{ $('Weather Node').item.json.temp }}" (using expression for dynamic part only)
392
- - INCORRECT: "text": "={{ $('⚠️ Weather').item.json.temp }}" (emoji in node name)
393
- - INCORRECT: "text": "={{ 'ALERT' }} {{ $('Weather').item.json.city }}" (mixing methods)
394
-
395
- ## Output Format
396
- Return valid JSON that can be consumed by the n8n platform. Your response must match the tool's required schema.`);
397
- const humanTemplate = `
398
- <user_workflow_prompt>
399
- {user_workflow_prompt}
400
- </user_workflow_prompt>
401
- <selected_n8n_nodes>
402
- {nodes}
403
- </selected_n8n_nodes>
404
- `;
405
- exports.nodesComposerPrompt = prompts_1.ChatPromptTemplate.fromMessages([
406
- systemPrompt,
407
- prompts_1.HumanMessagePromptTemplate.fromTemplate(humanTemplate),
408
- ]);
409
- const nodeConfigSchema = zod_1.z.object({
410
- nodes: zod_1.z
411
- .array(zod_1.z
412
- .object({
413
- parameters: zod_1.z
414
- .record(zod_1.z.string(), zod_1.z.any())
415
- .describe("The node's configuration parameters. Must include all required parameters for the node type to function properly. For expressions referencing other nodes, use the format: \"={{ $('Node Name').item.json.field }}\"")
416
- .refine((data) => Object.keys(data).length > 0, {
417
- message: 'Parameters cannot be empty',
418
- }),
419
- type: zod_1.z
420
- .string()
421
- .describe('The full node type identifier (e.g., "n8n-nodes-base.httpRequest")'),
422
- name: zod_1.z
423
- .string()
424
- .describe('A descriptive name for the node that clearly indicates its purpose in the workflow'),
425
- })
426
- .describe('A complete n8n node configuration'))
427
- .describe('Array of all nodes for the workflow with their complete configurations'),
428
- });
429
- const generateNodeConfigTool = new tools_1.DynamicStructuredTool({
430
- name: 'generate_n8n_nodes',
431
- description: 'Generate fully configured n8n nodes with appropriate parameters based on the workflow requirements and selected node types.',
432
- schema: nodeConfigSchema,
433
- func: async (input) => {
434
- return { nodes: input.nodes };
435
- },
436
- });
437
- const nodesComposerChain = (llm) => {
438
- if (!llm.bindTools) {
439
- throw new n8n_workflow_1.OperationalError("LLM doesn't support binding tools");
440
- }
441
- return exports.nodesComposerPrompt
442
- .pipe(llm.bindTools([generateNodeConfigTool], {
443
- tool_choice: generateNodeConfigTool.name,
444
- }))
445
- .pipe((x) => {
446
- const toolCall = x.tool_calls?.[0];
447
- return (toolCall?.args).nodes;
448
- });
449
- };
450
- exports.nodesComposerChain = nodesComposerChain;
451
- //# sourceMappingURL=nodes-composer.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"nodes-composer.js","sourceRoot":"","sources":["../../src/chains/nodes-composer.ts"],"names":[],"mappings":";;;AAEA,uDAAyD;AACzD,qDAAyF;AACzF,iDAA8D;AAC9D,+CAAgD;AAChD,6BAAwB;AAIxB,MAAM,YAAY,GAAG,IAAI,wBAAa,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iHAmY0E,CAAC,CAAC;AAEnH,MAAM,aAAa,GAAG;;;;;;;CAOrB,CAAC;AAEW,QAAA,mBAAmB,GAAG,4BAAkB,CAAC,YAAY,CAAC;IAClE,YAAY;IACZ,oCAA0B,CAAC,YAAY,CAAC,aAAa,CAAC;CACtD,CAAC,CAAC;AAEH,MAAM,gBAAgB,GAAG,OAAC,CAAC,MAAM,CAAC;IACjC,KAAK,EAAE,OAAC;SACN,KAAK,CACL,OAAC;SACC,MAAM,CAAC;QACP,UAAU,EAAE,OAAC;aACX,MAAM,CAAC,OAAC,CAAC,MAAM,EAAE,EAAE,OAAC,CAAC,GAAG,EAAE,CAAC;aAC3B,QAAQ,CACR,sNAAsN,CACtN;aACA,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,MAAM,GAAG,CAAC,EAAE;YAC/C,OAAO,EAAE,4BAA4B;SACrC,CAAC;QACH,IAAI,EAAE,OAAC;aACL,MAAM,EAAE;aACR,QAAQ,CAAC,oEAAoE,CAAC;QAChF,IAAI,EAAE,OAAC;aACL,MAAM,EAAE;aACR,QAAQ,CACR,oFAAoF,CACpF;KACF,CAAC;SACD,QAAQ,CAAC,mCAAmC,CAAC,CAC/C;SACA,QAAQ,CAAC,wEAAwE,CAAC;CACpF,CAAC,CAAC;AAEH,MAAM,sBAAsB,GAAG,IAAI,6BAAqB,CAAC;IACxD,IAAI,EAAE,oBAAoB;IAC1B,WAAW,EACV,6HAA6H;IAC9H,MAAM,EAAE,gBAAgB;IACxB,IAAI,EAAE,KAAK,EAAE,KAAK,EAAE,EAAE;QACrB,OAAO,EAAE,KAAK,EAAE,KAAK,CAAC,KAAK,EAAE,CAAC;IAC/B,CAAC;CACD,CAAC,CAAC;AAEI,MAAM,kBAAkB,GAAG,CAAC,GAAkB,EAAE,EAAE;IACxD,IAAI,CAAC,GAAG,CAAC,SAAS,EAAE,CAAC;QACpB,MAAM,IAAI,+BAAgB,CAAC,mCAAmC,CAAC,CAAC;IACjE,CAAC;IAED,OAAO,2BAAmB;SACxB,IAAI,CACJ,GAAG,CAAC,SAAS,CAAC,CAAC,sBAAsB,CAAC,EAAE;QACvC,WAAW,EAAE,sBAAsB,CAAC,IAAI;KACxC,CAAC,CACF;SACA,IAAI,CAAC,CAAC,CAAiB,EAAE,EAAE;QAC3B,MAAM,QAAQ,GAAG,CAAC,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC,CAAC;QACnC,OAAO,CAAC,QAAQ,EAAE,IAAyC,CAAA,CAAC,KAAK,CAAC;IACnE,CAAC,CAAC,CAAC;AACL,CAAC,CAAC;AAfW,QAAA,kBAAkB,sBAe7B"}
@@ -1,2 +0,0 @@
1
- import type { BaseChatModel } from '@langchain/core/language_models/chat_models';
2
- export declare const validatorChain: (llm: BaseChatModel) => import("@langchain/core/runnables").Runnable<any, boolean, import("@langchain/core/runnables").RunnableConfig<Record<string, any>>>;
@@ -1,67 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.validatorChain = void 0;
4
- const messages_1 = require("@langchain/core/messages");
5
- const prompts_1 = require("@langchain/core/prompts");
6
- const tools_1 = require("@langchain/core/tools");
7
- const n8n_workflow_1 = require("n8n-workflow");
8
- const zod_1 = require("zod");
9
- const validatorPrompt = new messages_1.SystemMessage(`You are a workflow prompt validator for n8n. You need to analyze the user's prompt and determine
10
- if they're actually trying to build a workflow that connects different online services or automates a task.
11
-
12
- A workflow prompt should:
13
- - Describe an automation or integration task
14
- - Potentially mention connecting services (like Google Sheets, Slack, etc.)
15
- - Describe a process that could be broken down into steps
16
- - Mention something that could be automated
17
-
18
- Examples of VALID workflow prompts:
19
- - "Create a workflow that sends a Slack message when a new row is added to Google Sheets"
20
- - "I want to automatically save Gmail attachments to Dropbox"
21
- - "Build a workflow that posts new Twitter mentions to a Discord channel"
22
- - "When I get a new lead in my CRM, add them to my email marketing list"
23
-
24
- Examples of INVALID workflow prompts:
25
- - "What's the weather like today?"
26
- - "Tell me a joke"
27
- - "What is n8n?"
28
- - "Help me fix my computer"
29
- - "What time is it?"
30
-
31
-
32
- Analyze the prompt and determine if it's a valid workflow prompt. Respond with just true or false.`);
33
- const validatorSchema = zod_1.z.object({
34
- isWorkflowPrompt: zod_1.z.boolean(),
35
- });
36
- const validatorTool = new tools_1.DynamicStructuredTool({
37
- name: 'validate_prompt',
38
- description: 'Validate if the user prompt is a workflow prompt',
39
- schema: validatorSchema,
40
- func: async ({ isWorkflowPrompt }) => {
41
- return { isWorkflowPrompt };
42
- },
43
- });
44
- const humanTemplate = `
45
- <user_prompt>
46
- {prompt}
47
- </user_prompt>
48
- `;
49
- const chatPrompt = prompts_1.ChatPromptTemplate.fromMessages([
50
- validatorPrompt,
51
- prompts_1.HumanMessagePromptTemplate.fromTemplate(humanTemplate),
52
- ]);
53
- const validatorChain = (llm) => {
54
- if (!llm.bindTools) {
55
- throw new n8n_workflow_1.OperationalError("LLM doesn't support binding tools");
56
- }
57
- return chatPrompt
58
- .pipe(llm.bindTools([validatorTool], {
59
- tool_choice: validatorTool.name,
60
- }))
61
- .pipe((x) => {
62
- const toolCall = x.tool_calls?.[0];
63
- return (toolCall?.args).isWorkflowPrompt;
64
- });
65
- };
66
- exports.validatorChain = validatorChain;
67
- //# sourceMappingURL=validator.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"validator.js","sourceRoot":"","sources":["../../src/chains/validator.ts"],"names":[],"mappings":";;;AAEA,uDAAyD;AACzD,qDAAyF;AACzF,iDAA8D;AAC9D,+CAAgD;AAChD,6BAAwB;AAExB,MAAM,eAAe,GAAG,IAAI,wBAAa,CACxC;;;;;;;;;;;;;;;;;;;;;;;mGAuBkG,CAClG,CAAC;AAEF,MAAM,eAAe,GAAG,OAAC,CAAC,MAAM,CAAC;IAChC,gBAAgB,EAAE,OAAC,CAAC,OAAO,EAAE;CAC7B,CAAC,CAAC;AAEH,MAAM,aAAa,GAAG,IAAI,6BAAqB,CAAC;IAC/C,IAAI,EAAE,iBAAiB;IACvB,WAAW,EAAE,kDAAkD;IAC/D,MAAM,EAAE,eAAe;IACvB,IAAI,EAAE,KAAK,EAAE,EAAE,gBAAgB,EAAE,EAAE,EAAE;QACpC,OAAO,EAAE,gBAAgB,EAAE,CAAC;IAC7B,CAAC;CACD,CAAC,CAAC;AAEH,MAAM,aAAa,GAAG;;;;CAIrB,CAAC;AAEF,MAAM,UAAU,GAAG,4BAAkB,CAAC,YAAY,CAAC;IAClD,eAAe;IACf,oCAA0B,CAAC,YAAY,CAAC,aAAa,CAAC;CACtD,CAAC,CAAC;AAEI,MAAM,cAAc,GAAG,CAAC,GAAkB,EAAE,EAAE;IACpD,IAAI,CAAC,GAAG,CAAC,SAAS,EAAE,CAAC;QACpB,MAAM,IAAI,+BAAgB,CAAC,mCAAmC,CAAC,CAAC;IACjE,CAAC;IAED,OAAO,UAAU;SACf,IAAI,CACJ,GAAG,CAAC,SAAS,CAAC,CAAC,aAAa,CAAC,EAAE;QAC9B,WAAW,EAAE,aAAa,CAAC,IAAI;KAC/B,CAAC,CACF;SACA,IAAI,CAAC,CAAC,CAAiB,EAAE,EAAE;QAC3B,MAAM,QAAQ,GAAG,CAAC,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC,CAAC;QACnC,OAAO,CAAC,QAAQ,EAAE,IAA6C,CAAA,CAAC,gBAAgB,CAAC;IAClF,CAAC,CAAC,CAAC;AACL,CAAC,CAAC;AAfW,QAAA,cAAc,kBAezB"}