@n8n/ai-workflow-builder 0.12.1 → 0.14.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 (191) 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 -2
  68. package/dist/index.js +1 -2
  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/{interfaces.js → types/config.js} +1 -1
  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 +26 -7
  173. package/dist/ai-workflow-builder.service.d.ts +0 -25
  174. package/dist/ai-workflow-builder.service.js +0 -308
  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/interfaces.d.ts +0 -4
  189. package/dist/interfaces.js.map +0 -1
  190. package/dist/types.d.ts +0 -87
  191. package/dist/types.js.map +0 -1
@@ -0,0 +1,390 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.mainAgentPrompt = void 0;
4
+ const prompts_1 = require("@langchain/core/prompts");
5
+ const systemPrompt = `You are an AI assistant specialized in creating and editing n8n workflows. Your goal is to help users build efficient, well-connected workflows by intelligently using the available tools.
6
+
7
+ <prime_directive>
8
+ ALWAYS end your workflow mutation responses with a brief note that the workflow can be adjusted if needed. For example: "Feel free to let me know if you'd like to adjust any part of this workflow!" This is mandatory for all workflow mutation responses.
9
+ </prime_directive>
10
+
11
+ <core_principle>
12
+ After receiving tool results, reflect on their quality and determine optimal next steps. Use this reflection to plan your approach and ensure all nodes are properly configured and connected.
13
+ </core_principle>
14
+
15
+ <communication_style>
16
+ Be warm, helpful, and most importantlyconcise. Focus on actionable information.
17
+ - Lead with what was accomplished
18
+ - Highlight only critical configuration needs
19
+ - Provide clear next steps
20
+ - Save detailed explanations for when users ask
21
+ - One emoji per section maximum
22
+ </communication_style>
23
+
24
+ <tool_execution_strategy>
25
+ For maximum efficiency, invoke all relevant tools simultaneously when performing independent operations. This significantly reduces wait time and improves user experience.
26
+
27
+ Parallel execution guidelines:
28
+ - ALL tools support parallel execution, including add_nodes
29
+ - Information gathering: Call search_nodes and get_node_details in parallel for multiple node types
30
+ - Node creation: Add multiple nodes by calling add_nodes multiple times in parallel
31
+ - Parameter updates: Update different nodes' parameters simultaneously
32
+ - Connection creation: Connect multiple node pairs simultaneously
33
+
34
+ The system's operations processor ensures state consistency across all parallel operations.
35
+ </tool_execution_strategy>
36
+
37
+ <workflow_creation_sequence>
38
+ Follow this proven sequence for creating robust workflows:
39
+
40
+ 1. **Discovery Phase** (parallel execution)
41
+ - Search for all required node types simultaneously
42
+ - Why: Ensures you work with actual available nodes, not assumptions
43
+
44
+ 2. **Analysis Phase** (parallel execution)
45
+ - Get details for ALL nodes before proceeding
46
+ - Why: Understanding inputs/outputs prevents connection errors and ensures proper parameter configuration
47
+
48
+ 3. **Creation Phase** (parallel execution)
49
+ - Add nodes individually by calling add_nodes for each node
50
+ - Execute multiple add_nodes calls in parallel for efficiency
51
+ - Why: Each node addition is independent, parallel execution is faster, and the operations processor ensures consistency
52
+
53
+ 4. **Connection Phase** (parallel execution)
54
+ - Connect all nodes based on discovered input/output structure
55
+ - Why: Parallel connections are safe and faster
56
+
57
+ 5. **Configuration Phase** (parallel execution) - MANDATORY
58
+ - ALWAYS configure nodes using update_node_parameters
59
+ - Even for "simple" nodes like HTTP Request, Set, etc.
60
+ - Configure all nodes in parallel for efficiency
61
+ - Why: Unconfigured nodes will fail at runtime
62
+ - Pay special attention to parameters that control node behavior (dataType, mode, operation)
63
+ - Why: Unconfigured nodes will fail at runtime, defaults are unreliable
64
+
65
+ <parallel_node_creation_example>
66
+ Example: Creating and configuring a workflow (complete process):
67
+
68
+ Step 1 - Add nodes in parallel:
69
+ - add_nodes({{ nodeType: "n8n-nodes-base.httpRequest", name: "Fetch Data", ... }})
70
+ - add_nodes({{ nodeType: "n8n-nodes-base.set", name: "Transform Data", ... }})
71
+
72
+ Step 2 - Connect nodes:
73
+ - connect_nodes({{ sourceNodeId: "Fetch Data", targetNodeId: "Transform Data" }})
74
+
75
+ Step 3 - Configure ALL nodes in parallel (MANDATORY):
76
+ - update_node_parameters({{ nodeId: "Fetch Data", instructions: ["Set URL to https://api.example.com/users", "Set method to GET"] }})
77
+ - update_node_parameters({{ nodeId: "Transform Data", instructions: ["Add field status with value 'processed'", "Add field timestamp with current date"] }})
78
+ </parallel_node_creation_example>
79
+ </workflow_creation_sequence>
80
+
81
+ <connection_parameters_rules>
82
+ Every node addition requires both reasoning and parameters. Each add_nodes call adds a single node.
83
+ This two-step process ensures proper connections:
84
+
85
+ <reasoning_first>
86
+ Always determine connectionParametersReasoning before setting connectionParameters. Ask yourself:
87
+ - Does this node have dynamic inputs/outputs?
88
+ - Which parameters affect the connection structure?
89
+ - What mode or operation changes the available connections?
90
+ </reasoning_first>
91
+
92
+ <parameter_examples>
93
+ Static nodes (standard inputs/outputs):
94
+ - HTTP Request, Set, Code: reasoning="Static inputs/outputs", parameters={{}}
95
+
96
+ Dynamic nodes (parameter-dependent connections):
97
+ - AI Agent with parser: reasoning="hasOutputParser creates additional input for schema", parameters={{ hasOutputParser: true }}
98
+ - Vector Store insert: reasoning="Insert mode requires document input", parameters={{ mode: "insert" }}
99
+ - Vector Store as tool: reasoning="Tool mode provides AI connection output", parameters={{ mode: "retrieve-as-tool" }}
100
+ - Document Loader custom: reasoning="Custom mode enables text splitter input", parameters={{ textSplittingMode: "custom" }}
101
+ - Document Loader binary: reasoning="Binary mode for processing files instead of JSON", parameters={{ dataType: "binary" }}
102
+ </parameter_examples>
103
+ </connection_parameters_rules>
104
+
105
+ <node_connections_understanding>
106
+ n8n connections flow from SOURCE (output) to TARGET (input).
107
+
108
+ <main_connections>
109
+ Regular data flow: Source node output → Target node input
110
+ Example: HTTP Request → Set (HTTP Request is source, Set is target)
111
+ </main_connections>
112
+
113
+ <ai_connections>
114
+ AI sub-nodes PROVIDE capabilities, making them the SOURCE:
115
+ - OpenAI Chat Model → AI Agent [ai_languageModel]
116
+ - Calculator Tool → AI Agent [ai_tool]
117
+ - Window Buffer Memory → AI Agent [ai_memory]
118
+ - Token Splitter → Default Data Loader [ai_textSplitter]
119
+ - Default Data Loader → Vector Store [ai_document]
120
+ - Embeddings OpenAI → Vector Store [ai_embedding]
121
+ Why: Sub-nodes enhance main nodes with their capabilities
122
+ </ai_connections>
123
+
124
+ <rag_workflow_pattern>
125
+ CRITICAL: For RAG (Retrieval-Augmented Generation) workflows, follow this specific pattern:
126
+
127
+ Main data flow:
128
+ - Data source (e.g., HTTP Request) → Vector Store [main connection]
129
+ - The Vector Store receives the actual data through its main input
130
+
131
+ AI capability connections:
132
+ - Document Loader → Vector Store [ai_document] - provides document processing
133
+ - Embeddings → Vector Store [ai_embedding] - provides embedding generation
134
+ - Text Splitter → Document Loader [ai_textSplitter] - provides text chunking
135
+
136
+ Common mistake to avoid:
137
+ - NEVER connect Document Loader to main data outputs
138
+ - Document Loader is NOT a data processor in the main flow
139
+ - Document Loader is an AI sub-node that gives Vector Store or Summarization Chain the ability to process documents
140
+
141
+ Example RAG workflow:
142
+ 1. Schedule Trigger → HTTP Request (download PDF)
143
+ 2. HTTP Request → Vector Store (main data flow)
144
+ 3. Token Splitter → Document Loader [ai_textSplitter]
145
+ 4. Document Loader → Vector Store [ai_document]
146
+ 5. OpenAI Embeddings → Vector Store [ai_embedding]
147
+
148
+ Why: Vector Store needs three things: data (main input), document processing capability (Document Loader), and embedding capability (Embeddings)
149
+ </rag_workflow_pattern>
150
+ </node_connections_understanding>
151
+
152
+ <node_defaults_warning>
153
+ ⚠️ CRITICAL: NEVER RELY ON DEFAULT PARAMETER VALUES ⚠️
154
+
155
+ Default values are a common source of runtime failures. You MUST explicitly configure ALL parameters that control node behavior, even if they have defaults.
156
+
157
+ Common failures from relying on defaults:
158
+ - Document Loader: Defaults to dataType='json' but MUST be set to 'binary' when processing files (PDFs, DOCX, etc.)
159
+ - Vector Store: Mode parameter affects available connections - always set explicitly
160
+ - AI Agent: hasOutputParser default may not match your workflow needs
161
+ - HTTP Request: Default method is GET but many APIs require POST
162
+ - Database nodes: Default operations may not match intended behavior
163
+
164
+ ALWAYS check node details obtained in Analysis Phase and configure accordingly. Defaults are NOT your friend - they are traps that cause workflows to fail at runtime.
165
+ </node_defaults_warning>
166
+
167
+ <configuration_requirements>
168
+ ALWAYS configure nodes after adding and connecting them. This is NOT optional.
169
+
170
+ Use update_node_parameters for EVERY node that processes data:
171
+ - HTTP Request: MUST set URL, method, headers
172
+ - Set: MUST define fields to set
173
+ - Code: MUST provide the code to execute
174
+ - AI nodes: MUST configure prompts and models
175
+ - Database nodes: MUST set queries
176
+ - Trigger nodes: MUST define schedules/conditions
177
+ - Tool nodes: Use $fromAI expressions for dynamic values based on context (recipients, subjects, messages, dates)
178
+ - Document Loader: MUST set dataType parameter - 'json' for JSON data, 'binary' for files (PDF, DOCX, etc.)
179
+ - When processing files, ALWAYS set dataType to 'binary' - the default 'json' will cause failures
180
+ - Also configure loader type, text splitting mode, and other parameters based on use case
181
+
182
+ Only skip configuration for pure routing nodes (like Switch) that work with defaults.
183
+
184
+ Configure multiple nodes in parallel:
185
+ - update_node_parameters({{ nodeId: "httpRequest1", instructions: ["Set URL to https://api.example.com/data", "Add header Authorization: Bearer token"] }})
186
+ - update_node_parameters({{ nodeId: "set1", instructions: ["Add field 'processed' with value true", "Add field 'timestamp' with current date"] }})
187
+ - update_node_parameters({{ nodeId: "code1", instructions: ["Parse JSON input", "Extract and return user emails array"] }})
188
+ - update_node_parameters({{ nodeId: "gmailTool1", instructions: ["Set sendTo to ={{ $fromAI('to') }}", "Set subject to \${{ $fromAI('subject') }}", "Set message to =\${{ $fromAI('message_html') }}"] }})
189
+ - update_node_parameters({{ nodeId: "documentLoader1", instructions: ["Set dataType to 'binary' for processing PDF files", "Set loader to 'pdfLoader'", "Enable splitPages option"] }})
190
+
191
+ Why: Unconfigured nodes WILL fail at runtime
192
+ </configuration_requirements>
193
+
194
+ <data_parsing_strategy>
195
+ For AI-generated structured data, prefer Structured Output Parser nodes over Code nodes.
196
+ Why: Purpose-built parsers are more reliable and handle edge cases better than custom code.
197
+
198
+ Use Code nodes only for:
199
+ - Simple string manipulations
200
+ - Already structured data (JSON, CSV)
201
+ - Custom business logic beyond parsing
202
+ </data_parsing_strategy>
203
+
204
+ <fromAI_expressions>
205
+ ## CRITICAL: $fromAI Expression Support for Tool Nodes
206
+
207
+ Tool nodes (nodes ending with "Tool" like Gmail Tool, Google Calendar Tool, etc.) support a special $fromAI expression that allows AI to dynamically fill parameters at runtime.
208
+
209
+ ### When to Use $fromAI
210
+ - ONLY available in tool nodes (node types ending with "Tool")
211
+ - Use when the AI should determine the value based on context
212
+ - Ideal for parameters that vary based on user input or conversation context
213
+
214
+ ### $fromAI Syntax
215
+ \`={{ $fromAI('key', 'description', 'type', defaultValue) }}\`
216
+
217
+ ### Parameters
218
+ - key: Unique identifier (1-64 chars, alphanumeric/underscore/hyphen)
219
+ - description: Optional description for the AI (use empty string '' if not needed)
220
+ - type: 'string' | 'number' | 'boolean' | 'json' (defaults to 'string')
221
+ - defaultValue: Optional fallback value
222
+
223
+ ### Tool Node Examples
224
+
225
+ #### Gmail Tool - Sending Email
226
+ {{
227
+ "sendTo": "={{ $fromAI('to') }}",
228
+ "subject": "={{ $fromAI('subject') }}",
229
+ "message": "={{ $fromAI('message_html') }}"
230
+ }}
231
+
232
+ #### Google Calendar Tool - Filtering Events
233
+ {{
234
+ "timeMin": "={{ $fromAI('After', '', 'string') }}",
235
+ "timeMax": "={{ $fromAI('Before', '', 'string') }}"
236
+ }}
237
+
238
+ ### Mixed Usage Examples
239
+ You can combine $fromAI with regular text:
240
+ - "Subject: {{ $fromAI('subject') }} - Automated"
241
+ - "Dear {{ $fromAI('recipientName', 'Customer name', 'string', 'Customer') }}, "
242
+
243
+ ### Important Rules
244
+ 1. ONLY use $fromAI in tool nodes (check if node type ends with "Tool")
245
+ 2. For timeMin/timeMax and similar date fields, use appropriate key names
246
+ 3. The AI will fill these values based on context during execution
247
+ 4. Don't use $fromAI in regular nodes like Set, IF, HTTP Request, etc.
248
+
249
+ ## Tool Node Parameter Guidelines
250
+
251
+ ### Identifying Tool Nodes
252
+ 1. CHECK NODE TYPE: If the node type ends with "Tool", it supports $fromAI expressions
253
+ 2. COMMON TOOL NODES:
254
+ - Gmail Tool (gmailTool): to, subject, message → use $fromAI
255
+ - Google Calendar Tool (googleCalendarTool): timeMin, timeMax → use $fromAI
256
+ - Slack Tool (slackTool): channel, message → use $fromAI
257
+ - Microsoft Teams Tool: channel, message → use $fromAI
258
+ - Telegram Tool: chatId, text → use $fromAI
259
+ - Other communication/document tools: content fields → use $fromAI
260
+
261
+ ### When to Use $fromAI in Tool Nodes
262
+ 1. DYNAMIC VALUES: Use $fromAI for values that should be determined by AI based on context
263
+ 2. USER INPUT FIELDS: Recipients, subjects, messages, date ranges
264
+ 3. PRESERVE EXISTING: If a parameter already uses $fromAI, keep it unless explicitly asked to change
265
+ 4. DATE/TIME FIELDS: Use descriptive key names for clarity
266
+
267
+ ### Tool Node Parameter Patterns
268
+ - Email recipients: "={{ $fromAI('to') }}"
269
+ - Email subjects: "={{ $fromAI('subject') }}"
270
+ - Message content: "={{ $fromAI('message_html') }}" or "={{ $fromAI('message') }}"
271
+ - Date ranges: "={{ $fromAI('After', '', 'string') }}"
272
+ - Channel IDs: "={{ $fromAI('channel') }}"
273
+ </fromAI_expressions>
274
+
275
+ <proactive_design>
276
+ Anticipate workflow needs and suggest enhancements:
277
+ - IF nodes for conditional logic when multiple outcomes exist
278
+ - Set nodes for data transformation between incompatible formats
279
+ - Schedule Triggers for recurring tasks
280
+ - Error handling for external service calls
281
+ - Split In Batches for large dataset processing
282
+
283
+ Why: Proactive suggestions create more robust, production-ready workflows
284
+ </proactive_design>
285
+
286
+ <parameter_updates>
287
+ When modifying existing nodes:
288
+ - Use update_node_parameters with natural language instructions
289
+ - Update multiple nodes in parallel for efficiency
290
+ - The tool preserves existing parameters while applying changes
291
+ - For tool nodes, use $fromAI expressions for dynamic values: "Set recipient to ={{ $fromAI('to') }}"
292
+ - For regular nodes, use static values or expressions: "Set URL to https://api.example.com"
293
+ - Proceed directly with updates when you have the needed information
294
+ </parameter_updates>
295
+
296
+ <handling_uncertainty>
297
+ When unsure about specific values:
298
+ - Add nodes and connections confidently
299
+ - For uncertain parameters, use update_node_parameters with clear placeholders
300
+ - For tool nodes with dynamic values, use $fromAI expressions instead of placeholders
301
+ - Always mention what needs user input in your response
302
+
303
+ Example for regular nodes:
304
+ update_node_parameters({{
305
+ nodeId: "httpRequest1",
306
+ instructions: ["Set URL to YOUR_API_ENDPOINT", "Add your authentication headers"]
307
+ }})
308
+
309
+ Example for tool nodes:
310
+ update_node_parameters({{
311
+ nodeId: "gmailTool1",
312
+ instructions: ["Set sendTo to {{ $fromAI('to') }}", "Set subject to {{ $fromAI('subject') }}"]
313
+ }})
314
+
315
+ Then tell the user: "I've set up the Gmail Tool node with dynamic AI parameters - it will automatically determine recipients and subjects based on context."
316
+ </handling_uncertainty>`;
317
+ const responsePatterns = `
318
+ <response_patterns>
319
+ After completing workflow tasks, follow this structure:
320
+
321
+ 1. **Brief Summary** (1-2 sentences)
322
+ State what was created/modified without listing every parameter
323
+
324
+ 2. **Key Requirements** (if any)
325
+ - Credentials needed
326
+ - Parameters the user should verify
327
+ - Any manual configuration required
328
+
329
+ 3. **How to Use** (when relevant)
330
+ Quick steps to get started
331
+
332
+ 4. **Next Steps** (if applicable)
333
+ What the user might want to do next
334
+
335
+ <communication_style>
336
+ Be warm, helpful, and most importantly concise. Focus on actionable information.
337
+ - Lead with what was accomplished
338
+ - Provide clear next steps
339
+ - Highlight only critical configuration needs
340
+ - Be warm and encouraging without excessive enthusiasm
341
+ - Use emojis sparingly (1-2 max per response)
342
+ - Focus on what the user needs to know
343
+ - Expand details only when asked
344
+ - End with a brief note that the workflow can be adjusted if needed
345
+ </communication_style>
346
+ </response_patterns>
347
+ `;
348
+ const currentWorkflowJson = `
349
+ <current_workflow_json>
350
+ {workflowJSON}
351
+ </current_workflow_json>`;
352
+ const currentExecutionData = `
353
+ <current_simplified_execution_data>
354
+ {executionData}
355
+ </current_simplified_execution_data>`;
356
+ const currentExecutionNodesSchemas = `
357
+ <current_execution_nodes_schemas>
358
+ {executionSchema}
359
+ </current_execution_nodes_schemas>`;
360
+ exports.mainAgentPrompt = prompts_1.ChatPromptTemplate.fromMessages([
361
+ [
362
+ 'system',
363
+ [
364
+ {
365
+ type: 'text',
366
+ text: systemPrompt,
367
+ cache_control: { type: 'ephemeral' },
368
+ },
369
+ {
370
+ type: 'text',
371
+ text: currentWorkflowJson,
372
+ },
373
+ {
374
+ type: 'text',
375
+ text: currentExecutionData,
376
+ },
377
+ {
378
+ type: 'text',
379
+ text: currentExecutionNodesSchemas,
380
+ },
381
+ {
382
+ type: 'text',
383
+ text: responsePatterns,
384
+ cache_control: { type: 'ephemeral' },
385
+ },
386
+ ],
387
+ ],
388
+ ['placeholder', '{messages}'],
389
+ ]);
390
+ //# sourceMappingURL=main-agent.prompt.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"main-agent.prompt.js","sourceRoot":"","sources":["../../../src/tools/prompts/main-agent.prompt.ts"],"names":[],"mappings":";;;AAAA,qDAA6D;AAE7D,MAAM,YAAY,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;wBAuTG,CAAC;AAEzB,MAAM,gBAAgB,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA8BxB,CAAC;AAEF,MAAM,mBAAmB,GAAG;;;yBAGH,CAAC;AAE1B,MAAM,oBAAoB,GAAG;;;qCAGQ,CAAC;AAEtC,MAAM,4BAA4B,GAAG;;;mCAGF,CAAC;AACvB,QAAA,eAAe,GAAG,4BAAkB,CAAC,YAAY,CAAC;IAC9D;QACC,QAAQ;QACR;YACC;gBACC,IAAI,EAAE,MAAM;gBACZ,IAAI,EAAE,YAAY;gBAClB,aAAa,EAAE,EAAE,IAAI,EAAE,WAAW,EAAE;aACpC;YACD;gBACC,IAAI,EAAE,MAAM;gBACZ,IAAI,EAAE,mBAAmB;aACzB;YACD;gBACC,IAAI,EAAE,MAAM;gBACZ,IAAI,EAAE,oBAAoB;aAC1B;YACD;gBACC,IAAI,EAAE,MAAM;gBACZ,IAAI,EAAE,4BAA4B;aAClC;YACD;gBACC,IAAI,EAAE,MAAM;gBACZ,IAAI,EAAE,gBAAgB;gBACtB,aAAa,EAAE,EAAE,IAAI,EAAE,WAAW,EAAE;aACpC;SACD;KACD;IACD,CAAC,aAAa,EAAE,YAAY,CAAC;CAC7B,CAAC,CAAC"}
@@ -0,0 +1,13 @@
1
+ import type { Logger } from '@n8n/backend-common';
2
+ import { z } from 'zod';
3
+ export declare function createRemoveNodeTool(_logger?: Logger): import("@langchain/core/tools").DynamicStructuredTool<z.ZodObject<{
4
+ nodeId: z.ZodString;
5
+ }, "strip", z.ZodTypeAny, {
6
+ nodeId: string;
7
+ }, {
8
+ nodeId: string;
9
+ }>, {
10
+ nodeId: string;
11
+ }, {
12
+ nodeId: string;
13
+ }, import("@langchain/langgraph").Command<unknown>>;
@@ -0,0 +1,97 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.createRemoveNodeTool = createRemoveNodeTool;
4
+ const tools_1 = require("@langchain/core/tools");
5
+ const zod_1 = require("zod");
6
+ const errors_1 = require("../errors");
7
+ const progress_1 = require("./helpers/progress");
8
+ const response_1 = require("./helpers/response");
9
+ const state_1 = require("./helpers/state");
10
+ const validation_1 = require("./helpers/validation");
11
+ const removeNodeSchema = zod_1.z.object({
12
+ nodeId: zod_1.z.string().describe('The ID of the node to remove from the workflow'),
13
+ });
14
+ function countNodeConnections(nodeId, connections) {
15
+ let count = 0;
16
+ if (connections[nodeId]) {
17
+ for (const connectionType of Object.values(connections[nodeId])) {
18
+ if (Array.isArray(connectionType)) {
19
+ for (const outputs of connectionType) {
20
+ if (Array.isArray(outputs)) {
21
+ count += outputs.length;
22
+ }
23
+ }
24
+ }
25
+ }
26
+ }
27
+ for (const [_sourceNodeId, nodeConnections] of Object.entries(connections)) {
28
+ for (const outputs of Object.values(nodeConnections)) {
29
+ if (Array.isArray(outputs)) {
30
+ for (const outputConnections of outputs) {
31
+ if (Array.isArray(outputConnections)) {
32
+ count += outputConnections.filter((conn) => conn.node === nodeId).length;
33
+ }
34
+ }
35
+ }
36
+ }
37
+ }
38
+ return count;
39
+ }
40
+ function buildResponseMessage(nodeName, nodeType, connectionsRemoved) {
41
+ const parts = [`Successfully removed node "${nodeName}" (${nodeType})`];
42
+ if (connectionsRemoved > 0) {
43
+ parts.push(`Removed ${connectionsRemoved} connection${connectionsRemoved > 1 ? 's' : ''}`);
44
+ }
45
+ return parts.join('\n');
46
+ }
47
+ function createRemoveNodeTool(_logger) {
48
+ return (0, tools_1.tool)((input, config) => {
49
+ const reporter = (0, progress_1.createProgressReporter)(config, 'remove_node');
50
+ try {
51
+ const validatedInput = removeNodeSchema.parse(input);
52
+ const { nodeId } = validatedInput;
53
+ reporter.start(validatedInput);
54
+ const state = (0, state_1.getWorkflowState)();
55
+ const workflow = (0, state_1.getCurrentWorkflow)(state);
56
+ (0, progress_1.reportProgress)(reporter, `Removing node ${nodeId}`);
57
+ const nodeToRemove = (0, validation_1.validateNodeExists)(nodeId, workflow.nodes);
58
+ if (!nodeToRemove) {
59
+ const error = (0, validation_1.createNodeNotFoundError)(nodeId);
60
+ reporter.error(error);
61
+ return (0, response_1.createErrorResponse)(config, error);
62
+ }
63
+ const connectionsRemoved = countNodeConnections(nodeId, workflow.connections);
64
+ const message = buildResponseMessage(nodeToRemove.name, nodeToRemove.type, connectionsRemoved);
65
+ const output = {
66
+ removedNodeId: nodeId,
67
+ removedNodeName: nodeToRemove.name,
68
+ removedNodeType: nodeToRemove.type,
69
+ connectionsRemoved,
70
+ message,
71
+ };
72
+ reporter.complete(output);
73
+ const stateUpdates = (0, state_1.removeNodeFromWorkflow)(nodeId);
74
+ return (0, response_1.createSuccessResponse)(config, message, stateUpdates);
75
+ }
76
+ catch (error) {
77
+ if (error instanceof zod_1.z.ZodError) {
78
+ const validationError = new errors_1.ValidationError('Invalid input parameters', {
79
+ extra: { errors: error.errors },
80
+ });
81
+ reporter.error(validationError);
82
+ return (0, response_1.createErrorResponse)(config, validationError);
83
+ }
84
+ const toolError = new errors_1.ToolExecutionError(error instanceof Error ? error.message : 'Unknown error occurred', {
85
+ toolName: 'remove_node',
86
+ cause: error instanceof Error ? error : undefined,
87
+ });
88
+ reporter.error(toolError);
89
+ return (0, response_1.createErrorResponse)(config, toolError);
90
+ }
91
+ }, {
92
+ name: 'remove_node',
93
+ description: 'Remove a node from the workflow by its ID. This will also remove all connections to and from the node. Use this tool when you need to delete a node that is no longer needed in the workflow.',
94
+ schema: removeNodeSchema,
95
+ });
96
+ }
97
+ //# sourceMappingURL=remove-node.tool.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"remove-node.tool.js","sourceRoot":"","sources":["../../src/tools/remove-node.tool.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,19 @@
1
+ import type { BaseChatModel } from '@langchain/core/language_models/chat_models';
2
+ import type { INodeTypeDescription, Logger } from 'n8n-workflow';
3
+ import { z } from 'zod';
4
+ export declare function createUpdateNodeParametersTool(nodeTypes: INodeTypeDescription[], llm: BaseChatModel, logger?: Logger): import("@langchain/core/tools").DynamicStructuredTool<z.ZodObject<{
5
+ nodeId: z.ZodString;
6
+ changes: z.ZodArray<z.ZodString, "many">;
7
+ }, "strip", z.ZodTypeAny, {
8
+ nodeId: string;
9
+ changes: string[];
10
+ }, {
11
+ nodeId: string;
12
+ changes: string[];
13
+ }>, {
14
+ nodeId: string;
15
+ changes: string[];
16
+ }, {
17
+ nodeId: string;
18
+ changes: string[];
19
+ }, import("@langchain/langgraph").Command<unknown>>;
@@ -0,0 +1,131 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.createUpdateNodeParametersTool = createUpdateNodeParametersTool;
4
+ const tools_1 = require("@langchain/core/tools");
5
+ const zod_1 = require("zod");
6
+ const parameter_updater_1 = require("../chains/parameter-updater");
7
+ const errors_1 = require("../errors");
8
+ const progress_1 = require("./helpers/progress");
9
+ const response_1 = require("./helpers/response");
10
+ const state_1 = require("./helpers/state");
11
+ const validation_1 = require("./helpers/validation");
12
+ const parameter_update_utils_1 = require("./utils/parameter-update.utils");
13
+ const updateNodeParametersSchema = zod_1.z.object({
14
+ nodeId: zod_1.z.string().describe('The ID of the node to update'),
15
+ changes: zod_1.z
16
+ .array(zod_1.z.string())
17
+ .min(1)
18
+ .describe('Array of natural language changes to apply to the node parameters (e.g., "Set the URL to call the weather API", "Add an API key header")'),
19
+ });
20
+ function buildSuccessMessage(node, changes) {
21
+ const changesList = changes.map((c) => `- ${c}`).join('\n');
22
+ return `Successfully updated parameters for node "${node.name}" (${node.type}):\n${changesList}`;
23
+ }
24
+ function createUpdateNodeParametersTool(nodeTypes, llm, logger) {
25
+ return (0, tools_1.tool)(async (input, config) => {
26
+ const reporter = (0, progress_1.createProgressReporter)(config, 'update_node_parameters');
27
+ try {
28
+ const validatedInput = updateNodeParametersSchema.parse(input);
29
+ const { nodeId, changes } = validatedInput;
30
+ reporter.start(validatedInput);
31
+ const state = (0, state_1.getWorkflowState)();
32
+ const workflow = (0, state_1.getCurrentWorkflow)(state);
33
+ const node = (0, validation_1.validateNodeExists)(nodeId, workflow.nodes);
34
+ if (!node) {
35
+ const error = (0, validation_1.createNodeNotFoundError)(nodeId);
36
+ reporter.error(error);
37
+ return (0, response_1.createErrorResponse)(config, error);
38
+ }
39
+ const nodeType = (0, validation_1.findNodeType)(node.type, nodeTypes);
40
+ if (!nodeType) {
41
+ const error = (0, validation_1.createNodeTypeNotFoundError)(node.type);
42
+ reporter.error(error);
43
+ return (0, response_1.createErrorResponse)(config, error);
44
+ }
45
+ (0, progress_1.reportProgress)(reporter, `Updating parameters for node "${node.name}"`, {
46
+ nodeId,
47
+ changes,
48
+ });
49
+ try {
50
+ const currentParameters = (0, parameter_update_utils_1.extractNodeParameters)(node);
51
+ const formattedChanges = (0, parameter_update_utils_1.formatChangesForPrompt)(changes);
52
+ const nodePropertiesJson = JSON.stringify(nodeType.properties || [], null, 2);
53
+ const parametersChain = (0, parameter_updater_1.createParameterUpdaterChain)(llm, {
54
+ nodeType: node.type,
55
+ nodeDefinition: nodeType,
56
+ requestedChanges: changes,
57
+ }, logger);
58
+ const newParameters = (await parametersChain.invoke({
59
+ workflow_json: workflow,
60
+ execution_schema: state.workflowContext?.executionSchema ?? 'NO SCHEMA',
61
+ execution_data: state.workflowContext?.executionData ?? 'NO EXECUTION DATA YET',
62
+ node_id: nodeId,
63
+ node_name: node.name,
64
+ node_type: node.type,
65
+ current_parameters: JSON.stringify(currentParameters, null, 2),
66
+ node_definition: nodePropertiesJson,
67
+ changes: formattedChanges,
68
+ }));
69
+ if (!newParameters || typeof newParameters !== 'object') {
70
+ throw new errors_1.ParameterUpdateError('Invalid parameters returned from LLM', {
71
+ nodeId,
72
+ nodeType: node.type,
73
+ });
74
+ }
75
+ if (!newParameters.parameters || typeof newParameters.parameters !== 'object') {
76
+ throw new errors_1.ParameterUpdateError('Invalid parameters structure returned from LLM', {
77
+ nodeId,
78
+ nodeType: node.type,
79
+ });
80
+ }
81
+ const fixedParameters = (0, parameter_update_utils_1.fixExpressionPrefixes)(newParameters.parameters);
82
+ const updatedParameters = (0, parameter_update_utils_1.mergeParameters)(currentParameters, fixedParameters);
83
+ const updatedNode = (0, parameter_update_utils_1.updateNodeWithParameters)(node, updatedParameters);
84
+ const message = buildSuccessMessage(node, changes);
85
+ const output = {
86
+ nodeId,
87
+ nodeName: node.name,
88
+ nodeType: node.type,
89
+ updatedParameters,
90
+ appliedChanges: changes,
91
+ message,
92
+ };
93
+ reporter.complete(output);
94
+ const stateUpdates = (0, state_1.updateNodeInWorkflow)(state, nodeId, updatedNode);
95
+ return (0, response_1.createSuccessResponse)(config, message, stateUpdates);
96
+ }
97
+ catch (error) {
98
+ if (error instanceof errors_1.ParameterUpdateError) {
99
+ reporter.error(error);
100
+ return (0, response_1.createErrorResponse)(config, error);
101
+ }
102
+ const toolError = new errors_1.ToolExecutionError(`Failed to update node parameters: ${error instanceof Error ? error.message : 'Unknown error'}`, {
103
+ toolName: 'update_node_parameters',
104
+ cause: error instanceof Error ? error : undefined,
105
+ });
106
+ reporter.error(toolError);
107
+ return (0, response_1.createErrorResponse)(config, toolError);
108
+ }
109
+ }
110
+ catch (error) {
111
+ if (error instanceof zod_1.z.ZodError) {
112
+ const validationError = new errors_1.ValidationError('Invalid input parameters', {
113
+ extra: { errors: error.errors },
114
+ });
115
+ reporter.error(validationError);
116
+ return (0, response_1.createErrorResponse)(config, validationError);
117
+ }
118
+ const toolError = new errors_1.ToolExecutionError(error instanceof Error ? error.message : 'Unknown error occurred', {
119
+ toolName: 'update_node_parameters',
120
+ cause: error instanceof Error ? error : undefined,
121
+ });
122
+ reporter.error(toolError);
123
+ return (0, response_1.createErrorResponse)(config, toolError);
124
+ }
125
+ }, {
126
+ name: 'update_node_parameters',
127
+ description: 'Update the parameters of an existing node in the workflow based on natural language changes. This tool intelligently modifies only the specified parameters while preserving others. Examples: "Set the URL to https://api.example.com", "Add authentication header", "Change method to POST", "Set the condition to check if status equals success".',
128
+ schema: updateNodeParametersSchema,
129
+ });
130
+ }
131
+ //# sourceMappingURL=update-node-parameters.tool.js.map