@elizaos/plugin-n8n-workflow 1.0.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.
- package/README.md +199 -0
- package/dist/actions/activateWorkflow.d.ts +4 -0
- package/dist/actions/activateWorkflow.d.ts.map +1 -0
- package/dist/actions/activateWorkflow.js +116 -0
- package/dist/actions/activateWorkflow.js.map +1 -0
- package/dist/actions/createWorkflow.d.ts +4 -0
- package/dist/actions/createWorkflow.d.ts.map +1 -0
- package/dist/actions/createWorkflow.js +141 -0
- package/dist/actions/createWorkflow.js.map +1 -0
- package/dist/actions/deactivateWorkflow.d.ts +4 -0
- package/dist/actions/deactivateWorkflow.d.ts.map +1 -0
- package/dist/actions/deactivateWorkflow.js +121 -0
- package/dist/actions/deactivateWorkflow.js.map +1 -0
- package/dist/actions/deleteWorkflow.d.ts +4 -0
- package/dist/actions/deleteWorkflow.d.ts.map +1 -0
- package/dist/actions/deleteWorkflow.js +115 -0
- package/dist/actions/deleteWorkflow.js.map +1 -0
- package/dist/actions/executeWorkflow.d.ts +4 -0
- package/dist/actions/executeWorkflow.d.ts.map +1 -0
- package/dist/actions/executeWorkflow.js +74 -0
- package/dist/actions/executeWorkflow.js.map +1 -0
- package/dist/actions/getExecutions.d.ts +4 -0
- package/dist/actions/getExecutions.d.ts.map +1 -0
- package/dist/actions/getExecutions.js +108 -0
- package/dist/actions/getExecutions.js.map +1 -0
- package/dist/actions/index.d.ts +9 -0
- package/dist/actions/index.d.ts.map +1 -0
- package/dist/actions/index.js +9 -0
- package/dist/actions/index.js.map +1 -0
- package/dist/actions/listCredentials.d.ts +4 -0
- package/dist/actions/listCredentials.d.ts.map +1 -0
- package/dist/actions/listCredentials.js +102 -0
- package/dist/actions/listCredentials.js.map +1 -0
- package/dist/actions/listWorkflows.d.ts +4 -0
- package/dist/actions/listWorkflows.d.ts.map +1 -0
- package/dist/actions/listWorkflows.js +97 -0
- package/dist/actions/listWorkflows.js.map +1 -0
- package/dist/data/defaultNodes.json +427888 -0
- package/dist/index.d.ts +35 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +75 -0
- package/dist/index.js.map +1 -0
- package/dist/prompts/index.d.ts +3 -0
- package/dist/prompts/index.d.ts.map +1 -0
- package/dist/prompts/index.js +3 -0
- package/dist/prompts/index.js.map +1 -0
- package/dist/prompts/keywordExtraction.d.ts +6 -0
- package/dist/prompts/keywordExtraction.d.ts.map +1 -0
- package/dist/prompts/keywordExtraction.js +19 -0
- package/dist/prompts/keywordExtraction.js.map +1 -0
- package/dist/prompts/workflowGeneration.d.ts +7 -0
- package/dist/prompts/workflowGeneration.d.ts.map +1 -0
- package/dist/prompts/workflowGeneration.js +330 -0
- package/dist/prompts/workflowGeneration.js.map +1 -0
- package/dist/prompts/workflowMatching.d.ts +7 -0
- package/dist/prompts/workflowMatching.d.ts.map +1 -0
- package/dist/prompts/workflowMatching.js +25 -0
- package/dist/prompts/workflowMatching.js.map +1 -0
- package/dist/providers/activeWorkflows.d.ts +12 -0
- package/dist/providers/activeWorkflows.d.ts.map +1 -0
- package/dist/providers/activeWorkflows.js +69 -0
- package/dist/providers/activeWorkflows.js.map +1 -0
- package/dist/providers/index.d.ts +3 -0
- package/dist/providers/index.d.ts.map +1 -0
- package/dist/providers/index.js +3 -0
- package/dist/providers/index.js.map +1 -0
- package/dist/providers/workflowStatus.d.ts +4 -0
- package/dist/providers/workflowStatus.d.ts.map +1 -0
- package/dist/providers/workflowStatus.js +66 -0
- package/dist/providers/workflowStatus.js.map +1 -0
- package/dist/schemas/index.d.ts +3 -0
- package/dist/schemas/index.d.ts.map +1 -0
- package/dist/schemas/index.js +3 -0
- package/dist/schemas/index.js.map +1 -0
- package/dist/schemas/keywordExtraction.d.ts +14 -0
- package/dist/schemas/keywordExtraction.d.ts.map +1 -0
- package/dist/schemas/keywordExtraction.js +12 -0
- package/dist/schemas/keywordExtraction.js.map +1 -0
- package/dist/schemas/workflowMatching.d.ts +36 -0
- package/dist/schemas/workflowMatching.d.ts.map +1 -0
- package/dist/schemas/workflowMatching.js +30 -0
- package/dist/schemas/workflowMatching.js.map +1 -0
- package/dist/services/index.d.ts +2 -0
- package/dist/services/index.d.ts.map +1 -0
- package/dist/services/index.js +2 -0
- package/dist/services/index.js.map +1 -0
- package/dist/services/n8n-workflow-service.d.ts +83 -0
- package/dist/services/n8n-workflow-service.d.ts.map +1 -0
- package/dist/services/n8n-workflow-service.js +234 -0
- package/dist/services/n8n-workflow-service.js.map +1 -0
- package/dist/types/index.d.ts +313 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +43 -0
- package/dist/types/index.js.map +1 -0
- package/dist/utils/api.d.ts +137 -0
- package/dist/utils/api.d.ts.map +1 -0
- package/dist/utils/api.js +247 -0
- package/dist/utils/api.js.map +1 -0
- package/dist/utils/catalog.d.ts +22 -0
- package/dist/utils/catalog.d.ts.map +1 -0
- package/dist/utils/catalog.js +81 -0
- package/dist/utils/catalog.js.map +1 -0
- package/dist/utils/context.d.ts +8 -0
- package/dist/utils/context.d.ts.map +1 -0
- package/dist/utils/context.js +17 -0
- package/dist/utils/context.js.map +1 -0
- package/dist/utils/credentialResolver.d.ts +13 -0
- package/dist/utils/credentialResolver.d.ts.map +1 -0
- package/dist/utils/credentialResolver.js +177 -0
- package/dist/utils/credentialResolver.js.map +1 -0
- package/dist/utils/generation.d.ts +46 -0
- package/dist/utils/generation.d.ts.map +1 -0
- package/dist/utils/generation.js +145 -0
- package/dist/utils/generation.js.map +1 -0
- package/dist/utils/index.d.ts +6 -0
- package/dist/utils/index.d.ts.map +1 -0
- package/dist/utils/index.js +11 -0
- package/dist/utils/index.js.map +1 -0
- package/dist/utils/workflow.d.ts +27 -0
- package/dist/utils/workflow.d.ts.map +1 -0
- package/dist/utils/workflow.js +289 -0
- package/dist/utils/workflow.js.map +1 -0
- package/package.json +65 -0
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import { logger } from '@elizaos/core';
|
|
2
|
+
import { N8N_WORKFLOW_SERVICE_TYPE } from '../services/index';
|
|
3
|
+
/**
|
|
4
|
+
* Provider that enriches state with user's active workflows
|
|
5
|
+
*
|
|
6
|
+
* This provider runs for every message and adds workflow information to the state,
|
|
7
|
+
* allowing the LLM to automatically extract workflow IDs and references from context.
|
|
8
|
+
*
|
|
9
|
+
* Example: User says "run my Stripe workflow" → LLM can see all workflows and extract the right ID
|
|
10
|
+
*/
|
|
11
|
+
export const activeWorkflowsProvider = {
|
|
12
|
+
name: 'ACTIVE_N8N_WORKFLOWS',
|
|
13
|
+
description: "User's active n8n workflows with IDs and descriptions",
|
|
14
|
+
get: async (runtime, _message, _state) => {
|
|
15
|
+
try {
|
|
16
|
+
const service = runtime.getService(N8N_WORKFLOW_SERVICE_TYPE);
|
|
17
|
+
if (!service) {
|
|
18
|
+
return {
|
|
19
|
+
text: '',
|
|
20
|
+
data: {},
|
|
21
|
+
values: {},
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
const userId = _message.entityId;
|
|
25
|
+
const workflows = await service.listWorkflows(userId);
|
|
26
|
+
if (workflows.length === 0) {
|
|
27
|
+
return {
|
|
28
|
+
text: '',
|
|
29
|
+
data: { workflows: [] },
|
|
30
|
+
values: { hasWorkflows: false },
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
const workflowList = workflows
|
|
34
|
+
.slice(0, 20)
|
|
35
|
+
.map((wf) => {
|
|
36
|
+
const status = wf.active ? 'ACTIVE' : 'INACTIVE';
|
|
37
|
+
const nodeCount = wf.nodes?.length || 0;
|
|
38
|
+
return `- **${wf.name}** (ID: ${wf.id}, Status: ${status}, Nodes: ${nodeCount})`;
|
|
39
|
+
})
|
|
40
|
+
.join('\n');
|
|
41
|
+
const text = `# Available Workflows\n\n${workflowList}`;
|
|
42
|
+
return {
|
|
43
|
+
text,
|
|
44
|
+
data: {
|
|
45
|
+
workflows: workflows.map((wf) => ({
|
|
46
|
+
id: wf.id,
|
|
47
|
+
name: wf.name,
|
|
48
|
+
active: wf.active || false,
|
|
49
|
+
nodeCount: wf.nodes?.length || 0,
|
|
50
|
+
})),
|
|
51
|
+
},
|
|
52
|
+
values: {
|
|
53
|
+
hasWorkflows: true,
|
|
54
|
+
workflowCount: workflows.length,
|
|
55
|
+
},
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
catch (error) {
|
|
59
|
+
logger.error({ src: 'plugin:n8n-workflow:providers:active-workflows' }, `Failed to get active workflows: ${error instanceof Error ? error.message : String(error)}`);
|
|
60
|
+
return {
|
|
61
|
+
text: '',
|
|
62
|
+
data: {},
|
|
63
|
+
values: {},
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
},
|
|
67
|
+
};
|
|
68
|
+
export default activeWorkflowsProvider;
|
|
69
|
+
//# sourceMappingURL=activeWorkflows.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"activeWorkflows.js","sourceRoot":"","sources":["../../src/providers/activeWorkflows.ts"],"names":[],"mappings":"AAAA,OAAO,EAAsB,MAAM,EAA0C,MAAM,eAAe,CAAC;AACnG,OAAO,EAAE,yBAAyB,EAA2B,MAAM,mBAAmB,CAAC;AAEvF;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,uBAAuB,GAAa;IAC/C,IAAI,EAAE,sBAAsB;IAC5B,WAAW,EAAE,uDAAuD;IAEpE,GAAG,EAAE,KAAK,EAAE,OAAsB,EAAE,QAAgB,EAAE,MAAa,EAAE,EAAE;QACrE,IAAI,CAAC;YACH,MAAM,OAAO,GAAG,OAAO,CAAC,UAAU,CAAqB,yBAAyB,CAAC,CAAC;YAElF,IAAI,CAAC,OAAO,EAAE,CAAC;gBACb,OAAO;oBACL,IAAI,EAAE,EAAE;oBACR,IAAI,EAAE,EAAE;oBACR,MAAM,EAAE,EAAE;iBACX,CAAC;YACJ,CAAC;YAED,MAAM,MAAM,GAAG,QAAQ,CAAC,QAAQ,CAAC;YACjC,MAAM,SAAS,GAAG,MAAM,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC;YAEtD,IAAI,SAAS,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;gBAC3B,OAAO;oBACL,IAAI,EAAE,EAAE;oBACR,IAAI,EAAE,EAAE,SAAS,EAAE,EAAE,EAAE;oBACvB,MAAM,EAAE,EAAE,YAAY,EAAE,KAAK,EAAE;iBAChC,CAAC;YACJ,CAAC;YAED,MAAM,YAAY,GAAG,SAAS;iBAC3B,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC;iBACZ,GAAG,CAAC,CAAC,EAAE,EAAE,EAAE;gBACV,MAAM,MAAM,GAAG,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,UAAU,CAAC;gBACjD,MAAM,SAAS,GAAG,EAAE,CAAC,KAAK,EAAE,MAAM,IAAI,CAAC,CAAC;gBACxC,OAAO,OAAO,EAAE,CAAC,IAAI,WAAW,EAAE,CAAC,EAAE,aAAa,MAAM,YAAY,SAAS,GAAG,CAAC;YACnF,CAAC,CAAC;iBACD,IAAI,CAAC,IAAI,CAAC,CAAC;YAEd,MAAM,IAAI,GAAG,4BAA4B,YAAY,EAAE,CAAC;YAExD,OAAO;gBACL,IAAI;gBACJ,IAAI,EAAE;oBACJ,SAAS,EAAE,SAAS,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC;wBAChC,EAAE,EAAE,EAAE,CAAC,EAAE;wBACT,IAAI,EAAE,EAAE,CAAC,IAAI;wBACb,MAAM,EAAE,EAAE,CAAC,MAAM,IAAI,KAAK;wBAC1B,SAAS,EAAE,EAAE,CAAC,KAAK,EAAE,MAAM,IAAI,CAAC;qBACjC,CAAC,CAAC;iBACJ;gBACD,MAAM,EAAE;oBACN,YAAY,EAAE,IAAI;oBAClB,aAAa,EAAE,SAAS,CAAC,MAAM;iBAChC;aACF,CAAC;QACJ,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,CAAC,KAAK,CACV,EAAE,GAAG,EAAE,gDAAgD,EAAE,EACzD,mCAAmC,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAC5F,CAAC;YACF,OAAO;gBACL,IAAI,EAAE,EAAE;gBACR,IAAI,EAAE,EAAE;gBACR,MAAM,EAAE,EAAE;aACX,CAAC;QACJ,CAAC;IACH,CAAC;CACF,CAAC;AAEF,eAAe,uBAAuB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/providers/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,sBAAsB,EAAE,MAAM,kBAAkB,CAAC;AAC1D,OAAO,EAAE,uBAAuB,EAAE,MAAM,mBAAmB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/providers/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,sBAAsB,EAAE,MAAM,kBAAkB,CAAC;AAC1D,OAAO,EAAE,uBAAuB,EAAE,MAAM,mBAAmB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"workflowStatus.d.ts","sourceRoot":"","sources":["../../src/providers/workflowStatus.ts"],"names":[],"mappings":"AAAA,OAAO,EAA2C,KAAK,QAAQ,EAAc,MAAM,eAAe,CAAC;AAGnG,eAAO,MAAM,sBAAsB,EAAE,QAgFpC,CAAC;AAEF,eAAe,sBAAsB,CAAC"}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import { logger } from '@elizaos/core';
|
|
2
|
+
import { N8N_WORKFLOW_SERVICE_TYPE } from '../services/index';
|
|
3
|
+
export const workflowStatusProvider = {
|
|
4
|
+
name: 'n8n_workflow_status',
|
|
5
|
+
get: async (runtime, _message, _state) => {
|
|
6
|
+
try {
|
|
7
|
+
const service = runtime.getService(N8N_WORKFLOW_SERVICE_TYPE);
|
|
8
|
+
if (!service) {
|
|
9
|
+
logger.warn({ src: 'plugin:n8n-workflow:provider:workflowStatus' }, 'N8n Workflow service not available for provider');
|
|
10
|
+
return {
|
|
11
|
+
text: '',
|
|
12
|
+
data: {},
|
|
13
|
+
values: {},
|
|
14
|
+
};
|
|
15
|
+
}
|
|
16
|
+
// Get workflows for the user
|
|
17
|
+
const userId = _message.entityId;
|
|
18
|
+
const workflows = await service.listWorkflows(userId);
|
|
19
|
+
if (workflows.length === 0) {
|
|
20
|
+
return {
|
|
21
|
+
text: 'No n8n workflows configured yet.',
|
|
22
|
+
data: {},
|
|
23
|
+
values: {},
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
let status = `Current n8n workflows (${workflows.length}):\n\n`;
|
|
27
|
+
for (const workflow of workflows.slice(0, 10)) {
|
|
28
|
+
const statusEmoji = workflow.active ? '✅' : '⏸️';
|
|
29
|
+
status += `${statusEmoji} ${workflow.name} (ID: ${workflow.id})\n`;
|
|
30
|
+
status += ` Nodes: ${workflow.nodes?.length || 0}\n`;
|
|
31
|
+
// Try to get last execution (if possible)
|
|
32
|
+
try {
|
|
33
|
+
const executions = await service.getWorkflowExecutions(workflow.id, 1);
|
|
34
|
+
if (executions.length > 0) {
|
|
35
|
+
const lastExec = executions[0];
|
|
36
|
+
const execEmoji = lastExec.status === 'success' ? '✅' : lastExec.status === 'error' ? '❌' : '⏳';
|
|
37
|
+
status += ` Last run: ${execEmoji} ${lastExec.status} at ${new Date(lastExec.startedAt).toLocaleString()}\n`;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
catch (_error) {
|
|
41
|
+
// Ignore execution fetch errors
|
|
42
|
+
logger.debug({ src: 'plugin:n8n-workflow:provider:workflowStatus' }, `Could not fetch executions for workflow ${workflow.id}`);
|
|
43
|
+
}
|
|
44
|
+
status += '\n';
|
|
45
|
+
}
|
|
46
|
+
if (workflows.length > 10) {
|
|
47
|
+
status += `\n... and ${workflows.length - 10} more workflows.`;
|
|
48
|
+
}
|
|
49
|
+
return {
|
|
50
|
+
text: status,
|
|
51
|
+
data: { workflows },
|
|
52
|
+
values: { workflowCount: workflows.length },
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
catch (error) {
|
|
56
|
+
logger.error({ src: 'plugin:n8n-workflow:provider:workflowStatus' }, `Failed to get workflow status: ${error instanceof Error ? error.message : String(error)}`);
|
|
57
|
+
return {
|
|
58
|
+
text: '',
|
|
59
|
+
data: {},
|
|
60
|
+
values: {},
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
},
|
|
64
|
+
};
|
|
65
|
+
export default workflowStatusProvider;
|
|
66
|
+
//# sourceMappingURL=workflowStatus.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"workflowStatus.js","sourceRoot":"","sources":["../../src/providers/workflowStatus.ts"],"names":[],"mappings":"AAAA,OAAO,EAAsB,MAAM,EAA0C,MAAM,eAAe,CAAC;AACnG,OAAO,EAAE,yBAAyB,EAA2B,MAAM,mBAAmB,CAAC;AAEvF,MAAM,CAAC,MAAM,sBAAsB,GAAa;IAC9C,IAAI,EAAE,qBAAqB;IAE3B,GAAG,EAAE,KAAK,EAAE,OAAsB,EAAE,QAAgB,EAAE,MAAa,EAAE,EAAE;QACrE,IAAI,CAAC;YACH,MAAM,OAAO,GAAG,OAAO,CAAC,UAAU,CAAqB,yBAAyB,CAAC,CAAC;YAElF,IAAI,CAAC,OAAO,EAAE,CAAC;gBACb,MAAM,CAAC,IAAI,CACT,EAAE,GAAG,EAAE,6CAA6C,EAAE,EACtD,iDAAiD,CAClD,CAAC;gBACF,OAAO;oBACL,IAAI,EAAE,EAAE;oBACR,IAAI,EAAE,EAAE;oBACR,MAAM,EAAE,EAAE;iBACX,CAAC;YACJ,CAAC;YAED,6BAA6B;YAC7B,MAAM,MAAM,GAAG,QAAQ,CAAC,QAAQ,CAAC;YAEjC,MAAM,SAAS,GAAG,MAAM,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC;YAEtD,IAAI,SAAS,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;gBAC3B,OAAO;oBACL,IAAI,EAAE,kCAAkC;oBACxC,IAAI,EAAE,EAAE;oBACR,MAAM,EAAE,EAAE;iBACX,CAAC;YACJ,CAAC;YAED,IAAI,MAAM,GAAG,0BAA0B,SAAS,CAAC,MAAM,QAAQ,CAAC;YAEhE,KAAK,MAAM,QAAQ,IAAI,SAAS,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC;gBAC9C,MAAM,WAAW,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC;gBACjD,MAAM,IAAI,GAAG,WAAW,IAAI,QAAQ,CAAC,IAAI,SAAS,QAAQ,CAAC,EAAE,KAAK,CAAC;gBACnE,MAAM,IAAI,aAAa,QAAQ,CAAC,KAAK,EAAE,MAAM,IAAI,CAAC,IAAI,CAAC;gBAEvD,0CAA0C;gBAC1C,IAAI,CAAC;oBACH,MAAM,UAAU,GAAG,MAAM,OAAO,CAAC,qBAAqB,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC;oBACvE,IAAI,UAAU,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;wBAC1B,MAAM,QAAQ,GAAG,UAAU,CAAC,CAAC,CAAC,CAAC;wBAC/B,MAAM,SAAS,GACb,QAAQ,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,QAAQ,CAAC,MAAM,KAAK,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC;wBAChF,MAAM,IAAI,gBAAgB,SAAS,IAAI,QAAQ,CAAC,MAAM,OAAO,IAAI,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC,cAAc,EAAE,IAAI,CAAC;oBACjH,CAAC;gBACH,CAAC;gBAAC,OAAO,MAAM,EAAE,CAAC;oBAChB,gCAAgC;oBAChC,MAAM,CAAC,KAAK,CACV,EAAE,GAAG,EAAE,6CAA6C,EAAE,EACtD,2CAA2C,QAAQ,CAAC,EAAE,EAAE,CACzD,CAAC;gBACJ,CAAC;gBAED,MAAM,IAAI,IAAI,CAAC;YACjB,CAAC;YAED,IAAI,SAAS,CAAC,MAAM,GAAG,EAAE,EAAE,CAAC;gBAC1B,MAAM,IAAI,aAAa,SAAS,CAAC,MAAM,GAAG,EAAE,kBAAkB,CAAC;YACjE,CAAC;YAED,OAAO;gBACL,IAAI,EAAE,MAAM;gBACZ,IAAI,EAAE,EAAE,SAAS,EAAE;gBACnB,MAAM,EAAE,EAAE,aAAa,EAAE,SAAS,CAAC,MAAM,EAAE;aAC5C,CAAC;QACJ,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,CAAC,KAAK,CACV,EAAE,GAAG,EAAE,6CAA6C,EAAE,EACtD,kCAAkC,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAC3F,CAAC;YACF,OAAO;gBACL,IAAI,EAAE,EAAE;gBACR,IAAI,EAAE,EAAE;gBACR,MAAM,EAAE,EAAE;aACX,CAAC;QACJ,CAAC;IACH,CAAC;CACF,CAAC;AAEF,eAAe,sBAAsB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/schemas/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,uBAAuB,EAAE,MAAM,qBAAqB,CAAC;AAC9D,OAAO,EAAE,sBAAsB,EAAE,MAAM,oBAAoB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/schemas/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,uBAAuB,EAAE,MAAM,qBAAqB,CAAC;AAC9D,OAAO,EAAE,sBAAsB,EAAE,MAAM,oBAAoB,CAAC"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export declare const keywordExtractionSchema: {
|
|
2
|
+
type: string;
|
|
3
|
+
properties: {
|
|
4
|
+
keywords: {
|
|
5
|
+
type: string;
|
|
6
|
+
items: {
|
|
7
|
+
type: string;
|
|
8
|
+
};
|
|
9
|
+
description: string;
|
|
10
|
+
};
|
|
11
|
+
};
|
|
12
|
+
required: string[];
|
|
13
|
+
};
|
|
14
|
+
//# sourceMappingURL=keywordExtraction.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"keywordExtraction.d.ts","sourceRoot":"","sources":["../../src/schemas/keywordExtraction.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,uBAAuB;;;;;;;;;;;;CAUnC,CAAC"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export const keywordExtractionSchema = {
|
|
2
|
+
type: 'object',
|
|
3
|
+
properties: {
|
|
4
|
+
keywords: {
|
|
5
|
+
type: 'array',
|
|
6
|
+
items: { type: 'string' },
|
|
7
|
+
description: 'Up to 5 relevant keywords or phrases',
|
|
8
|
+
},
|
|
9
|
+
},
|
|
10
|
+
required: ['keywords'],
|
|
11
|
+
};
|
|
12
|
+
//# sourceMappingURL=keywordExtraction.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"keywordExtraction.js","sourceRoot":"","sources":["../../src/schemas/keywordExtraction.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,uBAAuB,GAAG;IACrC,IAAI,EAAE,QAAQ;IACd,UAAU,EAAE;QACV,QAAQ,EAAE;YACR,IAAI,EAAE,OAAO;YACb,KAAK,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;YACzB,WAAW,EAAE,sCAAsC;SACpD;KACF;IACD,QAAQ,EAAE,CAAC,UAAU,CAAC;CACvB,CAAC"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
export declare const workflowMatchingSchema: {
|
|
2
|
+
type: string;
|
|
3
|
+
properties: {
|
|
4
|
+
matchedWorkflowId: {
|
|
5
|
+
type: string;
|
|
6
|
+
nullable: boolean;
|
|
7
|
+
};
|
|
8
|
+
confidence: {
|
|
9
|
+
type: string;
|
|
10
|
+
enum: string[];
|
|
11
|
+
};
|
|
12
|
+
matches: {
|
|
13
|
+
type: string;
|
|
14
|
+
items: {
|
|
15
|
+
type: string;
|
|
16
|
+
properties: {
|
|
17
|
+
id: {
|
|
18
|
+
type: string;
|
|
19
|
+
};
|
|
20
|
+
name: {
|
|
21
|
+
type: string;
|
|
22
|
+
};
|
|
23
|
+
score: {
|
|
24
|
+
type: string;
|
|
25
|
+
};
|
|
26
|
+
};
|
|
27
|
+
required: string[];
|
|
28
|
+
};
|
|
29
|
+
};
|
|
30
|
+
reason: {
|
|
31
|
+
type: string;
|
|
32
|
+
};
|
|
33
|
+
};
|
|
34
|
+
required: string[];
|
|
35
|
+
};
|
|
36
|
+
//# sourceMappingURL=workflowMatching.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"workflowMatching.d.ts","sourceRoot":"","sources":["../../src/schemas/workflowMatching.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,sBAAsB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA4BlC,CAAC"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
export const workflowMatchingSchema = {
|
|
2
|
+
type: 'object',
|
|
3
|
+
properties: {
|
|
4
|
+
matchedWorkflowId: {
|
|
5
|
+
type: 'string',
|
|
6
|
+
nullable: true,
|
|
7
|
+
},
|
|
8
|
+
confidence: {
|
|
9
|
+
type: 'string',
|
|
10
|
+
enum: ['high', 'medium', 'low', 'none'],
|
|
11
|
+
},
|
|
12
|
+
matches: {
|
|
13
|
+
type: 'array',
|
|
14
|
+
items: {
|
|
15
|
+
type: 'object',
|
|
16
|
+
properties: {
|
|
17
|
+
id: { type: 'string' },
|
|
18
|
+
name: { type: 'string' },
|
|
19
|
+
score: { type: 'number' },
|
|
20
|
+
},
|
|
21
|
+
required: ['id', 'name', 'score'],
|
|
22
|
+
},
|
|
23
|
+
},
|
|
24
|
+
reason: {
|
|
25
|
+
type: 'string',
|
|
26
|
+
},
|
|
27
|
+
},
|
|
28
|
+
required: ['matchedWorkflowId', 'confidence', 'matches', 'reason'],
|
|
29
|
+
};
|
|
30
|
+
//# sourceMappingURL=workflowMatching.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"workflowMatching.js","sourceRoot":"","sources":["../../src/schemas/workflowMatching.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,sBAAsB,GAAG;IACpC,IAAI,EAAE,QAAQ;IACd,UAAU,EAAE;QACV,iBAAiB,EAAE;YACjB,IAAI,EAAE,QAAQ;YACd,QAAQ,EAAE,IAAI;SACf;QACD,UAAU,EAAE;YACV,IAAI,EAAE,QAAQ;YACd,IAAI,EAAE,CAAC,MAAM,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,CAAC;SACxC;QACD,OAAO,EAAE;YACP,IAAI,EAAE,OAAO;YACb,KAAK,EAAE;gBACL,IAAI,EAAE,QAAQ;gBACd,UAAU,EAAE;oBACV,EAAE,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;oBACtB,IAAI,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;oBACxB,KAAK,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;iBAC1B;gBACD,QAAQ,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC;aAClC;SACF;QACD,MAAM,EAAE;YACN,IAAI,EAAE,QAAQ;SACf;KACF;IACD,QAAQ,EAAE,CAAC,mBAAmB,EAAE,YAAY,EAAE,SAAS,EAAE,QAAQ,CAAC;CACnE,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/services/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,kBAAkB,EAClB,yBAAyB,EACzB,KAAK,wBAAwB,GAC9B,MAAM,wBAAwB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/services/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,kBAAkB,EAClB,yBAAyB,GAE1B,MAAM,wBAAwB,CAAC"}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import { type IAgentRuntime, Service } from '@elizaos/core';
|
|
2
|
+
import type { N8nWorkflowResponse, N8nExecution, N8nCredential, WorkflowCreationResult } from '../types/index';
|
|
3
|
+
export declare const N8N_WORKFLOW_SERVICE_TYPE = "n8n_workflow";
|
|
4
|
+
/**
|
|
5
|
+
* Configuration for the N8n Workflow Service
|
|
6
|
+
*/
|
|
7
|
+
export interface N8nWorkflowServiceConfig {
|
|
8
|
+
apiKey: string;
|
|
9
|
+
host: string;
|
|
10
|
+
credentials?: Record<string, string>;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* N8n Workflow Service - Orchestrates the RAG pipeline for workflow generation
|
|
14
|
+
*
|
|
15
|
+
* Pipeline:
|
|
16
|
+
* 1. Extract keywords from user prompt (LLM - OBJECT_SMALL)
|
|
17
|
+
* 2. Search node catalog for relevant nodes (local search)
|
|
18
|
+
* 3. Generate workflow JSON (LLM - TEXT_LARGE)
|
|
19
|
+
* 4. Validate workflow structure
|
|
20
|
+
* 5. Position nodes on canvas
|
|
21
|
+
* 6. Resolve credentials (cloud/local/placeholder)
|
|
22
|
+
* 7. Deploy to n8n Cloud via REST API
|
|
23
|
+
*/
|
|
24
|
+
export declare class N8nWorkflowService extends Service {
|
|
25
|
+
static readonly serviceType = "n8n_workflow";
|
|
26
|
+
capabilityDescription: string;
|
|
27
|
+
private apiClient;
|
|
28
|
+
private serviceConfig;
|
|
29
|
+
/**
|
|
30
|
+
* Start the N8n Workflow Service
|
|
31
|
+
*/
|
|
32
|
+
static start(runtime: IAgentRuntime): Promise<N8nWorkflowService>;
|
|
33
|
+
stop(): Promise<void>;
|
|
34
|
+
/**
|
|
35
|
+
* Get the API client (throws if service not initialized)
|
|
36
|
+
*/
|
|
37
|
+
private getClient;
|
|
38
|
+
/**
|
|
39
|
+
* Get the service configuration (throws if service not initialized)
|
|
40
|
+
*/
|
|
41
|
+
private getConfig;
|
|
42
|
+
/**
|
|
43
|
+
* Main RAG pipeline: Create workflow from natural language prompt
|
|
44
|
+
*
|
|
45
|
+
* @param prompt - User's natural language request
|
|
46
|
+
* @param userId - User ID for tagging and credential resolution
|
|
47
|
+
* @returns Workflow creation result with ID and metadata
|
|
48
|
+
*/
|
|
49
|
+
createWorkflowFromPrompt(prompt: string, userId?: string): Promise<WorkflowCreationResult>;
|
|
50
|
+
/**
|
|
51
|
+
* List workflows (optionally filtered by user)
|
|
52
|
+
*/
|
|
53
|
+
listWorkflows(userId?: string): Promise<N8nWorkflowResponse[]>;
|
|
54
|
+
/**
|
|
55
|
+
* Activate a workflow
|
|
56
|
+
*/
|
|
57
|
+
activateWorkflow(workflowId: string): Promise<void>;
|
|
58
|
+
/**
|
|
59
|
+
* Deactivate a workflow
|
|
60
|
+
*/
|
|
61
|
+
deactivateWorkflow(workflowId: string): Promise<void>;
|
|
62
|
+
/**
|
|
63
|
+
* Delete a workflow
|
|
64
|
+
*/
|
|
65
|
+
deleteWorkflow(workflowId: string): Promise<void>;
|
|
66
|
+
/**
|
|
67
|
+
* Execute a workflow manually
|
|
68
|
+
*/
|
|
69
|
+
executeWorkflow(workflowId: string): Promise<N8nExecution>;
|
|
70
|
+
/**
|
|
71
|
+
* Get execution history for a workflow
|
|
72
|
+
*/
|
|
73
|
+
getWorkflowExecutions(workflowId: string, limit?: number): Promise<N8nExecution[]>;
|
|
74
|
+
/**
|
|
75
|
+
* Get detailed execution information
|
|
76
|
+
*/
|
|
77
|
+
getExecutionDetail(executionId: string): Promise<N8nExecution>;
|
|
78
|
+
/**
|
|
79
|
+
* List available credentials (for local mode)
|
|
80
|
+
*/
|
|
81
|
+
listCredentials(): Promise<N8nCredential[]>;
|
|
82
|
+
}
|
|
83
|
+
//# sourceMappingURL=n8n-workflow-service.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"n8n-workflow-service.d.ts","sourceRoot":"","sources":["../../src/services/n8n-workflow-service.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,aAAa,EAAU,OAAO,EAAE,MAAM,eAAe,CAAC;AAMpE,OAAO,KAAK,EACV,mBAAmB,EACnB,YAAY,EACZ,aAAa,EACb,sBAAsB,EACvB,MAAM,gBAAgB,CAAC;AAExB,eAAO,MAAM,yBAAyB,iBAAiB,CAAC;AAExD;;GAEG;AACH,MAAM,WAAW,wBAAwB;IACvC,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACtC;AAED;;;;;;;;;;;GAWG;AACH,qBAAa,kBAAmB,SAAQ,OAAO;IAC7C,gBAAyB,WAAW,kBAA6B;IAExD,qBAAqB,SAE+C;IAE7E,OAAO,CAAC,SAAS,CAA6B;IAC9C,OAAO,CAAC,aAAa,CAAyC;IAE9D;;OAEG;WACU,KAAK,CAAC,OAAO,EAAE,aAAa,GAAG,OAAO,CAAC,kBAAkB,CAAC;IA6CxD,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAOpC;;OAEG;IACH,OAAO,CAAC,SAAS;IAOjB;;OAEG;IACH,OAAO,CAAC,SAAS;IAOjB;;;;;;OAMG;IACG,wBAAwB,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,sBAAsB,CAAC;IAqIhG;;OAEG;IACG,aAAa,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,mBAAmB,EAAE,CAAC;IAqBpE;;OAEG;IACG,gBAAgB,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAMzD;;OAEG;IACG,kBAAkB,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAM3D;;OAEG;IACG,cAAc,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAMvD;;OAEG;IACG,eAAe,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC;IAUhE;;OAEG;IACG,qBAAqB,CAAC,UAAU,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC;IAMxF;;OAEG;IACG,kBAAkB,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC;IAKpE;;OAEG;IACG,eAAe,IAAI,OAAO,CAAC,aAAa,EAAE,CAAC;CAKlD"}
|
|
@@ -0,0 +1,234 @@
|
|
|
1
|
+
import { logger, Service } from '@elizaos/core';
|
|
2
|
+
import { N8nApiClient } from '../utils/api';
|
|
3
|
+
import { searchNodes } from '../utils/catalog';
|
|
4
|
+
import { extractKeywords, generateWorkflow } from '../utils/generation';
|
|
5
|
+
import { positionNodes, validateWorkflow } from '../utils/workflow';
|
|
6
|
+
import { resolveCredentials, getMissingCredentials } from '../utils/credentialResolver';
|
|
7
|
+
export const N8N_WORKFLOW_SERVICE_TYPE = 'n8n_workflow';
|
|
8
|
+
/**
|
|
9
|
+
* N8n Workflow Service - Orchestrates the RAG pipeline for workflow generation
|
|
10
|
+
*
|
|
11
|
+
* Pipeline:
|
|
12
|
+
* 1. Extract keywords from user prompt (LLM - OBJECT_SMALL)
|
|
13
|
+
* 2. Search node catalog for relevant nodes (local search)
|
|
14
|
+
* 3. Generate workflow JSON (LLM - TEXT_LARGE)
|
|
15
|
+
* 4. Validate workflow structure
|
|
16
|
+
* 5. Position nodes on canvas
|
|
17
|
+
* 6. Resolve credentials (cloud/local/placeholder)
|
|
18
|
+
* 7. Deploy to n8n Cloud via REST API
|
|
19
|
+
*/
|
|
20
|
+
export class N8nWorkflowService extends Service {
|
|
21
|
+
static serviceType = N8N_WORKFLOW_SERVICE_TYPE;
|
|
22
|
+
capabilityDescription = 'Generate and deploy n8n workflows from natural language using RAG pipeline. ' +
|
|
23
|
+
'Supports workflow CRUD, execution management, and credential resolution.';
|
|
24
|
+
apiClient = null;
|
|
25
|
+
serviceConfig = null;
|
|
26
|
+
/**
|
|
27
|
+
* Start the N8n Workflow Service
|
|
28
|
+
*/
|
|
29
|
+
static async start(runtime) {
|
|
30
|
+
logger.info({ src: 'plugin:n8n-workflow:service:main' }, 'Starting N8n Workflow Service...');
|
|
31
|
+
// Validate configuration
|
|
32
|
+
const apiKey = runtime.getSetting('N8N_API_KEY');
|
|
33
|
+
const host = runtime.getSetting('N8N_HOST');
|
|
34
|
+
if (!apiKey || typeof apiKey !== 'string') {
|
|
35
|
+
throw new Error('N8N_API_KEY is required in settings');
|
|
36
|
+
}
|
|
37
|
+
if (!host || typeof host !== 'string') {
|
|
38
|
+
throw new Error('N8N_HOST is required in settings (e.g., https://your.n8n.cloud)');
|
|
39
|
+
}
|
|
40
|
+
// Get optional pre-configured credentials
|
|
41
|
+
const n8nSettings = runtime.getSetting('n8n');
|
|
42
|
+
const credentials = n8nSettings?.credentials;
|
|
43
|
+
const service = new N8nWorkflowService(runtime);
|
|
44
|
+
service.serviceConfig = {
|
|
45
|
+
apiKey,
|
|
46
|
+
host,
|
|
47
|
+
credentials,
|
|
48
|
+
};
|
|
49
|
+
// Initialize API client
|
|
50
|
+
service.apiClient = new N8nApiClient(host, apiKey);
|
|
51
|
+
logger.info({ src: 'plugin:n8n-workflow:service:main' }, `N8n Workflow Service started - connected to ${host}`);
|
|
52
|
+
if (credentials) {
|
|
53
|
+
logger.info({ src: 'plugin:n8n-workflow:service:main' }, `Pre-configured credentials: ${Object.keys(credentials).join(', ')}`);
|
|
54
|
+
}
|
|
55
|
+
return service;
|
|
56
|
+
}
|
|
57
|
+
async stop() {
|
|
58
|
+
logger.info({ src: 'plugin:n8n-workflow:service:main' }, 'Stopping N8n Workflow Service...');
|
|
59
|
+
this.apiClient = null;
|
|
60
|
+
this.serviceConfig = null;
|
|
61
|
+
logger.info({ src: 'plugin:n8n-workflow:service:main' }, 'N8n Workflow Service stopped');
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Get the API client (throws if service not initialized)
|
|
65
|
+
*/
|
|
66
|
+
getClient() {
|
|
67
|
+
if (!this.apiClient) {
|
|
68
|
+
throw new Error('N8n Workflow Service not initialized');
|
|
69
|
+
}
|
|
70
|
+
return this.apiClient;
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Get the service configuration (throws if service not initialized)
|
|
74
|
+
*/
|
|
75
|
+
getConfig() {
|
|
76
|
+
if (!this.serviceConfig) {
|
|
77
|
+
throw new Error('N8n Workflow Service not initialized');
|
|
78
|
+
}
|
|
79
|
+
return this.serviceConfig;
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Main RAG pipeline: Create workflow from natural language prompt
|
|
83
|
+
*
|
|
84
|
+
* @param prompt - User's natural language request
|
|
85
|
+
* @param userId - User ID for tagging and credential resolution
|
|
86
|
+
* @returns Workflow creation result with ID and metadata
|
|
87
|
+
*/
|
|
88
|
+
async createWorkflowFromPrompt(prompt, userId) {
|
|
89
|
+
logger.info({ src: 'plugin:n8n-workflow:service:main' }, `Creating workflow from prompt for user ${userId || 'unknown'}`);
|
|
90
|
+
try {
|
|
91
|
+
// Step 1: Extract keywords (LLM - OBJECT_SMALL)
|
|
92
|
+
logger.debug({ src: 'plugin:n8n-workflow:service:main' }, 'Step 1: Extracting keywords...');
|
|
93
|
+
const keywords = await extractKeywords(this.runtime, prompt);
|
|
94
|
+
logger.debug({ src: 'plugin:n8n-workflow:service:main' }, `Extracted keywords: ${keywords.join(', ')}`);
|
|
95
|
+
// Step 2: Search node catalog (local)
|
|
96
|
+
logger.debug({ src: 'plugin:n8n-workflow:service:main' }, 'Step 2: Searching node catalog...');
|
|
97
|
+
const relevantNodes = searchNodes(keywords, 15);
|
|
98
|
+
logger.debug({ src: 'plugin:n8n-workflow:service:main' }, `Found ${relevantNodes.length} relevant nodes`);
|
|
99
|
+
if (relevantNodes.length === 0) {
|
|
100
|
+
throw new Error('No relevant n8n nodes found for the given prompt. Please be more specific about the integrations you want to use (e.g., Gmail, Slack, Stripe).');
|
|
101
|
+
}
|
|
102
|
+
// Step 3: Generate workflow JSON (LLM - TEXT_LARGE)
|
|
103
|
+
logger.debug({ src: 'plugin:n8n-workflow:service:main' }, 'Step 3: Generating workflow JSON...');
|
|
104
|
+
const workflow = await generateWorkflow(this.runtime, prompt, relevantNodes.map((r) => r.node));
|
|
105
|
+
logger.debug({ src: 'plugin:n8n-workflow:service:main' }, `Generated workflow with ${workflow.nodes?.length || 0} nodes`);
|
|
106
|
+
// Step 4: Validate workflow structure
|
|
107
|
+
logger.debug({ src: 'plugin:n8n-workflow:service:main' }, 'Step 4: Validating workflow...');
|
|
108
|
+
const validationResult = validateWorkflow(workflow);
|
|
109
|
+
if (!validationResult.valid) {
|
|
110
|
+
logger.error({ src: 'plugin:n8n-workflow:service:main' }, `Validation errors: ${validationResult.errors.join(', ')}`);
|
|
111
|
+
throw new Error(`Generated workflow is invalid: ${validationResult.errors[0]}`);
|
|
112
|
+
}
|
|
113
|
+
if (validationResult.warnings.length > 0) {
|
|
114
|
+
logger.warn({ src: 'plugin:n8n-workflow:service:main' }, `Validation warnings: ${validationResult.warnings.join(', ')}`);
|
|
115
|
+
}
|
|
116
|
+
// Step 5: Position nodes on canvas
|
|
117
|
+
logger.debug({ src: 'plugin:n8n-workflow:service:main' }, 'Step 5: Positioning nodes...');
|
|
118
|
+
const positionedWorkflow = positionNodes(workflow);
|
|
119
|
+
// Step 6: Resolve credentials
|
|
120
|
+
logger.debug({ src: 'plugin:n8n-workflow:service:main' }, 'Step 6: Resolving credentials...');
|
|
121
|
+
const config = this.getConfig();
|
|
122
|
+
const client = this.getClient();
|
|
123
|
+
const credentialResult = await resolveCredentials(positionedWorkflow, userId || '', this.runtime, client, config);
|
|
124
|
+
// Step 7: Deploy to n8n Cloud
|
|
125
|
+
logger.debug({ src: 'plugin:n8n-workflow:service:main' }, 'Step 7: Deploying to n8n Cloud...');
|
|
126
|
+
const createdWorkflow = await client.createWorkflow(credentialResult.workflow);
|
|
127
|
+
// Tag workflow with user ID if provided
|
|
128
|
+
if (userId) {
|
|
129
|
+
try {
|
|
130
|
+
// Check if tag exists, create if not
|
|
131
|
+
const tagsResponse = await client.listTags();
|
|
132
|
+
let userTag = tagsResponse.data.find((t) => t.name === `user:${userId}`);
|
|
133
|
+
if (!userTag) {
|
|
134
|
+
userTag = await client.createTag(`user:${userId}`);
|
|
135
|
+
}
|
|
136
|
+
// Assign tag to workflow
|
|
137
|
+
await client.updateWorkflowTags(createdWorkflow.id, [userTag.id]);
|
|
138
|
+
logger.debug({ src: 'plugin:n8n-workflow:service:main' }, `Tagged workflow ${createdWorkflow.id} with user:${userId}`);
|
|
139
|
+
}
|
|
140
|
+
catch (error) {
|
|
141
|
+
logger.warn({ src: 'plugin:n8n-workflow:service:main' }, `Failed to tag workflow: ${error instanceof Error ? error.message : String(error)}`);
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
logger.info({ src: 'plugin:n8n-workflow:service:main' }, `Workflow created successfully: ${createdWorkflow.id}`);
|
|
145
|
+
return {
|
|
146
|
+
id: createdWorkflow.id,
|
|
147
|
+
name: createdWorkflow.name,
|
|
148
|
+
active: createdWorkflow.active ?? false,
|
|
149
|
+
nodeCount: createdWorkflow.nodes?.length || 0,
|
|
150
|
+
missingCredentials: getMissingCredentials(credentialResult.workflow),
|
|
151
|
+
};
|
|
152
|
+
}
|
|
153
|
+
catch (error) {
|
|
154
|
+
logger.error({ src: 'plugin:n8n-workflow:service:main' }, `Failed to create workflow: ${error instanceof Error ? error.message : String(error)}`);
|
|
155
|
+
throw error;
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
/**
|
|
159
|
+
* List workflows (optionally filtered by user)
|
|
160
|
+
*/
|
|
161
|
+
async listWorkflows(userId) {
|
|
162
|
+
const client = this.getClient();
|
|
163
|
+
if (userId) {
|
|
164
|
+
// Filter by user tag
|
|
165
|
+
const tagsResponse = await client.listTags();
|
|
166
|
+
const userTag = tagsResponse.data.find((t) => t.name === `user:${userId}`);
|
|
167
|
+
if (!userTag) {
|
|
168
|
+
return []; // No workflows for this user
|
|
169
|
+
}
|
|
170
|
+
// Get all workflows and filter by tag
|
|
171
|
+
const workflowsResponse = await client.listWorkflows();
|
|
172
|
+
return workflowsResponse.data.filter((w) => w.tags?.some((t) => t.id === userTag.id));
|
|
173
|
+
}
|
|
174
|
+
const response = await client.listWorkflows();
|
|
175
|
+
return response.data;
|
|
176
|
+
}
|
|
177
|
+
/**
|
|
178
|
+
* Activate a workflow
|
|
179
|
+
*/
|
|
180
|
+
async activateWorkflow(workflowId) {
|
|
181
|
+
const client = this.getClient();
|
|
182
|
+
await client.activateWorkflow(workflowId);
|
|
183
|
+
logger.info({ src: 'plugin:n8n-workflow:service:main' }, `Workflow ${workflowId} activated`);
|
|
184
|
+
}
|
|
185
|
+
/**
|
|
186
|
+
* Deactivate a workflow
|
|
187
|
+
*/
|
|
188
|
+
async deactivateWorkflow(workflowId) {
|
|
189
|
+
const client = this.getClient();
|
|
190
|
+
await client.deactivateWorkflow(workflowId);
|
|
191
|
+
logger.info({ src: 'plugin:n8n-workflow:service:main' }, `Workflow ${workflowId} deactivated`);
|
|
192
|
+
}
|
|
193
|
+
/**
|
|
194
|
+
* Delete a workflow
|
|
195
|
+
*/
|
|
196
|
+
async deleteWorkflow(workflowId) {
|
|
197
|
+
const client = this.getClient();
|
|
198
|
+
await client.deleteWorkflow(workflowId);
|
|
199
|
+
logger.info({ src: 'plugin:n8n-workflow:service:main' }, `Workflow ${workflowId} deleted`);
|
|
200
|
+
}
|
|
201
|
+
/**
|
|
202
|
+
* Execute a workflow manually
|
|
203
|
+
*/
|
|
204
|
+
async executeWorkflow(workflowId) {
|
|
205
|
+
const client = this.getClient();
|
|
206
|
+
const execution = await client.executeWorkflow(workflowId);
|
|
207
|
+
logger.info({ src: 'plugin:n8n-workflow:service:main' }, `Workflow ${workflowId} executed - execution ID: ${execution.id}`);
|
|
208
|
+
return execution;
|
|
209
|
+
}
|
|
210
|
+
/**
|
|
211
|
+
* Get execution history for a workflow
|
|
212
|
+
*/
|
|
213
|
+
async getWorkflowExecutions(workflowId, limit) {
|
|
214
|
+
const client = this.getClient();
|
|
215
|
+
const response = await client.listExecutions({ workflowId, limit });
|
|
216
|
+
return response.data;
|
|
217
|
+
}
|
|
218
|
+
/**
|
|
219
|
+
* Get detailed execution information
|
|
220
|
+
*/
|
|
221
|
+
async getExecutionDetail(executionId) {
|
|
222
|
+
const client = this.getClient();
|
|
223
|
+
return client.getExecution(executionId);
|
|
224
|
+
}
|
|
225
|
+
/**
|
|
226
|
+
* List available credentials (for local mode)
|
|
227
|
+
*/
|
|
228
|
+
async listCredentials() {
|
|
229
|
+
const client = this.getClient();
|
|
230
|
+
const response = await client.listCredentials();
|
|
231
|
+
return response.data;
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
//# sourceMappingURL=n8n-workflow-service.js.map
|