@cascadeflow/n8n-nodes-cascadeflow 0.4.12 → 0.4.14
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/nodes/LmChatCascadeFlow/LmChatCascadeFlow.node.d.ts.map +1 -1
- package/dist/nodes/LmChatCascadeFlow/LmChatCascadeFlow.node.js +59 -135
- package/dist/nodes/LmChatCascadeFlow/LmChatCascadeFlow.node.js.map +1 -1
- package/package.json +2 -9
- package/dist/nodes/CascadeFlow/CascadeFlow.node.d.ts +0 -6
- package/dist/nodes/CascadeFlow/CascadeFlow.node.d.ts.map +0 -1
- package/dist/nodes/CascadeFlow/CascadeFlow.node.js +0 -283
- package/dist/nodes/CascadeFlow/CascadeFlow.node.js.map +0 -1
- package/dist/nodes/CascadeFlow/cascadeflow.svg +0 -15
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"LmChatCascadeFlow.node.d.ts","sourceRoot":"","sources":["../../../nodes/LmChatCascadeFlow/LmChatCascadeFlow.node.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,SAAS,EACT,oBAAoB,EACpB,oBAAoB,EACpB,UAAU,EACX,MAAM,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"LmChatCascadeFlow.node.d.ts","sourceRoot":"","sources":["../../../nodes/LmChatCascadeFlow/LmChatCascadeFlow.node.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,SAAS,EACT,oBAAoB,EACpB,oBAAoB,EACpB,UAAU,EACX,MAAM,cAAc,CAAC;AA4GtB,qBAAa,iBAAkB,YAAW,SAAS;IACjD,WAAW,EAAE,oBAAoB,CAyD/B;IAEI,UAAU,CAAC,IAAI,EAAE,oBAAoB,GAAG,OAAO,CAAC,UAAU,CAAC;CA6ClE"}
|
|
@@ -3,15 +3,18 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.LmChatCascadeFlow = void 0;
|
|
4
4
|
const n8n_workflow_1 = require("n8n-workflow");
|
|
5
5
|
const chat_models_1 = require("@langchain/core/language_models/chat_models");
|
|
6
|
-
const openai_1 = require("@langchain/openai");
|
|
7
|
-
const anthropic_1 = require("@langchain/anthropic");
|
|
8
6
|
/**
|
|
9
7
|
* Custom CascadeChatModel that wraps two models (drafter and verifier)
|
|
10
|
-
* and implements cascading logic
|
|
8
|
+
* and implements cascading logic with cost tracking
|
|
11
9
|
*/
|
|
12
10
|
class CascadeChatModel extends chat_models_1.BaseChatModel {
|
|
13
11
|
constructor(drafterModel, verifierModel, qualityThreshold = 0.7) {
|
|
14
12
|
super({});
|
|
13
|
+
// Cost tracking
|
|
14
|
+
this.drafterCost = 0;
|
|
15
|
+
this.verifierCost = 0;
|
|
16
|
+
this.drafterCount = 0;
|
|
17
|
+
this.verifierCount = 0;
|
|
15
18
|
this.drafterModel = drafterModel;
|
|
16
19
|
this.verifierModel = verifierModel;
|
|
17
20
|
this.qualityThreshold = qualityThreshold;
|
|
@@ -27,27 +30,45 @@ class CascadeChatModel extends chat_models_1.BaseChatModel {
|
|
|
27
30
|
const drafterResult = await this.drafterModel._generate(messages, options, runManager);
|
|
28
31
|
const drafterLatency = Date.now() - drafterStartTime;
|
|
29
32
|
const drafterMessage = drafterResult.generations[0].message;
|
|
30
|
-
|
|
31
|
-
//
|
|
33
|
+
this.drafterCount++;
|
|
34
|
+
// Step 2: Quality check
|
|
32
35
|
const responseText = drafterMessage.content.toString();
|
|
33
|
-
const qualityScore = Math.min(responseText.length / 100, 1.0);
|
|
36
|
+
const qualityScore = Math.min(responseText.length / 100, 1.0);
|
|
34
37
|
// Step 3: If quality is sufficient, return drafter response
|
|
35
38
|
if (qualityScore >= this.qualityThreshold) {
|
|
36
|
-
|
|
39
|
+
// Estimate cost savings
|
|
40
|
+
const estimatedDrafterCost = 0.0001; // $0.0001 per request (rough estimate)
|
|
41
|
+
const estimatedVerifierCost = 0.0016; // $0.0016 per request (rough estimate)
|
|
42
|
+
const savings = ((estimatedVerifierCost - estimatedDrafterCost) / estimatedVerifierCost * 100).toFixed(1);
|
|
43
|
+
console.log(`✅ CascadeFlow: Drafter accepted!`);
|
|
44
|
+
console.log(` Quality: ${qualityScore.toFixed(2)} (threshold: ${this.qualityThreshold})`);
|
|
45
|
+
console.log(` Latency: ${drafterLatency}ms`);
|
|
46
|
+
console.log(` 💰 Cost savings: ~${savings}% (used cheap model)`);
|
|
47
|
+
console.log(` 📊 Stats: ${this.drafterCount} drafter, ${this.verifierCount} verifier`);
|
|
37
48
|
return drafterResult;
|
|
38
49
|
}
|
|
39
50
|
// Step 4: Otherwise, escalate to verifier
|
|
40
|
-
console.log(`⚠️ CascadeFlow:
|
|
51
|
+
console.log(`⚠️ CascadeFlow: Quality below threshold, escalating to verifier...`);
|
|
52
|
+
console.log(` Quality: ${qualityScore.toFixed(2)} < ${this.qualityThreshold}`);
|
|
53
|
+
console.log(` Drafter latency: ${drafterLatency}ms`);
|
|
41
54
|
const verifierStartTime = Date.now();
|
|
42
55
|
const verifierResult = await this.verifierModel._generate(messages, options, runManager);
|
|
43
56
|
const verifierLatency = Date.now() - verifierStartTime;
|
|
44
|
-
|
|
57
|
+
this.verifierCount++;
|
|
58
|
+
const totalLatency = drafterLatency + verifierLatency;
|
|
59
|
+
const acceptanceRate = (this.drafterCount / (this.drafterCount + this.verifierCount) * 100).toFixed(1);
|
|
60
|
+
console.log(`✅ CascadeFlow: Verifier completed`);
|
|
61
|
+
console.log(` Verifier latency: ${verifierLatency}ms`);
|
|
62
|
+
console.log(` Total latency: ${totalLatency}ms`);
|
|
63
|
+
console.log(` 📊 Stats: ${this.drafterCount} drafter (${acceptanceRate}%), ${this.verifierCount} verifier`);
|
|
45
64
|
return verifierResult;
|
|
46
65
|
}
|
|
47
66
|
catch (error) {
|
|
48
67
|
// Fallback to verifier on error
|
|
49
|
-
console.log(`❌ CascadeFlow: Drafter failed, falling back to verifier
|
|
68
|
+
console.log(`❌ CascadeFlow: Drafter failed, falling back to verifier`);
|
|
69
|
+
console.log(` Error: ${error instanceof Error ? error.message : String(error)}`);
|
|
50
70
|
const verifierResult = await this.verifierModel._generate(messages, options, runManager);
|
|
71
|
+
this.verifierCount++;
|
|
51
72
|
console.log('✅ CascadeFlow: Verifier fallback completed');
|
|
52
73
|
return verifierResult;
|
|
53
74
|
}
|
|
@@ -56,14 +77,14 @@ class CascadeChatModel extends chat_models_1.BaseChatModel {
|
|
|
56
77
|
class LmChatCascadeFlow {
|
|
57
78
|
constructor() {
|
|
58
79
|
this.description = {
|
|
59
|
-
displayName: 'CascadeFlow
|
|
80
|
+
displayName: 'CascadeFlow',
|
|
60
81
|
name: 'lmChatCascadeFlow',
|
|
61
82
|
icon: 'file:cascadeflow.svg',
|
|
62
83
|
group: ['transform'],
|
|
63
84
|
version: 1,
|
|
64
|
-
description: 'Smart AI model cascading with 40-85% cost savings.
|
|
85
|
+
description: 'Smart AI model cascading with 40-85% cost savings. Connect two AI models (drafter and verifier) and intelligently cascade between them.',
|
|
65
86
|
defaults: {
|
|
66
|
-
name: 'CascadeFlow
|
|
87
|
+
name: 'CascadeFlow',
|
|
67
88
|
},
|
|
68
89
|
codex: {
|
|
69
90
|
categories: ['AI'],
|
|
@@ -78,93 +99,27 @@ class LmChatCascadeFlow {
|
|
|
78
99
|
],
|
|
79
100
|
},
|
|
80
101
|
},
|
|
81
|
-
// Sub-node:
|
|
102
|
+
// Sub-node: accepts AI model connections
|
|
82
103
|
// eslint-disable-next-line n8n-nodes-base/node-class-description-inputs-wrong-regular-node
|
|
83
|
-
inputs: [
|
|
84
|
-
// Outputs an AI model that can be connected to Agent
|
|
85
|
-
// eslint-disable-next-line n8n-nodes-base/node-class-description-outputs-wrong
|
|
86
|
-
outputs: ['ai_languageModel'],
|
|
87
|
-
outputNames: ['Model'],
|
|
88
|
-
credentials: [
|
|
89
|
-
{
|
|
90
|
-
name: 'cascadeFlowApi',
|
|
91
|
-
required: true,
|
|
92
|
-
},
|
|
93
|
-
],
|
|
94
|
-
properties: [
|
|
95
|
-
// Drafter Model Configuration
|
|
104
|
+
inputs: [
|
|
96
105
|
{
|
|
97
106
|
displayName: 'Drafter Model',
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
default: 'gpt-4o-mini',
|
|
107
|
+
type: 'ai_languageModel',
|
|
108
|
+
maxConnections: 1,
|
|
101
109
|
required: true,
|
|
102
|
-
description: 'The cheaper model to try first (e.g., gpt-4o-mini, claude-3-5-haiku-20241022)',
|
|
103
|
-
placeholder: 'gpt-4o-mini',
|
|
104
110
|
},
|
|
105
|
-
{
|
|
106
|
-
displayName: 'Drafter Provider',
|
|
107
|
-
name: 'drafterProvider',
|
|
108
|
-
type: 'options',
|
|
109
|
-
default: 'openai',
|
|
110
|
-
required: true,
|
|
111
|
-
options: [
|
|
112
|
-
{
|
|
113
|
-
name: 'OpenAI',
|
|
114
|
-
value: 'openai',
|
|
115
|
-
},
|
|
116
|
-
{
|
|
117
|
-
name: 'Anthropic',
|
|
118
|
-
value: 'anthropic',
|
|
119
|
-
},
|
|
120
|
-
{
|
|
121
|
-
name: 'Groq',
|
|
122
|
-
value: 'groq',
|
|
123
|
-
},
|
|
124
|
-
{
|
|
125
|
-
name: 'Together AI',
|
|
126
|
-
value: 'together',
|
|
127
|
-
},
|
|
128
|
-
],
|
|
129
|
-
description: 'Provider for the drafter model',
|
|
130
|
-
},
|
|
131
|
-
// Verifier Model Configuration
|
|
132
111
|
{
|
|
133
112
|
displayName: 'Verifier Model',
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
default: 'gpt-4o',
|
|
137
|
-
required: true,
|
|
138
|
-
description: 'The quality model to escalate to if needed (e.g., gpt-4o, claude-3-5-sonnet-20241022)',
|
|
139
|
-
placeholder: 'gpt-4o',
|
|
140
|
-
},
|
|
141
|
-
{
|
|
142
|
-
displayName: 'Verifier Provider',
|
|
143
|
-
name: 'verifierProvider',
|
|
144
|
-
type: 'options',
|
|
145
|
-
default: 'openai',
|
|
113
|
+
type: 'ai_languageModel',
|
|
114
|
+
maxConnections: 1,
|
|
146
115
|
required: true,
|
|
147
|
-
options: [
|
|
148
|
-
{
|
|
149
|
-
name: 'OpenAI',
|
|
150
|
-
value: 'openai',
|
|
151
|
-
},
|
|
152
|
-
{
|
|
153
|
-
name: 'Anthropic',
|
|
154
|
-
value: 'anthropic',
|
|
155
|
-
},
|
|
156
|
-
{
|
|
157
|
-
name: 'Groq',
|
|
158
|
-
value: 'groq',
|
|
159
|
-
},
|
|
160
|
-
{
|
|
161
|
-
name: 'Together AI',
|
|
162
|
-
value: 'together',
|
|
163
|
-
},
|
|
164
|
-
],
|
|
165
|
-
description: 'Provider for the verifier model',
|
|
166
116
|
},
|
|
167
|
-
|
|
117
|
+
],
|
|
118
|
+
// Outputs an AI model that can be connected to Chain nodes
|
|
119
|
+
// eslint-disable-next-line n8n-nodes-base/node-class-description-outputs-wrong
|
|
120
|
+
outputs: ['ai_languageModel'],
|
|
121
|
+
outputNames: ['Model'],
|
|
122
|
+
properties: [
|
|
168
123
|
{
|
|
169
124
|
displayName: 'Quality Threshold',
|
|
170
125
|
name: 'qualityThreshold',
|
|
@@ -181,52 +136,21 @@ class LmChatCascadeFlow {
|
|
|
181
136
|
};
|
|
182
137
|
}
|
|
183
138
|
async supplyData() {
|
|
184
|
-
// Get credentials
|
|
185
|
-
const credentials = await this.getCredentials('cascadeFlowApi');
|
|
186
139
|
// Get parameters
|
|
187
|
-
const drafterModelName = this.getNodeParameter('drafterModel', 0);
|
|
188
|
-
const drafterProvider = this.getNodeParameter('drafterProvider', 0);
|
|
189
|
-
const verifierModelName = this.getNodeParameter('verifierModel', 0);
|
|
190
|
-
const verifierProvider = this.getNodeParameter('verifierProvider', 0);
|
|
191
140
|
const qualityThreshold = this.getNodeParameter('qualityThreshold', 0, 0.7);
|
|
192
|
-
//
|
|
193
|
-
const
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
switch (provider) {
|
|
206
|
-
case 'openai':
|
|
207
|
-
case 'groq':
|
|
208
|
-
case 'together':
|
|
209
|
-
return new openai_1.ChatOpenAI({
|
|
210
|
-
modelName,
|
|
211
|
-
apiKey,
|
|
212
|
-
configuration: provider === 'groq' ? {
|
|
213
|
-
baseURL: 'https://api.groq.com/openai/v1',
|
|
214
|
-
} : provider === 'together' ? {
|
|
215
|
-
baseURL: 'https://api.together.xyz/v1',
|
|
216
|
-
} : undefined,
|
|
217
|
-
});
|
|
218
|
-
case 'anthropic':
|
|
219
|
-
return new anthropic_1.ChatAnthropic({
|
|
220
|
-
modelName,
|
|
221
|
-
apiKey,
|
|
222
|
-
});
|
|
223
|
-
default:
|
|
224
|
-
throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Unsupported provider: ${provider}`);
|
|
225
|
-
}
|
|
226
|
-
};
|
|
227
|
-
// Create drafter and verifier models
|
|
228
|
-
const drafterModel = createModel(drafterProvider, drafterModelName);
|
|
229
|
-
const verifierModel = createModel(verifierProvider, verifierModelName);
|
|
141
|
+
// Get the connected chat models from inputs
|
|
142
|
+
const drafterModel = (await this.getInputConnectionData('ai_languageModel', 0));
|
|
143
|
+
const verifierModel = (await this.getInputConnectionData('ai_languageModel', 1));
|
|
144
|
+
if (!drafterModel) {
|
|
145
|
+
throw new n8n_workflow_1.NodeOperationError(this.getNode(), 'Drafter model is required. Please connect an AI chat model (OpenAI, Anthropic, Ollama, etc.) to the "Drafter Model" input.');
|
|
146
|
+
}
|
|
147
|
+
if (!verifierModel) {
|
|
148
|
+
throw new n8n_workflow_1.NodeOperationError(this.getNode(), 'Verifier model is required. Please connect an AI chat model (OpenAI, Anthropic, Ollama, etc.) to the "Verifier Model" input.');
|
|
149
|
+
}
|
|
150
|
+
console.log('🚀 CascadeFlow initialized');
|
|
151
|
+
console.log(` Drafter: ${typeof drafterModel._llmType === 'function' ? drafterModel._llmType() : 'connected'}`);
|
|
152
|
+
console.log(` Verifier: ${typeof verifierModel._llmType === 'function' ? verifierModel._llmType() : 'connected'}`);
|
|
153
|
+
console.log(` Quality threshold: ${qualityThreshold}`);
|
|
230
154
|
// Create and return the cascade model
|
|
231
155
|
const cascadeModel = new CascadeChatModel(drafterModel, verifierModel, qualityThreshold);
|
|
232
156
|
return {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"LmChatCascadeFlow.node.js","sourceRoot":"","sources":["../../../nodes/LmChatCascadeFlow/LmChatCascadeFlow.node.ts"],"names":[],"mappings":";;;AAOA,+CAAsE;AAEtE,6EAA4E;
|
|
1
|
+
{"version":3,"file":"LmChatCascadeFlow.node.js","sourceRoot":"","sources":["../../../nodes/LmChatCascadeFlow/LmChatCascadeFlow.node.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cascadeflow/n8n-nodes-cascadeflow",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.14",
|
|
4
4
|
"description": "n8n node for cascadeflow - Smart AI model cascading with 40-85% cost savings",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"n8n-community-node-package",
|
|
@@ -30,7 +30,6 @@
|
|
|
30
30
|
"dist/credentials/CascadeFlowApi.credentials.js"
|
|
31
31
|
],
|
|
32
32
|
"nodes": [
|
|
33
|
-
"dist/nodes/CascadeFlow/CascadeFlow.node.js",
|
|
34
33
|
"dist/nodes/LmChatCascadeFlow/LmChatCascadeFlow.node.js"
|
|
35
34
|
]
|
|
36
35
|
},
|
|
@@ -48,13 +47,7 @@
|
|
|
48
47
|
"n8n-workflow": "*"
|
|
49
48
|
},
|
|
50
49
|
"dependencies": {
|
|
51
|
-
"@
|
|
52
|
-
"openai": "^4.73.1",
|
|
53
|
-
"@anthropic-ai/sdk": "^0.30.0",
|
|
54
|
-
"groq-sdk": "^0.5.0",
|
|
55
|
-
"@langchain/core": "^0.3.0",
|
|
56
|
-
"@langchain/openai": "^0.3.0",
|
|
57
|
-
"@langchain/anthropic": "^0.3.0"
|
|
50
|
+
"@langchain/core": "^0.3.0"
|
|
58
51
|
},
|
|
59
52
|
"scripts": {
|
|
60
53
|
"build": "tsc && gulp build:icons",
|
|
@@ -1,6 +0,0 @@
|
|
|
1
|
-
import { IExecuteFunctions, INodeExecutionData, INodeType, INodeTypeDescription } from 'n8n-workflow';
|
|
2
|
-
export declare class CascadeFlow implements INodeType {
|
|
3
|
-
description: INodeTypeDescription;
|
|
4
|
-
execute(this: IExecuteFunctions): Promise<INodeExecutionData[][]>;
|
|
5
|
-
}
|
|
6
|
-
//# sourceMappingURL=CascadeFlow.node.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"CascadeFlow.node.d.ts","sourceRoot":"","sources":["../../../nodes/CascadeFlow/CascadeFlow.node.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,iBAAiB,EACjB,kBAAkB,EAClB,SAAS,EACT,oBAAoB,EAErB,MAAM,cAAc,CAAC;AAItB,qBAAa,WAAY,YAAW,SAAS;IAC3C,WAAW,EAAE,oBAAoB,CAmE/B;IAEI,OAAO,CAAC,IAAI,EAAE,iBAAiB,GAAG,OAAO,CAAC,kBAAkB,EAAE,EAAE,CAAC;CAuOxE"}
|
|
@@ -1,283 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.CascadeFlow = void 0;
|
|
4
|
-
const n8n_workflow_1 = require("n8n-workflow");
|
|
5
|
-
const core_1 = require("@cascadeflow/core");
|
|
6
|
-
class CascadeFlow {
|
|
7
|
-
constructor() {
|
|
8
|
-
this.description = {
|
|
9
|
-
displayName: 'CascadeFlow',
|
|
10
|
-
name: 'cascadeFlow',
|
|
11
|
-
icon: 'file:cascadeflow.svg',
|
|
12
|
-
group: ['transform'],
|
|
13
|
-
version: 3,
|
|
14
|
-
subtitle: 'AI Model Cascading',
|
|
15
|
-
description: 'Smart AI model cascading with 40-85% cost savings',
|
|
16
|
-
defaults: {
|
|
17
|
-
name: 'CascadeFlow',
|
|
18
|
-
},
|
|
19
|
-
// eslint-disable-next-line n8n-nodes-base/node-class-description-inputs-wrong-regular-node
|
|
20
|
-
inputs: ['main', 'main', 'main'],
|
|
21
|
-
inputNames: ['Chat/Agent Output', 'Drafter Provider', 'Verifier Provider'],
|
|
22
|
-
// eslint-disable-next-line n8n-nodes-base/node-class-description-outputs-wrong
|
|
23
|
-
outputs: ['main', 'main'],
|
|
24
|
-
outputNames: ['Draft Accepted', 'Escalated to Verifier'],
|
|
25
|
-
properties: [
|
|
26
|
-
// Quality Threshold
|
|
27
|
-
{
|
|
28
|
-
displayName: 'Quality Threshold',
|
|
29
|
-
name: 'qualityThreshold',
|
|
30
|
-
type: 'number',
|
|
31
|
-
default: 0.7,
|
|
32
|
-
typeOptions: {
|
|
33
|
-
minValue: 0,
|
|
34
|
-
maxValue: 1,
|
|
35
|
-
numberPrecision: 2,
|
|
36
|
-
},
|
|
37
|
-
description: 'Minimum quality score (0-1) to accept drafter response. Lower = more cost savings, higher = better quality.',
|
|
38
|
-
},
|
|
39
|
-
// Split Output by Path
|
|
40
|
-
{
|
|
41
|
-
displayName: 'Split Output by Path',
|
|
42
|
-
name: 'splitOutput',
|
|
43
|
-
type: 'boolean',
|
|
44
|
-
default: false,
|
|
45
|
-
description: 'Whether to split output into two connectors: one for draft-accepted responses, one for escalated responses. Enables visual flow tracking.',
|
|
46
|
-
},
|
|
47
|
-
// Output Options
|
|
48
|
-
{
|
|
49
|
-
displayName: 'Output Format',
|
|
50
|
-
name: 'output',
|
|
51
|
-
type: 'options',
|
|
52
|
-
default: 'contentOnly',
|
|
53
|
-
options: [
|
|
54
|
-
{
|
|
55
|
-
name: 'Content Only',
|
|
56
|
-
value: 'contentOnly',
|
|
57
|
-
description: 'Return only the AI response text',
|
|
58
|
-
},
|
|
59
|
-
{
|
|
60
|
-
name: 'Metrics Summary',
|
|
61
|
-
value: 'metricsSummary',
|
|
62
|
-
description: 'Return response + key metrics (cost, savings, model)',
|
|
63
|
-
},
|
|
64
|
-
{
|
|
65
|
-
name: 'Full Metrics',
|
|
66
|
-
value: 'fullMetrics',
|
|
67
|
-
description: 'Return response + all cascade metrics',
|
|
68
|
-
},
|
|
69
|
-
],
|
|
70
|
-
description: 'What data to return',
|
|
71
|
-
},
|
|
72
|
-
],
|
|
73
|
-
};
|
|
74
|
-
}
|
|
75
|
-
async execute() {
|
|
76
|
-
const returnData = [];
|
|
77
|
-
const escalatedData = [];
|
|
78
|
-
// Get data from all three inputs
|
|
79
|
-
const inputData = this.getInputData(0); // Input (prompt/query)
|
|
80
|
-
const drafterInputData = this.getInputData(1); // Drafter model
|
|
81
|
-
const verifierInputData = this.getInputData(2); // Verifier model
|
|
82
|
-
// Helper to extract model config from provider node output
|
|
83
|
-
const extractModelConfig = (providerData, inputName) => {
|
|
84
|
-
if (!providerData || providerData.length === 0) {
|
|
85
|
-
throw new n8n_workflow_1.NodeOperationError(this.getNode(), `No data received from ${inputName} input. Please connect a provider node (OpenAI, Anthropic, vLLM, Ollama, etc.).`);
|
|
86
|
-
}
|
|
87
|
-
const data = providerData[0].json;
|
|
88
|
-
// Extract model information - handle various provider formats
|
|
89
|
-
// OpenAI, Anthropic, Groq typically use 'model'
|
|
90
|
-
// Some custom providers might use 'modelName' or 'name'
|
|
91
|
-
const modelName = data.model ||
|
|
92
|
-
data.modelName ||
|
|
93
|
-
data.name ||
|
|
94
|
-
data.model_name ||
|
|
95
|
-
'gpt-4o-mini';
|
|
96
|
-
// Try to detect provider from various fields
|
|
97
|
-
let providerStr = data.provider ||
|
|
98
|
-
data.providerName ||
|
|
99
|
-
'';
|
|
100
|
-
// If no explicit provider, try to infer from model name or base_url
|
|
101
|
-
if (!providerStr) {
|
|
102
|
-
if (modelName.includes('gpt') || modelName.includes('o1') || modelName.includes('o3')) {
|
|
103
|
-
providerStr = 'openai';
|
|
104
|
-
}
|
|
105
|
-
else if (modelName.includes('claude')) {
|
|
106
|
-
providerStr = 'anthropic';
|
|
107
|
-
}
|
|
108
|
-
else if (modelName.includes('llama') || modelName.includes('mixtral') || modelName.includes('qwen')) {
|
|
109
|
-
// Check for vLLM or Ollama
|
|
110
|
-
const baseUrl = data.baseUrl || data.base_url || '';
|
|
111
|
-
if (baseUrl.includes('ollama') || baseUrl.includes('11434')) {
|
|
112
|
-
providerStr = 'ollama';
|
|
113
|
-
}
|
|
114
|
-
else {
|
|
115
|
-
providerStr = 'vllm';
|
|
116
|
-
}
|
|
117
|
-
}
|
|
118
|
-
else {
|
|
119
|
-
providerStr = 'openai'; // Default fallback
|
|
120
|
-
}
|
|
121
|
-
}
|
|
122
|
-
// Extract API configuration
|
|
123
|
-
const apiKey = data.apiKey ||
|
|
124
|
-
data.api_key ||
|
|
125
|
-
data.token ||
|
|
126
|
-
'';
|
|
127
|
-
const baseUrl = data.baseUrl ||
|
|
128
|
-
data.base_url ||
|
|
129
|
-
undefined;
|
|
130
|
-
// Cost estimation - use provided cost or estimate based on provider
|
|
131
|
-
let cost = data.cost || data.modelCost;
|
|
132
|
-
if (!cost) {
|
|
133
|
-
// Rough estimates per 1K tokens (blended input/output)
|
|
134
|
-
if (providerStr === 'anthropic') {
|
|
135
|
-
cost = modelName.includes('opus') ? 0.03 : 0.006;
|
|
136
|
-
}
|
|
137
|
-
else if (providerStr === 'openai') {
|
|
138
|
-
if (modelName.includes('o1') || modelName.includes('o3'))
|
|
139
|
-
cost = 0.03;
|
|
140
|
-
else if (modelName.includes('gpt-4'))
|
|
141
|
-
cost = 0.006;
|
|
142
|
-
else
|
|
143
|
-
cost = 0.0004;
|
|
144
|
-
}
|
|
145
|
-
else {
|
|
146
|
-
cost = 0.001; // Default for local/other providers
|
|
147
|
-
}
|
|
148
|
-
}
|
|
149
|
-
const config = {
|
|
150
|
-
name: modelName,
|
|
151
|
-
provider: providerStr,
|
|
152
|
-
cost,
|
|
153
|
-
apiKey,
|
|
154
|
-
};
|
|
155
|
-
// Add baseUrl if provided (for vLLM, Ollama, custom endpoints)
|
|
156
|
-
if (baseUrl) {
|
|
157
|
-
config.baseUrl = baseUrl;
|
|
158
|
-
}
|
|
159
|
-
return config;
|
|
160
|
-
};
|
|
161
|
-
// Extract model configurations from provider inputs
|
|
162
|
-
const drafterConfig = extractModelConfig(drafterInputData, 'Drafter Model');
|
|
163
|
-
const verifierConfig = extractModelConfig(verifierInputData, 'Verifier Model');
|
|
164
|
-
const modelConfigs = [drafterConfig, verifierConfig];
|
|
165
|
-
// Get split output setting (same for all items)
|
|
166
|
-
const splitOutput = this.getNodeParameter('splitOutput', 0, false);
|
|
167
|
-
// Process each input item
|
|
168
|
-
for (let itemIndex = 0; itemIndex < inputData.length; itemIndex++) {
|
|
169
|
-
try {
|
|
170
|
-
// Get parameters
|
|
171
|
-
const qualityThreshold = this.getNodeParameter('qualityThreshold', itemIndex, 0.7);
|
|
172
|
-
const outputMode = this.getNodeParameter('output', itemIndex, 'contentOnly');
|
|
173
|
-
// Extract prompt from input data - support various field names
|
|
174
|
-
const item = inputData[itemIndex].json;
|
|
175
|
-
const prompt = item.prompt ||
|
|
176
|
-
item.message ||
|
|
177
|
-
item.query ||
|
|
178
|
-
item.text ||
|
|
179
|
-
item.input ||
|
|
180
|
-
JSON.stringify(item);
|
|
181
|
-
if (!prompt || prompt.length === 0) {
|
|
182
|
-
throw new n8n_workflow_1.NodeOperationError(this.getNode(), 'No prompt found in input data. Connect a node that provides prompt, message, query, text, or input field.', { itemIndex });
|
|
183
|
-
}
|
|
184
|
-
// Extract tools if provided (for function calling)
|
|
185
|
-
const tools = item.tools || undefined;
|
|
186
|
-
// Create CascadeAgent
|
|
187
|
-
const agent = new core_1.CascadeAgent({
|
|
188
|
-
models: modelConfigs,
|
|
189
|
-
quality: {
|
|
190
|
-
threshold: qualityThreshold,
|
|
191
|
-
requireMinimumTokens: 10,
|
|
192
|
-
},
|
|
193
|
-
});
|
|
194
|
-
// Prepare run options
|
|
195
|
-
const runOptions = {};
|
|
196
|
-
if (tools) {
|
|
197
|
-
runOptions.tools = tools;
|
|
198
|
-
}
|
|
199
|
-
// Execute cascade
|
|
200
|
-
const result = await agent.run(prompt, runOptions);
|
|
201
|
-
// Format output based on outputMode
|
|
202
|
-
let outputData;
|
|
203
|
-
switch (outputMode) {
|
|
204
|
-
case 'contentOnly':
|
|
205
|
-
outputData = {
|
|
206
|
-
content: result.content,
|
|
207
|
-
toolCalls: result.toolCalls,
|
|
208
|
-
};
|
|
209
|
-
break;
|
|
210
|
-
case 'metricsSummary':
|
|
211
|
-
outputData = {
|
|
212
|
-
content: result.content,
|
|
213
|
-
toolCalls: result.toolCalls,
|
|
214
|
-
modelUsed: result.modelUsed,
|
|
215
|
-
totalCost: result.totalCost,
|
|
216
|
-
savingsPercentage: result.savingsPercentage,
|
|
217
|
-
cascaded: result.cascaded,
|
|
218
|
-
draftAccepted: result.draftAccepted,
|
|
219
|
-
latencyMs: result.latencyMs,
|
|
220
|
-
};
|
|
221
|
-
break;
|
|
222
|
-
case 'fullMetrics':
|
|
223
|
-
outputData = {
|
|
224
|
-
...result,
|
|
225
|
-
// Add n8n-friendly summary
|
|
226
|
-
summary: {
|
|
227
|
-
saved: `${result.savingsPercentage?.toFixed(1)}%`,
|
|
228
|
-
cost: `$${result.totalCost.toFixed(6)}`,
|
|
229
|
-
model: result.modelUsed,
|
|
230
|
-
speed: `${result.latencyMs}ms`,
|
|
231
|
-
status: result.draftAccepted ? '✅ Draft accepted' : '⚠️ Escalated to verifier',
|
|
232
|
-
},
|
|
233
|
-
};
|
|
234
|
-
break;
|
|
235
|
-
default:
|
|
236
|
-
outputData = result;
|
|
237
|
-
}
|
|
238
|
-
const outputItem = {
|
|
239
|
-
json: outputData,
|
|
240
|
-
pairedItem: { item: itemIndex },
|
|
241
|
-
};
|
|
242
|
-
// Route to appropriate output based on splitOutput setting
|
|
243
|
-
if (splitOutput) {
|
|
244
|
-
if (result.draftAccepted) {
|
|
245
|
-
returnData.push(outputItem);
|
|
246
|
-
}
|
|
247
|
-
else {
|
|
248
|
-
escalatedData.push(outputItem);
|
|
249
|
-
}
|
|
250
|
-
}
|
|
251
|
-
else {
|
|
252
|
-
returnData.push(outputItem);
|
|
253
|
-
}
|
|
254
|
-
}
|
|
255
|
-
catch (error) {
|
|
256
|
-
if (this.continueOnFail()) {
|
|
257
|
-
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
258
|
-
const errorItem = {
|
|
259
|
-
json: {
|
|
260
|
-
error: errorMessage,
|
|
261
|
-
},
|
|
262
|
-
pairedItem: { item: itemIndex },
|
|
263
|
-
};
|
|
264
|
-
// Errors always go to first output
|
|
265
|
-
returnData.push(errorItem);
|
|
266
|
-
continue;
|
|
267
|
-
}
|
|
268
|
-
throw error;
|
|
269
|
-
}
|
|
270
|
-
}
|
|
271
|
-
// Return appropriate outputs based on splitOutput setting
|
|
272
|
-
if (splitOutput) {
|
|
273
|
-
// Split mode: Draft accepted goes to output 0, escalated to output 1
|
|
274
|
-
return [returnData, escalatedData];
|
|
275
|
-
}
|
|
276
|
-
else {
|
|
277
|
-
// Single output mode: All results go to output 0, output 1 is empty
|
|
278
|
-
return [returnData, []];
|
|
279
|
-
}
|
|
280
|
-
}
|
|
281
|
-
}
|
|
282
|
-
exports.CascadeFlow = CascadeFlow;
|
|
283
|
-
//# sourceMappingURL=CascadeFlow.node.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"CascadeFlow.node.js","sourceRoot":"","sources":["../../../nodes/CascadeFlow/CascadeFlow.node.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
<?xml version="1.0" encoding="UTF-8"?>
|
|
2
|
-
<svg id="Layer_1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 91.76 91.76">
|
|
3
|
-
<defs>
|
|
4
|
-
<style>
|
|
5
|
-
.cls-1 {
|
|
6
|
-
fill: #667eea;
|
|
7
|
-
}
|
|
8
|
-
</style>
|
|
9
|
-
</defs>
|
|
10
|
-
<path class="cls-1" d="M38.19,54.36c-4.15-4.15-4.15-10.87,0-15.02,4.15-4.15,10.87-4.15,15.02,0,4.15,4.15,4.15,10.87,0,15.02s-10.87,4.15-15.02,0Z"/>
|
|
11
|
-
<path class="cls-1" d="M63.4,91.76H28.7c-7.93,0-14.35-6.42-14.35-14.35h49.05v14.35Z"/>
|
|
12
|
-
<path class="cls-1" d="M14.35,77.41c-7.93,0-14.35-6.42-14.35-14.35V29.8h14.35v47.61Z"/>
|
|
13
|
-
<path class="cls-1" d="M28.36,0h34.7c7.93,0,14.35,6.42,14.35,14.35H28.36V0Z"/>
|
|
14
|
-
<path class="cls-1" d="M77.41,14.35c7.93,0,14.35,6.42,14.35,14.35v33.26h-14.35V14.35Z"/>
|
|
15
|
-
</svg>
|