@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.
- package/dist/build.tsbuildinfo +1 -1
- package/dist/chains/prompt-categorization.d.ts +3 -0
- package/dist/chains/prompt-categorization.js +109 -0
- package/dist/chains/prompt-categorization.js.map +1 -0
- package/dist/chains/prompts/parameter-types/system-message.d.ts +1 -0
- package/dist/chains/prompts/parameter-types/system-message.js +75 -0
- package/dist/chains/prompts/parameter-types/system-message.js.map +1 -0
- package/dist/chains/prompts/prompt-builder.d.ts +1 -0
- package/dist/chains/prompts/prompt-builder.js +23 -1
- package/dist/chains/prompts/prompt-builder.js.map +1 -1
- package/dist/chains/test/integration/test-helpers.d.ts +3 -0
- package/dist/chains/test/integration/test-helpers.js +16 -0
- package/dist/chains/test/integration/test-helpers.js.map +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +3 -0
- package/dist/index.js.map +1 -1
- package/dist/tools/best-practices/chatbot.d.ts +7 -0
- package/dist/tools/best-practices/chatbot.js +118 -0
- package/dist/tools/best-practices/chatbot.js.map +1 -0
- package/dist/tools/best-practices/content-generation.d.ts +7 -0
- package/dist/tools/best-practices/content-generation.js +79 -0
- package/dist/tools/best-practices/content-generation.js.map +1 -0
- package/dist/tools/best-practices/data-extraction.d.ts +7 -0
- package/dist/tools/best-practices/data-extraction.js +105 -0
- package/dist/tools/best-practices/data-extraction.js.map +1 -0
- package/dist/tools/best-practices/form-input.d.ts +7 -0
- package/dist/tools/best-practices/form-input.js +173 -0
- package/dist/tools/best-practices/form-input.js.map +1 -0
- package/dist/tools/best-practices/index.d.ts +3 -0
- package/dist/tools/best-practices/index.js +27 -0
- package/dist/tools/best-practices/index.js.map +1 -0
- package/dist/tools/best-practices/scraping-and-research.d.ts +7 -0
- package/dist/tools/best-practices/scraping-and-research.js +147 -0
- package/dist/tools/best-practices/scraping-and-research.js.map +1 -0
- package/dist/tools/builder-tools.js +9 -0
- package/dist/tools/builder-tools.js.map +1 -1
- package/dist/tools/categorize-prompt.tool.d.ts +5 -0
- package/dist/tools/categorize-prompt.tool.js +84 -0
- package/dist/tools/categorize-prompt.tool.js.map +1 -0
- package/dist/tools/engines/node-search-engine.d.ts +0 -9
- package/dist/tools/engines/node-search-engine.js +52 -72
- package/dist/tools/engines/node-search-engine.js.map +1 -1
- package/dist/tools/get-best-practices.tool.d.ts +33 -0
- package/dist/tools/get-best-practices.tool.js +94 -0
- package/dist/tools/get-best-practices.tool.js.map +1 -0
- package/dist/tools/prompts/main-agent.prompt.js +116 -5
- package/dist/tools/prompts/main-agent.prompt.js.map +1 -1
- package/dist/tools/validate-workflow.tool.d.ts +5 -0
- package/dist/tools/validate-workflow.tool.js +61 -0
- package/dist/tools/validate-workflow.tool.js.map +1 -0
- package/dist/types/best-practices.d.ts +6 -0
- package/dist/types/best-practices.js +3 -0
- package/dist/types/best-practices.js.map +1 -0
- package/dist/types/categorization.d.ts +23 -0
- package/dist/types/categorization.js +38 -0
- package/dist/types/categorization.js.map +1 -0
- package/dist/types/index.d.ts +2 -0
- package/dist/types/tools.d.ts +4 -0
- package/dist/utils/operations-processor.d.ts +2 -0
- package/dist/utils/operations-processor.js +1 -0
- package/dist/utils/operations-processor.js.map +1 -1
- package/dist/utils/stream-processor.d.ts +1 -0
- package/dist/utils/stream-processor.js +99 -59
- package/dist/utils/stream-processor.js.map +1 -1
- package/dist/utils/workflow-validation.d.ts +2 -0
- package/dist/utils/workflow-validation.js +36 -0
- package/dist/utils/workflow-validation.js.map +1 -0
- package/dist/validation/checks/agent-prompt.d.ts +3 -0
- package/dist/validation/checks/agent-prompt.js +45 -0
- package/dist/validation/checks/agent-prompt.js.map +1 -0
- package/dist/validation/checks/connections.d.ts +4 -0
- package/dist/validation/checks/connections.js +162 -0
- package/dist/validation/checks/connections.js.map +1 -0
- package/dist/validation/checks/from-ai.d.ts +4 -0
- package/dist/validation/checks/from-ai.js +59 -0
- package/dist/validation/checks/from-ai.js.map +1 -0
- package/dist/validation/checks/index.d.ts +5 -0
- package/dist/validation/checks/index.js +14 -0
- package/dist/validation/checks/index.js.map +1 -0
- package/dist/validation/checks/tools.d.ts +4 -0
- package/dist/validation/checks/tools.js +44 -0
- package/dist/validation/checks/tools.js.map +1 -0
- package/dist/validation/checks/trigger.d.ts +8 -0
- package/dist/validation/checks/trigger.js +35 -0
- package/dist/validation/checks/trigger.js.map +1 -0
- package/dist/validation/programmatic.d.ts +3 -0
- package/dist/validation/programmatic.js +20 -0
- package/dist/validation/programmatic.js.map +1 -0
- package/dist/validation/types.d.ts +41 -0
- package/dist/validation/types.js +3 -0
- package/dist/validation/types.js.map +1 -0
- package/dist/validation/utils/expressions.d.ts +3 -0
- package/dist/validation/utils/expressions.js +37 -0
- package/dist/validation/utils/expressions.js.map +1 -0
- package/dist/validation/utils/is-tool.d.ts +2 -0
- package/dist/validation/utils/is-tool.js +7 -0
- package/dist/validation/utils/is-tool.js.map +1 -0
- package/dist/validation/utils/resolve-connections.d.ts +8 -0
- package/dist/validation/utils/resolve-connections.js +64 -0
- package/dist/validation/utils/resolve-connections.js.map +1 -0
- package/dist/workflow-builder-agent.d.ts +2 -0
- package/dist/workflow-builder-agent.js +28 -25
- package/dist/workflow-builder-agent.js.map +1 -1
- package/dist/workflow-state.d.ts +3 -1
- package/dist/workflow-state.js +4 -0
- package/dist/workflow-state.js.map +1 -1
- 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
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
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
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
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
|
-
|
|
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":";;;
|
|
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":";;;AAgDA,gEA4EC;AA5HD,iDAA6C;AAC7C,6BAAwB;AAExB,qCAA+D;AAC/D,2DAAuD;AACvD,uDAAkE;AAClE,uDAAsF;AACtF,2DAAuF;AAGvF,MAAM,sBAAsB,GAAG,OAAC,CAAC,MAAM,CAAC;IACvC,UAAU,EAAE,OAAC;SACX,KAAK,CAAC,OAAC,CAAC,UAAU,CAAC,kCAAiB,CAAC,CAAC;SACtC,GAAG,CAAC,CAAC,CAAC;SACN,QAAQ,CAAC,4DAA4D,CAAC;CACxE,CAAC,CAAC;AAKH,SAAS,mBAAmB,CAAC,UAAmC;IAC/D,MAAM,KAAK,GAAa,EAAE,CAAC;IAC3B,MAAM,SAAS,GAAa,EAAE,CAAC;IAE/B,KAAK,MAAM,SAAS,IAAI,UAAU,EAAE,CAAC;QACpC,MAAM,GAAG,GAAG,8BAAa,CAAC,SAAS,CAAC,CAAC;QACrC,IAAI,GAAG,EAAE,CAAC;YACT,SAAS,CAAC,IAAI,CAAC,GAAG,CAAC,gBAAgB,EAAE,CAAC,CAAC;QACxC,CAAC;IACF,CAAC;IAED,IAAI,SAAS,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC1B,KAAK,CAAC,IAAI,CAAC,kBAAkB,CAAC,CAAC;QAC/B,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC;QACtC,KAAK,CAAC,IAAI,CAAC,mBAAmB,CAAC,CAAC;IACjC,CAAC;IAED,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AACzB,CAAC;AAEY,QAAA,uBAAuB,GAAoB;IACvD,QAAQ,EAAE,oBAAoB;IAC9B,YAAY,EAAE,wBAAwB;CACtC,CAAC;AAKF,SAAgB,0BAA0B;IACzC,MAAM,WAAW,GAAG,IAAA,YAAI,EACvB,CAAC,KAAc,EAAE,MAAM,EAAE,EAAE;QAC1B,MAAM,QAAQ,GAAG,IAAA,iCAAsB,EACtC,MAAM,EACN,+BAAuB,CAAC,QAAQ,EAChC,+BAAuB,CAAC,YAAY,CACpC,CAAC;QAEF,IAAI,CAAC;YACJ,MAAM,cAAc,GAAG,sBAAsB,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;YAC3D,MAAM,EAAE,UAAU,EAAE,GAAG,cAAc,CAAC;YAEtC,QAAQ,CAAC,KAAK,CAAC,cAAc,CAAC,CAAC;YAE/B,QAAQ,CAAC,QAAQ,CAAC,iCAAiC,UAAU,CAAC,MAAM,kBAAkB,CAAC,CAAC;YAGxF,MAAM,aAAa,GAAG,UAAU,CAAC,MAAM,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,8BAAa,CAAC,SAAS,CAAC,CAAC,CAAC;YAEjF,IAAI,aAAa,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;gBAChC,MAAM,OAAO,GAAG,2EAA2E,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;gBACnH,QAAQ,CAAC,QAAQ,CAAC,EAAE,UAAU,EAAE,KAAK,EAAE,CAAC,EAAE,CAAC,CAAC;gBAC5C,OAAO,IAAA,gCAAqB,EAAC,MAAM,EAAE,OAAO,CAAC,CAAC;YAC/C,CAAC;YAGD,MAAM,OAAO,GAAG,mBAAmB,CAAC,UAAU,CAAC,CAAC;YAEhD,QAAQ,CAAC,QAAQ,CAAC;gBACjB,UAAU;gBACV,KAAK,EAAE,aAAa,CAAC,MAAM;gBAC3B,OAAO,EAAE,UAAU,CAAC,MAAM,GAAG,aAAa,CAAC,MAAM;aACjD,CAAC,CAAC;YAEH,OAAO,IAAA,gCAAqB,EAAC,MAAM,EAAE,OAAO,CAAC,CAAC;QAC/C,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,wBAAwB,EACjE;gBACC,QAAQ,EAAE,+BAAuB,CAAC,QAAQ;gBAC1C,KAAK,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS;aACjD,CACD,CAAC;YACF,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,+BAAuB,CAAC,QAAQ;QACtC,WAAW,EAAE;;;;;;;;;4FAS4E;QACzF,MAAM,EAAE,sBAAsB;KAC9B,CACD,CAAC;IAEF,OAAO;QACN,IAAI,EAAE,WAAW;QACjB,GAAG,+BAAuB;KAC1B,CAAC;AACH,CAAC"}
|
|
@@ -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. **
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
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 @@
|
|
|
1
|
+
{"version":3,"file":"best-practices.js","sourceRoot":"","sources":["../../src/types/best-practices.ts"],"names":[],"mappings":""}
|