@juspay/neurolink 9.3.0 → 9.5.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/CHANGELOG.md +12 -0
- package/README.md +8 -8
- package/dist/cli/commands/config.d.ts +3 -3
- package/dist/cli/index.js +1 -0
- package/dist/index.d.ts +35 -0
- package/dist/index.js +17 -0
- package/dist/lib/agent/directTools.d.ts +5 -5
- package/dist/lib/index.d.ts +35 -0
- package/dist/lib/index.js +17 -0
- package/dist/lib/neurolink.d.ts +12 -1
- package/dist/lib/neurolink.js +265 -4
- package/dist/lib/server/utils/validation.d.ts +8 -8
- package/dist/lib/types/generateTypes.d.ts +28 -0
- package/dist/lib/types/index.d.ts +6 -0
- package/dist/lib/types/index.js +12 -0
- package/dist/lib/types/modelTypes.d.ts +2 -2
- package/dist/lib/types/streamTypes.d.ts +35 -0
- package/dist/lib/types/workflowTypes.d.ts +558 -0
- package/dist/lib/types/workflowTypes.js +32 -0
- package/dist/lib/workflow/LAYER-EXAMPLES.d.ts +13 -0
- package/dist/lib/workflow/LAYER-EXAMPLES.js +312 -0
- package/dist/lib/workflow/PROMPT-EXAMPLES.d.ts +117 -0
- package/dist/lib/workflow/PROMPT-EXAMPLES.js +246 -0
- package/dist/lib/workflow/config.d.ts +1569 -0
- package/dist/lib/workflow/config.js +399 -0
- package/dist/lib/workflow/core/ensembleExecutor.d.ts +56 -0
- package/dist/lib/workflow/core/ensembleExecutor.js +398 -0
- package/dist/lib/workflow/core/judgeScorer.d.ts +26 -0
- package/dist/lib/workflow/core/judgeScorer.js +527 -0
- package/dist/lib/workflow/core/responseConditioner.d.ts +22 -0
- package/dist/lib/workflow/core/responseConditioner.js +226 -0
- package/dist/lib/workflow/core/types/conditionerTypes.d.ts +7 -0
- package/dist/lib/workflow/core/types/conditionerTypes.js +8 -0
- package/dist/lib/workflow/core/types/ensembleTypes.d.ts +7 -0
- package/dist/lib/workflow/core/types/ensembleTypes.js +8 -0
- package/dist/lib/workflow/core/types/index.d.ts +7 -0
- package/dist/lib/workflow/core/types/index.js +8 -0
- package/dist/lib/workflow/core/types/judgeTypes.d.ts +7 -0
- package/dist/lib/workflow/core/types/judgeTypes.js +8 -0
- package/dist/lib/workflow/core/types/layerTypes.d.ts +7 -0
- package/dist/lib/workflow/core/types/layerTypes.js +8 -0
- package/dist/lib/workflow/core/types/registryTypes.d.ts +7 -0
- package/dist/lib/workflow/core/types/registryTypes.js +8 -0
- package/dist/lib/workflow/core/workflowRegistry.d.ts +73 -0
- package/dist/lib/workflow/core/workflowRegistry.js +305 -0
- package/dist/lib/workflow/core/workflowRunner.d.ts +115 -0
- package/dist/lib/workflow/core/workflowRunner.js +554 -0
- package/dist/lib/workflow/index.d.ts +36 -0
- package/dist/lib/workflow/index.js +51 -0
- package/dist/lib/workflow/types.d.ts +19 -0
- package/dist/lib/workflow/types.js +10 -0
- package/dist/lib/workflow/utils/types/index.d.ts +7 -0
- package/dist/lib/workflow/utils/types/index.js +8 -0
- package/dist/lib/workflow/utils/types/metricsTypes.d.ts +7 -0
- package/dist/lib/workflow/utils/types/metricsTypes.js +8 -0
- package/dist/lib/workflow/utils/types/validationTypes.d.ts +7 -0
- package/dist/lib/workflow/utils/types/validationTypes.js +8 -0
- package/dist/lib/workflow/utils/workflowMetrics.d.ts +76 -0
- package/dist/lib/workflow/utils/workflowMetrics.js +312 -0
- package/dist/lib/workflow/utils/workflowValidation.d.ts +29 -0
- package/dist/lib/workflow/utils/workflowValidation.js +421 -0
- package/dist/lib/workflow/workflows/adaptiveWorkflow.d.ts +72 -0
- package/dist/lib/workflow/workflows/adaptiveWorkflow.js +367 -0
- package/dist/lib/workflow/workflows/consensusWorkflow.d.ts +69 -0
- package/dist/lib/workflow/workflows/consensusWorkflow.js +193 -0
- package/dist/lib/workflow/workflows/fallbackWorkflow.d.ts +49 -0
- package/dist/lib/workflow/workflows/fallbackWorkflow.js +226 -0
- package/dist/lib/workflow/workflows/multiJudgeWorkflow.d.ts +70 -0
- package/dist/lib/workflow/workflows/multiJudgeWorkflow.js +352 -0
- package/dist/neurolink.d.ts +12 -1
- package/dist/neurolink.js +265 -4
- package/dist/types/generateTypes.d.ts +28 -0
- package/dist/types/index.d.ts +6 -0
- package/dist/types/index.js +12 -0
- package/dist/types/streamTypes.d.ts +35 -0
- package/dist/types/workflowTypes.d.ts +558 -0
- package/dist/types/workflowTypes.js +31 -0
- package/dist/workflow/LAYER-EXAMPLES.d.ts +13 -0
- package/dist/workflow/LAYER-EXAMPLES.js +311 -0
- package/dist/workflow/PROMPT-EXAMPLES.d.ts +117 -0
- package/dist/workflow/PROMPT-EXAMPLES.js +245 -0
- package/dist/workflow/config.d.ts +1569 -0
- package/dist/workflow/config.js +398 -0
- package/dist/workflow/core/ensembleExecutor.d.ts +56 -0
- package/dist/workflow/core/ensembleExecutor.js +397 -0
- package/dist/workflow/core/judgeScorer.d.ts +26 -0
- package/dist/workflow/core/judgeScorer.js +526 -0
- package/dist/workflow/core/responseConditioner.d.ts +22 -0
- package/dist/workflow/core/responseConditioner.js +225 -0
- package/dist/workflow/core/types/conditionerTypes.d.ts +7 -0
- package/dist/workflow/core/types/conditionerTypes.js +7 -0
- package/dist/workflow/core/types/ensembleTypes.d.ts +7 -0
- package/dist/workflow/core/types/ensembleTypes.js +7 -0
- package/dist/workflow/core/types/index.d.ts +7 -0
- package/dist/workflow/core/types/index.js +7 -0
- package/dist/workflow/core/types/judgeTypes.d.ts +7 -0
- package/dist/workflow/core/types/judgeTypes.js +7 -0
- package/dist/workflow/core/types/layerTypes.d.ts +7 -0
- package/dist/workflow/core/types/layerTypes.js +7 -0
- package/dist/workflow/core/types/registryTypes.d.ts +7 -0
- package/dist/workflow/core/types/registryTypes.js +7 -0
- package/dist/workflow/core/workflowRegistry.d.ts +73 -0
- package/dist/workflow/core/workflowRegistry.js +304 -0
- package/dist/workflow/core/workflowRunner.d.ts +115 -0
- package/dist/workflow/core/workflowRunner.js +553 -0
- package/dist/workflow/index.d.ts +36 -0
- package/dist/workflow/index.js +50 -0
- package/dist/workflow/types.d.ts +19 -0
- package/dist/workflow/types.js +9 -0
- package/dist/workflow/utils/types/index.d.ts +7 -0
- package/dist/workflow/utils/types/index.js +7 -0
- package/dist/workflow/utils/types/metricsTypes.d.ts +7 -0
- package/dist/workflow/utils/types/metricsTypes.js +7 -0
- package/dist/workflow/utils/types/validationTypes.d.ts +7 -0
- package/dist/workflow/utils/types/validationTypes.js +7 -0
- package/dist/workflow/utils/workflowMetrics.d.ts +76 -0
- package/dist/workflow/utils/workflowMetrics.js +311 -0
- package/dist/workflow/utils/workflowValidation.d.ts +29 -0
- package/dist/workflow/utils/workflowValidation.js +420 -0
- package/dist/workflow/workflows/adaptiveWorkflow.d.ts +72 -0
- package/dist/workflow/workflows/adaptiveWorkflow.js +366 -0
- package/dist/workflow/workflows/consensusWorkflow.d.ts +69 -0
- package/dist/workflow/workflows/consensusWorkflow.js +192 -0
- package/dist/workflow/workflows/fallbackWorkflow.d.ts +49 -0
- package/dist/workflow/workflows/fallbackWorkflow.js +225 -0
- package/dist/workflow/workflows/multiJudgeWorkflow.d.ts +70 -0
- package/dist/workflow/workflows/multiJudgeWorkflow.js +351 -0
- package/package.json +3 -2
|
@@ -0,0 +1,398 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* workflow/core/ensembleExecutor.ts
|
|
3
|
+
* Parallel execution engine for ensemble workflows
|
|
4
|
+
*/
|
|
5
|
+
import pLimit from "p-limit";
|
|
6
|
+
import { AIProviderFactory } from "../../core/factory.js";
|
|
7
|
+
import { logger } from "../../utils/logger.js";
|
|
8
|
+
import { WorkflowError } from "../types.js";
|
|
9
|
+
const functionTag = "EnsembleExecutor";
|
|
10
|
+
// ============================================================================
|
|
11
|
+
// EXECUTION FUNCTIONS
|
|
12
|
+
// ============================================================================
|
|
13
|
+
/**
|
|
14
|
+
* Execute ensemble of models in parallel
|
|
15
|
+
* @param options - Execution options including prompt and models
|
|
16
|
+
* @returns Ensemble execution result with all responses and metrics
|
|
17
|
+
*/
|
|
18
|
+
export async function executeEnsemble(options) {
|
|
19
|
+
const startTime = Date.now();
|
|
20
|
+
const { prompt, models, executionConfig, systemPrompt, workflowDefaults } = options;
|
|
21
|
+
logger.info(`[${functionTag}] Starting ensemble execution`, {
|
|
22
|
+
modelCount: models.length,
|
|
23
|
+
parallelism: executionConfig?.parallelism || 10,
|
|
24
|
+
});
|
|
25
|
+
// Set up concurrency limiter
|
|
26
|
+
const limit = pLimit(executionConfig?.parallelism || 10);
|
|
27
|
+
// Create execution promises
|
|
28
|
+
const executionPromises = models.map((model) => limit(() => executeModel({
|
|
29
|
+
model,
|
|
30
|
+
prompt,
|
|
31
|
+
systemPrompt,
|
|
32
|
+
timeout: model.timeout || executionConfig?.modelTimeout || 15000,
|
|
33
|
+
}, workflowDefaults?.systemPrompt)));
|
|
34
|
+
// Execute all models
|
|
35
|
+
const responses = await Promise.all(executionPromises);
|
|
36
|
+
const totalTime = Date.now() - startTime;
|
|
37
|
+
const successCount = responses.filter((r) => r.status === "success").length;
|
|
38
|
+
const failureCount = responses.filter((r) => r.status === "failure").length;
|
|
39
|
+
// Collect errors
|
|
40
|
+
const errors = responses
|
|
41
|
+
.filter((r) => r.status === "failure" && r.error)
|
|
42
|
+
.map((r) => {
|
|
43
|
+
const errorMsg = typeof r.error === "string" ? r.error : "Unknown error";
|
|
44
|
+
return new WorkflowError(errorMsg, {
|
|
45
|
+
code: "MODEL_EXECUTION_ERROR",
|
|
46
|
+
workflowId: "ensemble",
|
|
47
|
+
phase: "ensemble",
|
|
48
|
+
retryable: true,
|
|
49
|
+
});
|
|
50
|
+
});
|
|
51
|
+
// Check if we met minimum response threshold
|
|
52
|
+
const minResponses = executionConfig?.minResponses || 1;
|
|
53
|
+
if (successCount < minResponses) {
|
|
54
|
+
const error = new WorkflowError(`Insufficient successful responses: ${successCount}/${minResponses} required`, {
|
|
55
|
+
code: "INSUFFICIENT_RESPONSES",
|
|
56
|
+
workflowId: "ensemble",
|
|
57
|
+
phase: "ensemble",
|
|
58
|
+
retryable: false,
|
|
59
|
+
});
|
|
60
|
+
errors.push(error);
|
|
61
|
+
}
|
|
62
|
+
logger.info(`[${functionTag}] Ensemble execution completed`, {
|
|
63
|
+
totalTime,
|
|
64
|
+
successCount,
|
|
65
|
+
failureCount,
|
|
66
|
+
totalResponses: responses.length,
|
|
67
|
+
});
|
|
68
|
+
return {
|
|
69
|
+
responses,
|
|
70
|
+
totalTime,
|
|
71
|
+
successCount,
|
|
72
|
+
failureCount,
|
|
73
|
+
errors,
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Execute a single model with timeout and error handling
|
|
78
|
+
* @param options - Model execution options
|
|
79
|
+
* @returns Ensemble response with result or error
|
|
80
|
+
*/
|
|
81
|
+
async function executeModel(options, workflowDefaultSystemPrompt) {
|
|
82
|
+
const { model, prompt, systemPrompt, timeout } = options;
|
|
83
|
+
const startTime = Date.now();
|
|
84
|
+
logger.debug(`[${functionTag}] Executing model`, {
|
|
85
|
+
provider: model.provider,
|
|
86
|
+
model: model.model,
|
|
87
|
+
timeout,
|
|
88
|
+
});
|
|
89
|
+
try {
|
|
90
|
+
// Create provider instance
|
|
91
|
+
const provider = await createProvider(model);
|
|
92
|
+
// Resolve system prompt with hierarchical fallback:
|
|
93
|
+
// 1. Direct parameter (highest priority)
|
|
94
|
+
// 2. Model-specific systemPrompt
|
|
95
|
+
// 3. Workflow-level default
|
|
96
|
+
// 4. undefined (provider default)
|
|
97
|
+
const resolvedSystemPrompt = systemPrompt || model.systemPrompt || workflowDefaultSystemPrompt;
|
|
98
|
+
// Execute with timeout
|
|
99
|
+
const result = await executeWithTimeout(async () => {
|
|
100
|
+
return await provider.generate({
|
|
101
|
+
prompt,
|
|
102
|
+
systemPrompt: resolvedSystemPrompt,
|
|
103
|
+
temperature: model.temperature,
|
|
104
|
+
maxTokens: model.maxTokens,
|
|
105
|
+
});
|
|
106
|
+
}, timeout, `Model ${model.provider}/${model.model} timed out after ${timeout}ms`);
|
|
107
|
+
const responseTime = Date.now() - startTime;
|
|
108
|
+
logger.debug(`[${functionTag}] Model execution successful`, {
|
|
109
|
+
provider: model.provider,
|
|
110
|
+
model: model.model,
|
|
111
|
+
responseTime,
|
|
112
|
+
contentLength: result?.content?.length || 0,
|
|
113
|
+
});
|
|
114
|
+
return {
|
|
115
|
+
provider: model.provider,
|
|
116
|
+
model: model.model,
|
|
117
|
+
modelLabel: model.label,
|
|
118
|
+
content: result?.content || "",
|
|
119
|
+
status: "success",
|
|
120
|
+
responseTime,
|
|
121
|
+
usage: result?.usage
|
|
122
|
+
? {
|
|
123
|
+
inputTokens: result.usage.input,
|
|
124
|
+
outputTokens: result.usage.output,
|
|
125
|
+
totalTokens: result.usage.total,
|
|
126
|
+
}
|
|
127
|
+
: undefined,
|
|
128
|
+
metadata: model.metadata,
|
|
129
|
+
timestamp: new Date().toISOString(),
|
|
130
|
+
};
|
|
131
|
+
}
|
|
132
|
+
catch (error) {
|
|
133
|
+
const responseTime = Date.now() - startTime;
|
|
134
|
+
const err = error;
|
|
135
|
+
logger.warn(`[${functionTag}] Model execution failed`, {
|
|
136
|
+
provider: model.provider,
|
|
137
|
+
model: model.model,
|
|
138
|
+
error: err.message,
|
|
139
|
+
responseTime,
|
|
140
|
+
});
|
|
141
|
+
return {
|
|
142
|
+
provider: model.provider,
|
|
143
|
+
model: model.model,
|
|
144
|
+
modelLabel: model.label,
|
|
145
|
+
content: "",
|
|
146
|
+
status: "failure",
|
|
147
|
+
responseTime,
|
|
148
|
+
error: err.message,
|
|
149
|
+
timestamp: new Date().toISOString(),
|
|
150
|
+
};
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
/**
|
|
154
|
+
* Create provider instance from model config
|
|
155
|
+
* @param model - Model configuration
|
|
156
|
+
* @returns Provider instance
|
|
157
|
+
*/
|
|
158
|
+
async function createProvider(model) {
|
|
159
|
+
return await AIProviderFactory.createProvider(model.provider, model.model);
|
|
160
|
+
}
|
|
161
|
+
/**
|
|
162
|
+
* Execute function with timeout
|
|
163
|
+
* @param fn - Async function to execute
|
|
164
|
+
* @param timeoutMs - Timeout in milliseconds
|
|
165
|
+
* @param timeoutMessage - Error message for timeout
|
|
166
|
+
* @returns Result of function execution
|
|
167
|
+
*/
|
|
168
|
+
async function executeWithTimeout(fn, timeoutMs, timeoutMessage) {
|
|
169
|
+
let timeoutHandle;
|
|
170
|
+
const timeoutPromise = new Promise((_, reject) => {
|
|
171
|
+
timeoutHandle = setTimeout(() => {
|
|
172
|
+
const error = new WorkflowError(timeoutMessage, {
|
|
173
|
+
code: "TIMEOUT",
|
|
174
|
+
workflowId: "ensemble",
|
|
175
|
+
phase: "ensemble",
|
|
176
|
+
retryable: true,
|
|
177
|
+
});
|
|
178
|
+
reject(error);
|
|
179
|
+
}, timeoutMs);
|
|
180
|
+
});
|
|
181
|
+
try {
|
|
182
|
+
const result = await Promise.race([fn(), timeoutPromise]);
|
|
183
|
+
if (timeoutHandle) {
|
|
184
|
+
clearTimeout(timeoutHandle);
|
|
185
|
+
}
|
|
186
|
+
return result;
|
|
187
|
+
}
|
|
188
|
+
catch (error) {
|
|
189
|
+
if (timeoutHandle) {
|
|
190
|
+
clearTimeout(timeoutHandle);
|
|
191
|
+
}
|
|
192
|
+
throw error;
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
/**
|
|
196
|
+
* Filter successful responses from ensemble result
|
|
197
|
+
* @param responses - Array of ensemble responses
|
|
198
|
+
* @returns Array of successful responses
|
|
199
|
+
*/
|
|
200
|
+
export function getSuccessfulResponses(responses) {
|
|
201
|
+
return responses.filter((r) => r.status === "success");
|
|
202
|
+
}
|
|
203
|
+
/**
|
|
204
|
+
* Get response by model identifier
|
|
205
|
+
* @param responses - Array of ensemble responses
|
|
206
|
+
* @param provider - Provider name
|
|
207
|
+
* @param model - Model name
|
|
208
|
+
* @returns Response for specified model or undefined
|
|
209
|
+
*/
|
|
210
|
+
export function getResponseByModel(responses, provider, model) {
|
|
211
|
+
return responses.find((r) => r.provider === provider && r.model === model);
|
|
212
|
+
}
|
|
213
|
+
/**
|
|
214
|
+
* Calculate total tokens used across all responses
|
|
215
|
+
* @param responses - Array of ensemble responses
|
|
216
|
+
* @returns Total token count
|
|
217
|
+
*/
|
|
218
|
+
export function calculateTotalTokens(responses) {
|
|
219
|
+
return responses.reduce((total, response) => {
|
|
220
|
+
if (response.usage?.totalTokens) {
|
|
221
|
+
return total + response.usage.totalTokens;
|
|
222
|
+
}
|
|
223
|
+
return total;
|
|
224
|
+
}, 0);
|
|
225
|
+
}
|
|
226
|
+
/**
|
|
227
|
+
* Sort responses by response time
|
|
228
|
+
* @param responses - Array of ensemble responses
|
|
229
|
+
* @param ascending - Sort in ascending order (default: true)
|
|
230
|
+
* @returns Sorted array of responses
|
|
231
|
+
*/
|
|
232
|
+
export function sortByResponseTime(responses, ascending = true) {
|
|
233
|
+
return [...responses].sort((a, b) => {
|
|
234
|
+
return ascending
|
|
235
|
+
? a.responseTime - b.responseTime
|
|
236
|
+
: b.responseTime - a.responseTime;
|
|
237
|
+
});
|
|
238
|
+
}
|
|
239
|
+
/**
|
|
240
|
+
* Get fastest successful response
|
|
241
|
+
* @param responses - Array of ensemble responses
|
|
242
|
+
* @returns Fastest successful response or undefined
|
|
243
|
+
*/
|
|
244
|
+
export function getFastestResponse(responses) {
|
|
245
|
+
const successful = getSuccessfulResponses(responses);
|
|
246
|
+
if (successful.length === 0) {
|
|
247
|
+
return undefined;
|
|
248
|
+
}
|
|
249
|
+
return sortByResponseTime(successful, true)[0];
|
|
250
|
+
}
|
|
251
|
+
// ============================================================================
|
|
252
|
+
// LAYER-BASED EXECUTION (for ModelGroups)
|
|
253
|
+
// ============================================================================
|
|
254
|
+
/**
|
|
255
|
+
* Execute model groups sequentially (layers)
|
|
256
|
+
* Each group executes according to its executionStrategy
|
|
257
|
+
* @param groups - Array of model groups to execute
|
|
258
|
+
* @param prompt - User prompt
|
|
259
|
+
* @param executionConfig - Execution configuration
|
|
260
|
+
* @param systemPrompt - Direct system prompt override
|
|
261
|
+
* @param workflowDefaultSystemPrompt - Workflow-level default system prompt
|
|
262
|
+
* @returns Ensemble execution result with all responses
|
|
263
|
+
*/
|
|
264
|
+
export async function executeModelGroups(groups, prompt, _executionConfig, systemPrompt, workflowDefaultSystemPrompt) {
|
|
265
|
+
const startTime = Date.now();
|
|
266
|
+
const allResponses = [];
|
|
267
|
+
const allErrors = [];
|
|
268
|
+
let totalSuccessCount = 0;
|
|
269
|
+
let totalFailureCount = 0;
|
|
270
|
+
logger.info(`[${functionTag}] Executing ${groups.length} model groups sequentially`);
|
|
271
|
+
// Execute groups sequentially
|
|
272
|
+
for (const group of groups) {
|
|
273
|
+
logger.info(`[${functionTag}] Executing group: ${group.id}`, {
|
|
274
|
+
groupName: group.name,
|
|
275
|
+
modelCount: group.models.length,
|
|
276
|
+
strategy: group.executionStrategy,
|
|
277
|
+
});
|
|
278
|
+
const layerResult = await executeLayer({
|
|
279
|
+
group,
|
|
280
|
+
prompt,
|
|
281
|
+
systemPrompt,
|
|
282
|
+
workflowDefaultSystemPrompt,
|
|
283
|
+
});
|
|
284
|
+
// Collect results
|
|
285
|
+
allResponses.push(...layerResult.responses);
|
|
286
|
+
totalSuccessCount += layerResult.successCount;
|
|
287
|
+
totalFailureCount += layerResult.failureCount;
|
|
288
|
+
// Check if we should continue to next group
|
|
289
|
+
if (!layerResult.shouldContinue) {
|
|
290
|
+
logger.warn(`[${functionTag}] Stopping execution after group: ${group.id}`, {
|
|
291
|
+
reason: `Failed to meet minSuccessful threshold (${group.minSuccessful || 1})`,
|
|
292
|
+
});
|
|
293
|
+
// Add error for incomplete execution
|
|
294
|
+
if (group.continueOnFailure === false) {
|
|
295
|
+
const error = new WorkflowError(`Group ${group.id} failed to meet minSuccessful threshold`, {
|
|
296
|
+
code: "GROUP_EXECUTION_FAILED",
|
|
297
|
+
workflowId: "ensemble",
|
|
298
|
+
phase: "ensemble",
|
|
299
|
+
retryable: false,
|
|
300
|
+
details: {
|
|
301
|
+
groupId: group.id,
|
|
302
|
+
successCount: layerResult.successCount,
|
|
303
|
+
minRequired: group.minSuccessful || 1,
|
|
304
|
+
},
|
|
305
|
+
});
|
|
306
|
+
allErrors.push(error);
|
|
307
|
+
}
|
|
308
|
+
break;
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
const totalTime = Date.now() - startTime;
|
|
312
|
+
logger.info(`[${functionTag}] Model groups execution completed`, {
|
|
313
|
+
totalTime,
|
|
314
|
+
totalResponses: allResponses.length,
|
|
315
|
+
successCount: totalSuccessCount,
|
|
316
|
+
failureCount: totalFailureCount,
|
|
317
|
+
});
|
|
318
|
+
return {
|
|
319
|
+
responses: allResponses,
|
|
320
|
+
totalTime,
|
|
321
|
+
successCount: totalSuccessCount,
|
|
322
|
+
failureCount: totalFailureCount,
|
|
323
|
+
errors: allErrors,
|
|
324
|
+
};
|
|
325
|
+
}
|
|
326
|
+
/**
|
|
327
|
+
* Execute a single layer/group of models
|
|
328
|
+
* @param options - Layer execution options
|
|
329
|
+
* @returns Layer execution result
|
|
330
|
+
*/
|
|
331
|
+
async function executeLayer(options) {
|
|
332
|
+
const startTime = Date.now();
|
|
333
|
+
const { group, prompt, systemPrompt, workflowDefaultSystemPrompt } = options;
|
|
334
|
+
if (group.executionStrategy === "parallel") {
|
|
335
|
+
// Execute all models in parallel
|
|
336
|
+
const result = await executeEnsemble({
|
|
337
|
+
prompt,
|
|
338
|
+
models: group.models,
|
|
339
|
+
executionConfig: {
|
|
340
|
+
parallelism: group.parallelism || 10,
|
|
341
|
+
modelTimeout: group.timeout,
|
|
342
|
+
},
|
|
343
|
+
systemPrompt,
|
|
344
|
+
workflowDefaults: {
|
|
345
|
+
systemPrompt: workflowDefaultSystemPrompt,
|
|
346
|
+
},
|
|
347
|
+
});
|
|
348
|
+
const shouldContinue = result.successCount >= (group.minSuccessful || 1) ||
|
|
349
|
+
group.continueOnFailure !== false;
|
|
350
|
+
return {
|
|
351
|
+
groupId: group.id,
|
|
352
|
+
responses: result.responses,
|
|
353
|
+
successCount: result.successCount,
|
|
354
|
+
failureCount: result.failureCount,
|
|
355
|
+
executionTime: Date.now() - startTime,
|
|
356
|
+
shouldContinue,
|
|
357
|
+
};
|
|
358
|
+
}
|
|
359
|
+
else {
|
|
360
|
+
// Execute models sequentially (one after another)
|
|
361
|
+
const responses = [];
|
|
362
|
+
let successCount = 0;
|
|
363
|
+
let failureCount = 0;
|
|
364
|
+
for (const model of group.models) {
|
|
365
|
+
const response = await executeModel({
|
|
366
|
+
model,
|
|
367
|
+
prompt,
|
|
368
|
+
systemPrompt,
|
|
369
|
+
timeout: model.timeout || group.timeout || 15000,
|
|
370
|
+
}, workflowDefaultSystemPrompt);
|
|
371
|
+
responses.push(response);
|
|
372
|
+
if (response.status === "success") {
|
|
373
|
+
successCount++;
|
|
374
|
+
}
|
|
375
|
+
else {
|
|
376
|
+
failureCount++;
|
|
377
|
+
}
|
|
378
|
+
logger.debug(`[${functionTag}] Sequential execution progress`, {
|
|
379
|
+
groupId: group.id,
|
|
380
|
+
model: `${model.provider}/${model.model}`,
|
|
381
|
+
status: response.status,
|
|
382
|
+
successCount,
|
|
383
|
+
failureCount,
|
|
384
|
+
});
|
|
385
|
+
}
|
|
386
|
+
const shouldContinue = successCount >= (group.minSuccessful || 1) ||
|
|
387
|
+
group.continueOnFailure !== false;
|
|
388
|
+
return {
|
|
389
|
+
groupId: group.id,
|
|
390
|
+
responses,
|
|
391
|
+
successCount,
|
|
392
|
+
failureCount,
|
|
393
|
+
executionTime: Date.now() - startTime,
|
|
394
|
+
shouldContinue,
|
|
395
|
+
};
|
|
396
|
+
}
|
|
397
|
+
}
|
|
398
|
+
//# sourceMappingURL=ensembleExecutor.js.map
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* workflow/core/judgeScorer.ts
|
|
3
|
+
* Judge-based scoring system for ensemble response evaluation
|
|
4
|
+
*/
|
|
5
|
+
import type { EnsembleResponse, JudgeScores, MultiJudgeScores } from "../types.js";
|
|
6
|
+
import type { ScoreOptions, ScoreResult } from "./types/index.js";
|
|
7
|
+
/**
|
|
8
|
+
* Execute judge scoring on ensemble responses
|
|
9
|
+
* @param options - Scoring options including judges and responses
|
|
10
|
+
* @returns Score result with judge evaluation
|
|
11
|
+
*/
|
|
12
|
+
export declare function scoreEnsemble(options: ScoreOptions): Promise<ScoreResult>;
|
|
13
|
+
/**
|
|
14
|
+
* Get best response from judge scores
|
|
15
|
+
* @param scores - Judge scores or multi-judge scores
|
|
16
|
+
* @param responses - Original ensemble responses
|
|
17
|
+
* @returns Best ensemble response
|
|
18
|
+
*/
|
|
19
|
+
export declare function getBestResponse(scores: JudgeScores | MultiJudgeScores, responses: EnsembleResponse[]): EnsembleResponse | undefined;
|
|
20
|
+
/**
|
|
21
|
+
* Get ranked responses
|
|
22
|
+
* @param scores - Judge scores or multi-judge scores
|
|
23
|
+
* @param responses - Original ensemble responses
|
|
24
|
+
* @returns Responses sorted by ranking
|
|
25
|
+
*/
|
|
26
|
+
export declare function getRankedResponses(scores: JudgeScores | MultiJudgeScores, responses: EnsembleResponse[]): EnsembleResponse[];
|