@juspay/neurolink 7.6.1 → 7.7.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 +9 -4
- package/README.md +78 -3
- package/dist/cli/commands/config.d.ts +275 -3
- package/dist/cli/commands/config.js +121 -0
- package/dist/cli/commands/mcp.js +77 -28
- package/dist/cli/factories/commandFactory.js +359 -6
- package/dist/core/analytics.js +7 -27
- package/dist/core/baseProvider.js +43 -4
- package/dist/core/constants.d.ts +46 -0
- package/dist/core/constants.js +47 -0
- package/dist/core/dynamicModels.d.ts +16 -4
- package/dist/core/dynamicModels.js +130 -26
- package/dist/core/evaluation.js +5 -1
- package/dist/core/evaluationProviders.d.ts +6 -2
- package/dist/core/evaluationProviders.js +41 -125
- package/dist/core/factory.d.ts +5 -0
- package/dist/core/factory.js +62 -50
- package/dist/core/modelConfiguration.d.ts +246 -0
- package/dist/core/modelConfiguration.js +775 -0
- package/dist/core/types.d.ts +22 -3
- package/dist/core/types.js +5 -1
- package/dist/factories/providerRegistry.js +3 -3
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/lib/core/analytics.js +7 -27
- package/dist/lib/core/baseProvider.js +43 -4
- package/dist/lib/core/constants.d.ts +46 -0
- package/dist/lib/core/constants.js +47 -0
- package/dist/lib/core/dynamicModels.d.ts +16 -4
- package/dist/lib/core/dynamicModels.js +130 -26
- package/dist/lib/core/evaluation.js +5 -1
- package/dist/lib/core/evaluationProviders.d.ts +6 -2
- package/dist/lib/core/evaluationProviders.js +41 -125
- package/dist/lib/core/factory.d.ts +5 -0
- package/dist/lib/core/factory.js +63 -50
- package/dist/lib/core/modelConfiguration.d.ts +246 -0
- package/dist/lib/core/modelConfiguration.js +775 -0
- package/dist/lib/core/types.d.ts +22 -3
- package/dist/lib/core/types.js +5 -1
- package/dist/lib/factories/providerRegistry.js +3 -3
- package/dist/lib/index.d.ts +1 -1
- package/dist/lib/index.js +1 -1
- package/dist/lib/mcp/factory.d.ts +5 -5
- package/dist/lib/mcp/factory.js +2 -2
- package/dist/lib/mcp/servers/utilities/utilityServer.d.ts +1 -1
- package/dist/lib/mcp/servers/utilities/utilityServer.js +1 -1
- package/dist/lib/mcp/toolRegistry.js +2 -2
- package/dist/lib/neurolink.d.ts +168 -12
- package/dist/lib/neurolink.js +685 -123
- package/dist/lib/providers/anthropic.js +52 -2
- package/dist/lib/providers/googleAiStudio.js +4 -0
- package/dist/lib/providers/googleVertex.d.ts +75 -9
- package/dist/lib/providers/googleVertex.js +365 -46
- package/dist/lib/providers/huggingFace.d.ts +52 -11
- package/dist/lib/providers/huggingFace.js +180 -42
- package/dist/lib/providers/litellm.d.ts +9 -9
- package/dist/lib/providers/litellm.js +103 -16
- package/dist/lib/providers/ollama.d.ts +52 -17
- package/dist/lib/providers/ollama.js +276 -68
- package/dist/lib/sdk/toolRegistration.d.ts +42 -0
- package/dist/lib/sdk/toolRegistration.js +269 -27
- package/dist/lib/telemetry/telemetryService.d.ts +6 -0
- package/dist/lib/telemetry/telemetryService.js +38 -3
- package/dist/lib/types/contextTypes.d.ts +75 -11
- package/dist/lib/types/contextTypes.js +227 -1
- package/dist/lib/types/domainTypes.d.ts +62 -0
- package/dist/lib/types/domainTypes.js +5 -0
- package/dist/lib/types/generateTypes.d.ts +52 -0
- package/dist/lib/types/index.d.ts +1 -0
- package/dist/lib/types/mcpTypes.d.ts +1 -1
- package/dist/lib/types/mcpTypes.js +1 -1
- package/dist/lib/types/streamTypes.d.ts +14 -0
- package/dist/lib/types/universalProviderOptions.d.ts +1 -1
- package/dist/lib/utils/errorHandling.d.ts +142 -0
- package/dist/lib/utils/errorHandling.js +316 -0
- package/dist/lib/utils/factoryProcessing.d.ts +74 -0
- package/dist/lib/utils/factoryProcessing.js +588 -0
- package/dist/lib/utils/optionsConversion.d.ts +54 -0
- package/dist/lib/utils/optionsConversion.js +126 -0
- package/dist/lib/utils/optionsUtils.d.ts +246 -0
- package/dist/lib/utils/optionsUtils.js +960 -0
- package/dist/lib/utils/providerHealth.d.ts +107 -0
- package/dist/lib/utils/providerHealth.js +507 -0
- package/dist/lib/utils/providerUtils.d.ts +17 -0
- package/dist/lib/utils/providerUtils.js +271 -16
- package/dist/lib/utils/timeout.js +1 -1
- package/dist/lib/utils/tokenLimits.d.ts +33 -0
- package/dist/lib/utils/tokenLimits.js +118 -0
- package/dist/mcp/factory.d.ts +5 -5
- package/dist/mcp/factory.js +2 -2
- package/dist/mcp/servers/utilities/utilityServer.d.ts +1 -1
- package/dist/mcp/servers/utilities/utilityServer.js +1 -1
- package/dist/mcp/toolRegistry.js +2 -2
- package/dist/neurolink.d.ts +168 -12
- package/dist/neurolink.js +685 -123
- package/dist/providers/anthropic.js +52 -2
- package/dist/providers/googleAiStudio.js +4 -0
- package/dist/providers/googleVertex.d.ts +75 -9
- package/dist/providers/googleVertex.js +365 -46
- package/dist/providers/huggingFace.d.ts +52 -11
- package/dist/providers/huggingFace.js +181 -43
- package/dist/providers/litellm.d.ts +9 -9
- package/dist/providers/litellm.js +103 -16
- package/dist/providers/ollama.d.ts +52 -17
- package/dist/providers/ollama.js +276 -68
- package/dist/sdk/toolRegistration.d.ts +42 -0
- package/dist/sdk/toolRegistration.js +269 -27
- package/dist/telemetry/telemetryService.d.ts +6 -0
- package/dist/telemetry/telemetryService.js +38 -3
- package/dist/types/contextTypes.d.ts +75 -11
- package/dist/types/contextTypes.js +227 -2
- package/dist/types/domainTypes.d.ts +62 -0
- package/dist/types/domainTypes.js +5 -0
- package/dist/types/generateTypes.d.ts +52 -0
- package/dist/types/index.d.ts +1 -0
- package/dist/types/mcpTypes.d.ts +1 -1
- package/dist/types/mcpTypes.js +1 -1
- package/dist/types/streamTypes.d.ts +14 -0
- package/dist/types/universalProviderOptions.d.ts +1 -1
- package/dist/types/universalProviderOptions.js +0 -1
- package/dist/utils/errorHandling.d.ts +142 -0
- package/dist/utils/errorHandling.js +316 -0
- package/dist/utils/factoryProcessing.d.ts +74 -0
- package/dist/utils/factoryProcessing.js +588 -0
- package/dist/utils/optionsConversion.d.ts +54 -0
- package/dist/utils/optionsConversion.js +126 -0
- package/dist/utils/optionsUtils.d.ts +246 -0
- package/dist/utils/optionsUtils.js +960 -0
- package/dist/utils/providerHealth.d.ts +107 -0
- package/dist/utils/providerHealth.js +507 -0
- package/dist/utils/providerUtils.d.ts +17 -0
- package/dist/utils/providerUtils.js +271 -16
- package/dist/utils/timeout.js +1 -1
- package/dist/utils/tokenLimits.d.ts +33 -0
- package/dist/utils/tokenLimits.js +118 -0
- package/package.json +2 -2
package/dist/core/types.d.ts
CHANGED
|
@@ -77,12 +77,16 @@ export declare enum OpenAIModels {
|
|
|
77
77
|
*/
|
|
78
78
|
export declare enum VertexModels {
|
|
79
79
|
CLAUDE_4_0_SONNET = "claude-sonnet-4@20250514",
|
|
80
|
-
|
|
80
|
+
GEMINI_2_0_FLASH_001 = "gemini-2.0-flash-001",
|
|
81
|
+
GEMINI_2_5_PRO = "gemini-2.5-pro",
|
|
82
|
+
GEMINI_2_5_FLASH = "gemini-2.5-flash",
|
|
83
|
+
GEMINI_2_5_FLASH_LITE = "gemini-2.5-flash-lite"
|
|
81
84
|
}
|
|
82
85
|
/**
|
|
83
86
|
* Supported Models for Google AI Studio
|
|
84
87
|
*/
|
|
85
88
|
export declare enum GoogleAIModels {
|
|
89
|
+
GEMINI_2_0_FLASH_001 = "gemini-2.0-flash-001",
|
|
86
90
|
GEMINI_2_5_PRO = "gemini-2.5-pro",
|
|
87
91
|
GEMINI_2_5_FLASH = "gemini-2.5-flash",
|
|
88
92
|
GEMINI_1_5_FLASH_LITE = "gemini-2.5-flash-lite"
|
|
@@ -152,8 +156,8 @@ export interface AnalyticsData {
|
|
|
152
156
|
context?: Record<string, JsonValue>;
|
|
153
157
|
}
|
|
154
158
|
/**
|
|
155
|
-
* Response quality evaluation scores
|
|
156
|
-
*
|
|
159
|
+
* Response quality evaluation scores
|
|
160
|
+
* Comprehensive evaluation interface for response quality assessment
|
|
157
161
|
*/
|
|
158
162
|
export interface EvaluationData {
|
|
159
163
|
relevance: number;
|
|
@@ -169,6 +173,7 @@ export interface EvaluationData {
|
|
|
169
173
|
suggestedImprovements?: string;
|
|
170
174
|
evaluationModel: string;
|
|
171
175
|
evaluationTime: number;
|
|
176
|
+
evaluationDomain?: string;
|
|
172
177
|
evaluationProvider?: string;
|
|
173
178
|
evaluationAttempt?: number;
|
|
174
179
|
evaluationConfig?: {
|
|
@@ -176,6 +181,20 @@ export interface EvaluationData {
|
|
|
176
181
|
fallbackUsed: boolean;
|
|
177
182
|
costEstimate: number;
|
|
178
183
|
};
|
|
184
|
+
domainConfig?: {
|
|
185
|
+
domainName: string;
|
|
186
|
+
domainDescription: string;
|
|
187
|
+
keyTerms: string[];
|
|
188
|
+
failurePatterns: string[];
|
|
189
|
+
successPatterns: string[];
|
|
190
|
+
evaluationCriteria?: Record<string, unknown>;
|
|
191
|
+
};
|
|
192
|
+
domainEvaluation?: {
|
|
193
|
+
domainRelevance: number;
|
|
194
|
+
terminologyAccuracy: number;
|
|
195
|
+
domainExpertise: number;
|
|
196
|
+
domainSpecificInsights: string[];
|
|
197
|
+
};
|
|
179
198
|
}
|
|
180
199
|
/**
|
|
181
200
|
* BACKWARD COMPATIBILITY: Legacy evaluation interface
|
package/dist/core/types.js
CHANGED
|
@@ -43,13 +43,17 @@ export var OpenAIModels;
|
|
|
43
43
|
export var VertexModels;
|
|
44
44
|
(function (VertexModels) {
|
|
45
45
|
VertexModels["CLAUDE_4_0_SONNET"] = "claude-sonnet-4@20250514";
|
|
46
|
-
VertexModels["
|
|
46
|
+
VertexModels["GEMINI_2_0_FLASH_001"] = "gemini-2.0-flash-001";
|
|
47
|
+
VertexModels["GEMINI_2_5_PRO"] = "gemini-2.5-pro";
|
|
48
|
+
VertexModels["GEMINI_2_5_FLASH"] = "gemini-2.5-flash";
|
|
49
|
+
VertexModels["GEMINI_2_5_FLASH_LITE"] = "gemini-2.5-flash-lite";
|
|
47
50
|
})(VertexModels || (VertexModels = {}));
|
|
48
51
|
/**
|
|
49
52
|
* Supported Models for Google AI Studio
|
|
50
53
|
*/
|
|
51
54
|
export var GoogleAIModels;
|
|
52
55
|
(function (GoogleAIModels) {
|
|
56
|
+
GoogleAIModels["GEMINI_2_0_FLASH_001"] = "gemini-2.0-flash-001";
|
|
53
57
|
GoogleAIModels["GEMINI_2_5_PRO"] = "gemini-2.5-pro";
|
|
54
58
|
GoogleAIModels["GEMINI_2_5_FLASH"] = "gemini-2.5-flash";
|
|
55
59
|
GoogleAIModels["GEMINI_1_5_FLASH_LITE"] = "gemini-2.5-flash-lite";
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { ProviderFactory } from "./providerFactory.js";
|
|
2
|
-
//
|
|
2
|
+
// Lazy loading all providers to avoid circular dependencies
|
|
3
3
|
// Removed all static imports - providers loaded dynamically when needed
|
|
4
4
|
// This breaks the circular dependency chain completely
|
|
5
5
|
import { AIProviderName, GoogleAIModels, OpenAIModels } from "../core/types.js";
|
|
@@ -21,7 +21,7 @@ export class ProviderRegistry {
|
|
|
21
21
|
return;
|
|
22
22
|
}
|
|
23
23
|
try {
|
|
24
|
-
//
|
|
24
|
+
// Register providers with dynamic import factory functions
|
|
25
25
|
const { ProviderFactory } = await import("./providerFactory.js");
|
|
26
26
|
// Register Google AI Studio Provider (our validated baseline)
|
|
27
27
|
ProviderFactory.registerProvider(AIProviderName.GOOGLE_AI, async (modelName, providerName, sdk) => {
|
|
@@ -55,7 +55,7 @@ export class ProviderRegistry {
|
|
|
55
55
|
ProviderFactory.registerProvider(AIProviderName.VERTEX, async (modelName) => {
|
|
56
56
|
const { GoogleVertexProvider } = await import("../providers/googleVertex.js");
|
|
57
57
|
return new GoogleVertexProvider(modelName);
|
|
58
|
-
}, "gemini-2.5-
|
|
58
|
+
}, "gemini-2.5-flash", ["vertex", "googleVertex"]);
|
|
59
59
|
// Register Hugging Face provider (Unified Router implementation)
|
|
60
60
|
ProviderFactory.registerProvider(AIProviderName.HUGGINGFACE, async (modelName) => {
|
|
61
61
|
const { HuggingFaceProvider } = await import("../providers/huggingFace.js");
|
package/dist/index.d.ts
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* A unified AI provider interface with support for multiple providers,
|
|
5
5
|
* automatic fallback, streaming, and tool integration.
|
|
6
6
|
*
|
|
7
|
-
*
|
|
7
|
+
* Provides comprehensive AI functionality with proven patterns.
|
|
8
8
|
*/
|
|
9
9
|
import { AIProviderFactory } from "./core/factory.js";
|
|
10
10
|
export { AIProviderFactory };
|
package/dist/index.js
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* A unified AI provider interface with support for multiple providers,
|
|
5
5
|
* automatic fallback, streaming, and tool integration.
|
|
6
6
|
*
|
|
7
|
-
*
|
|
7
|
+
* Provides comprehensive AI functionality with proven patterns.
|
|
8
8
|
*/
|
|
9
9
|
// Core exports
|
|
10
10
|
import { AIProviderFactory } from "./core/factory.js";
|
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
* including tokens, costs, performance metrics, and custom context.
|
|
6
6
|
*/
|
|
7
7
|
import { logger } from "../utils/logger.js";
|
|
8
|
+
import { modelConfig } from "./modelConfiguration.js";
|
|
8
9
|
/**
|
|
9
10
|
* Create analytics data structure from AI response
|
|
10
11
|
*/
|
|
@@ -89,35 +90,14 @@ function extractTokenUsage(result) {
|
|
|
89
90
|
*/
|
|
90
91
|
function estimateCost(provider, model, tokens) {
|
|
91
92
|
try {
|
|
92
|
-
//
|
|
93
|
-
const
|
|
94
|
-
|
|
95
|
-
"gpt-4": { input: 0.03, output: 0.06 },
|
|
96
|
-
"gpt-4-turbo": { input: 0.01, output: 0.03 },
|
|
97
|
-
"gpt-3.5-turbo": { input: 0.0015, output: 0.002 },
|
|
98
|
-
},
|
|
99
|
-
anthropic: {
|
|
100
|
-
"claude-3-opus": { input: 0.015, output: 0.075 },
|
|
101
|
-
"claude-3-sonnet": { input: 0.003, output: 0.015 },
|
|
102
|
-
"claude-3-haiku": { input: 0.00025, output: 0.00125 },
|
|
103
|
-
},
|
|
104
|
-
"google-ai": {
|
|
105
|
-
"gemini-pro": { input: 0.00035, output: 0.00105 },
|
|
106
|
-
"gemini-2.5-flash": { input: 0.000075, output: 0.0003 },
|
|
107
|
-
},
|
|
108
|
-
};
|
|
109
|
-
const providerCosts = costMap[provider.toLowerCase()];
|
|
110
|
-
if (!providerCosts) {
|
|
111
|
-
return undefined;
|
|
112
|
-
}
|
|
113
|
-
// Find best matching model
|
|
114
|
-
const modelKey = Object.keys(providerCosts).find((key) => model.toLowerCase().includes(key) || key.includes(model.toLowerCase()));
|
|
115
|
-
if (!modelKey) {
|
|
93
|
+
// Use the new configuration system instead of hardcoded costs
|
|
94
|
+
const costInfo = modelConfig.getCostInfo(provider.toLowerCase(), model);
|
|
95
|
+
if (!costInfo) {
|
|
116
96
|
return undefined;
|
|
117
97
|
}
|
|
118
|
-
|
|
119
|
-
const inputCost = (tokens.input / 1000) *
|
|
120
|
-
const outputCost = (tokens.output / 1000) *
|
|
98
|
+
// Calculate cost using the configuration system
|
|
99
|
+
const inputCost = (tokens.input / 1000) * costInfo.input;
|
|
100
|
+
const outputCost = (tokens.output / 1000) * costInfo.output;
|
|
121
101
|
return Math.round((inputCost + outputCost) * 100000) / 100000; // Round to 5 decimal places
|
|
122
102
|
}
|
|
123
103
|
catch (error) {
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { logger } from "../utils/logger.js";
|
|
2
2
|
import { SYSTEM_LIMITS } from "../core/constants.js";
|
|
3
3
|
import { directAgentTools } from "../agent/directTools.js";
|
|
4
|
+
import { getSafeMaxTokens } from "../utils/tokenLimits.js";
|
|
4
5
|
/**
|
|
5
6
|
* Validates if a result contains a valid toolsObject structure
|
|
6
7
|
* @param result - The result object to validate
|
|
@@ -192,6 +193,29 @@ export class BaseProvider {
|
|
|
192
193
|
}
|
|
193
194
|
// Remove duplicates
|
|
194
195
|
const uniqueToolsUsed = [...new Set(toolsUsed)];
|
|
196
|
+
// ✅ Extract tool executions from AI SDK result
|
|
197
|
+
const toolExecutions = [];
|
|
198
|
+
// Extract tool executions from AI SDK result steps
|
|
199
|
+
// Extract tool executions from steps (where tool results are stored)
|
|
200
|
+
if (result.steps &&
|
|
201
|
+
Array.isArray(result.steps)) {
|
|
202
|
+
for (const step of result.steps ||
|
|
203
|
+
[]) {
|
|
204
|
+
// Focus only on tool results (which have complete execution data)
|
|
205
|
+
// Tool calls are just the requests, tool results contain the actual execution data
|
|
206
|
+
if (step?.toolResults && Array.isArray(step.toolResults)) {
|
|
207
|
+
for (const toolResult of step.toolResults) {
|
|
208
|
+
const trRecord = toolResult;
|
|
209
|
+
toolExecutions.push({
|
|
210
|
+
name: trRecord.toolName || "unknown",
|
|
211
|
+
input: trRecord.args || {},
|
|
212
|
+
output: trRecord.result || "success",
|
|
213
|
+
duration: 0, // AI SDK doesn't track duration
|
|
214
|
+
});
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
}
|
|
195
219
|
// Format the result with tool executions included
|
|
196
220
|
const enhancedResult = {
|
|
197
221
|
content: result.text,
|
|
@@ -217,6 +241,7 @@ export class BaseProvider {
|
|
|
217
241
|
: [],
|
|
218
242
|
toolResults: result.toolResults,
|
|
219
243
|
toolsUsed: uniqueToolsUsed,
|
|
244
|
+
toolExecutions, // ✅ Add extracted tool executions
|
|
220
245
|
};
|
|
221
246
|
// Enhanced result with analytics and evaluation
|
|
222
247
|
return await this.enhanceResult(enhancedResult, options, startTime);
|
|
@@ -327,33 +352,47 @@ export class BaseProvider {
|
|
|
327
352
|
// ===================
|
|
328
353
|
normalizeTextOptions(optionsOrPrompt) {
|
|
329
354
|
if (typeof optionsOrPrompt === "string") {
|
|
355
|
+
const safeMaxTokens = getSafeMaxTokens(this.providerName, this.modelName);
|
|
330
356
|
return {
|
|
331
357
|
prompt: optionsOrPrompt,
|
|
332
358
|
provider: this.providerName,
|
|
333
359
|
model: this.modelName,
|
|
360
|
+
maxTokens: safeMaxTokens,
|
|
334
361
|
};
|
|
335
362
|
}
|
|
336
363
|
// Handle both prompt and input.text formats
|
|
337
364
|
const prompt = optionsOrPrompt.prompt || optionsOrPrompt.input?.text || "";
|
|
365
|
+
const modelName = optionsOrPrompt.model || this.modelName;
|
|
366
|
+
const providerName = optionsOrPrompt.provider || this.providerName;
|
|
367
|
+
// Apply safe maxTokens based on provider and model
|
|
368
|
+
const safeMaxTokens = getSafeMaxTokens(providerName, modelName, optionsOrPrompt.maxTokens);
|
|
338
369
|
return {
|
|
339
370
|
...optionsOrPrompt,
|
|
340
371
|
prompt,
|
|
341
|
-
provider:
|
|
342
|
-
model:
|
|
372
|
+
provider: providerName,
|
|
373
|
+
model: modelName,
|
|
374
|
+
maxTokens: safeMaxTokens,
|
|
343
375
|
};
|
|
344
376
|
}
|
|
345
377
|
normalizeStreamOptions(optionsOrPrompt) {
|
|
346
378
|
if (typeof optionsOrPrompt === "string") {
|
|
379
|
+
const safeMaxTokens = getSafeMaxTokens(this.providerName, this.modelName);
|
|
347
380
|
return {
|
|
348
381
|
input: { text: optionsOrPrompt },
|
|
349
382
|
provider: this.providerName,
|
|
350
383
|
model: this.modelName,
|
|
384
|
+
maxTokens: safeMaxTokens,
|
|
351
385
|
};
|
|
352
386
|
}
|
|
387
|
+
const modelName = optionsOrPrompt.model || this.modelName;
|
|
388
|
+
const providerName = optionsOrPrompt.provider || this.providerName;
|
|
389
|
+
// Apply safe maxTokens based on provider and model
|
|
390
|
+
const safeMaxTokens = getSafeMaxTokens(providerName, modelName, optionsOrPrompt.maxTokens);
|
|
353
391
|
return {
|
|
354
392
|
...optionsOrPrompt,
|
|
355
|
-
provider:
|
|
356
|
-
model:
|
|
393
|
+
provider: providerName,
|
|
394
|
+
model: modelName,
|
|
395
|
+
maxTokens: safeMaxTokens,
|
|
357
396
|
};
|
|
358
397
|
}
|
|
359
398
|
async enhanceResult(result, options, startTime) {
|
|
@@ -24,6 +24,52 @@ export declare const PROVIDER_CONFIG: {
|
|
|
24
24
|
temperature: number;
|
|
25
25
|
};
|
|
26
26
|
};
|
|
27
|
+
export declare const PROVIDER_MAX_TOKENS: {
|
|
28
|
+
anthropic: {
|
|
29
|
+
"claude-3-haiku-20240307": number;
|
|
30
|
+
"claude-3-5-sonnet-20241022": number;
|
|
31
|
+
"claude-3-opus-20240229": number;
|
|
32
|
+
"claude-3-5-sonnet-20240620": number;
|
|
33
|
+
default: number;
|
|
34
|
+
};
|
|
35
|
+
openai: {
|
|
36
|
+
"gpt-4o": number;
|
|
37
|
+
"gpt-4o-mini": number;
|
|
38
|
+
"gpt-3.5-turbo": number;
|
|
39
|
+
"gpt-4": number;
|
|
40
|
+
"gpt-4-turbo": number;
|
|
41
|
+
default: number;
|
|
42
|
+
};
|
|
43
|
+
"google-ai": {
|
|
44
|
+
"gemini-1.5-pro": number;
|
|
45
|
+
"gemini-1.5-flash": number;
|
|
46
|
+
"gemini-2.5-pro": number;
|
|
47
|
+
"gemini-2.5-flash": number;
|
|
48
|
+
"gemini-pro": number;
|
|
49
|
+
default: number;
|
|
50
|
+
};
|
|
51
|
+
vertex: {
|
|
52
|
+
"gemini-1.5-pro": number;
|
|
53
|
+
"gemini-1.5-flash": number;
|
|
54
|
+
"gemini-2.5-pro": number;
|
|
55
|
+
"gemini-2.5-flash": number;
|
|
56
|
+
"claude-4.0-sonnet": number;
|
|
57
|
+
default: number;
|
|
58
|
+
};
|
|
59
|
+
bedrock: {
|
|
60
|
+
"anthropic.claude-3-sonnet-20240229-v1:0": number;
|
|
61
|
+
"anthropic.claude-3-haiku-20240307-v1:0": number;
|
|
62
|
+
"anthropic.claude-3-5-sonnet-20240620-v1:0": number;
|
|
63
|
+
default: number;
|
|
64
|
+
};
|
|
65
|
+
ollama: {
|
|
66
|
+
default: number;
|
|
67
|
+
};
|
|
68
|
+
litellm: {
|
|
69
|
+
default: number;
|
|
70
|
+
};
|
|
71
|
+
default: number;
|
|
72
|
+
};
|
|
27
73
|
export declare const CLI_LIMITS: {
|
|
28
74
|
maxTokens: {
|
|
29
75
|
min: number;
|
|
@@ -27,6 +27,53 @@ export const PROVIDER_CONFIG = {
|
|
|
27
27
|
temperature: 0.4,
|
|
28
28
|
},
|
|
29
29
|
};
|
|
30
|
+
// Provider-specific maxTokens limits (discovered through testing)
|
|
31
|
+
export const PROVIDER_MAX_TOKENS = {
|
|
32
|
+
anthropic: {
|
|
33
|
+
"claude-3-haiku-20240307": 4096,
|
|
34
|
+
"claude-3-5-sonnet-20241022": 4096,
|
|
35
|
+
"claude-3-opus-20240229": 4096,
|
|
36
|
+
"claude-3-5-sonnet-20240620": 4096,
|
|
37
|
+
default: 4096, // Conservative default for Anthropic
|
|
38
|
+
},
|
|
39
|
+
openai: {
|
|
40
|
+
"gpt-4o": 16384,
|
|
41
|
+
"gpt-4o-mini": 16384,
|
|
42
|
+
"gpt-3.5-turbo": 4096,
|
|
43
|
+
"gpt-4": 8192,
|
|
44
|
+
"gpt-4-turbo": 4096,
|
|
45
|
+
default: 8192, // OpenAI generally supports higher limits
|
|
46
|
+
},
|
|
47
|
+
"google-ai": {
|
|
48
|
+
"gemini-1.5-pro": 8192,
|
|
49
|
+
"gemini-1.5-flash": 8192,
|
|
50
|
+
"gemini-2.5-pro": 8192,
|
|
51
|
+
"gemini-2.5-flash": 8192,
|
|
52
|
+
"gemini-pro": 4096,
|
|
53
|
+
default: 4096, // Conservative default due to 500 errors at high limits
|
|
54
|
+
},
|
|
55
|
+
vertex: {
|
|
56
|
+
"gemini-1.5-pro": 8192,
|
|
57
|
+
"gemini-1.5-flash": 8192,
|
|
58
|
+
"gemini-2.5-pro": 8192,
|
|
59
|
+
"gemini-2.5-flash": 8192,
|
|
60
|
+
"claude-4.0-sonnet": 4096,
|
|
61
|
+
default: 4096,
|
|
62
|
+
},
|
|
63
|
+
bedrock: {
|
|
64
|
+
"anthropic.claude-3-sonnet-20240229-v1:0": 4096,
|
|
65
|
+
"anthropic.claude-3-haiku-20240307-v1:0": 4096,
|
|
66
|
+
"anthropic.claude-3-5-sonnet-20240620-v1:0": 4096,
|
|
67
|
+
default: 4096,
|
|
68
|
+
},
|
|
69
|
+
ollama: {
|
|
70
|
+
default: 8192, // Ollama typically supports higher limits
|
|
71
|
+
},
|
|
72
|
+
litellm: {
|
|
73
|
+
default: 4096, // Conservative default
|
|
74
|
+
},
|
|
75
|
+
default: 4096, // Safe default across all providers
|
|
76
|
+
};
|
|
30
77
|
// CLI Validation Limits
|
|
31
78
|
export const CLI_LIMITS = {
|
|
32
79
|
maxTokens: {
|
|
@@ -102,8 +102,8 @@ declare const ModelRegistrySchema: z.ZodObject<{
|
|
|
102
102
|
releaseDate: string;
|
|
103
103
|
}>>;
|
|
104
104
|
lastUpdated: string;
|
|
105
|
-
aliases?: Record<string, string> | undefined;
|
|
106
105
|
defaults?: Record<string, string> | undefined;
|
|
106
|
+
aliases?: Record<string, string> | undefined;
|
|
107
107
|
}, {
|
|
108
108
|
version: string;
|
|
109
109
|
models: Record<string, Record<string, {
|
|
@@ -119,8 +119,8 @@ declare const ModelRegistrySchema: z.ZodObject<{
|
|
|
119
119
|
releaseDate: string;
|
|
120
120
|
}>>;
|
|
121
121
|
lastUpdated: string;
|
|
122
|
-
aliases?: Record<string, string> | undefined;
|
|
123
122
|
defaults?: Record<string, string> | undefined;
|
|
123
|
+
aliases?: Record<string, string> | undefined;
|
|
124
124
|
}>;
|
|
125
125
|
export type ModelConfig = z.infer<typeof ModelConfigSchema>;
|
|
126
126
|
export type ModelRegistry = z.infer<typeof ModelRegistrySchema>;
|
|
@@ -136,11 +136,23 @@ export declare class DynamicModelProvider {
|
|
|
136
136
|
private constructor();
|
|
137
137
|
static getInstance(): DynamicModelProvider;
|
|
138
138
|
/**
|
|
139
|
-
* Initialize the model registry from multiple sources
|
|
139
|
+
* Initialize the model registry from multiple sources with timeout handling
|
|
140
|
+
* Addresses hanging issues when localhost:3001 is not running or GitHub URLs timeout
|
|
140
141
|
*/
|
|
141
142
|
initialize(): Promise<void>;
|
|
142
143
|
/**
|
|
143
|
-
* Load configuration from a source
|
|
144
|
+
* Load configuration from a source with timeout handling
|
|
145
|
+
* Prevents hanging when local servers are down or network requests timeout
|
|
146
|
+
*/
|
|
147
|
+
private loadFromSourceWithTimeout;
|
|
148
|
+
/**
|
|
149
|
+
* Quick health check for localhost endpoints
|
|
150
|
+
* Prevents hanging on non-responsive local servers
|
|
151
|
+
*/
|
|
152
|
+
private healthCheckLocalhost;
|
|
153
|
+
/**
|
|
154
|
+
* Load configuration from a source (URL or file path) - Legacy method for compatibility
|
|
155
|
+
* @deprecated Use loadFromSourceWithTimeout instead
|
|
144
156
|
*/
|
|
145
157
|
private loadFromSource;
|
|
146
158
|
/**
|
|
@@ -39,60 +39,164 @@ export class DynamicModelProvider {
|
|
|
39
39
|
return this.instance;
|
|
40
40
|
}
|
|
41
41
|
/**
|
|
42
|
-
* Initialize the model registry from multiple sources
|
|
42
|
+
* Initialize the model registry from multiple sources with timeout handling
|
|
43
|
+
* Addresses hanging issues when localhost:3001 is not running or GitHub URLs timeout
|
|
43
44
|
*/
|
|
44
45
|
async initialize() {
|
|
45
46
|
const sources = [
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
47
|
+
{
|
|
48
|
+
url: process.env.MODEL_CONFIG_URL || "http://localhost:3001/api/v1/models",
|
|
49
|
+
timeout: 3000, // 3s for localhost
|
|
50
|
+
name: "local-server",
|
|
51
|
+
},
|
|
52
|
+
{
|
|
53
|
+
url: `https://raw.githubusercontent.com/${process.env.MODEL_CONFIG_GITHUB_REPO || "juspay/neurolink"}/${process.env.MODEL_CONFIG_GITHUB_BRANCH || "release"}/config/models.json`,
|
|
54
|
+
timeout: 5000, // 5s for GitHub
|
|
55
|
+
name: "github-raw",
|
|
56
|
+
},
|
|
57
|
+
{
|
|
58
|
+
url: "./config/models.json",
|
|
59
|
+
timeout: 1000, // 1s for local file
|
|
60
|
+
name: "local-file",
|
|
61
|
+
},
|
|
49
62
|
];
|
|
63
|
+
const errors = [];
|
|
50
64
|
for (const source of sources) {
|
|
51
65
|
try {
|
|
52
|
-
logger.debug(`[DynamicModelProvider] Attempting to load from: ${source}`);
|
|
53
|
-
const config = await this.
|
|
66
|
+
logger.debug(`[DynamicModelProvider] Attempting to load from: ${source.url} (timeout: ${source.timeout}ms)`);
|
|
67
|
+
const config = await this.loadFromSourceWithTimeout(source.url, source.timeout);
|
|
54
68
|
// Validate the configuration
|
|
55
69
|
const validatedConfig = ModelRegistrySchema.parse(config);
|
|
56
70
|
this.modelRegistry = validatedConfig;
|
|
57
71
|
this.lastFetch = Date.now();
|
|
58
|
-
logger.info(`[DynamicModelProvider] Successfully loaded model registry from: ${source}`, {
|
|
72
|
+
logger.info(`[DynamicModelProvider] Successfully loaded model registry from: ${source.name}`, {
|
|
73
|
+
source: source.url,
|
|
59
74
|
modelCount: this.getTotalModelCount(),
|
|
60
75
|
providerCount: Object.keys(validatedConfig.models).length,
|
|
76
|
+
loadTime: `<${source.timeout}ms`,
|
|
61
77
|
});
|
|
62
78
|
return; // Success, stop trying other sources
|
|
63
79
|
}
|
|
64
80
|
catch (error) {
|
|
65
|
-
|
|
81
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
82
|
+
errors.push({ source: source.name, error: errorMessage });
|
|
83
|
+
logger.warn(`[DynamicModelProvider] Failed to load from ${source.name} (${source.url}):`, {
|
|
84
|
+
error: errorMessage,
|
|
85
|
+
timeout: source.timeout,
|
|
86
|
+
});
|
|
66
87
|
continue;
|
|
67
88
|
}
|
|
68
89
|
}
|
|
69
|
-
|
|
90
|
+
// Log all failures for debugging
|
|
91
|
+
logger.warn(`[DynamicModelProvider] All model configuration sources failed`, { errors });
|
|
92
|
+
throw new Error(`Failed to load model configuration from any source. Attempted: ${errors.map((e) => e.source).join(", ")}`);
|
|
70
93
|
}
|
|
71
94
|
/**
|
|
72
|
-
* Load configuration from a source
|
|
95
|
+
* Load configuration from a source with timeout handling
|
|
96
|
+
* Prevents hanging when local servers are down or network requests timeout
|
|
73
97
|
*/
|
|
74
|
-
async
|
|
98
|
+
async loadFromSourceWithTimeout(source, timeoutMs) {
|
|
75
99
|
if (source.startsWith("http")) {
|
|
76
|
-
//
|
|
77
|
-
const
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
100
|
+
// Setup timeout and abort controller
|
|
101
|
+
const controller = new AbortController();
|
|
102
|
+
const timeoutId = setTimeout(() => controller.abort(), timeoutMs);
|
|
103
|
+
try {
|
|
104
|
+
// Add health check for localhost before attempting full request
|
|
105
|
+
if (source.includes("localhost") || source.includes("127.0.0.1")) {
|
|
106
|
+
await this.healthCheckLocalhost(source, Math.min(timeoutMs, 1000));
|
|
107
|
+
}
|
|
108
|
+
const response = await fetch(source, {
|
|
109
|
+
headers: {
|
|
110
|
+
"User-Agent": "NeuroLink/1.0 (+https://github.com/sachinsharma92/neurolink)",
|
|
111
|
+
Accept: "application/json",
|
|
112
|
+
"Cache-Control": "no-cache",
|
|
113
|
+
},
|
|
114
|
+
signal: controller.signal,
|
|
115
|
+
});
|
|
116
|
+
clearTimeout(timeoutId);
|
|
117
|
+
if (!response.ok) {
|
|
118
|
+
throw new Error(`HTTP ${response.status}: ${response.statusText}`);
|
|
119
|
+
}
|
|
120
|
+
const data = await response.json();
|
|
121
|
+
return data;
|
|
122
|
+
}
|
|
123
|
+
catch (error) {
|
|
124
|
+
clearTimeout(timeoutId);
|
|
125
|
+
if (error instanceof Error && error.name === "AbortError") {
|
|
126
|
+
throw new Error(`Request timeout after ${timeoutMs}ms`);
|
|
127
|
+
}
|
|
128
|
+
throw error;
|
|
84
129
|
}
|
|
85
|
-
return response.json();
|
|
86
130
|
}
|
|
87
131
|
else {
|
|
88
|
-
// Load from local file
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
132
|
+
// Load from local file with timeout (for very large files)
|
|
133
|
+
return new Promise((resolve, reject) => {
|
|
134
|
+
const timeoutId = setTimeout(() => {
|
|
135
|
+
reject(new Error(`File read timeout after ${timeoutMs}ms`));
|
|
136
|
+
}, timeoutMs);
|
|
137
|
+
(async () => {
|
|
138
|
+
try {
|
|
139
|
+
const fs = await import("fs");
|
|
140
|
+
const path = await import("path");
|
|
141
|
+
const fullPath = path.resolve(source);
|
|
142
|
+
// Check if file exists first
|
|
143
|
+
if (!fs.existsSync(fullPath)) {
|
|
144
|
+
throw new Error(`File not found: ${fullPath}`);
|
|
145
|
+
}
|
|
146
|
+
const content = fs.readFileSync(fullPath, "utf8");
|
|
147
|
+
const data = JSON.parse(content);
|
|
148
|
+
clearTimeout(timeoutId);
|
|
149
|
+
resolve(data);
|
|
150
|
+
}
|
|
151
|
+
catch (error) {
|
|
152
|
+
clearTimeout(timeoutId);
|
|
153
|
+
reject(error);
|
|
154
|
+
}
|
|
155
|
+
})();
|
|
156
|
+
});
|
|
94
157
|
}
|
|
95
158
|
}
|
|
159
|
+
/**
|
|
160
|
+
* Quick health check for localhost endpoints
|
|
161
|
+
* Prevents hanging on non-responsive local servers
|
|
162
|
+
*/
|
|
163
|
+
async healthCheckLocalhost(url, timeoutMs) {
|
|
164
|
+
const healthUrl = url.replace(/\/api\/.*$/, "/health") || `${url}/health`;
|
|
165
|
+
const controller = new AbortController();
|
|
166
|
+
const timeoutId = setTimeout(() => controller.abort(), timeoutMs);
|
|
167
|
+
try {
|
|
168
|
+
const response = await fetch(healthUrl, {
|
|
169
|
+
method: "HEAD", // Lightweight request
|
|
170
|
+
signal: controller.signal,
|
|
171
|
+
});
|
|
172
|
+
clearTimeout(timeoutId);
|
|
173
|
+
// Don't throw on 404 - the main endpoint might still work
|
|
174
|
+
if (response.status >= 500) {
|
|
175
|
+
throw new Error(`Server error: ${response.status}`);
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
catch (error) {
|
|
179
|
+
clearTimeout(timeoutId);
|
|
180
|
+
if (error instanceof Error && error.name === "AbortError") {
|
|
181
|
+
throw new Error(`Localhost health check timeout - server may not be running`);
|
|
182
|
+
}
|
|
183
|
+
// For connection refused, throw a more specific error
|
|
184
|
+
if (error instanceof Error && error.message.includes("ECONNREFUSED")) {
|
|
185
|
+
throw new Error(`Localhost server not running at ${url}`);
|
|
186
|
+
}
|
|
187
|
+
// For other errors, let the main request handle them
|
|
188
|
+
logger.debug(`Health check failed for ${url}, proceeding with main request`, {
|
|
189
|
+
error: error instanceof Error ? error.message : String(error),
|
|
190
|
+
});
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
/**
|
|
194
|
+
* Load configuration from a source (URL or file path) - Legacy method for compatibility
|
|
195
|
+
* @deprecated Use loadFromSourceWithTimeout instead
|
|
196
|
+
*/
|
|
197
|
+
async loadFromSource(source) {
|
|
198
|
+
return this.loadFromSourceWithTimeout(source, 10000); // 10s default timeout
|
|
199
|
+
}
|
|
96
200
|
/**
|
|
97
201
|
* Get all available models for a provider
|
|
98
202
|
*/
|
|
@@ -5,6 +5,7 @@ import { logger } from "../utils/logger.js";
|
|
|
5
5
|
import { AIProviderFactory } from "./factory.js";
|
|
6
6
|
import { z } from "zod";
|
|
7
7
|
import { ProviderRegistry } from "../factories/providerRegistry.js";
|
|
8
|
+
import { modelConfig } from "./modelConfiguration.js";
|
|
8
9
|
// Zod schema for validation
|
|
9
10
|
const UnifiedEvaluationSchema = z.object({
|
|
10
11
|
relevance: z.number().min(1).max(10),
|
|
@@ -152,7 +153,10 @@ export async function generateUnifiedEvaluation(context) {
|
|
|
152
153
|
await ProviderRegistry.registerAllProviders();
|
|
153
154
|
// Get evaluation provider
|
|
154
155
|
const evaluationProvider = process.env.NEUROLINK_EVALUATION_PROVIDER || "google-ai";
|
|
155
|
-
|
|
156
|
+
// Use configurable model selection instead of hardcoded default
|
|
157
|
+
const evaluationModel = process.env.NEUROLINK_EVALUATION_MODEL ||
|
|
158
|
+
modelConfig.getModelForTier(evaluationProvider, "fast") ||
|
|
159
|
+
"gemini-2.5-flash"; // Ultimate fallback
|
|
156
160
|
logger.debug(`[${functionTag}] Using provider: ${evaluationProvider}, model: ${evaluationModel}`);
|
|
157
161
|
const provider = await AIProviderFactory.createProvider(evaluationProvider, evaluationModel);
|
|
158
162
|
if (!provider) {
|