@juspay/neurolink 9.42.0 → 9.43.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 +8 -0
- package/dist/auth/anthropicOAuth.js +12 -0
- package/dist/browser/neurolink.min.js +335 -334
- package/dist/cli/commands/mcp.d.ts +6 -0
- package/dist/cli/commands/mcp.js +200 -184
- package/dist/cli/commands/proxy.js +560 -518
- package/dist/core/baseProvider.d.ts +6 -1
- package/dist/core/baseProvider.js +219 -232
- package/dist/core/factory.d.ts +3 -0
- package/dist/core/factory.js +140 -190
- package/dist/core/modules/ToolsManager.d.ts +1 -0
- package/dist/core/modules/ToolsManager.js +40 -42
- package/dist/core/toolEvents.d.ts +3 -0
- package/dist/core/toolEvents.js +7 -0
- package/dist/evaluation/pipeline/evaluationPipeline.js +5 -2
- package/dist/evaluation/scorers/scorerRegistry.d.ts +3 -0
- package/dist/evaluation/scorers/scorerRegistry.js +356 -284
- package/dist/lib/auth/anthropicOAuth.js +12 -0
- package/dist/lib/core/baseProvider.d.ts +6 -1
- package/dist/lib/core/baseProvider.js +219 -232
- package/dist/lib/core/factory.d.ts +3 -0
- package/dist/lib/core/factory.js +140 -190
- package/dist/lib/core/modules/ToolsManager.d.ts +1 -0
- package/dist/lib/core/modules/ToolsManager.js +40 -42
- package/dist/lib/core/toolEvents.d.ts +3 -0
- package/dist/lib/core/toolEvents.js +8 -0
- package/dist/lib/evaluation/pipeline/evaluationPipeline.js +5 -2
- package/dist/lib/evaluation/scorers/scorerRegistry.d.ts +3 -0
- package/dist/lib/evaluation/scorers/scorerRegistry.js +356 -284
- package/dist/lib/mcp/toolRegistry.d.ts +2 -0
- package/dist/lib/mcp/toolRegistry.js +32 -31
- package/dist/lib/neurolink.d.ts +38 -0
- package/dist/lib/neurolink.js +1890 -1707
- package/dist/lib/providers/googleAiStudio.js +0 -5
- package/dist/lib/providers/googleNativeGemini3.d.ts +4 -0
- package/dist/lib/providers/googleNativeGemini3.js +39 -1
- package/dist/lib/providers/googleVertex.d.ts +10 -0
- package/dist/lib/providers/googleVertex.js +445 -445
- package/dist/lib/providers/litellm.d.ts +1 -0
- package/dist/lib/providers/litellm.js +73 -64
- package/dist/lib/providers/ollama.js +17 -4
- package/dist/lib/providers/openAI.d.ts +2 -0
- package/dist/lib/providers/openAI.js +139 -140
- package/dist/lib/proxy/claudeFormat.js +14 -5
- package/dist/lib/proxy/oauthFetch.js +298 -318
- package/dist/lib/proxy/proxyConfig.js +3 -1
- package/dist/lib/proxy/proxyFetch.js +250 -222
- package/dist/lib/proxy/proxyHealth.d.ts +17 -0
- package/dist/lib/proxy/proxyHealth.js +55 -0
- package/dist/lib/proxy/requestLogger.js +140 -48
- package/dist/lib/proxy/routingPolicy.d.ts +33 -0
- package/dist/lib/proxy/routingPolicy.js +255 -0
- package/dist/lib/proxy/snapshotPersistence.d.ts +2 -0
- package/dist/lib/proxy/snapshotPersistence.js +41 -0
- package/dist/lib/proxy/sseInterceptor.js +36 -11
- package/dist/lib/server/routes/claudeProxyRoutes.d.ts +2 -1
- package/dist/lib/server/routes/claudeProxyRoutes.js +2916 -2377
- package/dist/lib/services/server/ai/observability/instrumentation.js +194 -218
- package/dist/lib/tasks/backends/bullmqBackend.js +24 -18
- package/dist/lib/tasks/store/redisTaskStore.js +42 -17
- package/dist/lib/tasks/taskManager.d.ts +2 -0
- package/dist/lib/tasks/taskManager.js +100 -5
- package/dist/lib/telemetry/telemetryService.js +9 -5
- package/dist/lib/types/cli.d.ts +4 -0
- package/dist/lib/types/proxyTypes.d.ts +211 -1
- package/dist/lib/types/tools.d.ts +18 -0
- package/dist/lib/utils/providerHealth.d.ts +1 -0
- package/dist/lib/utils/providerHealth.js +46 -31
- package/dist/lib/utils/providerUtils.js +11 -22
- package/dist/lib/utils/schemaConversion.d.ts +1 -0
- package/dist/lib/utils/schemaConversion.js +3 -0
- package/dist/mcp/toolRegistry.d.ts +2 -0
- package/dist/mcp/toolRegistry.js +32 -31
- package/dist/neurolink.d.ts +38 -0
- package/dist/neurolink.js +1890 -1707
- package/dist/providers/googleAiStudio.js +0 -5
- package/dist/providers/googleNativeGemini3.d.ts +4 -0
- package/dist/providers/googleNativeGemini3.js +39 -1
- package/dist/providers/googleVertex.d.ts +10 -0
- package/dist/providers/googleVertex.js +445 -445
- package/dist/providers/litellm.d.ts +1 -0
- package/dist/providers/litellm.js +73 -64
- package/dist/providers/ollama.js +17 -4
- package/dist/providers/openAI.d.ts +2 -0
- package/dist/providers/openAI.js +139 -140
- package/dist/proxy/claudeFormat.js +14 -5
- package/dist/proxy/oauthFetch.js +298 -318
- package/dist/proxy/proxyConfig.js +3 -1
- package/dist/proxy/proxyFetch.js +250 -222
- package/dist/proxy/proxyHealth.d.ts +17 -0
- package/dist/proxy/proxyHealth.js +54 -0
- package/dist/proxy/requestLogger.js +140 -48
- package/dist/proxy/routingPolicy.d.ts +33 -0
- package/dist/proxy/routingPolicy.js +254 -0
- package/dist/proxy/snapshotPersistence.d.ts +2 -0
- package/dist/proxy/snapshotPersistence.js +40 -0
- package/dist/proxy/sseInterceptor.js +36 -11
- package/dist/server/routes/claudeProxyRoutes.d.ts +2 -1
- package/dist/server/routes/claudeProxyRoutes.js +2916 -2377
- package/dist/services/server/ai/observability/instrumentation.js +194 -218
- package/dist/tasks/backends/bullmqBackend.js +24 -18
- package/dist/tasks/store/redisTaskStore.js +42 -17
- package/dist/tasks/taskManager.d.ts +2 -0
- package/dist/tasks/taskManager.js +100 -5
- package/dist/telemetry/telemetryService.js +9 -5
- package/dist/types/cli.d.ts +4 -0
- package/dist/types/proxyTypes.d.ts +211 -1
- package/dist/types/tools.d.ts +18 -0
- package/dist/utils/providerHealth.d.ts +1 -0
- package/dist/utils/providerHealth.js +46 -31
- package/dist/utils/providerUtils.js +12 -22
- package/dist/utils/schemaConversion.d.ts +1 -0
- package/dist/utils/schemaConversion.js +3 -0
- package/package.json +3 -2
- package/scripts/observability/check-proxy-telemetry.mjs +1 -1
- package/scripts/observability/manage-local-openobserve.sh +36 -5
package/dist/core/factory.js
CHANGED
|
@@ -7,7 +7,7 @@ import { ProviderRegistry } from "../factories/providerRegistry.js";
|
|
|
7
7
|
import { getBestProvider } from "../utils/providerUtils.js";
|
|
8
8
|
import { logger } from "../utils/logger.js";
|
|
9
9
|
import { dynamicModelProvider } from "./dynamicModels.js";
|
|
10
|
-
import { withTimeout } from "../utils/errorHandling.js";
|
|
10
|
+
import { withTimeout, ErrorFactory } from "../utils/errorHandling.js";
|
|
11
11
|
const componentIdentifier = "aiProviderFactory";
|
|
12
12
|
const factoryTracer = tracers.factory;
|
|
13
13
|
/**
|
|
@@ -34,7 +34,7 @@ export class AIProviderFactory {
|
|
|
34
34
|
const functionTag = "AIProviderFactory.initializeDynamicProviderWithTimeout";
|
|
35
35
|
const INIT_TIMEOUT = 10000; // 10 seconds total timeout for initialization
|
|
36
36
|
try {
|
|
37
|
-
await withTimeout(dynamicModelProvider.initialize(), INIT_TIMEOUT,
|
|
37
|
+
await withTimeout(dynamicModelProvider.initialize(), INIT_TIMEOUT, ErrorFactory.toolTimeout("dynamic-provider-init", INIT_TIMEOUT));
|
|
38
38
|
logger.debug(`[${functionTag}] Dynamic model provider initialized successfully`);
|
|
39
39
|
}
|
|
40
40
|
catch (error) {
|
|
@@ -47,6 +47,141 @@ export class AIProviderFactory {
|
|
|
47
47
|
// This ensures the factory continues to work even if dynamic models fail
|
|
48
48
|
}
|
|
49
49
|
}
|
|
50
|
+
static resolveModelFromEnvironment(providerName, modelName, functionTag) {
|
|
51
|
+
if (modelName && modelName !== "default") {
|
|
52
|
+
logger.debug(`[${functionTag}] Skipping environment variable check - explicit model provided: ${modelName}`);
|
|
53
|
+
return modelName;
|
|
54
|
+
}
|
|
55
|
+
logger.debug(`[${functionTag}] Checking environment variables for provider: ${providerName}`);
|
|
56
|
+
const normalizedProvider = providerName.toLowerCase();
|
|
57
|
+
const envConfigs = [
|
|
58
|
+
{
|
|
59
|
+
match: ["bedrock"],
|
|
60
|
+
label: "Bedrock",
|
|
61
|
+
vars: ["BEDROCK_MODEL", "BEDROCK_MODEL_ID"],
|
|
62
|
+
},
|
|
63
|
+
{
|
|
64
|
+
match: ["vertex"],
|
|
65
|
+
label: "Vertex",
|
|
66
|
+
vars: ["VERTEX_MODEL"],
|
|
67
|
+
},
|
|
68
|
+
{
|
|
69
|
+
match: ["azure"],
|
|
70
|
+
label: "Azure",
|
|
71
|
+
vars: [
|
|
72
|
+
"AZURE_OPENAI_MODEL",
|
|
73
|
+
"AZURE_OPENAI_DEPLOYMENT",
|
|
74
|
+
"AZURE_OPENAI_DEPLOYMENT_ID",
|
|
75
|
+
],
|
|
76
|
+
},
|
|
77
|
+
{
|
|
78
|
+
match: ["openai", "gpt", "chatgpt", "openai-compat"],
|
|
79
|
+
label: "OpenAI",
|
|
80
|
+
vars: ["OPENAI_MODEL"],
|
|
81
|
+
},
|
|
82
|
+
{
|
|
83
|
+
match: ["anthropic", "claude", "anthropic-claude"],
|
|
84
|
+
label: "Anthropic",
|
|
85
|
+
vars: ["ANTHROPIC_MODEL"],
|
|
86
|
+
},
|
|
87
|
+
{
|
|
88
|
+
match: ["google", "gemini"],
|
|
89
|
+
label: "Google AI",
|
|
90
|
+
vars: ["GOOGLE_AI_MODEL"],
|
|
91
|
+
},
|
|
92
|
+
{
|
|
93
|
+
match: ["mistral"],
|
|
94
|
+
label: "Mistral",
|
|
95
|
+
vars: ["MISTRAL_MODEL"],
|
|
96
|
+
},
|
|
97
|
+
{
|
|
98
|
+
match: ["ollama"],
|
|
99
|
+
label: "Ollama",
|
|
100
|
+
vars: ["OLLAMA_MODEL"],
|
|
101
|
+
},
|
|
102
|
+
{
|
|
103
|
+
match: ["litellm"],
|
|
104
|
+
label: "LiteLLM",
|
|
105
|
+
vars: ["LITELLM_MODEL"],
|
|
106
|
+
},
|
|
107
|
+
];
|
|
108
|
+
const envConfig = envConfigs.find((config) => config.match.some((match) => normalizedProvider.includes(match)));
|
|
109
|
+
if (!envConfig) {
|
|
110
|
+
logger.debug(`[${functionTag}] Provider ${providerName} - no environment variable check implemented`);
|
|
111
|
+
return modelName;
|
|
112
|
+
}
|
|
113
|
+
const matchedVar = envConfig.vars.find((name) => process.env[name]);
|
|
114
|
+
const envModel = matchedVar ? process.env[matchedVar] : undefined;
|
|
115
|
+
if (envModel) {
|
|
116
|
+
logger.debug(`[${functionTag}] Environment variable found for ${envConfig.label}`, {
|
|
117
|
+
envVariable: matchedVar,
|
|
118
|
+
resolvedModel: envModel,
|
|
119
|
+
});
|
|
120
|
+
return envModel;
|
|
121
|
+
}
|
|
122
|
+
logger.debug(`[${functionTag}] No ${envConfig.label} environment variables found (${envConfig.vars.join(", ")})`);
|
|
123
|
+
return modelName;
|
|
124
|
+
}
|
|
125
|
+
static async resolveDynamicModelName(providerName, modelName, resolvedModelName, functionTag) {
|
|
126
|
+
if ((resolvedModelName && resolvedModelName !== "default") ||
|
|
127
|
+
(modelName && modelName !== "default")) {
|
|
128
|
+
logger.debug(`[${functionTag}] Skipping dynamic model resolution`, {
|
|
129
|
+
resolvedModelName: resolvedModelName || "none",
|
|
130
|
+
reason: "Model already resolved from environment variables or explicit parameter",
|
|
131
|
+
});
|
|
132
|
+
return resolvedModelName;
|
|
133
|
+
}
|
|
134
|
+
logger.debug(`[${functionTag}] Attempting dynamic model resolution`, {
|
|
135
|
+
currentResolvedModel: resolvedModelName || "none",
|
|
136
|
+
reason: "No environment variable found and no explicit model provided",
|
|
137
|
+
});
|
|
138
|
+
try {
|
|
139
|
+
const normalizedProvider = this.normalizeProviderName(providerName);
|
|
140
|
+
if (dynamicModelProvider.needsRefresh()) {
|
|
141
|
+
logger.debug(`[${functionTag}] Dynamic model provider needs refresh - initializing`);
|
|
142
|
+
await this.initializeDynamicProviderWithTimeout();
|
|
143
|
+
}
|
|
144
|
+
const dynamicModel = dynamicModelProvider.resolveModel(normalizedProvider, modelName || undefined);
|
|
145
|
+
if (!dynamicModel) {
|
|
146
|
+
logger.debug(`[${functionTag}] Dynamic model resolution returned null`, {
|
|
147
|
+
provider: normalizedProvider,
|
|
148
|
+
requestedModel: modelName || "default",
|
|
149
|
+
});
|
|
150
|
+
return resolvedModelName;
|
|
151
|
+
}
|
|
152
|
+
logger.debug(`[${functionTag}] Resolved dynamic model`, {
|
|
153
|
+
provider: normalizedProvider,
|
|
154
|
+
requestedModel: modelName || "default",
|
|
155
|
+
resolvedModel: dynamicModel.id,
|
|
156
|
+
displayName: dynamicModel.displayName,
|
|
157
|
+
pricing: dynamicModel.pricing.input,
|
|
158
|
+
});
|
|
159
|
+
return dynamicModel.id;
|
|
160
|
+
}
|
|
161
|
+
catch (resolveError) {
|
|
162
|
+
logger.debug(`[${functionTag}] Dynamic model resolution failed, using static fallback`, {
|
|
163
|
+
error: resolveError instanceof Error
|
|
164
|
+
? resolveError.message
|
|
165
|
+
: String(resolveError),
|
|
166
|
+
});
|
|
167
|
+
return resolvedModelName;
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
static async createResolvedProvider(providerName, resolvedModelName, sdk, region, functionTag) {
|
|
171
|
+
await withTimeout(ProviderRegistry.registerAllProviders(), 30_000, ErrorFactory.toolTimeout("provider-registration", 30_000));
|
|
172
|
+
const normalizedName = this.normalizeProviderName(providerName);
|
|
173
|
+
const finalModelName = resolvedModelName === "default" || resolvedModelName === null
|
|
174
|
+
? undefined
|
|
175
|
+
: resolvedModelName;
|
|
176
|
+
logger.debug(`[${functionTag}] Final provider configuration`, {
|
|
177
|
+
originalProviderName: providerName,
|
|
178
|
+
normalizedProviderName: normalizedName,
|
|
179
|
+
resolvedModelName: resolvedModelName || "not resolved",
|
|
180
|
+
finalModelName: finalModelName || "using provider default",
|
|
181
|
+
});
|
|
182
|
+
const provider = await withTimeout(ProviderFactory.createProvider(normalizedName, finalModelName, sdk, region), 30_000, ErrorFactory.toolTimeout(`provider-creation:${normalizedName}`, 30_000));
|
|
183
|
+
return { normalizedName, finalModelName, provider };
|
|
184
|
+
}
|
|
50
185
|
/**
|
|
51
186
|
* Create a provider instance for the specified provider type
|
|
52
187
|
* @param providerName - Name of the provider ('vertex', 'bedrock', 'openai')
|
|
@@ -88,194 +223,9 @@ export class AIProviderFactory {
|
|
|
88
223
|
// - Enhanced error handling and logging for debugging
|
|
89
224
|
//
|
|
90
225
|
// The dynamic model provider now provides reliable functionality without hanging
|
|
91
|
-
let resolvedModelName = modelName;
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
logger.debug(`[${functionTag}] Checking environment variables for provider: ${providerName}`);
|
|
95
|
-
// Check for provider-specific environment variables first
|
|
96
|
-
if (providerName.toLowerCase().includes("bedrock")) {
|
|
97
|
-
const envModel = process.env.BEDROCK_MODEL || process.env.BEDROCK_MODEL_ID;
|
|
98
|
-
if (envModel) {
|
|
99
|
-
resolvedModelName = envModel;
|
|
100
|
-
logger.debug(`[${functionTag}] Environment variable found for Bedrock`, {
|
|
101
|
-
envVariable: process.env.BEDROCK_MODEL
|
|
102
|
-
? "BEDROCK_MODEL"
|
|
103
|
-
: "BEDROCK_MODEL_ID",
|
|
104
|
-
resolvedModel: envModel,
|
|
105
|
-
});
|
|
106
|
-
}
|
|
107
|
-
else {
|
|
108
|
-
logger.debug(`[${functionTag}] No Bedrock environment variables found (BEDROCK_MODEL, BEDROCK_MODEL_ID)`);
|
|
109
|
-
}
|
|
110
|
-
}
|
|
111
|
-
else if (providerName.toLowerCase().includes("vertex")) {
|
|
112
|
-
const envModel = process.env.VERTEX_MODEL;
|
|
113
|
-
if (envModel) {
|
|
114
|
-
resolvedModelName = envModel;
|
|
115
|
-
logger.debug(`[${functionTag}] Environment variable found for Vertex`, {
|
|
116
|
-
envVariable: "VERTEX_MODEL",
|
|
117
|
-
resolvedModel: envModel,
|
|
118
|
-
});
|
|
119
|
-
}
|
|
120
|
-
else {
|
|
121
|
-
logger.debug(`[${functionTag}] No Vertex environment variables found (VERTEX_MODEL)`);
|
|
122
|
-
}
|
|
123
|
-
}
|
|
124
|
-
else if (providerName.toLowerCase().includes("azure")) {
|
|
125
|
-
const envModel = process.env.AZURE_OPENAI_MODEL ||
|
|
126
|
-
process.env.AZURE_OPENAI_DEPLOYMENT ||
|
|
127
|
-
process.env.AZURE_OPENAI_DEPLOYMENT_ID;
|
|
128
|
-
if (envModel) {
|
|
129
|
-
resolvedModelName = envModel;
|
|
130
|
-
logger.debug(`[${functionTag}] Environment variable found for Azure`, {
|
|
131
|
-
envVariable: process.env.AZURE_OPENAI_MODEL
|
|
132
|
-
? "AZURE_OPENAI_MODEL"
|
|
133
|
-
: process.env.AZURE_OPENAI_DEPLOYMENT
|
|
134
|
-
? "AZURE_OPENAI_DEPLOYMENT"
|
|
135
|
-
: "AZURE_OPENAI_DEPLOYMENT_ID",
|
|
136
|
-
resolvedModel: envModel,
|
|
137
|
-
});
|
|
138
|
-
}
|
|
139
|
-
else {
|
|
140
|
-
logger.debug(`[${functionTag}] No Azure environment variables found (AZURE_OPENAI_MODEL, AZURE_OPENAI_DEPLOYMENT, AZURE_OPENAI_DEPLOYMENT_ID)`);
|
|
141
|
-
}
|
|
142
|
-
}
|
|
143
|
-
else if (providerName.toLowerCase().includes("openai")) {
|
|
144
|
-
const envModel = process.env.OPENAI_MODEL;
|
|
145
|
-
if (envModel) {
|
|
146
|
-
resolvedModelName = envModel;
|
|
147
|
-
logger.debug(`[${functionTag}] Environment variable found for OpenAI`, {
|
|
148
|
-
envVariable: "OPENAI_MODEL",
|
|
149
|
-
resolvedModel: envModel,
|
|
150
|
-
});
|
|
151
|
-
}
|
|
152
|
-
else {
|
|
153
|
-
logger.debug(`[${functionTag}] No OpenAI environment variables found (OPENAI_MODEL)`);
|
|
154
|
-
}
|
|
155
|
-
}
|
|
156
|
-
else if (providerName.toLowerCase().includes("anthropic")) {
|
|
157
|
-
const envModel = process.env.ANTHROPIC_MODEL;
|
|
158
|
-
if (envModel) {
|
|
159
|
-
resolvedModelName = envModel;
|
|
160
|
-
logger.debug(`[${functionTag}] Environment variable found for Anthropic`, {
|
|
161
|
-
envVariable: "ANTHROPIC_MODEL",
|
|
162
|
-
resolvedModel: envModel,
|
|
163
|
-
});
|
|
164
|
-
}
|
|
165
|
-
else {
|
|
166
|
-
logger.debug(`[${functionTag}] No Anthropic environment variables found (ANTHROPIC_MODEL)`);
|
|
167
|
-
}
|
|
168
|
-
}
|
|
169
|
-
else if (providerName.toLowerCase().includes("google") ||
|
|
170
|
-
providerName.toLowerCase().includes("gemini")) {
|
|
171
|
-
const envModel = process.env.GOOGLE_AI_MODEL;
|
|
172
|
-
if (envModel) {
|
|
173
|
-
resolvedModelName = envModel;
|
|
174
|
-
logger.debug(`[${functionTag}] Environment variable found for Google AI`, {
|
|
175
|
-
envVariable: "GOOGLE_AI_MODEL",
|
|
176
|
-
resolvedModel: envModel,
|
|
177
|
-
});
|
|
178
|
-
}
|
|
179
|
-
else {
|
|
180
|
-
logger.debug(`[${functionTag}] No Google AI environment variables found (GOOGLE_AI_MODEL)`);
|
|
181
|
-
}
|
|
182
|
-
}
|
|
183
|
-
else if (providerName.toLowerCase().includes("mistral")) {
|
|
184
|
-
const envModel = process.env.MISTRAL_MODEL;
|
|
185
|
-
if (envModel) {
|
|
186
|
-
resolvedModelName = envModel;
|
|
187
|
-
logger.debug(`[${functionTag}] Environment variable found for Mistral`, {
|
|
188
|
-
envVariable: "MISTRAL_MODEL",
|
|
189
|
-
resolvedModel: envModel,
|
|
190
|
-
});
|
|
191
|
-
}
|
|
192
|
-
else {
|
|
193
|
-
logger.debug(`[${functionTag}] No Mistral environment variables found (MISTRAL_MODEL)`);
|
|
194
|
-
}
|
|
195
|
-
}
|
|
196
|
-
else if (providerName.toLowerCase().includes("ollama")) {
|
|
197
|
-
const envModel = process.env.OLLAMA_MODEL;
|
|
198
|
-
if (envModel) {
|
|
199
|
-
resolvedModelName = envModel;
|
|
200
|
-
logger.debug(`[${functionTag}] Environment variable found for Ollama`, {
|
|
201
|
-
envVariable: "OLLAMA_MODEL",
|
|
202
|
-
resolvedModel: envModel,
|
|
203
|
-
});
|
|
204
|
-
}
|
|
205
|
-
else {
|
|
206
|
-
logger.debug(`[${functionTag}] No Ollama environment variables found (OLLAMA_MODEL)`);
|
|
207
|
-
}
|
|
208
|
-
}
|
|
209
|
-
else {
|
|
210
|
-
logger.debug(`[${functionTag}] Provider ${providerName} - no environment variable check implemented`);
|
|
211
|
-
}
|
|
212
|
-
}
|
|
213
|
-
else {
|
|
214
|
-
logger.debug(`[${functionTag}] Skipping environment variable check - explicit model provided: ${modelName}`);
|
|
215
|
-
}
|
|
216
|
-
// PRIORITY 2: Enable dynamic model resolution only if no env var found
|
|
217
|
-
if ((!resolvedModelName || resolvedModelName === "default") &&
|
|
218
|
-
(!modelName || modelName === "default")) {
|
|
219
|
-
logger.debug(`[${functionTag}] Attempting dynamic model resolution`, {
|
|
220
|
-
currentResolvedModel: resolvedModelName || "none",
|
|
221
|
-
reason: "No environment variable found and no explicit model provided",
|
|
222
|
-
});
|
|
223
|
-
try {
|
|
224
|
-
const normalizedProvider = this.normalizeProviderName(providerName);
|
|
225
|
-
// Initialize with timeout protection - won't hang anymore
|
|
226
|
-
if (dynamicModelProvider.needsRefresh()) {
|
|
227
|
-
logger.debug(`[${functionTag}] Dynamic model provider needs refresh - initializing`);
|
|
228
|
-
await this.initializeDynamicProviderWithTimeout();
|
|
229
|
-
}
|
|
230
|
-
const dynamicModel = dynamicModelProvider.resolveModel(normalizedProvider, modelName || undefined);
|
|
231
|
-
if (dynamicModel) {
|
|
232
|
-
resolvedModelName = dynamicModel.id;
|
|
233
|
-
logger.debug(`[${functionTag}] Resolved dynamic model`, {
|
|
234
|
-
provider: normalizedProvider,
|
|
235
|
-
requestedModel: modelName || "default",
|
|
236
|
-
resolvedModel: resolvedModelName,
|
|
237
|
-
displayName: dynamicModel.displayName,
|
|
238
|
-
pricing: dynamicModel.pricing.input,
|
|
239
|
-
});
|
|
240
|
-
}
|
|
241
|
-
else {
|
|
242
|
-
logger.debug(`[${functionTag}] Dynamic model resolution returned null`, {
|
|
243
|
-
provider: normalizedProvider,
|
|
244
|
-
requestedModel: modelName || "default",
|
|
245
|
-
});
|
|
246
|
-
}
|
|
247
|
-
}
|
|
248
|
-
catch (resolveError) {
|
|
249
|
-
logger.debug(`[${functionTag}] Dynamic model resolution failed, using static fallback`, {
|
|
250
|
-
error: resolveError instanceof Error
|
|
251
|
-
? resolveError.message
|
|
252
|
-
: String(resolveError),
|
|
253
|
-
});
|
|
254
|
-
// Continue with static model name - no functionality loss
|
|
255
|
-
}
|
|
256
|
-
}
|
|
257
|
-
else {
|
|
258
|
-
logger.debug(`[${functionTag}] Skipping dynamic model resolution`, {
|
|
259
|
-
resolvedModelName: resolvedModelName || "none",
|
|
260
|
-
reason: "Model already resolved from environment variables or explicit parameter",
|
|
261
|
-
});
|
|
262
|
-
}
|
|
263
|
-
// CRITICAL FIX: Initialize providers before using them
|
|
264
|
-
await withTimeout(ProviderRegistry.registerAllProviders(), 30_000, new Error("Provider registration timed out"));
|
|
265
|
-
// PURE FACTORY PATTERN: No switch statements - use ProviderFactory exclusively
|
|
266
|
-
const normalizedName = this.normalizeProviderName(providerName);
|
|
267
|
-
const finalModelName = resolvedModelName === "default" || resolvedModelName === null
|
|
268
|
-
? undefined
|
|
269
|
-
: resolvedModelName;
|
|
270
|
-
logger.debug(`[${functionTag}] Final provider configuration`, {
|
|
271
|
-
originalProviderName: providerName,
|
|
272
|
-
normalizedProviderName: normalizedName,
|
|
273
|
-
originalModelName: modelName || "not provided",
|
|
274
|
-
resolvedModelName: resolvedModelName || "not resolved",
|
|
275
|
-
finalModelName: finalModelName || "using provider default",
|
|
276
|
-
});
|
|
277
|
-
// Create provider with enhanced SDK and region support
|
|
278
|
-
const provider = await withTimeout(ProviderFactory.createProvider(normalizedName, finalModelName, sdk, region), 30_000, new Error(`Provider creation timed out for ${normalizedName}`));
|
|
226
|
+
let resolvedModelName = this.resolveModelFromEnvironment(providerName, modelName, functionTag);
|
|
227
|
+
resolvedModelName = await this.resolveDynamicModelName(providerName, modelName, resolvedModelName, functionTag);
|
|
228
|
+
const { normalizedName, finalModelName, provider } = await this.createResolvedProvider(providerName, resolvedModelName, sdk, region, functionTag);
|
|
279
229
|
// Summary logging in format expected by debugging tools
|
|
280
230
|
logger.debug(`[AIProviderFactory] Provider creation completed { providerName: '${normalizedName}', modelName: '${finalModelName}' }`);
|
|
281
231
|
logger.debug(`[AIProviderFactory] Resolved model: ${finalModelName}`);
|
|
@@ -35,6 +35,7 @@ export declare class ToolsManager {
|
|
|
35
35
|
* Set session context for MCP tools
|
|
36
36
|
*/
|
|
37
37
|
setSessionContext(sessionId?: string, userId?: string): void;
|
|
38
|
+
private emitToolEvent;
|
|
38
39
|
/**
|
|
39
40
|
* Set up tool executor for a provider to enable actual tool execution
|
|
40
41
|
* @param sdk - The NeuroLinkSDK instance for tool execution
|
|
@@ -16,6 +16,7 @@
|
|
|
16
16
|
*/
|
|
17
17
|
import { tool as createAISDKTool, jsonSchema } from "ai";
|
|
18
18
|
import { z } from "zod";
|
|
19
|
+
import { createToolEventPayload } from "../toolEvents.js";
|
|
19
20
|
import { tracers, ATTR, withSpan } from "../../telemetry/index.js";
|
|
20
21
|
import { SpanStatusCode } from "@opentelemetry/api";
|
|
21
22
|
import { logger } from "../../utils/logger.js";
|
|
@@ -50,6 +51,13 @@ export class ToolsManager {
|
|
|
50
51
|
this.sessionId = sessionId;
|
|
51
52
|
this.userId = userId;
|
|
52
53
|
}
|
|
54
|
+
emitToolEvent(eventName, toolName, payload) {
|
|
55
|
+
if (this.neurolink?.getEventEmitter) {
|
|
56
|
+
this.neurolink
|
|
57
|
+
.getEventEmitter()
|
|
58
|
+
.emit(eventName, createToolEventPayload(toolName, payload));
|
|
59
|
+
}
|
|
60
|
+
}
|
|
53
61
|
/**
|
|
54
62
|
* Set up tool executor for a provider to enable actual tool execution
|
|
55
63
|
* @param sdk - The NeuroLinkSDK instance for tool execution
|
|
@@ -175,27 +183,24 @@ export class ToolsManager {
|
|
|
175
183
|
tools[toolName] = {
|
|
176
184
|
...directTool,
|
|
177
185
|
execute: async (params) => {
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
const emitter = this.neurolink.getEventEmitter();
|
|
181
|
-
emitter.emit("tool:start", { tool: toolName, input: params });
|
|
182
|
-
}
|
|
186
|
+
const startTime = Date.now();
|
|
187
|
+
this.emitToolEvent("tool:start", toolName, { input: params });
|
|
183
188
|
try {
|
|
184
189
|
const result = await originalExecute(params);
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
}
|
|
190
|
+
this.emitToolEvent("tool:end", toolName, {
|
|
191
|
+
result,
|
|
192
|
+
success: true,
|
|
193
|
+
responseTime: Date.now() - startTime,
|
|
194
|
+
});
|
|
190
195
|
return result;
|
|
191
196
|
}
|
|
192
197
|
catch (error) {
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
}
|
|
198
|
+
const errorMsg = error instanceof Error ? error.message : String(error);
|
|
199
|
+
this.emitToolEvent("tool:end", toolName, {
|
|
200
|
+
error: errorMsg,
|
|
201
|
+
success: false,
|
|
202
|
+
responseTime: Date.now() - startTime,
|
|
203
|
+
});
|
|
199
204
|
throw error;
|
|
200
205
|
}
|
|
201
206
|
},
|
|
@@ -443,48 +448,41 @@ export class ToolsManager {
|
|
|
443
448
|
description: tool.description || `External MCP tool ${tool.name}`,
|
|
444
449
|
inputSchema: finalSchema, // AI SDK v6 uses inputSchema (not parameters)
|
|
445
450
|
execute: async (params) => {
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
const emitter = this.neurolink.getEventEmitter();
|
|
449
|
-
emitter.emit("tool:start", { tool: tool.name, input: params });
|
|
450
|
-
}
|
|
451
|
+
const startTime = Date.now();
|
|
452
|
+
this.emitToolEvent("tool:start", tool.name, { input: params });
|
|
451
453
|
// Execute via NeuroLink's direct tool execution
|
|
452
454
|
if (this.neurolink &&
|
|
453
455
|
typeof this.neurolink.executeExternalMCPTool === "function") {
|
|
454
456
|
try {
|
|
455
457
|
const result = await this.neurolink.executeExternalMCPTool(tool.serverId || "unknown", tool.name, params);
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
}
|
|
458
|
+
this.emitToolEvent("tool:end", tool.name, {
|
|
459
|
+
result,
|
|
460
|
+
success: true,
|
|
461
|
+
responseTime: Date.now() - startTime,
|
|
462
|
+
});
|
|
461
463
|
return result;
|
|
462
464
|
}
|
|
463
465
|
catch (mcpError) {
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
emitter.emit("tool:end", { tool: tool.name, error: errorMsg });
|
|
471
|
-
}
|
|
466
|
+
const errorMsg = mcpError instanceof Error ? mcpError.message : String(mcpError);
|
|
467
|
+
this.emitToolEvent("tool:end", tool.name, {
|
|
468
|
+
error: errorMsg,
|
|
469
|
+
success: false,
|
|
470
|
+
responseTime: Date.now() - startTime,
|
|
471
|
+
});
|
|
472
472
|
logger.error(`External MCP tool failed: ${tool.name}`, {
|
|
473
473
|
serverId: tool.serverId,
|
|
474
|
-
error:
|
|
475
|
-
? mcpError.message
|
|
476
|
-
: String(mcpError),
|
|
474
|
+
error: errorMsg,
|
|
477
475
|
});
|
|
478
476
|
throw mcpError;
|
|
479
477
|
}
|
|
480
478
|
}
|
|
481
479
|
else {
|
|
482
480
|
const error = `Cannot execute external MCP tool: NeuroLink executeExternalMCPTool not available`;
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
}
|
|
481
|
+
this.emitToolEvent("tool:end", tool.name, {
|
|
482
|
+
error,
|
|
483
|
+
success: false,
|
|
484
|
+
responseTime: Date.now() - startTime,
|
|
485
|
+
});
|
|
488
486
|
logger.error(error);
|
|
489
487
|
throw new Error(error);
|
|
490
488
|
}
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
* Multi-scorer orchestration with configurable execution
|
|
4
4
|
*/
|
|
5
5
|
import { logger } from "../../utils/logger.js";
|
|
6
|
-
import { withTimeout } from "../../utils/errorHandling.js";
|
|
6
|
+
import { ErrorFactory, withTimeout } from "../../utils/errorHandling.js";
|
|
7
7
|
import { DEFAULT_SCORE_SCALE } from "../scorers/baseScorer.js";
|
|
8
8
|
import { ScorerRegistry } from "../scorers/scorerRegistry.js";
|
|
9
9
|
/**
|
|
@@ -178,7 +178,10 @@ export class EvaluationPipeline {
|
|
|
178
178
|
const hasOnlyScorers = !!options?.onlyScorers && options.onlyScorers.length > 0;
|
|
179
179
|
const hasSkipScorers = !!options?.skipScorers && options.skipScorers.length > 0;
|
|
180
180
|
if (hasOnlyScorers && hasSkipScorers) {
|
|
181
|
-
throw
|
|
181
|
+
throw ErrorFactory.invalidConfiguration("evaluation pipeline execution options", "Cannot specify both 'onlyScorers' and 'skipScorers' options", {
|
|
182
|
+
onlyScorers: options?.onlyScorers,
|
|
183
|
+
skipScorers: options?.skipScorers,
|
|
184
|
+
});
|
|
182
185
|
}
|
|
183
186
|
}
|
|
184
187
|
/**
|
|
@@ -19,6 +19,9 @@ export declare class ScorerRegistry {
|
|
|
19
19
|
* Register a scorer using a simple configuration
|
|
20
20
|
*/
|
|
21
21
|
static registerScorer(metadata: ScorerMetadata, factory: ScorerFactory, aliases?: string[]): void;
|
|
22
|
+
private static registerScorerDefinitions;
|
|
23
|
+
private static registerBuiltInLLMScorers;
|
|
24
|
+
private static registerBuiltInRuleScorers;
|
|
22
25
|
/**
|
|
23
26
|
* Register built-in scorers using dynamic imports
|
|
24
27
|
*/
|