@juspay/neurolink 7.8.0 ā 7.9.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 +16 -5
- package/README.md +1 -0
- package/dist/cli/factories/commandFactory.js +6 -2
- package/dist/core/types.d.ts +15 -4
- package/dist/core/types.js +23 -3
- package/dist/factories/providerFactory.js +10 -1
- package/dist/factories/providerRegistry.js +1 -1
- package/dist/lib/core/types.d.ts +15 -4
- package/dist/lib/core/types.js +23 -3
- package/dist/lib/factories/providerFactory.js +10 -1
- package/dist/lib/factories/providerRegistry.js +1 -1
- package/dist/lib/neurolink.d.ts +15 -0
- package/dist/lib/neurolink.js +73 -1
- package/dist/lib/providers/googleVertex.d.ts +4 -0
- package/dist/lib/providers/googleVertex.js +44 -3
- package/dist/lib/providers/sagemaker/client.js +2 -2
- package/dist/lib/sdk/toolRegistration.d.ts +1 -1
- package/dist/lib/sdk/toolRegistration.js +13 -5
- package/dist/lib/utils/providerHealth.js +19 -4
- package/dist/neurolink.d.ts +15 -0
- package/dist/neurolink.js +73 -1
- package/dist/providers/googleVertex.d.ts +4 -0
- package/dist/providers/googleVertex.js +44 -3
- package/dist/providers/sagemaker/client.js +2 -2
- package/dist/sdk/toolRegistration.d.ts +1 -1
- package/dist/sdk/toolRegistration.js +13 -5
- package/dist/utils/providerHealth.js +19 -4
- package/package.json +5 -2
package/CHANGELOG.md
CHANGED
|
@@ -1,21 +1,32 @@
|
|
|
1
|
-
|
|
1
|
+
## [7.9.0](https://github.com/juspay/neurolink/compare/v7.8.0...v7.9.0) (2025-08-11)
|
|
2
|
+
|
|
3
|
+
### Features
|
|
2
4
|
|
|
5
|
+
* **(core):** add EventEmitter functionality for real-time event monitoring ([fd8b6b0](https://github.com/juspay/neurolink/commit/fd8b6b075ca46df4f35a58d26ad6cd4839fe2361))
|
|
3
6
|
|
|
4
7
|
### Bug Fixes
|
|
5
8
|
|
|
6
|
-
*
|
|
9
|
+
* **(ci):** add semantic-release configuration with dependencies and testing ([d48e274](https://github.com/juspay/neurolink/commit/d48e274bed6473df28403ae440d7109656216307))
|
|
10
|
+
* **(ci):** configure semantic-release to handle ticket prefixes with proper JSON escaping ([6d575dc](https://github.com/juspay/neurolink/commit/6d575dcf90611ad6a9854daff551dade3f06e001))
|
|
11
|
+
* **(ci):** correct JSON escaping in semantic-release configuration ([b9bbe50](https://github.com/juspay/neurolink/commit/b9bbe50461771f82e19cdbbb413ca6af6f28c31d))
|
|
12
|
+
* **(cli):** missing model name in analytics output ([416c5b7](https://github.com/juspay/neurolink/commit/416c5b74745776d1b3742557add4f501669f06f9))
|
|
13
|
+
* **(providers):** respect VERTEX_MODEL environment variable in model selection ([40eddb1](https://github.com/juspay/neurolink/commit/40eddb1d52a61891dec7fab5998b840f233352ee))
|
|
14
|
+
|
|
15
|
+
# [7.8.0](https://github.com/juspay/neurolink/compare/v7.7.1...v7.8.0) (2025-08-11)
|
|
16
|
+
|
|
17
|
+
### Bug Fixes
|
|
7
18
|
|
|
19
|
+
- exclude \_site directory from ESLint ([c0e5f1d](https://github.com/juspay/neurolink/commit/c0e5f1dce46e91ee76cd1a4954190569b4a8d1d9))
|
|
8
20
|
|
|
9
21
|
### Features
|
|
10
22
|
|
|
11
|
-
|
|
23
|
+
- **providers:** add comprehensive Amazon SageMaker provider integration ([9ef4ebe](https://github.com/juspay/neurolink/commit/9ef4ebeeda520a71a7461ca5f4f34a83c2062356))
|
|
12
24
|
|
|
13
25
|
## [7.7.1](https://github.com/juspay/neurolink/compare/v7.7.0...v7.7.1) (2025-08-11)
|
|
14
26
|
|
|
15
|
-
|
|
16
27
|
### Bug Fixes
|
|
17
28
|
|
|
18
|
-
|
|
29
|
+
- **providers:** resolve ESLint errors and improve validation in Vertex AI health checker ([a5822ee](https://github.com/juspay/neurolink/commit/a5822eee3f8b6beaf3d2168ebb8888a6beaa5cb4))
|
|
19
30
|
|
|
20
31
|
# [7.7.0](https://github.com/juspay/neurolink/compare/v7.6.1...v7.7.0) (2025-08-10)
|
|
21
32
|
|
package/README.md
CHANGED
|
@@ -68,6 +68,7 @@ npx @juspay/neurolink sagemaker benchmark my-endpoint # Performance testing
|
|
|
68
68
|
- **ā” Performance** - Fast response times with streaming support and 68% improved status checks
|
|
69
69
|
- **š”ļø Error Recovery** - Graceful failures with provider fallback and retry logic
|
|
70
70
|
- **š Analytics & Evaluation** - Built-in usage tracking and AI-powered quality assessment
|
|
71
|
+
- **šÆ Real-time Event Monitoring** - EventEmitter integration for progress tracking and debugging
|
|
71
72
|
- **š§ MCP Integration** - Model Context Protocol with 6 built-in tools and 58+ discoverable servers
|
|
72
73
|
- **š Lighthouse Integration** - Unified tool registration API supporting both object and array formats for seamless Lighthouse tool import
|
|
73
74
|
|
|
@@ -288,8 +288,12 @@ export class CLICommandFactory {
|
|
|
288
288
|
let analyticsText = "\n\nš Analytics:\n";
|
|
289
289
|
// Provider and model info
|
|
290
290
|
analyticsText += ` Provider: ${analytics.provider}`;
|
|
291
|
-
|
|
292
|
-
|
|
291
|
+
// Check for model in multiple locations: result.model, analytics.model, or any model property
|
|
292
|
+
const modelName = result.model ||
|
|
293
|
+
analytics.model ||
|
|
294
|
+
analytics.modelName;
|
|
295
|
+
if (modelName) {
|
|
296
|
+
analyticsText += ` (${modelName})`;
|
|
293
297
|
}
|
|
294
298
|
analyticsText += "\n";
|
|
295
299
|
// Token usage
|
package/dist/core/types.d.ts
CHANGED
|
@@ -78,19 +78,30 @@ export declare enum OpenAIModels {
|
|
|
78
78
|
*/
|
|
79
79
|
export declare enum VertexModels {
|
|
80
80
|
CLAUDE_4_0_SONNET = "claude-sonnet-4@20250514",
|
|
81
|
-
|
|
81
|
+
CLAUDE_4_0_OPUS = "claude-opus-4@20250514",
|
|
82
|
+
CLAUDE_3_5_SONNET = "claude-3-5-sonnet-20241022",
|
|
83
|
+
CLAUDE_3_5_HAIKU = "claude-3-5-haiku-20241022",
|
|
84
|
+
CLAUDE_3_SONNET = "claude-3-sonnet-20240229",
|
|
85
|
+
CLAUDE_3_OPUS = "claude-3-opus-20240229",
|
|
86
|
+
CLAUDE_3_HAIKU = "claude-3-haiku-20240307",
|
|
82
87
|
GEMINI_2_5_PRO = "gemini-2.5-pro",
|
|
83
88
|
GEMINI_2_5_FLASH = "gemini-2.5-flash",
|
|
84
|
-
GEMINI_2_5_FLASH_LITE = "gemini-2.5-flash-lite"
|
|
89
|
+
GEMINI_2_5_FLASH_LITE = "gemini-2.5-flash-lite",
|
|
90
|
+
GEMINI_2_0_FLASH_001 = "gemini-2.0-flash-001",
|
|
91
|
+
GEMINI_1_5_PRO = "gemini-1.5-pro",
|
|
92
|
+
GEMINI_1_5_FLASH = "gemini-1.5-flash"
|
|
85
93
|
}
|
|
86
94
|
/**
|
|
87
95
|
* Supported Models for Google AI Studio
|
|
88
96
|
*/
|
|
89
97
|
export declare enum GoogleAIModels {
|
|
90
|
-
GEMINI_2_0_FLASH_001 = "gemini-2.0-flash-001",
|
|
91
98
|
GEMINI_2_5_PRO = "gemini-2.5-pro",
|
|
92
99
|
GEMINI_2_5_FLASH = "gemini-2.5-flash",
|
|
93
|
-
|
|
100
|
+
GEMINI_2_5_FLASH_LITE = "gemini-2.5-flash-lite",
|
|
101
|
+
GEMINI_2_0_FLASH_001 = "gemini-2.0-flash-001",
|
|
102
|
+
GEMINI_1_5_PRO = "gemini-1.5-pro",
|
|
103
|
+
GEMINI_1_5_FLASH = "gemini-1.5-flash",
|
|
104
|
+
GEMINI_1_5_FLASH_LITE = "gemini-1.5-flash-lite"
|
|
94
105
|
}
|
|
95
106
|
/**
|
|
96
107
|
* Union type of all supported model names
|
package/dist/core/types.js
CHANGED
|
@@ -43,21 +43,41 @@ export var OpenAIModels;
|
|
|
43
43
|
*/
|
|
44
44
|
export var VertexModels;
|
|
45
45
|
(function (VertexModels) {
|
|
46
|
+
// Claude 4 Series (Latest - May 2025)
|
|
46
47
|
VertexModels["CLAUDE_4_0_SONNET"] = "claude-sonnet-4@20250514";
|
|
47
|
-
VertexModels["
|
|
48
|
+
VertexModels["CLAUDE_4_0_OPUS"] = "claude-opus-4@20250514";
|
|
49
|
+
// Claude 3.5 Series (Still supported)
|
|
50
|
+
VertexModels["CLAUDE_3_5_SONNET"] = "claude-3-5-sonnet-20241022";
|
|
51
|
+
VertexModels["CLAUDE_3_5_HAIKU"] = "claude-3-5-haiku-20241022";
|
|
52
|
+
// Claude 3 Series (Legacy support)
|
|
53
|
+
VertexModels["CLAUDE_3_SONNET"] = "claude-3-sonnet-20240229";
|
|
54
|
+
VertexModels["CLAUDE_3_OPUS"] = "claude-3-opus-20240229";
|
|
55
|
+
VertexModels["CLAUDE_3_HAIKU"] = "claude-3-haiku-20240307";
|
|
56
|
+
// Gemini 2.5 Series (Latest - 2025)
|
|
48
57
|
VertexModels["GEMINI_2_5_PRO"] = "gemini-2.5-pro";
|
|
49
58
|
VertexModels["GEMINI_2_5_FLASH"] = "gemini-2.5-flash";
|
|
50
59
|
VertexModels["GEMINI_2_5_FLASH_LITE"] = "gemini-2.5-flash-lite";
|
|
60
|
+
// Gemini 2.0 Series
|
|
61
|
+
VertexModels["GEMINI_2_0_FLASH_001"] = "gemini-2.0-flash-001";
|
|
62
|
+
// Gemini 1.5 Series (Legacy support)
|
|
63
|
+
VertexModels["GEMINI_1_5_PRO"] = "gemini-1.5-pro";
|
|
64
|
+
VertexModels["GEMINI_1_5_FLASH"] = "gemini-1.5-flash";
|
|
51
65
|
})(VertexModels || (VertexModels = {}));
|
|
52
66
|
/**
|
|
53
67
|
* Supported Models for Google AI Studio
|
|
54
68
|
*/
|
|
55
69
|
export var GoogleAIModels;
|
|
56
70
|
(function (GoogleAIModels) {
|
|
57
|
-
|
|
71
|
+
// Gemini 2.5 Series (Latest - 2025)
|
|
58
72
|
GoogleAIModels["GEMINI_2_5_PRO"] = "gemini-2.5-pro";
|
|
59
73
|
GoogleAIModels["GEMINI_2_5_FLASH"] = "gemini-2.5-flash";
|
|
60
|
-
GoogleAIModels["
|
|
74
|
+
GoogleAIModels["GEMINI_2_5_FLASH_LITE"] = "gemini-2.5-flash-lite";
|
|
75
|
+
// Gemini 2.0 Series
|
|
76
|
+
GoogleAIModels["GEMINI_2_0_FLASH_001"] = "gemini-2.0-flash-001";
|
|
77
|
+
// Gemini 1.5 Series (Legacy support)
|
|
78
|
+
GoogleAIModels["GEMINI_1_5_PRO"] = "gemini-1.5-pro";
|
|
79
|
+
GoogleAIModels["GEMINI_1_5_FLASH"] = "gemini-1.5-flash";
|
|
80
|
+
GoogleAIModels["GEMINI_1_5_FLASH_LITE"] = "gemini-1.5-flash-lite";
|
|
61
81
|
})(GoogleAIModels || (GoogleAIModels = {}));
|
|
62
82
|
/**
|
|
63
83
|
* Default provider configurations
|
|
@@ -35,7 +35,16 @@ export class ProviderFactory {
|
|
|
35
35
|
if (!registration) {
|
|
36
36
|
throw new Error(`Unknown provider: ${providerName}. Available providers: ${this.getAvailableProviders().join(", ")}`);
|
|
37
37
|
}
|
|
38
|
-
|
|
38
|
+
// Respect environment variables before falling back to registry default
|
|
39
|
+
let model = modelName;
|
|
40
|
+
if (!model) {
|
|
41
|
+
// Check for provider-specific environment variables
|
|
42
|
+
if (providerName.toLowerCase().includes("vertex")) {
|
|
43
|
+
model = process.env.VERTEX_MODEL;
|
|
44
|
+
}
|
|
45
|
+
// Fallback to registry default if no env var
|
|
46
|
+
model = model || registration.defaultModel;
|
|
47
|
+
}
|
|
39
48
|
try {
|
|
40
49
|
// Try calling as factory function first, then fallback to constructor
|
|
41
50
|
let result;
|
|
@@ -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
|
-
}, "
|
|
58
|
+
}, "claude-sonnet-4@20250514", ["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/lib/core/types.d.ts
CHANGED
|
@@ -78,19 +78,30 @@ export declare enum OpenAIModels {
|
|
|
78
78
|
*/
|
|
79
79
|
export declare enum VertexModels {
|
|
80
80
|
CLAUDE_4_0_SONNET = "claude-sonnet-4@20250514",
|
|
81
|
-
|
|
81
|
+
CLAUDE_4_0_OPUS = "claude-opus-4@20250514",
|
|
82
|
+
CLAUDE_3_5_SONNET = "claude-3-5-sonnet-20241022",
|
|
83
|
+
CLAUDE_3_5_HAIKU = "claude-3-5-haiku-20241022",
|
|
84
|
+
CLAUDE_3_SONNET = "claude-3-sonnet-20240229",
|
|
85
|
+
CLAUDE_3_OPUS = "claude-3-opus-20240229",
|
|
86
|
+
CLAUDE_3_HAIKU = "claude-3-haiku-20240307",
|
|
82
87
|
GEMINI_2_5_PRO = "gemini-2.5-pro",
|
|
83
88
|
GEMINI_2_5_FLASH = "gemini-2.5-flash",
|
|
84
|
-
GEMINI_2_5_FLASH_LITE = "gemini-2.5-flash-lite"
|
|
89
|
+
GEMINI_2_5_FLASH_LITE = "gemini-2.5-flash-lite",
|
|
90
|
+
GEMINI_2_0_FLASH_001 = "gemini-2.0-flash-001",
|
|
91
|
+
GEMINI_1_5_PRO = "gemini-1.5-pro",
|
|
92
|
+
GEMINI_1_5_FLASH = "gemini-1.5-flash"
|
|
85
93
|
}
|
|
86
94
|
/**
|
|
87
95
|
* Supported Models for Google AI Studio
|
|
88
96
|
*/
|
|
89
97
|
export declare enum GoogleAIModels {
|
|
90
|
-
GEMINI_2_0_FLASH_001 = "gemini-2.0-flash-001",
|
|
91
98
|
GEMINI_2_5_PRO = "gemini-2.5-pro",
|
|
92
99
|
GEMINI_2_5_FLASH = "gemini-2.5-flash",
|
|
93
|
-
|
|
100
|
+
GEMINI_2_5_FLASH_LITE = "gemini-2.5-flash-lite",
|
|
101
|
+
GEMINI_2_0_FLASH_001 = "gemini-2.0-flash-001",
|
|
102
|
+
GEMINI_1_5_PRO = "gemini-1.5-pro",
|
|
103
|
+
GEMINI_1_5_FLASH = "gemini-1.5-flash",
|
|
104
|
+
GEMINI_1_5_FLASH_LITE = "gemini-1.5-flash-lite"
|
|
94
105
|
}
|
|
95
106
|
/**
|
|
96
107
|
* Union type of all supported model names
|
package/dist/lib/core/types.js
CHANGED
|
@@ -43,21 +43,41 @@ export var OpenAIModels;
|
|
|
43
43
|
*/
|
|
44
44
|
export var VertexModels;
|
|
45
45
|
(function (VertexModels) {
|
|
46
|
+
// Claude 4 Series (Latest - May 2025)
|
|
46
47
|
VertexModels["CLAUDE_4_0_SONNET"] = "claude-sonnet-4@20250514";
|
|
47
|
-
VertexModels["
|
|
48
|
+
VertexModels["CLAUDE_4_0_OPUS"] = "claude-opus-4@20250514";
|
|
49
|
+
// Claude 3.5 Series (Still supported)
|
|
50
|
+
VertexModels["CLAUDE_3_5_SONNET"] = "claude-3-5-sonnet-20241022";
|
|
51
|
+
VertexModels["CLAUDE_3_5_HAIKU"] = "claude-3-5-haiku-20241022";
|
|
52
|
+
// Claude 3 Series (Legacy support)
|
|
53
|
+
VertexModels["CLAUDE_3_SONNET"] = "claude-3-sonnet-20240229";
|
|
54
|
+
VertexModels["CLAUDE_3_OPUS"] = "claude-3-opus-20240229";
|
|
55
|
+
VertexModels["CLAUDE_3_HAIKU"] = "claude-3-haiku-20240307";
|
|
56
|
+
// Gemini 2.5 Series (Latest - 2025)
|
|
48
57
|
VertexModels["GEMINI_2_5_PRO"] = "gemini-2.5-pro";
|
|
49
58
|
VertexModels["GEMINI_2_5_FLASH"] = "gemini-2.5-flash";
|
|
50
59
|
VertexModels["GEMINI_2_5_FLASH_LITE"] = "gemini-2.5-flash-lite";
|
|
60
|
+
// Gemini 2.0 Series
|
|
61
|
+
VertexModels["GEMINI_2_0_FLASH_001"] = "gemini-2.0-flash-001";
|
|
62
|
+
// Gemini 1.5 Series (Legacy support)
|
|
63
|
+
VertexModels["GEMINI_1_5_PRO"] = "gemini-1.5-pro";
|
|
64
|
+
VertexModels["GEMINI_1_5_FLASH"] = "gemini-1.5-flash";
|
|
51
65
|
})(VertexModels || (VertexModels = {}));
|
|
52
66
|
/**
|
|
53
67
|
* Supported Models for Google AI Studio
|
|
54
68
|
*/
|
|
55
69
|
export var GoogleAIModels;
|
|
56
70
|
(function (GoogleAIModels) {
|
|
57
|
-
|
|
71
|
+
// Gemini 2.5 Series (Latest - 2025)
|
|
58
72
|
GoogleAIModels["GEMINI_2_5_PRO"] = "gemini-2.5-pro";
|
|
59
73
|
GoogleAIModels["GEMINI_2_5_FLASH"] = "gemini-2.5-flash";
|
|
60
|
-
GoogleAIModels["
|
|
74
|
+
GoogleAIModels["GEMINI_2_5_FLASH_LITE"] = "gemini-2.5-flash-lite";
|
|
75
|
+
// Gemini 2.0 Series
|
|
76
|
+
GoogleAIModels["GEMINI_2_0_FLASH_001"] = "gemini-2.0-flash-001";
|
|
77
|
+
// Gemini 1.5 Series (Legacy support)
|
|
78
|
+
GoogleAIModels["GEMINI_1_5_PRO"] = "gemini-1.5-pro";
|
|
79
|
+
GoogleAIModels["GEMINI_1_5_FLASH"] = "gemini-1.5-flash";
|
|
80
|
+
GoogleAIModels["GEMINI_1_5_FLASH_LITE"] = "gemini-1.5-flash-lite";
|
|
61
81
|
})(GoogleAIModels || (GoogleAIModels = {}));
|
|
62
82
|
/**
|
|
63
83
|
* Default provider configurations
|
|
@@ -35,7 +35,16 @@ export class ProviderFactory {
|
|
|
35
35
|
if (!registration) {
|
|
36
36
|
throw new Error(`Unknown provider: ${providerName}. Available providers: ${this.getAvailableProviders().join(", ")}`);
|
|
37
37
|
}
|
|
38
|
-
|
|
38
|
+
// Respect environment variables before falling back to registry default
|
|
39
|
+
let model = modelName;
|
|
40
|
+
if (!model) {
|
|
41
|
+
// Check for provider-specific environment variables
|
|
42
|
+
if (providerName.toLowerCase().includes("vertex")) {
|
|
43
|
+
model = process.env.VERTEX_MODEL;
|
|
44
|
+
}
|
|
45
|
+
// Fallback to registry default if no env var
|
|
46
|
+
model = model || registration.defaultModel;
|
|
47
|
+
}
|
|
39
48
|
try {
|
|
40
49
|
// Try calling as factory function first, then fallback to constructor
|
|
41
50
|
let result;
|
|
@@ -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
|
-
}, "
|
|
58
|
+
}, "claude-sonnet-4@20250514", ["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/lib/neurolink.d.ts
CHANGED
|
@@ -10,6 +10,7 @@ import type { GenerateOptions, GenerateResult } from "./types/generateTypes.js";
|
|
|
10
10
|
import type { StreamOptions, StreamResult } from "./types/streamTypes.js";
|
|
11
11
|
import type { SimpleTool } from "./sdk/toolRegistration.js";
|
|
12
12
|
import type { InMemoryMCPServerConfig } from "./types/mcpTypes.js";
|
|
13
|
+
import { EventEmitter } from "events";
|
|
13
14
|
export interface ProviderStatus {
|
|
14
15
|
provider: string;
|
|
15
16
|
status: "working" | "failed" | "not-configured";
|
|
@@ -41,10 +42,19 @@ export interface MCPServerInfo {
|
|
|
41
42
|
}
|
|
42
43
|
export declare class NeuroLink {
|
|
43
44
|
private mcpInitialized;
|
|
45
|
+
private emitter;
|
|
44
46
|
private customTools;
|
|
45
47
|
private inMemoryServers;
|
|
46
48
|
private toolCircuitBreakers;
|
|
47
49
|
private toolExecutionMetrics;
|
|
50
|
+
/**
|
|
51
|
+
* Helper method to emit tool end event in a consistent way
|
|
52
|
+
* Used by executeTool in both success and error paths
|
|
53
|
+
* @param toolName - Name of the tool
|
|
54
|
+
* @param startTime - Timestamp when tool execution started
|
|
55
|
+
* @param success - Whether the tool execution was successful
|
|
56
|
+
*/
|
|
57
|
+
private emitToolEndEvent;
|
|
48
58
|
constructor();
|
|
49
59
|
/**
|
|
50
60
|
* Initialize MCP registry with enhanced error handling and resource cleanup
|
|
@@ -101,6 +111,11 @@ export declare class NeuroLink {
|
|
|
101
111
|
* Future-ready for multi-modal capabilities with current text focus
|
|
102
112
|
*/
|
|
103
113
|
stream(options: StreamOptions): Promise<StreamResult>;
|
|
114
|
+
/**
|
|
115
|
+
* Get the EventEmitter to listen to NeuroLink events
|
|
116
|
+
* @returns EventEmitter instance
|
|
117
|
+
*/
|
|
118
|
+
getEventEmitter(): EventEmitter<[never]>;
|
|
104
119
|
/**
|
|
105
120
|
* Register a custom tool that will be available to all AI providers
|
|
106
121
|
* @param name - Unique name for the tool
|
package/dist/lib/neurolink.js
CHANGED
|
@@ -26,15 +26,32 @@ import { validateTool, createMCPServerFromTools, } from "./sdk/toolRegistration.
|
|
|
26
26
|
import { processFactoryOptions, enhanceTextGenerationOptions, validateFactoryConfig, processStreamingFactoryOptions, createCleanStreamOptions, } from "./utils/factoryProcessing.js";
|
|
27
27
|
// Enhanced error handling imports
|
|
28
28
|
import { ErrorFactory, NeuroLinkError, withTimeout, withRetry, isRetriableError, logStructuredError, CircuitBreaker, } from "./utils/errorHandling.js";
|
|
29
|
+
import { EventEmitter } from "events";
|
|
29
30
|
// Core types imported from core/types.js
|
|
30
31
|
export class NeuroLink {
|
|
31
32
|
mcpInitialized = false;
|
|
33
|
+
emitter = new EventEmitter();
|
|
32
34
|
// Tool registration support
|
|
33
35
|
customTools = new Map();
|
|
34
36
|
inMemoryServers = new Map();
|
|
35
37
|
// Enhanced error handling support
|
|
36
38
|
toolCircuitBreakers = new Map();
|
|
37
39
|
toolExecutionMetrics = new Map();
|
|
40
|
+
/**
|
|
41
|
+
* Helper method to emit tool end event in a consistent way
|
|
42
|
+
* Used by executeTool in both success and error paths
|
|
43
|
+
* @param toolName - Name of the tool
|
|
44
|
+
* @param startTime - Timestamp when tool execution started
|
|
45
|
+
* @param success - Whether the tool execution was successful
|
|
46
|
+
*/
|
|
47
|
+
emitToolEndEvent(toolName, startTime, success) {
|
|
48
|
+
this.emitter.emit("tool:end", {
|
|
49
|
+
toolName,
|
|
50
|
+
responseTime: Date.now() - startTime,
|
|
51
|
+
success,
|
|
52
|
+
timestamp: Date.now(),
|
|
53
|
+
});
|
|
54
|
+
}
|
|
38
55
|
constructor() {
|
|
39
56
|
// SDK always disables manual MCP config for security
|
|
40
57
|
ProviderRegistry.setOptions({
|
|
@@ -91,7 +108,6 @@ export class NeuroLink {
|
|
|
91
108
|
* Replaces both generateText and legacy methods
|
|
92
109
|
*/
|
|
93
110
|
async generate(optionsOrPrompt) {
|
|
94
|
-
const startTime = Date.now();
|
|
95
111
|
// Convert string prompt to full options
|
|
96
112
|
const options = typeof optionsOrPrompt === "string"
|
|
97
113
|
? { input: { text: optionsOrPrompt } }
|
|
@@ -100,6 +116,12 @@ export class NeuroLink {
|
|
|
100
116
|
if (!options.input?.text || typeof options.input.text !== "string") {
|
|
101
117
|
throw new Error("Input text is required and must be a non-empty string");
|
|
102
118
|
}
|
|
119
|
+
const startTime = Date.now();
|
|
120
|
+
// Emit generation start event
|
|
121
|
+
this.emitter.emit("generation:start", {
|
|
122
|
+
provider: options.provider || "auto",
|
|
123
|
+
timestamp: startTime,
|
|
124
|
+
});
|
|
103
125
|
// Process factory configuration
|
|
104
126
|
const factoryResult = processFactoryOptions(options);
|
|
105
127
|
// Validate factory configuration if present
|
|
@@ -142,6 +164,13 @@ export class NeuroLink {
|
|
|
142
164
|
}
|
|
143
165
|
// Use redesigned generation logic
|
|
144
166
|
const textResult = await this.generateTextInternal(textOptions);
|
|
167
|
+
// Emit generation completion event
|
|
168
|
+
this.emitter.emit("generation:end", {
|
|
169
|
+
provider: textResult.provider,
|
|
170
|
+
responseTime: Date.now() - startTime,
|
|
171
|
+
toolsUsed: textResult.toolsUsed,
|
|
172
|
+
timestamp: Date.now(),
|
|
173
|
+
});
|
|
145
174
|
// Convert back to GenerateResult
|
|
146
175
|
const generateResult = {
|
|
147
176
|
content: textResult.content,
|
|
@@ -509,6 +538,11 @@ export class NeuroLink {
|
|
|
509
538
|
options.input.text.trim() === "") {
|
|
510
539
|
throw new Error("Stream options must include input.text as a non-empty string");
|
|
511
540
|
}
|
|
541
|
+
// Emit stream start event
|
|
542
|
+
this.emitter.emit("stream:start", {
|
|
543
|
+
provider: options.provider || "auto",
|
|
544
|
+
timestamp: startTime,
|
|
545
|
+
});
|
|
512
546
|
// Process factory configuration for streaming
|
|
513
547
|
const factoryResult = processFactoryOptions(options);
|
|
514
548
|
const streamingResult = processStreamingFactoryOptions(options);
|
|
@@ -576,6 +610,11 @@ export class NeuroLink {
|
|
|
576
610
|
responseTime,
|
|
577
611
|
provider: providerName,
|
|
578
612
|
});
|
|
613
|
+
// Emit stream completion event
|
|
614
|
+
this.emitter.emit("stream:end", {
|
|
615
|
+
provider: providerName,
|
|
616
|
+
responseTime,
|
|
617
|
+
});
|
|
579
618
|
// Convert to StreamResult format - Include analytics and evaluation from provider
|
|
580
619
|
return {
|
|
581
620
|
stream,
|
|
@@ -615,6 +654,12 @@ export class NeuroLink {
|
|
|
615
654
|
const cleanOptions = createCleanStreamOptions(enhancedOptions);
|
|
616
655
|
const streamResult = await provider.stream(cleanOptions);
|
|
617
656
|
const responseTime = Date.now() - startTime;
|
|
657
|
+
// Emit stream completion event for fallback
|
|
658
|
+
this.emitter.emit("stream:end", {
|
|
659
|
+
provider: providerName,
|
|
660
|
+
responseTime,
|
|
661
|
+
fallback: true,
|
|
662
|
+
});
|
|
618
663
|
return {
|
|
619
664
|
stream: streamResult.stream,
|
|
620
665
|
provider: providerName,
|
|
@@ -643,6 +688,13 @@ export class NeuroLink {
|
|
|
643
688
|
};
|
|
644
689
|
}
|
|
645
690
|
}
|
|
691
|
+
/**
|
|
692
|
+
* Get the EventEmitter to listen to NeuroLink events
|
|
693
|
+
* @returns EventEmitter instance
|
|
694
|
+
*/
|
|
695
|
+
getEventEmitter() {
|
|
696
|
+
return this.emitter;
|
|
697
|
+
}
|
|
646
698
|
// ========================================
|
|
647
699
|
// Tool Registration API
|
|
648
700
|
// ========================================
|
|
@@ -652,6 +704,11 @@ export class NeuroLink {
|
|
|
652
704
|
* @param tool - Tool configuration
|
|
653
705
|
*/
|
|
654
706
|
registerTool(name, tool) {
|
|
707
|
+
// Emit tool registration start event
|
|
708
|
+
this.emitter.emit("tools-register:start", {
|
|
709
|
+
toolName: name,
|
|
710
|
+
timestamp: Date.now(),
|
|
711
|
+
});
|
|
655
712
|
try {
|
|
656
713
|
// Validate tool configuration
|
|
657
714
|
validateTool(name, tool);
|
|
@@ -666,6 +723,12 @@ export class NeuroLink {
|
|
|
666
723
|
// Store as in-memory server
|
|
667
724
|
this.inMemoryServers.set(serverId, mcpServer);
|
|
668
725
|
logger.info(`Registered custom tool: ${name}`);
|
|
726
|
+
// Emit tool registration success event
|
|
727
|
+
this.emitter.emit("tools-register:end", {
|
|
728
|
+
toolName: name,
|
|
729
|
+
success: true,
|
|
730
|
+
timestamp: Date.now(),
|
|
731
|
+
});
|
|
669
732
|
}
|
|
670
733
|
catch (error) {
|
|
671
734
|
logger.error(`Failed to register tool ${name}:`, error);
|
|
@@ -758,6 +821,11 @@ export class NeuroLink {
|
|
|
758
821
|
async executeTool(toolName, params = {}, options) {
|
|
759
822
|
const functionTag = "NeuroLink.executeTool";
|
|
760
823
|
const executionStartTime = Date.now();
|
|
824
|
+
// Emit tool start event
|
|
825
|
+
this.emitter.emit("tool:start", {
|
|
826
|
+
toolName,
|
|
827
|
+
timestamp: executionStartTime,
|
|
828
|
+
});
|
|
761
829
|
// Set default options
|
|
762
830
|
const finalOptions = {
|
|
763
831
|
timeout: options?.timeout || 30000, // 30 second default timeout
|
|
@@ -832,6 +900,8 @@ export class NeuroLink {
|
|
|
832
900
|
memoryDelta,
|
|
833
901
|
circuitBreakerState: circuitBreaker.getState(),
|
|
834
902
|
});
|
|
903
|
+
// Emit tool end event using the helper method
|
|
904
|
+
this.emitToolEndEvent(toolName, executionStartTime, true);
|
|
835
905
|
return result;
|
|
836
906
|
}
|
|
837
907
|
catch (error) {
|
|
@@ -867,6 +937,8 @@ export class NeuroLink {
|
|
|
867
937
|
else {
|
|
868
938
|
structuredError = ErrorFactory.toolExecutionFailed(toolName, new Error(String(error)));
|
|
869
939
|
}
|
|
940
|
+
// Emit tool end event using the helper method
|
|
941
|
+
this.emitToolEndEvent(toolName, executionStartTime, false);
|
|
870
942
|
// Add execution context to structured error
|
|
871
943
|
structuredError = new NeuroLinkError({
|
|
872
944
|
...structuredError,
|
|
@@ -108,6 +108,10 @@ export declare class GoogleVertexProvider extends BaseProvider {
|
|
|
108
108
|
maxTokens: number;
|
|
109
109
|
};
|
|
110
110
|
};
|
|
111
|
+
/**
|
|
112
|
+
* Get model suggestions when a model is not found
|
|
113
|
+
*/
|
|
114
|
+
private getModelSuggestions;
|
|
111
115
|
}
|
|
112
116
|
export default GoogleVertexProvider;
|
|
113
117
|
export { GoogleVertexProvider as GoogleVertexAI };
|
|
@@ -40,9 +40,9 @@ const getVertexLocation = () => {
|
|
|
40
40
|
"us-central1");
|
|
41
41
|
};
|
|
42
42
|
const getDefaultVertexModel = () => {
|
|
43
|
-
// Use gemini-
|
|
43
|
+
// Use gemini-2.5-flash as default - latest and best price-performance model
|
|
44
44
|
// Override with VERTEX_MODEL environment variable if needed
|
|
45
|
-
return process.env.VERTEX_MODEL || "gemini-
|
|
45
|
+
return process.env.VERTEX_MODEL || "gemini-2.5-flash";
|
|
46
46
|
};
|
|
47
47
|
const hasGoogleCredentials = () => {
|
|
48
48
|
return !!(process.env.GOOGLE_APPLICATION_CREDENTIALS ||
|
|
@@ -276,7 +276,8 @@ export class GoogleVertexProvider extends BaseProvider {
|
|
|
276
276
|
return new Error(`ā Google Vertex AI Permission Denied\n\nYour Google Cloud credentials don't have permission to access Vertex AI.\n\nRequired Steps:\n1. Ensure your service account has Vertex AI User role\n2. Check if Vertex AI API is enabled in your project\n3. Verify your project ID is correct\n4. Confirm your location/region has Vertex AI available`);
|
|
277
277
|
}
|
|
278
278
|
if (message.includes("NOT_FOUND")) {
|
|
279
|
-
|
|
279
|
+
const modelSuggestions = this.getModelSuggestions(this.modelName);
|
|
280
|
+
return new Error(`ā Google Vertex AI Model Not Found\n\n${message}\n\nModel '${this.modelName}' is not available.\n\nSuggested alternatives:\n${modelSuggestions}\n\nTroubleshooting:\n1. Check model name spelling and format\n2. Verify model is available in your region (${this.location})\n3. Ensure your project has access to the model\n4. For Claude models, enable Anthropic integration in Google Cloud Console`);
|
|
280
281
|
}
|
|
281
282
|
if (message.includes("QUOTA_EXCEEDED")) {
|
|
282
283
|
return new Error(`ā Google Vertex AI Quota Exceeded\n\n${message}\n\nSolutions:\n1. Check your Vertex AI quotas in Google Cloud Console\n2. Request quota increase if needed\n3. Try a different model or reduce request frequency\n4. Consider using a different region`);
|
|
@@ -520,6 +521,46 @@ export class GoogleVertexProvider extends BaseProvider {
|
|
|
520
521
|
},
|
|
521
522
|
};
|
|
522
523
|
}
|
|
524
|
+
/**
|
|
525
|
+
* Get model suggestions when a model is not found
|
|
526
|
+
*/
|
|
527
|
+
getModelSuggestions(requestedModel) {
|
|
528
|
+
const availableModels = {
|
|
529
|
+
google: [
|
|
530
|
+
"gemini-2.5-pro",
|
|
531
|
+
"gemini-2.5-flash",
|
|
532
|
+
"gemini-2.5-flash-lite",
|
|
533
|
+
"gemini-2.0-flash-001",
|
|
534
|
+
"gemini-1.5-pro",
|
|
535
|
+
"gemini-1.5-flash"
|
|
536
|
+
],
|
|
537
|
+
claude: [
|
|
538
|
+
"claude-sonnet-4@20250514",
|
|
539
|
+
"claude-opus-4@20250514",
|
|
540
|
+
"claude-3-5-sonnet-20241022",
|
|
541
|
+
"claude-3-5-haiku-20241022",
|
|
542
|
+
"claude-3-sonnet-20240229",
|
|
543
|
+
"claude-3-haiku-20240307",
|
|
544
|
+
"claude-3-opus-20240229",
|
|
545
|
+
],
|
|
546
|
+
};
|
|
547
|
+
let suggestions = "\nš¤ Google Models (always available):\n";
|
|
548
|
+
availableModels.google.forEach((model) => {
|
|
549
|
+
suggestions += ` ⢠${model}\n`;
|
|
550
|
+
});
|
|
551
|
+
suggestions += "\nš§ Claude Models (requires Anthropic integration):\n";
|
|
552
|
+
availableModels.claude.forEach((model) => {
|
|
553
|
+
suggestions += ` ⢠${model}\n`;
|
|
554
|
+
});
|
|
555
|
+
// If the requested model looks like a Claude model, provide specific guidance
|
|
556
|
+
if (requestedModel && requestedModel.toLowerCase().includes("claude")) {
|
|
557
|
+
suggestions += `\nš” Tip: "${requestedModel}" appears to be a Claude model.\n`;
|
|
558
|
+
suggestions +=
|
|
559
|
+
"Ensure Anthropic integration is enabled in your Google Cloud project.\n";
|
|
560
|
+
suggestions += "Try using an available Claude model from the list above.";
|
|
561
|
+
}
|
|
562
|
+
return suggestions;
|
|
563
|
+
}
|
|
523
564
|
}
|
|
524
565
|
export default GoogleVertexProvider;
|
|
525
566
|
// Re-export for compatibility
|
|
@@ -77,7 +77,7 @@ export class SageMakerRuntimeClient {
|
|
|
77
77
|
if (!client) {
|
|
78
78
|
throw new Error("SageMaker client has been disposed");
|
|
79
79
|
}
|
|
80
|
-
const response = await this.executeWithRetry(() => client.send(command), params.EndpointName);
|
|
80
|
+
const response = (await this.executeWithRetry(() => client.send(command), params.EndpointName));
|
|
81
81
|
const duration = Date.now() - startTime;
|
|
82
82
|
logger.debug("SageMaker endpoint invocation successful", {
|
|
83
83
|
endpointName: params.EndpointName,
|
|
@@ -134,7 +134,7 @@ export class SageMakerRuntimeClient {
|
|
|
134
134
|
if (!client) {
|
|
135
135
|
throw new Error("SageMaker client has been disposed");
|
|
136
136
|
}
|
|
137
|
-
const response = await this.executeWithRetry(() => client.send(command), params.EndpointName);
|
|
137
|
+
const response = (await this.executeWithRetry(() => client.send(command), params.EndpointName));
|
|
138
138
|
logger.debug("SageMaker streaming invocation started", {
|
|
139
139
|
endpointName: params.EndpointName,
|
|
140
140
|
setupDuration: Date.now() - startTime,
|
|
@@ -13,7 +13,7 @@ import type { JsonValue } from "../types/common.js";
|
|
|
13
13
|
*/
|
|
14
14
|
declare const VALIDATION_CONFIG: {
|
|
15
15
|
readonly NAME_MIN_LENGTH: 2;
|
|
16
|
-
readonly NAME_MAX_LENGTH:
|
|
16
|
+
readonly NAME_MAX_LENGTH: number;
|
|
17
17
|
readonly DESCRIPTION_MIN_LENGTH: 10;
|
|
18
18
|
readonly DESCRIPTION_MAX_LENGTH: number;
|
|
19
19
|
readonly RESERVED_NAMES: Set<string>;
|
|
@@ -8,15 +8,19 @@ import { logger } from "../utils/logger.js";
|
|
|
8
8
|
/**
|
|
9
9
|
* Configuration constants for tool validation
|
|
10
10
|
*/
|
|
11
|
-
const
|
|
12
|
-
|
|
11
|
+
const envDescValue = parseInt(process.env.NEUROLINK_TOOL_DESCRIPTION_MAX_LENGTH || "200", 10);
|
|
12
|
+
// Allow 0 to mean unlimited (no length restriction)
|
|
13
|
+
const DEFAULT_DESCRIPTION_MAX_LENGTH = Number.isInteger(envDescValue) && envDescValue >= 0 ? envDescValue : 200;
|
|
14
|
+
const envNameValue = parseInt(process.env.NEUROLINK_TOOL_NAME_MAX_LENGTH || "50", 10);
|
|
15
|
+
// Allow 0 to mean unlimited (no length restriction)
|
|
16
|
+
const DEFAULT_NAME_MAX_LENGTH = Number.isInteger(envNameValue) && envNameValue >= 0 ? envNameValue : 50;
|
|
13
17
|
/**
|
|
14
18
|
* Enhanced validation configuration
|
|
15
19
|
*/
|
|
16
20
|
const VALIDATION_CONFIG = {
|
|
17
21
|
// Tool name constraints
|
|
18
22
|
NAME_MIN_LENGTH: 2,
|
|
19
|
-
NAME_MAX_LENGTH:
|
|
23
|
+
NAME_MAX_LENGTH: DEFAULT_NAME_MAX_LENGTH,
|
|
20
24
|
// Description constraints
|
|
21
25
|
DESCRIPTION_MIN_LENGTH: 10,
|
|
22
26
|
DESCRIPTION_MAX_LENGTH: DEFAULT_DESCRIPTION_MAX_LENGTH,
|
|
@@ -210,7 +214,9 @@ function validateToolName(name) {
|
|
|
210
214
|
`Minimum length: ${VALIDATION_CONFIG.NAME_MIN_LENGTH} characters. ` +
|
|
211
215
|
`Example: 'get_data', 'send_email'`);
|
|
212
216
|
}
|
|
213
|
-
if (
|
|
217
|
+
// Only check name length if limit is greater than 0 (0 means unlimited)
|
|
218
|
+
if (VALIDATION_CONFIG.NAME_MAX_LENGTH > 0 &&
|
|
219
|
+
trimmedName.length > VALIDATION_CONFIG.NAME_MAX_LENGTH) {
|
|
214
220
|
throw new Error(`Tool name too long: '${name}' (${trimmedName.length} chars). ` +
|
|
215
221
|
`Maximum length: ${VALIDATION_CONFIG.NAME_MAX_LENGTH} characters. ` +
|
|
216
222
|
`Consider shortening: '${trimmedName.substring(0, 20)}...'`);
|
|
@@ -254,7 +260,9 @@ function validateToolDescription(name, description) {
|
|
|
254
260
|
`The description should clearly explain what the tool does and when to use it. ` +
|
|
255
261
|
`Example: "Fetches current weather data for a specified location using coordinates or city name"`);
|
|
256
262
|
}
|
|
257
|
-
if (
|
|
263
|
+
// Only check description length if limit is greater than 0 (0 means unlimited)
|
|
264
|
+
if (VALIDATION_CONFIG.DESCRIPTION_MAX_LENGTH > 0 &&
|
|
265
|
+
trimmedDescription.length > VALIDATION_CONFIG.DESCRIPTION_MAX_LENGTH) {
|
|
258
266
|
throw new Error(`Tool '${name}' description too long: ${trimmedDescription.length} characters. ` +
|
|
259
267
|
`Maximum length: ${VALIDATION_CONFIG.DESCRIPTION_MAX_LENGTH} characters. ` +
|
|
260
268
|
`Current description: "${trimmedDescription.substring(0, 50)}..." ` +
|
|
@@ -229,11 +229,19 @@ export class ProviderHealthChecker {
|
|
|
229
229
|
* Check model availability (if possible without making API calls)
|
|
230
230
|
*/
|
|
231
231
|
static async checkModelAvailability(providerName, healthStatus) {
|
|
232
|
-
//
|
|
233
|
-
// In the future, this could be enhanced with actual API calls
|
|
232
|
+
// Basic model name validation and recommendations
|
|
234
233
|
const commonModels = this.getCommonModelsForProvider(providerName);
|
|
235
234
|
if (commonModels.length > 0) {
|
|
236
|
-
|
|
235
|
+
if (providerName === AIProviderName.VERTEX) {
|
|
236
|
+
// Provide more detailed information for Vertex AI
|
|
237
|
+
healthStatus.recommendations.push(`Available models for ${providerName}:\n` +
|
|
238
|
+
` Google Models: gemini-1.5-pro, gemini-1.5-flash\n` +
|
|
239
|
+
` Claude Models: claude-3-5-sonnet-20241022, claude-3-sonnet-20240229, claude-3-haiku-20240307, claude-3-opus-20240229\n` +
|
|
240
|
+
` Note: Claude models require Anthropic integration to be enabled in your Google Cloud project`);
|
|
241
|
+
}
|
|
242
|
+
else {
|
|
243
|
+
healthStatus.recommendations.push(`Common models for ${providerName}: ${commonModels.slice(0, 3).join(", ")}`);
|
|
244
|
+
}
|
|
237
245
|
}
|
|
238
246
|
}
|
|
239
247
|
/**
|
|
@@ -408,7 +416,14 @@ export class ProviderHealthChecker {
|
|
|
408
416
|
case AIProviderName.GOOGLE_AI:
|
|
409
417
|
return ["gemini-1.5-pro", "gemini-1.5-flash", "gemini-pro"];
|
|
410
418
|
case AIProviderName.VERTEX:
|
|
411
|
-
return [
|
|
419
|
+
return [
|
|
420
|
+
"gemini-1.5-pro",
|
|
421
|
+
"gemini-1.5-flash",
|
|
422
|
+
"claude-3-5-sonnet-20241022",
|
|
423
|
+
"claude-3-sonnet-20240229",
|
|
424
|
+
"claude-3-haiku-20240307",
|
|
425
|
+
"claude-3-opus-20240229",
|
|
426
|
+
];
|
|
412
427
|
case AIProviderName.BEDROCK:
|
|
413
428
|
return [
|
|
414
429
|
"anthropic.claude-3-sonnet-20240229-v1:0",
|
package/dist/neurolink.d.ts
CHANGED
|
@@ -10,6 +10,7 @@ import type { GenerateOptions, GenerateResult } from "./types/generateTypes.js";
|
|
|
10
10
|
import type { StreamOptions, StreamResult } from "./types/streamTypes.js";
|
|
11
11
|
import type { SimpleTool } from "./sdk/toolRegistration.js";
|
|
12
12
|
import type { InMemoryMCPServerConfig } from "./types/mcpTypes.js";
|
|
13
|
+
import { EventEmitter } from "events";
|
|
13
14
|
export interface ProviderStatus {
|
|
14
15
|
provider: string;
|
|
15
16
|
status: "working" | "failed" | "not-configured";
|
|
@@ -41,10 +42,19 @@ export interface MCPServerInfo {
|
|
|
41
42
|
}
|
|
42
43
|
export declare class NeuroLink {
|
|
43
44
|
private mcpInitialized;
|
|
45
|
+
private emitter;
|
|
44
46
|
private customTools;
|
|
45
47
|
private inMemoryServers;
|
|
46
48
|
private toolCircuitBreakers;
|
|
47
49
|
private toolExecutionMetrics;
|
|
50
|
+
/**
|
|
51
|
+
* Helper method to emit tool end event in a consistent way
|
|
52
|
+
* Used by executeTool in both success and error paths
|
|
53
|
+
* @param toolName - Name of the tool
|
|
54
|
+
* @param startTime - Timestamp when tool execution started
|
|
55
|
+
* @param success - Whether the tool execution was successful
|
|
56
|
+
*/
|
|
57
|
+
private emitToolEndEvent;
|
|
48
58
|
constructor();
|
|
49
59
|
/**
|
|
50
60
|
* Initialize MCP registry with enhanced error handling and resource cleanup
|
|
@@ -101,6 +111,11 @@ export declare class NeuroLink {
|
|
|
101
111
|
* Future-ready for multi-modal capabilities with current text focus
|
|
102
112
|
*/
|
|
103
113
|
stream(options: StreamOptions): Promise<StreamResult>;
|
|
114
|
+
/**
|
|
115
|
+
* Get the EventEmitter to listen to NeuroLink events
|
|
116
|
+
* @returns EventEmitter instance
|
|
117
|
+
*/
|
|
118
|
+
getEventEmitter(): EventEmitter<[never]>;
|
|
104
119
|
/**
|
|
105
120
|
* Register a custom tool that will be available to all AI providers
|
|
106
121
|
* @param name - Unique name for the tool
|
package/dist/neurolink.js
CHANGED
|
@@ -26,15 +26,32 @@ import { validateTool, createMCPServerFromTools, } from "./sdk/toolRegistration.
|
|
|
26
26
|
import { processFactoryOptions, enhanceTextGenerationOptions, validateFactoryConfig, processStreamingFactoryOptions, createCleanStreamOptions, } from "./utils/factoryProcessing.js";
|
|
27
27
|
// Enhanced error handling imports
|
|
28
28
|
import { ErrorFactory, NeuroLinkError, withTimeout, withRetry, isRetriableError, logStructuredError, CircuitBreaker, } from "./utils/errorHandling.js";
|
|
29
|
+
import { EventEmitter } from "events";
|
|
29
30
|
// Core types imported from core/types.js
|
|
30
31
|
export class NeuroLink {
|
|
31
32
|
mcpInitialized = false;
|
|
33
|
+
emitter = new EventEmitter();
|
|
32
34
|
// Tool registration support
|
|
33
35
|
customTools = new Map();
|
|
34
36
|
inMemoryServers = new Map();
|
|
35
37
|
// Enhanced error handling support
|
|
36
38
|
toolCircuitBreakers = new Map();
|
|
37
39
|
toolExecutionMetrics = new Map();
|
|
40
|
+
/**
|
|
41
|
+
* Helper method to emit tool end event in a consistent way
|
|
42
|
+
* Used by executeTool in both success and error paths
|
|
43
|
+
* @param toolName - Name of the tool
|
|
44
|
+
* @param startTime - Timestamp when tool execution started
|
|
45
|
+
* @param success - Whether the tool execution was successful
|
|
46
|
+
*/
|
|
47
|
+
emitToolEndEvent(toolName, startTime, success) {
|
|
48
|
+
this.emitter.emit("tool:end", {
|
|
49
|
+
toolName,
|
|
50
|
+
responseTime: Date.now() - startTime,
|
|
51
|
+
success,
|
|
52
|
+
timestamp: Date.now(),
|
|
53
|
+
});
|
|
54
|
+
}
|
|
38
55
|
constructor() {
|
|
39
56
|
// SDK always disables manual MCP config for security
|
|
40
57
|
ProviderRegistry.setOptions({
|
|
@@ -91,7 +108,6 @@ export class NeuroLink {
|
|
|
91
108
|
* Replaces both generateText and legacy methods
|
|
92
109
|
*/
|
|
93
110
|
async generate(optionsOrPrompt) {
|
|
94
|
-
const startTime = Date.now();
|
|
95
111
|
// Convert string prompt to full options
|
|
96
112
|
const options = typeof optionsOrPrompt === "string"
|
|
97
113
|
? { input: { text: optionsOrPrompt } }
|
|
@@ -100,6 +116,12 @@ export class NeuroLink {
|
|
|
100
116
|
if (!options.input?.text || typeof options.input.text !== "string") {
|
|
101
117
|
throw new Error("Input text is required and must be a non-empty string");
|
|
102
118
|
}
|
|
119
|
+
const startTime = Date.now();
|
|
120
|
+
// Emit generation start event
|
|
121
|
+
this.emitter.emit("generation:start", {
|
|
122
|
+
provider: options.provider || "auto",
|
|
123
|
+
timestamp: startTime,
|
|
124
|
+
});
|
|
103
125
|
// Process factory configuration
|
|
104
126
|
const factoryResult = processFactoryOptions(options);
|
|
105
127
|
// Validate factory configuration if present
|
|
@@ -142,6 +164,13 @@ export class NeuroLink {
|
|
|
142
164
|
}
|
|
143
165
|
// Use redesigned generation logic
|
|
144
166
|
const textResult = await this.generateTextInternal(textOptions);
|
|
167
|
+
// Emit generation completion event
|
|
168
|
+
this.emitter.emit("generation:end", {
|
|
169
|
+
provider: textResult.provider,
|
|
170
|
+
responseTime: Date.now() - startTime,
|
|
171
|
+
toolsUsed: textResult.toolsUsed,
|
|
172
|
+
timestamp: Date.now(),
|
|
173
|
+
});
|
|
145
174
|
// Convert back to GenerateResult
|
|
146
175
|
const generateResult = {
|
|
147
176
|
content: textResult.content,
|
|
@@ -509,6 +538,11 @@ export class NeuroLink {
|
|
|
509
538
|
options.input.text.trim() === "") {
|
|
510
539
|
throw new Error("Stream options must include input.text as a non-empty string");
|
|
511
540
|
}
|
|
541
|
+
// Emit stream start event
|
|
542
|
+
this.emitter.emit("stream:start", {
|
|
543
|
+
provider: options.provider || "auto",
|
|
544
|
+
timestamp: startTime,
|
|
545
|
+
});
|
|
512
546
|
// Process factory configuration for streaming
|
|
513
547
|
const factoryResult = processFactoryOptions(options);
|
|
514
548
|
const streamingResult = processStreamingFactoryOptions(options);
|
|
@@ -576,6 +610,11 @@ export class NeuroLink {
|
|
|
576
610
|
responseTime,
|
|
577
611
|
provider: providerName,
|
|
578
612
|
});
|
|
613
|
+
// Emit stream completion event
|
|
614
|
+
this.emitter.emit("stream:end", {
|
|
615
|
+
provider: providerName,
|
|
616
|
+
responseTime,
|
|
617
|
+
});
|
|
579
618
|
// Convert to StreamResult format - Include analytics and evaluation from provider
|
|
580
619
|
return {
|
|
581
620
|
stream,
|
|
@@ -615,6 +654,12 @@ export class NeuroLink {
|
|
|
615
654
|
const cleanOptions = createCleanStreamOptions(enhancedOptions);
|
|
616
655
|
const streamResult = await provider.stream(cleanOptions);
|
|
617
656
|
const responseTime = Date.now() - startTime;
|
|
657
|
+
// Emit stream completion event for fallback
|
|
658
|
+
this.emitter.emit("stream:end", {
|
|
659
|
+
provider: providerName,
|
|
660
|
+
responseTime,
|
|
661
|
+
fallback: true,
|
|
662
|
+
});
|
|
618
663
|
return {
|
|
619
664
|
stream: streamResult.stream,
|
|
620
665
|
provider: providerName,
|
|
@@ -643,6 +688,13 @@ export class NeuroLink {
|
|
|
643
688
|
};
|
|
644
689
|
}
|
|
645
690
|
}
|
|
691
|
+
/**
|
|
692
|
+
* Get the EventEmitter to listen to NeuroLink events
|
|
693
|
+
* @returns EventEmitter instance
|
|
694
|
+
*/
|
|
695
|
+
getEventEmitter() {
|
|
696
|
+
return this.emitter;
|
|
697
|
+
}
|
|
646
698
|
// ========================================
|
|
647
699
|
// Tool Registration API
|
|
648
700
|
// ========================================
|
|
@@ -652,6 +704,11 @@ export class NeuroLink {
|
|
|
652
704
|
* @param tool - Tool configuration
|
|
653
705
|
*/
|
|
654
706
|
registerTool(name, tool) {
|
|
707
|
+
// Emit tool registration start event
|
|
708
|
+
this.emitter.emit("tools-register:start", {
|
|
709
|
+
toolName: name,
|
|
710
|
+
timestamp: Date.now(),
|
|
711
|
+
});
|
|
655
712
|
try {
|
|
656
713
|
// Validate tool configuration
|
|
657
714
|
validateTool(name, tool);
|
|
@@ -666,6 +723,12 @@ export class NeuroLink {
|
|
|
666
723
|
// Store as in-memory server
|
|
667
724
|
this.inMemoryServers.set(serverId, mcpServer);
|
|
668
725
|
logger.info(`Registered custom tool: ${name}`);
|
|
726
|
+
// Emit tool registration success event
|
|
727
|
+
this.emitter.emit("tools-register:end", {
|
|
728
|
+
toolName: name,
|
|
729
|
+
success: true,
|
|
730
|
+
timestamp: Date.now(),
|
|
731
|
+
});
|
|
669
732
|
}
|
|
670
733
|
catch (error) {
|
|
671
734
|
logger.error(`Failed to register tool ${name}:`, error);
|
|
@@ -758,6 +821,11 @@ export class NeuroLink {
|
|
|
758
821
|
async executeTool(toolName, params = {}, options) {
|
|
759
822
|
const functionTag = "NeuroLink.executeTool";
|
|
760
823
|
const executionStartTime = Date.now();
|
|
824
|
+
// Emit tool start event
|
|
825
|
+
this.emitter.emit("tool:start", {
|
|
826
|
+
toolName,
|
|
827
|
+
timestamp: executionStartTime,
|
|
828
|
+
});
|
|
761
829
|
// Set default options
|
|
762
830
|
const finalOptions = {
|
|
763
831
|
timeout: options?.timeout || 30000, // 30 second default timeout
|
|
@@ -832,6 +900,8 @@ export class NeuroLink {
|
|
|
832
900
|
memoryDelta,
|
|
833
901
|
circuitBreakerState: circuitBreaker.getState(),
|
|
834
902
|
});
|
|
903
|
+
// Emit tool end event using the helper method
|
|
904
|
+
this.emitToolEndEvent(toolName, executionStartTime, true);
|
|
835
905
|
return result;
|
|
836
906
|
}
|
|
837
907
|
catch (error) {
|
|
@@ -867,6 +937,8 @@ export class NeuroLink {
|
|
|
867
937
|
else {
|
|
868
938
|
structuredError = ErrorFactory.toolExecutionFailed(toolName, new Error(String(error)));
|
|
869
939
|
}
|
|
940
|
+
// Emit tool end event using the helper method
|
|
941
|
+
this.emitToolEndEvent(toolName, executionStartTime, false);
|
|
870
942
|
// Add execution context to structured error
|
|
871
943
|
structuredError = new NeuroLinkError({
|
|
872
944
|
...structuredError,
|
|
@@ -108,6 +108,10 @@ export declare class GoogleVertexProvider extends BaseProvider {
|
|
|
108
108
|
maxTokens: number;
|
|
109
109
|
};
|
|
110
110
|
};
|
|
111
|
+
/**
|
|
112
|
+
* Get model suggestions when a model is not found
|
|
113
|
+
*/
|
|
114
|
+
private getModelSuggestions;
|
|
111
115
|
}
|
|
112
116
|
export default GoogleVertexProvider;
|
|
113
117
|
export { GoogleVertexProvider as GoogleVertexAI };
|
|
@@ -40,9 +40,9 @@ const getVertexLocation = () => {
|
|
|
40
40
|
"us-central1");
|
|
41
41
|
};
|
|
42
42
|
const getDefaultVertexModel = () => {
|
|
43
|
-
// Use gemini-
|
|
43
|
+
// Use gemini-2.5-flash as default - latest and best price-performance model
|
|
44
44
|
// Override with VERTEX_MODEL environment variable if needed
|
|
45
|
-
return process.env.VERTEX_MODEL || "gemini-
|
|
45
|
+
return process.env.VERTEX_MODEL || "gemini-2.5-flash";
|
|
46
46
|
};
|
|
47
47
|
const hasGoogleCredentials = () => {
|
|
48
48
|
return !!(process.env.GOOGLE_APPLICATION_CREDENTIALS ||
|
|
@@ -276,7 +276,8 @@ export class GoogleVertexProvider extends BaseProvider {
|
|
|
276
276
|
return new Error(`ā Google Vertex AI Permission Denied\n\nYour Google Cloud credentials don't have permission to access Vertex AI.\n\nRequired Steps:\n1. Ensure your service account has Vertex AI User role\n2. Check if Vertex AI API is enabled in your project\n3. Verify your project ID is correct\n4. Confirm your location/region has Vertex AI available`);
|
|
277
277
|
}
|
|
278
278
|
if (message.includes("NOT_FOUND")) {
|
|
279
|
-
|
|
279
|
+
const modelSuggestions = this.getModelSuggestions(this.modelName);
|
|
280
|
+
return new Error(`ā Google Vertex AI Model Not Found\n\n${message}\n\nModel '${this.modelName}' is not available.\n\nSuggested alternatives:\n${modelSuggestions}\n\nTroubleshooting:\n1. Check model name spelling and format\n2. Verify model is available in your region (${this.location})\n3. Ensure your project has access to the model\n4. For Claude models, enable Anthropic integration in Google Cloud Console`);
|
|
280
281
|
}
|
|
281
282
|
if (message.includes("QUOTA_EXCEEDED")) {
|
|
282
283
|
return new Error(`ā Google Vertex AI Quota Exceeded\n\n${message}\n\nSolutions:\n1. Check your Vertex AI quotas in Google Cloud Console\n2. Request quota increase if needed\n3. Try a different model or reduce request frequency\n4. Consider using a different region`);
|
|
@@ -520,6 +521,46 @@ export class GoogleVertexProvider extends BaseProvider {
|
|
|
520
521
|
},
|
|
521
522
|
};
|
|
522
523
|
}
|
|
524
|
+
/**
|
|
525
|
+
* Get model suggestions when a model is not found
|
|
526
|
+
*/
|
|
527
|
+
getModelSuggestions(requestedModel) {
|
|
528
|
+
const availableModels = {
|
|
529
|
+
google: [
|
|
530
|
+
"gemini-2.5-pro",
|
|
531
|
+
"gemini-2.5-flash",
|
|
532
|
+
"gemini-2.5-flash-lite",
|
|
533
|
+
"gemini-2.0-flash-001",
|
|
534
|
+
"gemini-1.5-pro",
|
|
535
|
+
"gemini-1.5-flash"
|
|
536
|
+
],
|
|
537
|
+
claude: [
|
|
538
|
+
"claude-sonnet-4@20250514",
|
|
539
|
+
"claude-opus-4@20250514",
|
|
540
|
+
"claude-3-5-sonnet-20241022",
|
|
541
|
+
"claude-3-5-haiku-20241022",
|
|
542
|
+
"claude-3-sonnet-20240229",
|
|
543
|
+
"claude-3-haiku-20240307",
|
|
544
|
+
"claude-3-opus-20240229",
|
|
545
|
+
],
|
|
546
|
+
};
|
|
547
|
+
let suggestions = "\nš¤ Google Models (always available):\n";
|
|
548
|
+
availableModels.google.forEach((model) => {
|
|
549
|
+
suggestions += ` ⢠${model}\n`;
|
|
550
|
+
});
|
|
551
|
+
suggestions += "\nš§ Claude Models (requires Anthropic integration):\n";
|
|
552
|
+
availableModels.claude.forEach((model) => {
|
|
553
|
+
suggestions += ` ⢠${model}\n`;
|
|
554
|
+
});
|
|
555
|
+
// If the requested model looks like a Claude model, provide specific guidance
|
|
556
|
+
if (requestedModel && requestedModel.toLowerCase().includes("claude")) {
|
|
557
|
+
suggestions += `\nš” Tip: "${requestedModel}" appears to be a Claude model.\n`;
|
|
558
|
+
suggestions +=
|
|
559
|
+
"Ensure Anthropic integration is enabled in your Google Cloud project.\n";
|
|
560
|
+
suggestions += "Try using an available Claude model from the list above.";
|
|
561
|
+
}
|
|
562
|
+
return suggestions;
|
|
563
|
+
}
|
|
523
564
|
}
|
|
524
565
|
export default GoogleVertexProvider;
|
|
525
566
|
// Re-export for compatibility
|
|
@@ -77,7 +77,7 @@ export class SageMakerRuntimeClient {
|
|
|
77
77
|
if (!client) {
|
|
78
78
|
throw new Error("SageMaker client has been disposed");
|
|
79
79
|
}
|
|
80
|
-
const response = await this.executeWithRetry(() => client.send(command), params.EndpointName);
|
|
80
|
+
const response = (await this.executeWithRetry(() => client.send(command), params.EndpointName));
|
|
81
81
|
const duration = Date.now() - startTime;
|
|
82
82
|
logger.debug("SageMaker endpoint invocation successful", {
|
|
83
83
|
endpointName: params.EndpointName,
|
|
@@ -134,7 +134,7 @@ export class SageMakerRuntimeClient {
|
|
|
134
134
|
if (!client) {
|
|
135
135
|
throw new Error("SageMaker client has been disposed");
|
|
136
136
|
}
|
|
137
|
-
const response = await this.executeWithRetry(() => client.send(command), params.EndpointName);
|
|
137
|
+
const response = (await this.executeWithRetry(() => client.send(command), params.EndpointName));
|
|
138
138
|
logger.debug("SageMaker streaming invocation started", {
|
|
139
139
|
endpointName: params.EndpointName,
|
|
140
140
|
setupDuration: Date.now() - startTime,
|
|
@@ -13,7 +13,7 @@ import type { JsonValue } from "../types/common.js";
|
|
|
13
13
|
*/
|
|
14
14
|
declare const VALIDATION_CONFIG: {
|
|
15
15
|
readonly NAME_MIN_LENGTH: 2;
|
|
16
|
-
readonly NAME_MAX_LENGTH:
|
|
16
|
+
readonly NAME_MAX_LENGTH: number;
|
|
17
17
|
readonly DESCRIPTION_MIN_LENGTH: 10;
|
|
18
18
|
readonly DESCRIPTION_MAX_LENGTH: number;
|
|
19
19
|
readonly RESERVED_NAMES: Set<string>;
|
|
@@ -9,15 +9,19 @@ import { logger } from "../utils/logger.js";
|
|
|
9
9
|
/**
|
|
10
10
|
* Configuration constants for tool validation
|
|
11
11
|
*/
|
|
12
|
-
const
|
|
13
|
-
|
|
12
|
+
const envDescValue = parseInt(process.env.NEUROLINK_TOOL_DESCRIPTION_MAX_LENGTH || "200", 10);
|
|
13
|
+
// Allow 0 to mean unlimited (no length restriction)
|
|
14
|
+
const DEFAULT_DESCRIPTION_MAX_LENGTH = Number.isInteger(envDescValue) && envDescValue >= 0 ? envDescValue : 200;
|
|
15
|
+
const envNameValue = parseInt(process.env.NEUROLINK_TOOL_NAME_MAX_LENGTH || "50", 10);
|
|
16
|
+
// Allow 0 to mean unlimited (no length restriction)
|
|
17
|
+
const DEFAULT_NAME_MAX_LENGTH = Number.isInteger(envNameValue) && envNameValue >= 0 ? envNameValue : 50;
|
|
14
18
|
/**
|
|
15
19
|
* Enhanced validation configuration
|
|
16
20
|
*/
|
|
17
21
|
const VALIDATION_CONFIG = {
|
|
18
22
|
// Tool name constraints
|
|
19
23
|
NAME_MIN_LENGTH: 2,
|
|
20
|
-
NAME_MAX_LENGTH:
|
|
24
|
+
NAME_MAX_LENGTH: DEFAULT_NAME_MAX_LENGTH,
|
|
21
25
|
// Description constraints
|
|
22
26
|
DESCRIPTION_MIN_LENGTH: 10,
|
|
23
27
|
DESCRIPTION_MAX_LENGTH: DEFAULT_DESCRIPTION_MAX_LENGTH,
|
|
@@ -211,7 +215,9 @@ function validateToolName(name) {
|
|
|
211
215
|
`Minimum length: ${VALIDATION_CONFIG.NAME_MIN_LENGTH} characters. ` +
|
|
212
216
|
`Example: 'get_data', 'send_email'`);
|
|
213
217
|
}
|
|
214
|
-
if (
|
|
218
|
+
// Only check name length if limit is greater than 0 (0 means unlimited)
|
|
219
|
+
if (VALIDATION_CONFIG.NAME_MAX_LENGTH > 0 &&
|
|
220
|
+
trimmedName.length > VALIDATION_CONFIG.NAME_MAX_LENGTH) {
|
|
215
221
|
throw new Error(`Tool name too long: '${name}' (${trimmedName.length} chars). ` +
|
|
216
222
|
`Maximum length: ${VALIDATION_CONFIG.NAME_MAX_LENGTH} characters. ` +
|
|
217
223
|
`Consider shortening: '${trimmedName.substring(0, 20)}...'`);
|
|
@@ -255,7 +261,9 @@ function validateToolDescription(name, description) {
|
|
|
255
261
|
`The description should clearly explain what the tool does and when to use it. ` +
|
|
256
262
|
`Example: "Fetches current weather data for a specified location using coordinates or city name"`);
|
|
257
263
|
}
|
|
258
|
-
if (
|
|
264
|
+
// Only check description length if limit is greater than 0 (0 means unlimited)
|
|
265
|
+
if (VALIDATION_CONFIG.DESCRIPTION_MAX_LENGTH > 0 &&
|
|
266
|
+
trimmedDescription.length > VALIDATION_CONFIG.DESCRIPTION_MAX_LENGTH) {
|
|
259
267
|
throw new Error(`Tool '${name}' description too long: ${trimmedDescription.length} characters. ` +
|
|
260
268
|
`Maximum length: ${VALIDATION_CONFIG.DESCRIPTION_MAX_LENGTH} characters. ` +
|
|
261
269
|
`Current description: "${trimmedDescription.substring(0, 50)}..." ` +
|
|
@@ -229,11 +229,19 @@ export class ProviderHealthChecker {
|
|
|
229
229
|
* Check model availability (if possible without making API calls)
|
|
230
230
|
*/
|
|
231
231
|
static async checkModelAvailability(providerName, healthStatus) {
|
|
232
|
-
//
|
|
233
|
-
// In the future, this could be enhanced with actual API calls
|
|
232
|
+
// Basic model name validation and recommendations
|
|
234
233
|
const commonModels = this.getCommonModelsForProvider(providerName);
|
|
235
234
|
if (commonModels.length > 0) {
|
|
236
|
-
|
|
235
|
+
if (providerName === AIProviderName.VERTEX) {
|
|
236
|
+
// Provide more detailed information for Vertex AI
|
|
237
|
+
healthStatus.recommendations.push(`Available models for ${providerName}:\n` +
|
|
238
|
+
` Google Models: gemini-1.5-pro, gemini-1.5-flash\n` +
|
|
239
|
+
` Claude Models: claude-3-5-sonnet-20241022, claude-3-sonnet-20240229, claude-3-haiku-20240307, claude-3-opus-20240229\n` +
|
|
240
|
+
` Note: Claude models require Anthropic integration to be enabled in your Google Cloud project`);
|
|
241
|
+
}
|
|
242
|
+
else {
|
|
243
|
+
healthStatus.recommendations.push(`Common models for ${providerName}: ${commonModels.slice(0, 3).join(", ")}`);
|
|
244
|
+
}
|
|
237
245
|
}
|
|
238
246
|
}
|
|
239
247
|
/**
|
|
@@ -408,7 +416,14 @@ export class ProviderHealthChecker {
|
|
|
408
416
|
case AIProviderName.GOOGLE_AI:
|
|
409
417
|
return ["gemini-1.5-pro", "gemini-1.5-flash", "gemini-pro"];
|
|
410
418
|
case AIProviderName.VERTEX:
|
|
411
|
-
return [
|
|
419
|
+
return [
|
|
420
|
+
"gemini-1.5-pro",
|
|
421
|
+
"gemini-1.5-flash",
|
|
422
|
+
"claude-3-5-sonnet-20241022",
|
|
423
|
+
"claude-3-sonnet-20240229",
|
|
424
|
+
"claude-3-haiku-20240307",
|
|
425
|
+
"claude-3-opus-20240229",
|
|
426
|
+
];
|
|
412
427
|
case AIProviderName.BEDROCK:
|
|
413
428
|
return [
|
|
414
429
|
"anthropic.claude-3-sonnet-20240229-v1:0",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@juspay/neurolink",
|
|
3
|
-
"version": "7.
|
|
3
|
+
"version": "7.9.0",
|
|
4
4
|
"description": "Universal AI Development Platform with working MCP integration, multi-provider support, and professional CLI. Built-in tools operational, 58+ external MCP servers discoverable. Connect to filesystem, GitHub, database operations, and more. Build, test, and deploy AI applications with 9 major providers: OpenAI, Anthropic, Google AI, AWS Bedrock, Azure, Hugging Face, Ollama, and Mistral AI.",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "Juspay Technologies",
|
|
@@ -86,7 +86,9 @@
|
|
|
86
86
|
"reset": "pnpm run clean && pnpm install",
|
|
87
87
|
"audit": "pnpm audit && pnpm run build:analyze",
|
|
88
88
|
"// Release & Publishing": "",
|
|
89
|
-
"release": "pnpm run build:complete && pnpm run test:ci && changeset publish"
|
|
89
|
+
"release": "pnpm run build:complete && pnpm run test:ci && changeset publish",
|
|
90
|
+
"test:semantic-release": "node scripts/test-semantic-release.js",
|
|
91
|
+
"release:dry-run": "npx semantic-release --dry-run"
|
|
90
92
|
},
|
|
91
93
|
"files": [
|
|
92
94
|
"dist",
|
|
@@ -190,6 +192,7 @@
|
|
|
190
192
|
"@typescript-eslint/eslint-plugin": "^8.0.0",
|
|
191
193
|
"@typescript-eslint/parser": "^8.0.0",
|
|
192
194
|
"@vitest/coverage-v8": "^2.1.9",
|
|
195
|
+
"conventional-changelog-conventionalcommits": "^9.1.0",
|
|
193
196
|
"cors": "^2.8.5",
|
|
194
197
|
"eslint": "^9.0.0",
|
|
195
198
|
"express": "^5.1.0",
|