@juspay/neurolink 7.33.2 → 7.33.3
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 +2 -0
- package/dist/constants/index.d.ts +192 -0
- package/dist/constants/index.js +195 -0
- package/dist/constants/performance.d.ts +366 -0
- package/dist/constants/performance.js +389 -0
- package/dist/constants/retry.d.ts +224 -0
- package/dist/constants/retry.js +266 -0
- package/dist/constants/timeouts.d.ts +225 -0
- package/dist/constants/timeouts.js +182 -0
- package/dist/constants/tokens.d.ts +234 -0
- package/dist/constants/tokens.js +314 -0
- package/dist/core/types.d.ts +268 -0
- package/dist/core/types.js +153 -0
- package/dist/lib/constants/index.d.ts +192 -0
- package/dist/lib/constants/index.js +195 -0
- package/dist/lib/constants/performance.d.ts +366 -0
- package/dist/lib/constants/performance.js +389 -0
- package/dist/lib/constants/retry.d.ts +224 -0
- package/dist/lib/constants/retry.js +266 -0
- package/dist/lib/constants/timeouts.d.ts +225 -0
- package/dist/lib/constants/timeouts.js +182 -0
- package/dist/lib/constants/tokens.d.ts +234 -0
- package/dist/lib/constants/tokens.js +314 -0
- package/dist/lib/core/types.d.ts +268 -0
- package/dist/lib/core/types.js +153 -0
- package/dist/lib/models/modelRegistry.d.ts +1 -1
- package/dist/lib/models/modelRegistry.js +63 -37
- package/dist/lib/neurolink.js +35 -34
- package/dist/lib/providers/azureOpenai.d.ts +1 -1
- package/dist/lib/providers/azureOpenai.js +2 -1
- package/dist/lib/utils/providerConfig.d.ts +25 -0
- package/dist/lib/utils/providerConfig.js +24 -3
- package/dist/lib/utils/providerHealth.d.ts +1 -1
- package/dist/lib/utils/providerHealth.js +40 -33
- package/dist/lib/utils/providerSetupMessages.js +7 -6
- package/dist/lib/utils/providerUtils.js +16 -24
- package/dist/models/modelRegistry.d.ts +1 -1
- package/dist/models/modelRegistry.js +63 -37
- package/dist/neurolink.js +35 -34
- package/dist/providers/azureOpenai.d.ts +1 -1
- package/dist/providers/azureOpenai.js +2 -1
- package/dist/utils/providerConfig.d.ts +25 -0
- package/dist/utils/providerConfig.js +24 -3
- package/dist/utils/providerHealth.d.ts +1 -1
- package/dist/utils/providerHealth.js +40 -33
- package/dist/utils/providerSetupMessages.js +7 -6
- package/dist/utils/providerUtils.js +16 -24
- package/package.json +1 -1
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
import { AIProviderFactory } from "../core/factory.js";
|
|
6
6
|
import { logger } from "./logger.js";
|
|
7
7
|
import { ProviderHealthChecker } from "./providerHealth.js";
|
|
8
|
+
import { API_KEY_FORMATS, API_KEY_LENGTHS, PROJECT_ID_FORMAT, } from "./providerConfig.js";
|
|
8
9
|
/**
|
|
9
10
|
* Get the best available provider based on real-time availability checks
|
|
10
11
|
* Enhanced version consolidated from providerUtils-fixed.ts
|
|
@@ -123,15 +124,6 @@ async function isProviderAvailable(providerName) {
|
|
|
123
124
|
return false;
|
|
124
125
|
}
|
|
125
126
|
}
|
|
126
|
-
/**
|
|
127
|
-
* Google Cloud Project ID validation regex
|
|
128
|
-
* Format requirements:
|
|
129
|
-
* - Must start with a lowercase letter
|
|
130
|
-
* - Can contain lowercase letters, numbers, and hyphens
|
|
131
|
-
* - Must end with a lowercase letter or number
|
|
132
|
-
* - Total length must be 6-30 characters
|
|
133
|
-
*/
|
|
134
|
-
const GOOGLE_CLOUD_PROJECT_ID_REGEX = /^[a-z][a-z0-9-]{4,28}[a-z0-9]$/;
|
|
135
127
|
/**
|
|
136
128
|
* Validate environment variable values for a provider
|
|
137
129
|
* Addresses GitHub Copilot comment about adding environment variable validation
|
|
@@ -166,7 +158,7 @@ export function validateProviderEnvVars(provider) {
|
|
|
166
158
|
validateAnthropicCredentials(result);
|
|
167
159
|
break;
|
|
168
160
|
case "azure":
|
|
169
|
-
case "
|
|
161
|
+
case "azureopenai":
|
|
170
162
|
validateAzureCredentials(result);
|
|
171
163
|
break;
|
|
172
164
|
case "google-ai":
|
|
@@ -240,7 +232,7 @@ function validateVertexCredentials(result) {
|
|
|
240
232
|
if (!projectId) {
|
|
241
233
|
result.missingVars.push("GOOGLE_CLOUD_PROJECT_ID (or variant)");
|
|
242
234
|
}
|
|
243
|
-
else if (!
|
|
235
|
+
else if (!PROJECT_ID_FORMAT.PATTERN.test(projectId)) {
|
|
244
236
|
result.invalidVars.push("Project ID format invalid (must be 6-30 lowercase letters, digits, hyphens)");
|
|
245
237
|
}
|
|
246
238
|
if (!hasCredentials) {
|
|
@@ -259,8 +251,8 @@ function validateOpenAICredentials(result) {
|
|
|
259
251
|
if (!apiKey) {
|
|
260
252
|
result.missingVars.push("OPENAI_API_KEY");
|
|
261
253
|
}
|
|
262
|
-
else if (
|
|
263
|
-
result.invalidVars.push(
|
|
254
|
+
else if (!API_KEY_FORMATS.openai.test(apiKey)) {
|
|
255
|
+
result.invalidVars.push(`OPENAI_API_KEY (should start with 'sk-' followed by ${API_KEY_LENGTHS.OPENAI_MIN}+ characters)`);
|
|
264
256
|
}
|
|
265
257
|
}
|
|
266
258
|
/**
|
|
@@ -271,8 +263,8 @@ function validateAnthropicCredentials(result) {
|
|
|
271
263
|
if (!apiKey) {
|
|
272
264
|
result.missingVars.push("ANTHROPIC_API_KEY");
|
|
273
265
|
}
|
|
274
|
-
else if (
|
|
275
|
-
result.invalidVars.push(
|
|
266
|
+
else if (!API_KEY_FORMATS.anthropic.test(apiKey)) {
|
|
267
|
+
result.invalidVars.push(`ANTHROPIC_API_KEY (should start with 'sk-ant-' followed by ${API_KEY_LENGTHS.ANTHROPIC_MIN}+ characters)`);
|
|
276
268
|
}
|
|
277
269
|
}
|
|
278
270
|
/**
|
|
@@ -284,8 +276,8 @@ function validateAzureCredentials(result) {
|
|
|
284
276
|
if (!apiKey) {
|
|
285
277
|
result.missingVars.push("AZURE_OPENAI_API_KEY");
|
|
286
278
|
}
|
|
287
|
-
else if (
|
|
288
|
-
result.invalidVars.push(
|
|
279
|
+
else if (!API_KEY_FORMATS.azure.test(apiKey)) {
|
|
280
|
+
result.invalidVars.push(`AZURE_OPENAI_API_KEY (should be at least ${API_KEY_LENGTHS.AZURE_MIN} alphanumeric characters)`);
|
|
289
281
|
}
|
|
290
282
|
if (!endpoint) {
|
|
291
283
|
result.missingVars.push("AZURE_OPENAI_ENDPOINT");
|
|
@@ -302,8 +294,8 @@ function validateGoogleAICredentials(result) {
|
|
|
302
294
|
if (!apiKey) {
|
|
303
295
|
result.missingVars.push("GOOGLE_AI_API_KEY (or GOOGLE_GENERATIVE_AI_API_KEY)");
|
|
304
296
|
}
|
|
305
|
-
else if (
|
|
306
|
-
result.invalidVars.push(
|
|
297
|
+
else if (!API_KEY_FORMATS["google-ai"].test(apiKey)) {
|
|
298
|
+
result.invalidVars.push(`GOOGLE_AI_API_KEY (should be ${API_KEY_LENGTHS.GOOGLE_AI_EXACT} alphanumeric characters with dashes/underscores)`);
|
|
307
299
|
}
|
|
308
300
|
}
|
|
309
301
|
/**
|
|
@@ -314,8 +306,8 @@ function validateHuggingFaceCredentials(result) {
|
|
|
314
306
|
if (!apiKey) {
|
|
315
307
|
result.missingVars.push("HUGGINGFACE_API_KEY (or HF_TOKEN)");
|
|
316
308
|
}
|
|
317
|
-
else if (
|
|
318
|
-
result.invalidVars.push(
|
|
309
|
+
else if (!API_KEY_FORMATS.huggingface.test(apiKey)) {
|
|
310
|
+
result.invalidVars.push(`HUGGINGFACE_API_KEY (should start with 'hf_' followed by ${API_KEY_LENGTHS.HUGGINGFACE_EXACT} characters)`);
|
|
319
311
|
}
|
|
320
312
|
}
|
|
321
313
|
/**
|
|
@@ -326,8 +318,8 @@ function validateMistralCredentials(result) {
|
|
|
326
318
|
if (!apiKey) {
|
|
327
319
|
result.missingVars.push("MISTRAL_API_KEY");
|
|
328
320
|
}
|
|
329
|
-
else if (
|
|
330
|
-
result.invalidVars.push(
|
|
321
|
+
else if (!API_KEY_FORMATS.mistral.test(apiKey)) {
|
|
322
|
+
result.invalidVars.push(`MISTRAL_API_KEY (should be ${API_KEY_LENGTHS.MISTRAL_EXACT} alphanumeric characters)`);
|
|
331
323
|
}
|
|
332
324
|
}
|
|
333
325
|
/**
|
|
@@ -381,7 +373,7 @@ export function hasProviderEnvVars(provider) {
|
|
|
381
373
|
case "claude":
|
|
382
374
|
return !!process.env.ANTHROPIC_API_KEY;
|
|
383
375
|
case "azure":
|
|
384
|
-
case "
|
|
376
|
+
case "azureopenai":
|
|
385
377
|
return !!process.env.AZURE_OPENAI_API_KEY;
|
|
386
378
|
case "google-ai":
|
|
387
379
|
case "google-studio":
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
* Provides centralized model data for models command system
|
|
4
4
|
* Part of Phase 4.1 - Models Command System
|
|
5
5
|
*/
|
|
6
|
-
import { AIProviderName } from "../types
|
|
6
|
+
import { AIProviderName } from "../core/types.js";
|
|
7
7
|
import type { JsonValue } from "../types/common.js";
|
|
8
8
|
/**
|
|
9
9
|
* Model capabilities interface
|
|
@@ -3,14 +3,14 @@
|
|
|
3
3
|
* Provides centralized model data for models command system
|
|
4
4
|
* Part of Phase 4.1 - Models Command System
|
|
5
5
|
*/
|
|
6
|
-
import { AIProviderName } from "../types
|
|
6
|
+
import { AIProviderName, OpenAIModels, GoogleAIModels, AnthropicModels, DEFAULT_MODEL_ALIASES, } from "../core/types.js";
|
|
7
7
|
/**
|
|
8
8
|
* Comprehensive model registry
|
|
9
9
|
*/
|
|
10
10
|
export const MODEL_REGISTRY = {
|
|
11
11
|
// OpenAI Models
|
|
12
|
-
|
|
13
|
-
id:
|
|
12
|
+
[OpenAIModels.GPT_4O]: {
|
|
13
|
+
id: OpenAIModels.GPT_4O,
|
|
14
14
|
name: "GPT-4 Omni",
|
|
15
15
|
provider: AIProviderName.OPENAI,
|
|
16
16
|
description: "Most capable OpenAI model with vision and advanced reasoning",
|
|
@@ -53,8 +53,8 @@ export const MODEL_REGISTRY = {
|
|
|
53
53
|
releaseDate: "2024-05-13",
|
|
54
54
|
category: "general",
|
|
55
55
|
},
|
|
56
|
-
|
|
57
|
-
id:
|
|
56
|
+
[OpenAIModels.GPT_4O_MINI]: {
|
|
57
|
+
id: OpenAIModels.GPT_4O_MINI,
|
|
58
58
|
name: "GPT-4 Omni Mini",
|
|
59
59
|
provider: AIProviderName.OPENAI,
|
|
60
60
|
description: "Fast and cost-effective model with strong performance",
|
|
@@ -98,8 +98,8 @@ export const MODEL_REGISTRY = {
|
|
|
98
98
|
category: "general",
|
|
99
99
|
},
|
|
100
100
|
// Google AI Studio Models
|
|
101
|
-
|
|
102
|
-
id:
|
|
101
|
+
[GoogleAIModels.GEMINI_2_5_PRO]: {
|
|
102
|
+
id: GoogleAIModels.GEMINI_2_5_PRO,
|
|
103
103
|
name: "Gemini 2.5 Pro",
|
|
104
104
|
provider: AIProviderName.GOOGLE_AI,
|
|
105
105
|
description: "Google's most capable multimodal model with large context window",
|
|
@@ -142,8 +142,8 @@ export const MODEL_REGISTRY = {
|
|
|
142
142
|
releaseDate: "2024-12-11",
|
|
143
143
|
category: "reasoning",
|
|
144
144
|
},
|
|
145
|
-
|
|
146
|
-
id:
|
|
145
|
+
[GoogleAIModels.GEMINI_2_5_FLASH]: {
|
|
146
|
+
id: GoogleAIModels.GEMINI_2_5_FLASH,
|
|
147
147
|
name: "Gemini 2.5 Flash",
|
|
148
148
|
provider: AIProviderName.GOOGLE_AI,
|
|
149
149
|
description: "Fast and efficient multimodal model with large context",
|
|
@@ -187,8 +187,8 @@ export const MODEL_REGISTRY = {
|
|
|
187
187
|
category: "general",
|
|
188
188
|
},
|
|
189
189
|
// Anthropic Models
|
|
190
|
-
|
|
191
|
-
id:
|
|
190
|
+
[AnthropicModels.CLAUDE_3_5_SONNET]: {
|
|
191
|
+
id: AnthropicModels.CLAUDE_3_5_SONNET,
|
|
192
192
|
name: "Claude 3.5 Sonnet",
|
|
193
193
|
provider: AIProviderName.ANTHROPIC,
|
|
194
194
|
description: "Anthropic's most capable model with excellent reasoning and coding",
|
|
@@ -236,8 +236,8 @@ export const MODEL_REGISTRY = {
|
|
|
236
236
|
releaseDate: "2024-10-22",
|
|
237
237
|
category: "coding",
|
|
238
238
|
},
|
|
239
|
-
|
|
240
|
-
id:
|
|
239
|
+
[AnthropicModels.CLAUDE_3_5_HAIKU]: {
|
|
240
|
+
id: AnthropicModels.CLAUDE_3_5_HAIKU,
|
|
241
241
|
name: "Claude 3.5 Haiku",
|
|
242
242
|
provider: AIProviderName.ANTHROPIC,
|
|
243
243
|
description: "Fast and efficient Claude model for quick tasks",
|
|
@@ -380,39 +380,65 @@ Object.values(MODEL_REGISTRY).forEach((model) => {
|
|
|
380
380
|
MODEL_ALIASES[alias.toLowerCase()] = model.id;
|
|
381
381
|
});
|
|
382
382
|
});
|
|
383
|
-
//
|
|
384
|
-
Object.
|
|
385
|
-
|
|
386
|
-
fastest: "gpt-4o-mini",
|
|
387
|
-
cheapest: "gemini-2.5-flash",
|
|
388
|
-
"best-coding": "claude-3-5-sonnet-20241022",
|
|
389
|
-
"best-analysis": "gemini-2.5-pro",
|
|
390
|
-
"best-creative": "claude-3-5-sonnet-20241022",
|
|
391
|
-
"best-value": "gemini-2.5-flash",
|
|
392
|
-
local: "llama3.2:latest",
|
|
383
|
+
// Pull canonical alias recommendations from core/types
|
|
384
|
+
Object.entries(DEFAULT_MODEL_ALIASES).forEach(([k, v]) => {
|
|
385
|
+
MODEL_ALIASES[k.toLowerCase().replace(/_/g, "-")] = v;
|
|
393
386
|
});
|
|
387
|
+
MODEL_ALIASES.local = "llama3.2:latest";
|
|
394
388
|
/**
|
|
395
389
|
* Use case to model mappings
|
|
396
390
|
*/
|
|
397
391
|
export const USE_CASE_RECOMMENDATIONS = {
|
|
398
|
-
coding: [
|
|
399
|
-
|
|
400
|
-
|
|
392
|
+
coding: [
|
|
393
|
+
AnthropicModels.CLAUDE_3_5_SONNET,
|
|
394
|
+
OpenAIModels.GPT_4O,
|
|
395
|
+
GoogleAIModels.GEMINI_2_5_PRO,
|
|
396
|
+
],
|
|
397
|
+
creative: [
|
|
398
|
+
AnthropicModels.CLAUDE_3_5_SONNET,
|
|
399
|
+
OpenAIModels.GPT_4O,
|
|
400
|
+
GoogleAIModels.GEMINI_2_5_PRO,
|
|
401
|
+
],
|
|
402
|
+
analysis: [
|
|
403
|
+
GoogleAIModels.GEMINI_2_5_PRO,
|
|
404
|
+
AnthropicModels.CLAUDE_3_5_SONNET,
|
|
405
|
+
OpenAIModels.GPT_4O,
|
|
406
|
+
],
|
|
401
407
|
conversation: [
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
408
|
+
OpenAIModels.GPT_4O,
|
|
409
|
+
AnthropicModels.CLAUDE_3_5_SONNET,
|
|
410
|
+
AnthropicModels.CLAUDE_3_5_HAIKU,
|
|
411
|
+
],
|
|
412
|
+
reasoning: [
|
|
413
|
+
AnthropicModels.CLAUDE_3_5_SONNET,
|
|
414
|
+
GoogleAIModels.GEMINI_2_5_PRO,
|
|
415
|
+
OpenAIModels.GPT_4O,
|
|
416
|
+
],
|
|
417
|
+
translation: [
|
|
418
|
+
GoogleAIModels.GEMINI_2_5_PRO,
|
|
419
|
+
OpenAIModels.GPT_4O,
|
|
420
|
+
AnthropicModels.CLAUDE_3_5_HAIKU,
|
|
405
421
|
],
|
|
406
|
-
reasoning: ["claude-3-5-sonnet-20241022", "gemini-2.5-pro", "gpt-4o"],
|
|
407
|
-
translation: ["gemini-2.5-pro", "gpt-4o", "claude-3-5-haiku-20241022"],
|
|
408
422
|
summarization: [
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
423
|
+
GoogleAIModels.GEMINI_2_5_FLASH,
|
|
424
|
+
OpenAIModels.GPT_4O_MINI,
|
|
425
|
+
AnthropicModels.CLAUDE_3_5_HAIKU,
|
|
426
|
+
],
|
|
427
|
+
"cost-effective": [
|
|
428
|
+
GoogleAIModels.GEMINI_2_5_FLASH,
|
|
429
|
+
OpenAIModels.GPT_4O_MINI,
|
|
430
|
+
"mistral-small-latest",
|
|
431
|
+
],
|
|
432
|
+
"high-quality": [
|
|
433
|
+
AnthropicModels.CLAUDE_3_5_SONNET,
|
|
434
|
+
OpenAIModels.GPT_4O,
|
|
435
|
+
GoogleAIModels.GEMINI_2_5_PRO,
|
|
436
|
+
],
|
|
437
|
+
fast: [
|
|
438
|
+
OpenAIModels.GPT_4O_MINI,
|
|
439
|
+
GoogleAIModels.GEMINI_2_5_FLASH,
|
|
440
|
+
AnthropicModels.CLAUDE_3_5_HAIKU,
|
|
412
441
|
],
|
|
413
|
-
"cost-effective": ["gemini-2.5-flash", "gpt-4o-mini", "mistral-small-latest"],
|
|
414
|
-
"high-quality": ["claude-3-5-sonnet-20241022", "gpt-4o", "gemini-2.5-pro"],
|
|
415
|
-
fast: ["gpt-4o-mini", "gemini-2.5-flash", "claude-3-5-haiku-20241022"],
|
|
416
442
|
};
|
|
417
443
|
/**
|
|
418
444
|
* Get all models
|
package/dist/neurolink.js
CHANGED
|
@@ -16,6 +16,7 @@ catch {
|
|
|
16
16
|
import { AIProviderFactory } from "./core/factory.js";
|
|
17
17
|
import { mcpLogger } from "./utils/logger.js";
|
|
18
18
|
import { SYSTEM_LIMITS } from "./core/constants.js";
|
|
19
|
+
import { NANOSECOND_TO_MS_DIVISOR, MCP_TIMEOUTS, SERVER_CONFIG, TOOL_TIMEOUTS, RETRY_ATTEMPTS, RETRY_DELAYS, CIRCUIT_BREAKER, CIRCUIT_BREAKER_RESET_MS, MEMORY_THRESHOLDS, PROVIDER_TIMEOUTS, PERFORMANCE_THRESHOLDS, } from "./constants/index.js";
|
|
19
20
|
import pLimit from "p-limit";
|
|
20
21
|
import { toolRegistry } from "./mcp/toolRegistry.js";
|
|
21
22
|
import { logger } from "./utils/logger.js";
|
|
@@ -164,7 +165,7 @@ export class NeuroLink {
|
|
|
164
165
|
elapsedMs: Date.now() - constructorStartTime,
|
|
165
166
|
elapsedNs: (process.hrtime.bigint() - constructorHrTimeStart).toString(),
|
|
166
167
|
registrySetupDurationNs: registrySetupDurationNs.toString(),
|
|
167
|
-
registrySetupDurationMs: Number(registrySetupDurationNs) /
|
|
168
|
+
registrySetupDurationMs: Number(registrySetupDurationNs) / NANOSECOND_TO_MS_DIVISOR,
|
|
168
169
|
enableManualMCP: false,
|
|
169
170
|
message: "ProviderRegistry configured successfully with security settings",
|
|
170
171
|
});
|
|
@@ -179,7 +180,7 @@ export class NeuroLink {
|
|
|
179
180
|
elapsedMs: Date.now() - constructorStartTime,
|
|
180
181
|
elapsedNs: (process.hrtime.bigint() - constructorHrTimeStart).toString(),
|
|
181
182
|
registrySetupDurationNs: registrySetupDurationNs.toString(),
|
|
182
|
-
registrySetupDurationMs: Number(registrySetupDurationNs) /
|
|
183
|
+
registrySetupDurationMs: Number(registrySetupDurationNs) / NANOSECOND_TO_MS_DIVISOR,
|
|
183
184
|
error: error instanceof Error ? error.message : String(error),
|
|
184
185
|
errorName: error instanceof Error ? error.name : "UnknownError",
|
|
185
186
|
errorStack: error instanceof Error ? error.stack : undefined,
|
|
@@ -224,9 +225,9 @@ export class NeuroLink {
|
|
|
224
225
|
elapsedMs: Date.now() - constructorStartTime,
|
|
225
226
|
elapsedNs: (process.hrtime.bigint() - constructorHrTimeStart).toString(),
|
|
226
227
|
memoryInitDurationNs: memoryInitDurationNs.toString(),
|
|
227
|
-
memoryInitDurationMs: Number(memoryInitDurationNs) /
|
|
228
|
+
memoryInitDurationMs: Number(memoryInitDurationNs) / NANOSECOND_TO_MS_DIVISOR,
|
|
228
229
|
memoryManagerCreateDurationNs: memoryManagerCreateDurationNs.toString(),
|
|
229
|
-
memoryManagerCreateDurationMs: Number(memoryManagerCreateDurationNs) /
|
|
230
|
+
memoryManagerCreateDurationMs: Number(memoryManagerCreateDurationNs) / NANOSECOND_TO_MS_DIVISOR,
|
|
230
231
|
finalMemoryConfig: {
|
|
231
232
|
maxSessions: memoryConfig.maxSessions,
|
|
232
233
|
maxTurnsPerSession: memoryConfig.maxTurnsPerSession,
|
|
@@ -245,7 +246,7 @@ export class NeuroLink {
|
|
|
245
246
|
elapsedMs: Date.now() - constructorStartTime,
|
|
246
247
|
elapsedNs: (process.hrtime.bigint() - constructorHrTimeStart).toString(),
|
|
247
248
|
memoryInitDurationNs: memoryInitDurationNs.toString(),
|
|
248
|
-
memoryInitDurationMs: Number(memoryInitDurationNs) /
|
|
249
|
+
memoryInitDurationMs: Number(memoryInitDurationNs) / NANOSECOND_TO_MS_DIVISOR,
|
|
249
250
|
error: error instanceof Error ? error.message : String(error),
|
|
250
251
|
errorName: error instanceof Error ? error.name : "UnknownError",
|
|
251
252
|
errorStack: error instanceof Error ? error.stack : undefined,
|
|
@@ -289,8 +290,8 @@ export class NeuroLink {
|
|
|
289
290
|
elapsedNs: (process.hrtime.bigint() - constructorHrTimeStart).toString(),
|
|
290
291
|
externalServerInitStartTimeNs: externalServerInitStartTime.toString(),
|
|
291
292
|
serverManagerConfig: {
|
|
292
|
-
maxServers:
|
|
293
|
-
defaultTimeout:
|
|
293
|
+
maxServers: SERVER_CONFIG.MAX_MCP_SERVERS,
|
|
294
|
+
defaultTimeout: MCP_TIMEOUTS.EXTERNAL_SERVER_STARTUP_MS,
|
|
294
295
|
enableAutoRestart: true,
|
|
295
296
|
enablePerformanceMonitoring: true,
|
|
296
297
|
},
|
|
@@ -317,7 +318,7 @@ export class NeuroLink {
|
|
|
317
318
|
elapsedMs: Date.now() - constructorStartTime,
|
|
318
319
|
elapsedNs: (process.hrtime.bigint() - constructorHrTimeStart).toString(),
|
|
319
320
|
externalServerInitDurationNs: externalServerInitDurationNs.toString(),
|
|
320
|
-
externalServerInitDurationMs: Number(externalServerInitDurationNs) /
|
|
321
|
+
externalServerInitDurationMs: Number(externalServerInitDurationNs) / NANOSECOND_TO_MS_DIVISOR,
|
|
321
322
|
hasExternalServerManager: !!this.externalServerManager,
|
|
322
323
|
message: "External server manager initialized successfully",
|
|
323
324
|
});
|
|
@@ -333,7 +334,7 @@ export class NeuroLink {
|
|
|
333
334
|
elapsedMs: Date.now() - constructorStartTime,
|
|
334
335
|
elapsedNs: (process.hrtime.bigint() - constructorHrTimeStart).toString(),
|
|
335
336
|
externalServerInitDurationNs: externalServerInitDurationNs.toString(),
|
|
336
|
-
externalServerInitDurationMs: Number(externalServerInitDurationNs) /
|
|
337
|
+
externalServerInitDurationMs: Number(externalServerInitDurationNs) / NANOSECOND_TO_MS_DIVISOR,
|
|
337
338
|
error: error instanceof Error ? error.message : String(error),
|
|
338
339
|
errorName: error instanceof Error ? error.name : "UnknownError",
|
|
339
340
|
errorStack: error instanceof Error ? error.stack : undefined,
|
|
@@ -418,7 +419,7 @@ export class NeuroLink {
|
|
|
418
419
|
elapsedMs: Date.now() - constructorStartTime,
|
|
419
420
|
elapsedNs: (process.hrtime.bigint() - constructorHrTimeStart).toString(),
|
|
420
421
|
eventHandlerSetupDurationNs: eventHandlerSetupDurationNs.toString(),
|
|
421
|
-
eventHandlerSetupDurationMs: Number(eventHandlerSetupDurationNs) /
|
|
422
|
+
eventHandlerSetupDurationMs: Number(eventHandlerSetupDurationNs) / NANOSECOND_TO_MS_DIVISOR,
|
|
422
423
|
eventHandlersCount: 5,
|
|
423
424
|
eventHandlerTypes: [
|
|
424
425
|
"connected",
|
|
@@ -441,7 +442,7 @@ export class NeuroLink {
|
|
|
441
442
|
constructorId,
|
|
442
443
|
timestamp: new Date().toISOString(),
|
|
443
444
|
constructorDurationNs: constructorDurationNs.toString(),
|
|
444
|
-
constructorDurationMs: Number(constructorDurationNs) /
|
|
445
|
+
constructorDurationMs: Number(constructorDurationNs) / NANOSECOND_TO_MS_DIVISOR,
|
|
445
446
|
totalElapsedMs: Date.now() - constructorStartTime,
|
|
446
447
|
finalState: {
|
|
447
448
|
hasConversationMemory: !!this.conversationMemory,
|
|
@@ -542,7 +543,7 @@ export class NeuroLink {
|
|
|
542
543
|
elapsedMs: Date.now() - mcpInitStartTime,
|
|
543
544
|
elapsedNs: (process.hrtime.bigint() - mcpInitHrTimeStart).toString(),
|
|
544
545
|
performanceImportDurationNs: performanceImportDurationNs.toString(),
|
|
545
|
-
performanceImportDurationMs: Number(performanceImportDurationNs) /
|
|
546
|
+
performanceImportDurationMs: Number(performanceImportDurationNs) / NANOSECOND_TO_MS_DIVISOR,
|
|
546
547
|
hasMemoryManager: !!MemoryManager,
|
|
547
548
|
message: "MemoryManager imported successfully",
|
|
548
549
|
});
|
|
@@ -558,7 +559,7 @@ export class NeuroLink {
|
|
|
558
559
|
elapsedMs: Date.now() - mcpInitStartTime,
|
|
559
560
|
elapsedNs: (process.hrtime.bigint() - mcpInitHrTimeStart).toString(),
|
|
560
561
|
performanceImportDurationNs: performanceImportDurationNs.toString(),
|
|
561
|
-
performanceImportDurationMs: Number(performanceImportDurationNs) /
|
|
562
|
+
performanceImportDurationMs: Number(performanceImportDurationNs) / NANOSECOND_TO_MS_DIVISOR,
|
|
562
563
|
error: error instanceof Error ? error.message : String(error),
|
|
563
564
|
errorName: error instanceof Error ? error.name : "UnknownError",
|
|
564
565
|
message: "MemoryManager import failed - continuing without performance tracking",
|
|
@@ -590,7 +591,7 @@ export class NeuroLink {
|
|
|
590
591
|
*/
|
|
591
592
|
async initializeToolRegistryInternal(mcpInitId, mcpInitStartTime, mcpInitHrTimeStart) {
|
|
592
593
|
const toolRegistryStartTime = process.hrtime.bigint();
|
|
593
|
-
const initTimeout =
|
|
594
|
+
const initTimeout = MCP_TIMEOUTS.INITIALIZATION_MS;
|
|
594
595
|
logger.debug(`[NeuroLink] ⏱️ LOG_POINT_M007_TOOL_REGISTRY_TIMEOUT_SETUP`, {
|
|
595
596
|
logPoint: "M007_TOOL_REGISTRY_TIMEOUT_SETUP",
|
|
596
597
|
mcpInitId,
|
|
@@ -616,7 +617,7 @@ export class NeuroLink {
|
|
|
616
617
|
elapsedMs: Date.now() - mcpInitStartTime,
|
|
617
618
|
elapsedNs: (process.hrtime.bigint() - mcpInitHrTimeStart).toString(),
|
|
618
619
|
toolRegistryDurationNs: toolRegistryDurationNs.toString(),
|
|
619
|
-
toolRegistryDurationMs: Number(toolRegistryDurationNs) /
|
|
620
|
+
toolRegistryDurationMs: Number(toolRegistryDurationNs) / NANOSECOND_TO_MS_DIVISOR,
|
|
620
621
|
message: "Tool registry initialization completed within timeout",
|
|
621
622
|
});
|
|
622
623
|
}
|
|
@@ -644,7 +645,7 @@ export class NeuroLink {
|
|
|
644
645
|
elapsedMs: Date.now() - mcpInitStartTime,
|
|
645
646
|
elapsedNs: (process.hrtime.bigint() - mcpInitHrTimeStart).toString(),
|
|
646
647
|
providerRegistryDurationNs: providerRegistryDurationNs.toString(),
|
|
647
|
-
providerRegistryDurationMs: Number(providerRegistryDurationNs) /
|
|
648
|
+
providerRegistryDurationMs: Number(providerRegistryDurationNs) / NANOSECOND_TO_MS_DIVISOR,
|
|
648
649
|
message: "Provider registry registration completed successfully",
|
|
649
650
|
});
|
|
650
651
|
}
|
|
@@ -674,7 +675,7 @@ export class NeuroLink {
|
|
|
674
675
|
elapsedMs: Date.now() - mcpInitStartTime,
|
|
675
676
|
elapsedNs: (process.hrtime.bigint() - mcpInitHrTimeStart).toString(),
|
|
676
677
|
directToolsDurationNs: directToolsDurationNs.toString(),
|
|
677
|
-
directToolsDurationMs: Number(directToolsDurationNs) /
|
|
678
|
+
directToolsDurationMs: Number(directToolsDurationNs) / NANOSECOND_TO_MS_DIVISOR,
|
|
678
679
|
serverId: "neurolink-direct",
|
|
679
680
|
message: "Direct tools server registered successfully",
|
|
680
681
|
});
|
|
@@ -692,7 +693,7 @@ export class NeuroLink {
|
|
|
692
693
|
elapsedMs: Date.now() - mcpInitStartTime,
|
|
693
694
|
elapsedNs: (process.hrtime.bigint() - mcpInitHrTimeStart).toString(),
|
|
694
695
|
directToolsDurationNs: directToolsDurationNs.toString(),
|
|
695
|
-
directToolsDurationMs: Number(directToolsDurationNs) /
|
|
696
|
+
directToolsDurationMs: Number(directToolsDurationNs) / NANOSECOND_TO_MS_DIVISOR,
|
|
696
697
|
error: error instanceof Error ? error.message : String(error),
|
|
697
698
|
errorName: error instanceof Error ? error.name : "UnknownError",
|
|
698
699
|
errorStack: error instanceof Error ? error.stack : undefined,
|
|
@@ -731,7 +732,7 @@ export class NeuroLink {
|
|
|
731
732
|
elapsedMs: Date.now() - mcpInitStartTime,
|
|
732
733
|
elapsedNs: (process.hrtime.bigint() - mcpInitHrTimeStart).toString(),
|
|
733
734
|
mcpConfigDurationNs: mcpConfigDurationNs.toString(),
|
|
734
|
-
mcpConfigDurationMs: Number(mcpConfigDurationNs) /
|
|
735
|
+
mcpConfigDurationMs: Number(mcpConfigDurationNs) / NANOSECOND_TO_MS_DIVISOR,
|
|
735
736
|
serversLoaded: configResult.serversLoaded,
|
|
736
737
|
errorsCount: configResult.errors.length,
|
|
737
738
|
configResult: {
|
|
@@ -774,7 +775,7 @@ export class NeuroLink {
|
|
|
774
775
|
initTime: `${initTime}ms`,
|
|
775
776
|
memoryUsed: `${memoryDelta}MB`,
|
|
776
777
|
});
|
|
777
|
-
if (memoryDelta >
|
|
778
|
+
if (memoryDelta > MEMORY_THRESHOLDS.MODERATE_USAGE_MB) {
|
|
778
779
|
mcpLogger.debug("💡 Memory cleanup suggestion: MCP initialization used significant memory. Consider calling MemoryManager.forceGC() after heavy operations.");
|
|
779
780
|
}
|
|
780
781
|
}
|
|
@@ -1120,7 +1121,7 @@ export class NeuroLink {
|
|
|
1120
1121
|
elapsedMs: Date.now() - generateInternalStartTime,
|
|
1121
1122
|
elapsedNs: (process.hrtime.bigint() - generateInternalHrTimeStart).toString(),
|
|
1122
1123
|
conversationMemoryDurationNs: conversationMemoryDurationNs.toString(),
|
|
1123
|
-
conversationMemoryDurationMs: Number(conversationMemoryDurationNs) /
|
|
1124
|
+
conversationMemoryDurationMs: Number(conversationMemoryDurationNs) / NANOSECOND_TO_MS_DIVISOR,
|
|
1124
1125
|
message: "Conversation memory initialization completed successfully",
|
|
1125
1126
|
});
|
|
1126
1127
|
}
|
|
@@ -1165,7 +1166,7 @@ export class NeuroLink {
|
|
|
1165
1166
|
* Perform MCP generation with retry logic
|
|
1166
1167
|
*/
|
|
1167
1168
|
async performMCPGenerationRetries(options, generateInternalId, generateInternalStartTime, generateInternalHrTimeStart, functionTag) {
|
|
1168
|
-
const maxMcpRetries =
|
|
1169
|
+
const maxMcpRetries = RETRY_ATTEMPTS.QUICK;
|
|
1169
1170
|
const mcpRetryLoopStartTime = process.hrtime.bigint();
|
|
1170
1171
|
logger.debug(`[NeuroLink] 🔄 LOG_POINT_G006_MCP_RETRY_LOOP_START`, {
|
|
1171
1172
|
logPoint: "G006_MCP_RETRY_LOOP_START",
|
|
@@ -1207,7 +1208,7 @@ export class NeuroLink {
|
|
|
1207
1208
|
elapsedMs: Date.now() - generateInternalStartTime,
|
|
1208
1209
|
elapsedNs: (process.hrtime.bigint() - generateInternalHrTimeStart).toString(),
|
|
1209
1210
|
mcpAttemptDurationNs: mcpAttemptDurationNs.toString(),
|
|
1210
|
-
mcpAttemptDurationMs: Number(mcpAttemptDurationNs) /
|
|
1211
|
+
mcpAttemptDurationMs: Number(mcpAttemptDurationNs) / NANOSECOND_TO_MS_DIVISOR,
|
|
1211
1212
|
currentAttempt: attempt,
|
|
1212
1213
|
resultAnalysis: {
|
|
1213
1214
|
hasResult: !!mcpResult,
|
|
@@ -1326,7 +1327,7 @@ export class NeuroLink {
|
|
|
1326
1327
|
elapsedMs: Date.now() - tryMCPStartTime,
|
|
1327
1328
|
elapsedNs: (process.hrtime.bigint() - tryMCPHrTimeStart).toString(),
|
|
1328
1329
|
mcpInitCheckDurationNs: mcpInitCheckDurationNs.toString(),
|
|
1329
|
-
mcpInitCheckDurationMs: Number(mcpInitCheckDurationNs) /
|
|
1330
|
+
mcpInitCheckDurationMs: Number(mcpInitCheckDurationNs) / NANOSECOND_TO_MS_DIVISOR,
|
|
1330
1331
|
mcpInitializedAfter: this.mcpInitialized,
|
|
1331
1332
|
initializationSuccessful: this.mcpInitialized,
|
|
1332
1333
|
message: "MCP initialization check completed",
|
|
@@ -1782,7 +1783,7 @@ export class NeuroLink {
|
|
|
1782
1783
|
elapsedMs: Date.now() - startTime,
|
|
1783
1784
|
elapsedNs: (process.hrtime.bigint() - hrTimeStart).toString(),
|
|
1784
1785
|
validationDurationNs: validationDurationNs.toString(),
|
|
1785
|
-
validationDurationMs: Number(validationDurationNs) /
|
|
1786
|
+
validationDurationMs: Number(validationDurationNs) / NANOSECOND_TO_MS_DIVISOR,
|
|
1786
1787
|
validationError: "Stream options must include either input.text or input.audio",
|
|
1787
1788
|
message: "EXHAUSTIVE validation failure analysis with character-level debugging",
|
|
1788
1789
|
});
|
|
@@ -1797,7 +1798,7 @@ export class NeuroLink {
|
|
|
1797
1798
|
elapsedMs: Date.now() - startTime,
|
|
1798
1799
|
elapsedNs: (process.hrtime.bigint() - hrTimeStart).toString(),
|
|
1799
1800
|
validationDurationNs: validationDurationNs.toString(),
|
|
1800
|
-
validationDurationMs: Number(validationDurationNs) /
|
|
1801
|
+
validationDurationMs: Number(validationDurationNs) / NANOSECOND_TO_MS_DIVISOR,
|
|
1801
1802
|
inputTextValid: hasText,
|
|
1802
1803
|
inputAudioPresent: hasAudio,
|
|
1803
1804
|
inputTextLength: hasText ? options.input.text.length : 0,
|
|
@@ -2315,16 +2316,16 @@ export class NeuroLink {
|
|
|
2315
2316
|
this.emitter.emit("tool:start", toolName, params);
|
|
2316
2317
|
// Set default options
|
|
2317
2318
|
const finalOptions = {
|
|
2318
|
-
timeout: options?.timeout ||
|
|
2319
|
-
maxRetries: options?.maxRetries ||
|
|
2320
|
-
retryDelayMs: options?.retryDelayMs ||
|
|
2319
|
+
timeout: options?.timeout || TOOL_TIMEOUTS.EXECUTION_DEFAULT_MS, // 30 second default timeout
|
|
2320
|
+
maxRetries: options?.maxRetries || RETRY_ATTEMPTS.DEFAULT, // Default 2 retries for retriable errors
|
|
2321
|
+
retryDelayMs: options?.retryDelayMs || RETRY_DELAYS.BASE_MS, // 1 second delay between retries
|
|
2321
2322
|
};
|
|
2322
2323
|
// Track memory usage for tool execution
|
|
2323
2324
|
const { MemoryManager } = await import("./utils/performance.js");
|
|
2324
2325
|
const startMemory = MemoryManager.getMemoryUsageMB();
|
|
2325
2326
|
// Get or create circuit breaker for this tool
|
|
2326
2327
|
if (!this.toolCircuitBreakers.has(toolName)) {
|
|
2327
|
-
this.toolCircuitBreakers.set(toolName, new CircuitBreaker(
|
|
2328
|
+
this.toolCircuitBreakers.set(toolName, new CircuitBreaker(CIRCUIT_BREAKER.FAILURE_THRESHOLD, CIRCUIT_BREAKER_RESET_MS));
|
|
2328
2329
|
}
|
|
2329
2330
|
const circuitBreaker = this.toolCircuitBreakers.get(toolName);
|
|
2330
2331
|
// Initialize metrics for this tool if not exists
|
|
@@ -2647,10 +2648,10 @@ export class NeuroLink {
|
|
|
2647
2648
|
// Check memory usage after tool enumeration
|
|
2648
2649
|
const endMemory = MemoryManager.getMemoryUsageMB();
|
|
2649
2650
|
const memoryDelta = endMemory.heapUsed - startMemory.heapUsed;
|
|
2650
|
-
if (memoryDelta >
|
|
2651
|
+
if (memoryDelta > MEMORY_THRESHOLDS.LOW_USAGE_MB) {
|
|
2651
2652
|
mcpLogger.debug(`🔍 Tool listing used ${memoryDelta}MB memory (large tool registry detected)`);
|
|
2652
2653
|
// Optimized collection patterns should reduce memory usage significantly
|
|
2653
|
-
if (uniqueTools.length >
|
|
2654
|
+
if (uniqueTools.length > PERFORMANCE_THRESHOLDS.LARGE_TOOL_COLLECTION) {
|
|
2654
2655
|
mcpLogger.debug("💡 Tool collection optimized for large sets. Memory usage reduced through efficient object reuse.");
|
|
2655
2656
|
}
|
|
2656
2657
|
}
|
|
@@ -2722,7 +2723,7 @@ export class NeuroLink {
|
|
|
2722
2723
|
try {
|
|
2723
2724
|
const response = await fetch("http://localhost:11434/api/tags", {
|
|
2724
2725
|
method: "GET",
|
|
2725
|
-
signal: AbortSignal.timeout(
|
|
2726
|
+
signal: AbortSignal.timeout(PROVIDER_TIMEOUTS.AUTH_MS),
|
|
2726
2727
|
});
|
|
2727
2728
|
if (!response.ok) {
|
|
2728
2729
|
throw new Error("Ollama service not responding");
|
|
@@ -3099,7 +3100,7 @@ export class NeuroLink {
|
|
|
3099
3100
|
resetToolCircuitBreaker(toolName) {
|
|
3100
3101
|
if (this.toolCircuitBreakers.has(toolName)) {
|
|
3101
3102
|
// Create a new circuit breaker (effectively resets it)
|
|
3102
|
-
this.toolCircuitBreakers.set(toolName, new CircuitBreaker(
|
|
3103
|
+
this.toolCircuitBreakers.set(toolName, new CircuitBreaker(CIRCUIT_BREAKER.FAILURE_THRESHOLD, CIRCUIT_BREAKER_RESET_MS));
|
|
3103
3104
|
mcpLogger.info(`Circuit breaker reset for tool: ${toolName}`);
|
|
3104
3105
|
}
|
|
3105
3106
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { type LanguageModelV1 } from "ai";
|
|
2
2
|
import { BaseProvider } from "../core/baseProvider.js";
|
|
3
|
-
import type { AIProviderName } from "../types
|
|
3
|
+
import type { AIProviderName } from "../core/types.js";
|
|
4
4
|
import type { StreamOptions, StreamResult } from "../types/streamTypes.js";
|
|
5
5
|
export declare class AzureOpenAIProvider extends BaseProvider {
|
|
6
6
|
private apiKey;
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { createAzure } from "@ai-sdk/azure";
|
|
2
2
|
import { streamText } from "ai";
|
|
3
3
|
import { BaseProvider } from "../core/baseProvider.js";
|
|
4
|
+
import { APIVersions } from "../core/types.js";
|
|
4
5
|
import { validateApiKey, createAzureAPIKeyConfig, createAzureEndpointConfig, } from "../utils/providerConfig.js";
|
|
5
6
|
import { logger } from "../utils/logger.js";
|
|
6
7
|
import { buildMessagesArray } from "../utils/messageBuilder.js";
|
|
@@ -24,7 +25,7 @@ export class AzureOpenAIProvider extends BaseProvider {
|
|
|
24
25
|
process.env.AZURE_OPENAI_DEPLOYMENT ||
|
|
25
26
|
process.env.AZURE_OPENAI_DEPLOYMENT_ID ||
|
|
26
27
|
"gpt-4o";
|
|
27
|
-
this.apiVersion = process.env.AZURE_API_VERSION ||
|
|
28
|
+
this.apiVersion = process.env.AZURE_API_VERSION || APIVersions.AZURE_LATEST;
|
|
28
29
|
// Configuration validation - now using consolidated utility
|
|
29
30
|
if (!this.apiKey) {
|
|
30
31
|
validateApiKey(createAzureAPIKeyConfig());
|
|
@@ -15,6 +15,31 @@ export interface ProviderConfigOptions {
|
|
|
15
15
|
instructions: string[];
|
|
16
16
|
fallbackEnvVars?: string[];
|
|
17
17
|
}
|
|
18
|
+
/**
|
|
19
|
+
* API key format validation patterns (extracted from advanced validation system)
|
|
20
|
+
* Exported for use across the codebase to replace scattered regex patterns
|
|
21
|
+
*/
|
|
22
|
+
export declare const API_KEY_FORMATS: Record<string, RegExp>;
|
|
23
|
+
/**
|
|
24
|
+
* API key length constants to replace scattered magic numbers
|
|
25
|
+
*/
|
|
26
|
+
export declare const API_KEY_LENGTHS: {
|
|
27
|
+
readonly OPENAI_MIN: 48;
|
|
28
|
+
readonly ANTHROPIC_MIN: 95;
|
|
29
|
+
readonly HUGGINGFACE_EXACT: 37;
|
|
30
|
+
readonly AZURE_MIN: 32;
|
|
31
|
+
readonly MISTRAL_EXACT: 32;
|
|
32
|
+
readonly AWS_ACCESS_KEY: 20;
|
|
33
|
+
readonly GOOGLE_AI_EXACT: 39;
|
|
34
|
+
};
|
|
35
|
+
/**
|
|
36
|
+
* Project ID format validation (for Google Cloud)
|
|
37
|
+
*/
|
|
38
|
+
export declare const PROJECT_ID_FORMAT: {
|
|
39
|
+
readonly MIN_LENGTH: 6;
|
|
40
|
+
readonly MAX_LENGTH: 30;
|
|
41
|
+
readonly PATTERN: RegExp;
|
|
42
|
+
};
|
|
18
43
|
/**
|
|
19
44
|
* Enhanced validation result with format checking
|
|
20
45
|
*/
|