@juspay/neurolink 1.6.0 → 1.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.
Files changed (176) hide show
  1. package/CHANGELOG.md +193 -7
  2. package/README.md +100 -17
  3. package/dist/agent/direct-tools.d.ts +1203 -0
  4. package/dist/agent/direct-tools.js +387 -0
  5. package/dist/cli/commands/agent-generate.d.ts +2 -0
  6. package/dist/cli/commands/agent-generate.js +70 -0
  7. package/dist/cli/commands/config.d.ts +6 -6
  8. package/dist/cli/commands/config.js +326 -273
  9. package/dist/cli/commands/mcp.d.ts +2 -1
  10. package/dist/cli/commands/mcp.js +874 -146
  11. package/dist/cli/commands/ollama.d.ts +1 -1
  12. package/dist/cli/commands/ollama.js +153 -143
  13. package/dist/cli/index.js +589 -323
  14. package/dist/cli/utils/complete-setup.d.ts +19 -0
  15. package/dist/cli/utils/complete-setup.js +81 -0
  16. package/dist/cli/utils/env-manager.d.ts +44 -0
  17. package/dist/cli/utils/env-manager.js +226 -0
  18. package/dist/cli/utils/interactive-setup.d.ts +48 -0
  19. package/dist/cli/utils/interactive-setup.js +302 -0
  20. package/dist/core/dynamic-models.d.ts +208 -0
  21. package/dist/core/dynamic-models.js +250 -0
  22. package/dist/core/factory.d.ts +13 -6
  23. package/dist/core/factory.js +176 -61
  24. package/dist/core/types.d.ts +4 -2
  25. package/dist/core/types.js +4 -4
  26. package/dist/index.d.ts +16 -16
  27. package/dist/index.js +16 -16
  28. package/dist/lib/agent/direct-tools.d.ts +1203 -0
  29. package/dist/lib/agent/direct-tools.js +387 -0
  30. package/dist/lib/core/dynamic-models.d.ts +208 -0
  31. package/dist/lib/core/dynamic-models.js +250 -0
  32. package/dist/lib/core/factory.d.ts +13 -6
  33. package/dist/lib/core/factory.js +176 -61
  34. package/dist/lib/core/types.d.ts +4 -2
  35. package/dist/lib/core/types.js +4 -4
  36. package/dist/lib/index.d.ts +16 -16
  37. package/dist/lib/index.js +16 -16
  38. package/dist/lib/mcp/auto-discovery.d.ts +120 -0
  39. package/dist/lib/mcp/auto-discovery.js +793 -0
  40. package/dist/lib/mcp/client.d.ts +66 -0
  41. package/dist/lib/mcp/client.js +245 -0
  42. package/dist/lib/mcp/config.d.ts +31 -0
  43. package/dist/lib/mcp/config.js +74 -0
  44. package/dist/lib/mcp/context-manager.d.ts +4 -4
  45. package/dist/lib/mcp/context-manager.js +24 -18
  46. package/dist/lib/mcp/factory.d.ts +28 -11
  47. package/dist/lib/mcp/factory.js +36 -29
  48. package/dist/lib/mcp/function-calling.d.ts +51 -0
  49. package/dist/lib/mcp/function-calling.js +510 -0
  50. package/dist/lib/mcp/index.d.ts +190 -0
  51. package/dist/lib/mcp/index.js +156 -0
  52. package/dist/lib/mcp/initialize-tools.d.ts +28 -0
  53. package/dist/lib/mcp/initialize-tools.js +209 -0
  54. package/dist/lib/mcp/initialize.d.ts +17 -0
  55. package/dist/lib/mcp/initialize.js +51 -0
  56. package/dist/lib/mcp/logging.d.ts +71 -0
  57. package/dist/lib/mcp/logging.js +183 -0
  58. package/dist/lib/mcp/manager.d.ts +67 -0
  59. package/dist/lib/mcp/manager.js +176 -0
  60. package/dist/lib/mcp/neurolink-mcp-client.d.ts +96 -0
  61. package/dist/lib/mcp/neurolink-mcp-client.js +417 -0
  62. package/dist/lib/mcp/orchestrator.d.ts +3 -3
  63. package/dist/lib/mcp/orchestrator.js +46 -43
  64. package/dist/lib/mcp/registry.d.ts +2 -2
  65. package/dist/lib/mcp/registry.js +42 -33
  66. package/dist/lib/mcp/servers/ai-providers/ai-analysis-tools.d.ts +1 -1
  67. package/dist/lib/mcp/servers/ai-providers/ai-analysis-tools.js +204 -65
  68. package/dist/lib/mcp/servers/ai-providers/ai-core-server.js +142 -102
  69. package/dist/lib/mcp/servers/ai-providers/ai-workflow-tools.d.ts +6 -6
  70. package/dist/lib/mcp/servers/ai-providers/ai-workflow-tools.js +197 -142
  71. package/dist/lib/mcp/servers/utilities/utility-server.d.ts +8 -0
  72. package/dist/lib/mcp/servers/utilities/utility-server.js +326 -0
  73. package/dist/lib/mcp/tool-integration.d.ts +67 -0
  74. package/dist/lib/mcp/tool-integration.js +179 -0
  75. package/dist/lib/mcp/unified-registry.d.ts +269 -0
  76. package/dist/lib/mcp/unified-registry.js +1411 -0
  77. package/dist/lib/neurolink.d.ts +68 -6
  78. package/dist/lib/neurolink.js +304 -42
  79. package/dist/lib/providers/agent-enhanced-provider.d.ts +59 -0
  80. package/dist/lib/providers/agent-enhanced-provider.js +242 -0
  81. package/dist/lib/providers/amazonBedrock.d.ts +3 -3
  82. package/dist/lib/providers/amazonBedrock.js +54 -50
  83. package/dist/lib/providers/anthropic.d.ts +2 -2
  84. package/dist/lib/providers/anthropic.js +92 -84
  85. package/dist/lib/providers/azureOpenAI.d.ts +2 -2
  86. package/dist/lib/providers/azureOpenAI.js +97 -86
  87. package/dist/lib/providers/function-calling-provider.d.ts +70 -0
  88. package/dist/lib/providers/function-calling-provider.js +359 -0
  89. package/dist/lib/providers/googleAIStudio.d.ts +10 -5
  90. package/dist/lib/providers/googleAIStudio.js +60 -38
  91. package/dist/lib/providers/googleVertexAI.d.ts +3 -3
  92. package/dist/lib/providers/googleVertexAI.js +96 -86
  93. package/dist/lib/providers/huggingFace.d.ts +3 -3
  94. package/dist/lib/providers/huggingFace.js +70 -63
  95. package/dist/lib/providers/index.d.ts +11 -11
  96. package/dist/lib/providers/index.js +18 -18
  97. package/dist/lib/providers/mcp-provider.d.ts +62 -0
  98. package/dist/lib/providers/mcp-provider.js +183 -0
  99. package/dist/lib/providers/mistralAI.d.ts +3 -3
  100. package/dist/lib/providers/mistralAI.js +42 -36
  101. package/dist/lib/providers/ollama.d.ts +4 -4
  102. package/dist/lib/providers/ollama.js +113 -98
  103. package/dist/lib/providers/openAI.d.ts +7 -3
  104. package/dist/lib/providers/openAI.js +45 -33
  105. package/dist/lib/utils/logger.js +2 -2
  106. package/dist/lib/utils/providerUtils.js +53 -31
  107. package/dist/mcp/auto-discovery.d.ts +120 -0
  108. package/dist/mcp/auto-discovery.js +794 -0
  109. package/dist/mcp/client.d.ts +66 -0
  110. package/dist/mcp/client.js +245 -0
  111. package/dist/mcp/config.d.ts +31 -0
  112. package/dist/mcp/config.js +74 -0
  113. package/dist/mcp/context-manager.d.ts +4 -4
  114. package/dist/mcp/context-manager.js +24 -18
  115. package/dist/mcp/factory.d.ts +28 -11
  116. package/dist/mcp/factory.js +36 -29
  117. package/dist/mcp/function-calling.d.ts +51 -0
  118. package/dist/mcp/function-calling.js +510 -0
  119. package/dist/mcp/index.d.ts +190 -0
  120. package/dist/mcp/index.js +156 -0
  121. package/dist/mcp/initialize-tools.d.ts +28 -0
  122. package/dist/mcp/initialize-tools.js +210 -0
  123. package/dist/mcp/initialize.d.ts +17 -0
  124. package/dist/mcp/initialize.js +51 -0
  125. package/dist/mcp/logging.d.ts +71 -0
  126. package/dist/mcp/logging.js +183 -0
  127. package/dist/mcp/manager.d.ts +67 -0
  128. package/dist/mcp/manager.js +176 -0
  129. package/dist/mcp/neurolink-mcp-client.d.ts +96 -0
  130. package/dist/mcp/neurolink-mcp-client.js +417 -0
  131. package/dist/mcp/orchestrator.d.ts +3 -3
  132. package/dist/mcp/orchestrator.js +46 -43
  133. package/dist/mcp/registry.d.ts +2 -2
  134. package/dist/mcp/registry.js +42 -33
  135. package/dist/mcp/servers/ai-providers/ai-analysis-tools.d.ts +1 -1
  136. package/dist/mcp/servers/ai-providers/ai-analysis-tools.js +204 -65
  137. package/dist/mcp/servers/ai-providers/ai-core-server.js +142 -102
  138. package/dist/mcp/servers/ai-providers/ai-workflow-tools.d.ts +6 -6
  139. package/dist/mcp/servers/ai-providers/ai-workflow-tools.js +197 -142
  140. package/dist/mcp/servers/utilities/utility-server.d.ts +8 -0
  141. package/dist/mcp/servers/utilities/utility-server.js +326 -0
  142. package/dist/mcp/tool-integration.d.ts +67 -0
  143. package/dist/mcp/tool-integration.js +179 -0
  144. package/dist/mcp/unified-registry.d.ts +269 -0
  145. package/dist/mcp/unified-registry.js +1411 -0
  146. package/dist/neurolink.d.ts +68 -6
  147. package/dist/neurolink.js +304 -42
  148. package/dist/providers/agent-enhanced-provider.d.ts +59 -0
  149. package/dist/providers/agent-enhanced-provider.js +242 -0
  150. package/dist/providers/amazonBedrock.d.ts +3 -3
  151. package/dist/providers/amazonBedrock.js +54 -50
  152. package/dist/providers/anthropic.d.ts +2 -2
  153. package/dist/providers/anthropic.js +92 -84
  154. package/dist/providers/azureOpenAI.d.ts +2 -2
  155. package/dist/providers/azureOpenAI.js +97 -86
  156. package/dist/providers/function-calling-provider.d.ts +70 -0
  157. package/dist/providers/function-calling-provider.js +359 -0
  158. package/dist/providers/googleAIStudio.d.ts +10 -5
  159. package/dist/providers/googleAIStudio.js +60 -38
  160. package/dist/providers/googleVertexAI.d.ts +3 -3
  161. package/dist/providers/googleVertexAI.js +96 -86
  162. package/dist/providers/huggingFace.d.ts +3 -3
  163. package/dist/providers/huggingFace.js +70 -63
  164. package/dist/providers/index.d.ts +11 -11
  165. package/dist/providers/index.js +18 -18
  166. package/dist/providers/mcp-provider.d.ts +62 -0
  167. package/dist/providers/mcp-provider.js +183 -0
  168. package/dist/providers/mistralAI.d.ts +3 -3
  169. package/dist/providers/mistralAI.js +42 -36
  170. package/dist/providers/ollama.d.ts +4 -4
  171. package/dist/providers/ollama.js +113 -98
  172. package/dist/providers/openAI.d.ts +7 -3
  173. package/dist/providers/openAI.js +45 -33
  174. package/dist/utils/logger.js +2 -2
  175. package/dist/utils/providerUtils.js +53 -31
  176. package/package.json +175 -161
@@ -0,0 +1,250 @@
1
+ import { z } from "zod";
2
+ import { logger } from "../utils/logger.js";
3
+ /**
4
+ * Model configuration schema for validation
5
+ */
6
+ const ModelConfigSchema = z.object({
7
+ id: z.string(),
8
+ displayName: z.string(),
9
+ capabilities: z.array(z.string()),
10
+ deprecated: z.boolean(),
11
+ pricing: z.object({
12
+ input: z.number(),
13
+ output: z.number(),
14
+ }),
15
+ contextWindow: z.number(),
16
+ releaseDate: z.string(),
17
+ });
18
+ const ModelRegistrySchema = z.object({
19
+ version: z.string(),
20
+ lastUpdated: z.string(),
21
+ models: z.record(z.record(ModelConfigSchema)),
22
+ aliases: z.record(z.string()).optional(),
23
+ defaults: z.record(z.string()).optional(),
24
+ });
25
+ /**
26
+ * Dynamic Model Provider
27
+ * Loads and manages model configurations from external sources
28
+ */
29
+ export class DynamicModelProvider {
30
+ static instance;
31
+ modelRegistry = null;
32
+ lastFetch = 0;
33
+ CACHE_DURATION = 5 * 60 * 1000; // 5 minutes
34
+ constructor() { }
35
+ static getInstance() {
36
+ if (!this.instance) {
37
+ this.instance = new DynamicModelProvider();
38
+ }
39
+ return this.instance;
40
+ }
41
+ /**
42
+ * Initialize the model registry from multiple sources
43
+ */
44
+ async initialize() {
45
+ const sources = [
46
+ process.env.MODEL_CONFIG_URL || "http://localhost:3001/api/v1/models",
47
+ "https://raw.githubusercontent.com/sachinsharma92/neurolink/main/config/models.json",
48
+ "./config/models.json", // Local fallback
49
+ ];
50
+ for (const source of sources) {
51
+ try {
52
+ logger.debug(`[DynamicModelProvider] Attempting to load from: ${source}`);
53
+ const config = await this.loadFromSource(source);
54
+ // Validate the configuration
55
+ const validatedConfig = ModelRegistrySchema.parse(config);
56
+ this.modelRegistry = validatedConfig;
57
+ this.lastFetch = Date.now();
58
+ logger.info(`[DynamicModelProvider] Successfully loaded model registry from: ${source}`, {
59
+ modelCount: this.getTotalModelCount(),
60
+ providerCount: Object.keys(validatedConfig.models).length,
61
+ });
62
+ return; // Success, stop trying other sources
63
+ }
64
+ catch (error) {
65
+ logger.warn(`[DynamicModelProvider] Failed to load from ${source}:`, error);
66
+ continue;
67
+ }
68
+ }
69
+ throw new Error("Failed to load model configuration from any source");
70
+ }
71
+ /**
72
+ * Load configuration from a source (URL or file path)
73
+ */
74
+ async loadFromSource(source) {
75
+ if (source.startsWith("http")) {
76
+ // Load from URL
77
+ const response = await fetch(source, {
78
+ headers: {
79
+ "User-Agent": "NeuroLink/1.0 (+https://github.com/sachinsharma92/neurolink)",
80
+ },
81
+ });
82
+ if (!response.ok) {
83
+ throw new Error(`HTTP ${response.status}: ${response.statusText}`);
84
+ }
85
+ return response.json();
86
+ }
87
+ else {
88
+ // Load from local file
89
+ const fs = await import("fs");
90
+ const path = await import("path");
91
+ const fullPath = path.resolve(source);
92
+ const content = fs.readFileSync(fullPath, "utf8");
93
+ return JSON.parse(content);
94
+ }
95
+ }
96
+ /**
97
+ * Get all available models for a provider
98
+ */
99
+ getModelsForProvider(provider) {
100
+ this.ensureInitialized();
101
+ return this.modelRegistry?.models[provider] || {};
102
+ }
103
+ /**
104
+ * Resolve a model by provider and model hint
105
+ */
106
+ resolveModel(provider, modelHint) {
107
+ this.ensureInitialized();
108
+ const providerModels = this.getModelsForProvider(provider);
109
+ if (!modelHint) {
110
+ // Use default model for provider
111
+ const defaultModel = this.modelRegistry?.defaults?.[provider];
112
+ return defaultModel ? providerModels[defaultModel] : null;
113
+ }
114
+ // Check for exact match
115
+ if (providerModels[modelHint]) {
116
+ return providerModels[modelHint];
117
+ }
118
+ // Check aliases
119
+ const aliasTarget = this.modelRegistry?.aliases?.[modelHint];
120
+ if (aliasTarget) {
121
+ const [aliasProvider, aliasModel] = aliasTarget.split("/");
122
+ return this.resolveModel(aliasProvider, aliasModel);
123
+ }
124
+ // Fuzzy matching (partial string match)
125
+ const fuzzyMatch = Object.keys(providerModels).find((key) => key.toLowerCase().includes(modelHint.toLowerCase()) ||
126
+ modelHint.toLowerCase().includes(key.toLowerCase()));
127
+ return fuzzyMatch ? providerModels[fuzzyMatch] : null;
128
+ }
129
+ /**
130
+ * Search models by capabilities
131
+ */
132
+ searchByCapability(capability, options = {}) {
133
+ this.ensureInitialized();
134
+ const results = [];
135
+ for (const [providerName, models] of Object.entries(this.modelRegistry.models)) {
136
+ if (options.provider && providerName !== options.provider) {
137
+ continue;
138
+ }
139
+ for (const [modelName, modelConfig] of Object.entries(models)) {
140
+ if (options.excludeDeprecated && modelConfig.deprecated) {
141
+ continue;
142
+ }
143
+ if (options.maxPrice && modelConfig.pricing.input > options.maxPrice) {
144
+ continue;
145
+ }
146
+ if (!modelConfig.capabilities.includes(capability)) {
147
+ continue;
148
+ }
149
+ results.push({
150
+ provider: providerName,
151
+ model: modelName,
152
+ config: modelConfig,
153
+ });
154
+ }
155
+ }
156
+ // Sort by price (cheapest first)
157
+ return results.sort((a, b) => a.config.pricing.input - b.config.pricing.input);
158
+ }
159
+ /**
160
+ * Get the best model for a specific use case
161
+ */
162
+ getBestModelFor(useCase) {
163
+ this.ensureInitialized();
164
+ switch (useCase) {
165
+ case "coding":
166
+ return (this.searchByCapability("function-calling", {
167
+ excludeDeprecated: true,
168
+ })[0] || null);
169
+ case "analysis":
170
+ return (this.searchByCapability("analysis", { excludeDeprecated: true })[0] ||
171
+ null);
172
+ case "vision":
173
+ return (this.searchByCapability("vision", { excludeDeprecated: true })[0] ||
174
+ null);
175
+ case "fastest":
176
+ // Return cheapest as proxy for fastest (usually correlates)
177
+ return (this.getAllModels()
178
+ .filter((m) => !m.config.deprecated)
179
+ .sort((a, b) => a.config.pricing.input - b.config.pricing.input)[0] || null);
180
+ case "cheapest":
181
+ return (this.getAllModels()
182
+ .filter((m) => !m.config.deprecated)
183
+ .sort((a, b) => a.config.pricing.input - b.config.pricing.input)[0] || null);
184
+ default:
185
+ return null;
186
+ }
187
+ }
188
+ /**
189
+ * Get all models across all providers
190
+ */
191
+ getAllModels() {
192
+ this.ensureInitialized();
193
+ const results = [];
194
+ for (const [providerName, models] of Object.entries(this.modelRegistry.models)) {
195
+ for (const [modelName, modelConfig] of Object.entries(models)) {
196
+ results.push({
197
+ provider: providerName,
198
+ model: modelName,
199
+ config: modelConfig,
200
+ });
201
+ }
202
+ }
203
+ return results;
204
+ }
205
+ /**
206
+ * Get total number of models
207
+ */
208
+ getTotalModelCount() {
209
+ if (!this.modelRegistry) {
210
+ return 0;
211
+ }
212
+ return Object.values(this.modelRegistry.models).reduce((total, providerModels) => total + Object.keys(providerModels).length, 0);
213
+ }
214
+ /**
215
+ * Check if cache needs refresh
216
+ */
217
+ needsRefresh() {
218
+ return Date.now() - this.lastFetch > this.CACHE_DURATION;
219
+ }
220
+ /**
221
+ * Force refresh the model registry
222
+ */
223
+ async refresh() {
224
+ this.modelRegistry = null;
225
+ await this.initialize();
226
+ }
227
+ /**
228
+ * Ensure the registry is initialized
229
+ */
230
+ ensureInitialized() {
231
+ if (!this.modelRegistry) {
232
+ throw new Error("Model registry not initialized. Call initialize() first.");
233
+ }
234
+ }
235
+ /**
236
+ * Get registry metadata
237
+ */
238
+ getMetadata() {
239
+ if (!this.modelRegistry) {
240
+ return null;
241
+ }
242
+ return {
243
+ version: this.modelRegistry.version,
244
+ lastUpdated: this.modelRegistry.lastUpdated,
245
+ modelCount: this.getTotalModelCount(),
246
+ };
247
+ }
248
+ }
249
+ // Export singleton instance
250
+ export const dynamicModelProvider = DynamicModelProvider.getInstance();
@@ -1,40 +1,47 @@
1
- import type { AIProvider, AIProviderName, SupportedModelName } from './types.js';
1
+ import type { AIProvider, AIProviderName, SupportedModelName } from "./types.js";
2
2
  declare const componentIdentifier = "aiProviderFactory";
3
3
  /**
4
4
  * Factory for creating AI provider instances with centralized configuration
5
5
  */
6
6
  export declare class AIProviderFactory {
7
+ /**
8
+ * Normalize provider name to match dynamic model registry keys
9
+ */
10
+ private static normalizeProviderName;
7
11
  /**
8
12
  * Create a provider instance for the specified provider type
9
13
  * @param providerName - Name of the provider ('vertex', 'bedrock', 'openai')
10
14
  * @param modelName - Optional model name override
15
+ * @param enableMCP - Optional flag to enable MCP integration (default: true)
11
16
  * @returns AIProvider instance
12
17
  */
13
- static createProvider(providerName: string, modelName?: string | null): AIProvider;
18
+ static createProvider(providerName: string, modelName?: string | null, enableMCP?: boolean): Promise<AIProvider>;
14
19
  /**
15
20
  * Create a provider instance with specific provider enum and model
16
21
  * @param provider - Provider enum value
17
22
  * @param model - Specific model enum value
18
23
  * @returns AIProvider instance
19
24
  */
20
- static createProviderWithModel(provider: AIProviderName, model: SupportedModelName): AIProvider;
25
+ static createProviderWithModel(provider: AIProviderName, model: SupportedModelName): Promise<AIProvider>;
21
26
  /**
22
27
  * Create the best available provider automatically
23
28
  * @param requestedProvider - Optional preferred provider
24
29
  * @param modelName - Optional model name override
30
+ * @param enableMCP - Optional flag to enable MCP integration (default: true)
25
31
  * @returns AIProvider instance
26
32
  */
27
- static createBestProvider(requestedProvider?: string, modelName?: string | null): AIProvider;
33
+ static createBestProvider(requestedProvider?: string, modelName?: string | null, enableMCP?: boolean): Promise<AIProvider>;
28
34
  /**
29
35
  * Create primary and fallback provider instances
30
36
  * @param primaryProvider - Primary provider name
31
37
  * @param fallbackProvider - Fallback provider name
32
38
  * @param modelName - Optional model name override
39
+ * @param enableMCP - Optional flag to enable MCP integration (default: true)
33
40
  * @returns Object with primary and fallback providers
34
41
  */
35
- static createProviderWithFallback(primaryProvider: string, fallbackProvider: string, modelName?: string | null): {
42
+ static createProviderWithFallback(primaryProvider: string, fallbackProvider: string, modelName?: string | null, enableMCP?: boolean): Promise<{
36
43
  primary: AIProvider;
37
44
  fallback: AIProvider;
38
- };
45
+ }>;
39
46
  }
40
47
  export { componentIdentifier };
@@ -1,74 +1,184 @@
1
- import { GoogleVertexAI, AmazonBedrock, OpenAI, AnthropicProvider, AzureOpenAIProvider, GoogleAIStudio, HuggingFace, Ollama, MistralAI } from '../providers/index.js';
2
- import { getBestProvider } from '../utils/providerUtils.js';
3
- import { logger } from '../utils/logger.js';
4
- const componentIdentifier = 'aiProviderFactory';
1
+ import { GoogleVertexAI, AmazonBedrock, OpenAI, AnthropicProvider, AzureOpenAIProvider, GoogleAIStudio, HuggingFace, Ollama, MistralAI, } from "../providers/index.js";
2
+ import { getBestProvider } from "../utils/providerUtils.js";
3
+ import { logger } from "../utils/logger.js";
4
+ import { dynamicModelProvider } from "./dynamic-models.js";
5
+ const componentIdentifier = "aiProviderFactory";
5
6
  /**
6
7
  * Factory for creating AI provider instances with centralized configuration
7
8
  */
8
9
  export class AIProviderFactory {
10
+ /**
11
+ * Normalize provider name to match dynamic model registry keys
12
+ */
13
+ static normalizeProviderName(providerName) {
14
+ switch (providerName.toLowerCase()) {
15
+ case "vertex":
16
+ case "google":
17
+ case "gemini":
18
+ return "google";
19
+ case "bedrock":
20
+ case "amazon":
21
+ case "aws":
22
+ return "bedrock";
23
+ case "openai":
24
+ case "gpt":
25
+ return "openai";
26
+ case "anthropic":
27
+ case "claude":
28
+ return "anthropic";
29
+ case "azure":
30
+ case "azure-openai":
31
+ return "openai"; // Azure uses OpenAI models
32
+ case "google-ai":
33
+ case "google-studio":
34
+ return "google";
35
+ case "huggingface":
36
+ case "hugging-face":
37
+ case "hf":
38
+ return "huggingface";
39
+ case "ollama":
40
+ case "local":
41
+ case "local-ollama":
42
+ return "ollama";
43
+ case "mistral":
44
+ case "mistral-ai":
45
+ case "mistralai":
46
+ return "mistral";
47
+ default:
48
+ return providerName.toLowerCase();
49
+ }
50
+ }
9
51
  /**
10
52
  * Create a provider instance for the specified provider type
11
53
  * @param providerName - Name of the provider ('vertex', 'bedrock', 'openai')
12
54
  * @param modelName - Optional model name override
55
+ * @param enableMCP - Optional flag to enable MCP integration (default: true)
13
56
  * @returns AIProvider instance
14
57
  */
15
- static createProvider(providerName, modelName) {
16
- const functionTag = 'AIProviderFactory.createProvider';
58
+ static async createProvider(providerName, modelName, enableMCP = true) {
59
+ const functionTag = "AIProviderFactory.createProvider";
17
60
  logger.debug(`[${functionTag}] Provider creation started`, {
18
61
  providerName,
19
- modelName: modelName || 'default'
62
+ modelName: modelName || "default",
63
+ enableMCP,
20
64
  });
21
65
  try {
66
+ // EMERGENCY FIX: Skip dynamic model provider initialization to prevent hanging
67
+ // TODO: Fix the hanging dynamic model provider.initialize()
68
+ // Initialize dynamic model provider if not already done
69
+ // try {
70
+ // if (dynamicModelProvider.needsRefresh()) {
71
+ // // Add timeout to prevent hanging
72
+ // await Promise.race([
73
+ // dynamicModelProvider.initialize(),
74
+ // new Promise((_, reject) =>
75
+ // setTimeout(() => reject(new Error('Dynamic model provider timeout')), 3000)
76
+ // )
77
+ // ]);
78
+ // }
79
+ // } catch (dynamicError) {
80
+ // logger.warn(`[${functionTag}] Dynamic model provider initialization failed, using fallback`, {
81
+ // error: dynamicError instanceof Error ? dynamicError.message : String(dynamicError),
82
+ // });
83
+ // }
84
+ // Resolve dynamic model if available
85
+ let resolvedModelName = modelName;
86
+ if (!modelName || modelName === "default") {
87
+ try {
88
+ const normalizedProvider = this.normalizeProviderName(providerName);
89
+ const dynamicModel = dynamicModelProvider.resolveModel(normalizedProvider, modelName || undefined);
90
+ if (dynamicModel) {
91
+ resolvedModelName = dynamicModel.id;
92
+ logger.debug(`[${functionTag}] Resolved dynamic model`, {
93
+ provider: normalizedProvider,
94
+ requestedModel: modelName || "default",
95
+ resolvedModel: resolvedModelName,
96
+ displayName: dynamicModel.displayName,
97
+ pricing: dynamicModel.pricing.input,
98
+ });
99
+ }
100
+ }
101
+ catch (resolveError) {
102
+ logger.debug(`[${functionTag}] Dynamic model resolution failed, using fallback`, {
103
+ error: resolveError instanceof Error
104
+ ? resolveError.message
105
+ : String(resolveError),
106
+ });
107
+ }
108
+ }
22
109
  let provider;
23
110
  switch (providerName.toLowerCase()) {
24
- case 'vertex':
25
- case 'google':
26
- case 'gemini':
27
- provider = new GoogleVertexAI(modelName);
111
+ case "vertex":
112
+ case "google":
113
+ case "gemini":
114
+ provider = new GoogleVertexAI(resolvedModelName === "default" ? null : resolvedModelName);
28
115
  break;
29
- case 'bedrock':
30
- case 'amazon':
31
- case 'aws':
32
- provider = new AmazonBedrock(modelName);
116
+ case "bedrock":
117
+ case "amazon":
118
+ case "aws":
119
+ provider = new AmazonBedrock(resolvedModelName === "default" ? null : resolvedModelName);
33
120
  break;
34
- case 'openai':
35
- case 'gpt':
36
- provider = new OpenAI(modelName);
121
+ case "openai":
122
+ case "gpt":
123
+ provider = new OpenAI(resolvedModelName === "default" ? null : resolvedModelName);
37
124
  break;
38
- case 'anthropic':
39
- case 'claude':
125
+ case "anthropic":
126
+ case "claude":
40
127
  provider = new AnthropicProvider();
41
128
  break;
42
- case 'azure':
43
- case 'azure-openai':
129
+ case "azure":
130
+ case "azure-openai":
44
131
  provider = new AzureOpenAIProvider();
45
132
  break;
46
- case 'google-ai':
47
- case 'google-studio':
48
- provider = new GoogleAIStudio(modelName);
133
+ case "google-ai":
134
+ case "google-studio":
135
+ provider = new GoogleAIStudio(resolvedModelName === "default" ? null : resolvedModelName);
49
136
  break;
50
- case 'huggingface':
51
- case 'hugging-face':
52
- case 'hf':
53
- provider = new HuggingFace(modelName);
137
+ case "huggingface":
138
+ case "hugging-face":
139
+ case "hf":
140
+ provider = new HuggingFace(resolvedModelName === "default" ? null : resolvedModelName);
54
141
  break;
55
- case 'ollama':
56
- case 'local':
57
- case 'local-ollama':
58
- provider = new Ollama(modelName || undefined);
142
+ case "ollama":
143
+ case "local":
144
+ case "local-ollama":
145
+ provider = new Ollama(resolvedModelName === "default"
146
+ ? undefined
147
+ : resolvedModelName || undefined);
59
148
  break;
60
- case 'mistral':
61
- case 'mistral-ai':
62
- case 'mistralai':
63
- provider = new MistralAI(modelName);
149
+ case "mistral":
150
+ case "mistral-ai":
151
+ case "mistralai":
152
+ provider = new MistralAI(resolvedModelName === "default" ? null : resolvedModelName);
64
153
  break;
65
154
  default:
66
155
  throw new Error(`Unknown provider: ${providerName}. Supported providers: vertex, bedrock, openai, anthropic, azure, google-ai, huggingface, ollama, mistral`);
67
156
  }
157
+ // Wrap with MCP if enabled
158
+ if (enableMCP) {
159
+ try {
160
+ // TEMPORARY: Disable MCP wrapping to test for hanging issues
161
+ logger.debug(`[${functionTag}] MCP wrapping temporarily disabled for debugging`);
162
+ // const { createMCPAwareProviderV3 } = await import("../providers/function-calling-provider.js");
163
+ // provider = createMCPAwareProviderV3(provider, {
164
+ // providerName,
165
+ // modelName: resolvedModelName || undefined,
166
+ // enableMCP: true,
167
+ // enableFunctionCalling: true,
168
+ // });
169
+ // logger.debug(`[${functionTag}] Provider wrapped with MCP support`);
170
+ }
171
+ catch (mcpError) {
172
+ logger.warn(`[${functionTag}] Failed to wrap with MCP, using base provider`, {
173
+ error: mcpError instanceof Error ? mcpError.message : String(mcpError),
174
+ });
175
+ }
176
+ }
68
177
  logger.debug(`[${functionTag}] Provider creation succeeded`, {
69
178
  providerName,
70
- modelName: modelName || 'default',
71
- providerType: provider.constructor.name
179
+ modelName: modelName || "default",
180
+ providerType: provider.constructor.name,
181
+ mcpEnabled: enableMCP,
72
182
  });
73
183
  return provider;
74
184
  }
@@ -76,8 +186,8 @@ export class AIProviderFactory {
76
186
  const errorMessage = error instanceof Error ? error.message : String(error);
77
187
  logger.debug(`[${functionTag}] Provider creation failed`, {
78
188
  providerName,
79
- modelName: modelName || 'default',
80
- error: errorMessage
189
+ modelName: modelName || "default",
190
+ error: errorMessage,
81
191
  });
82
192
  throw error;
83
193
  }
@@ -88,18 +198,18 @@ export class AIProviderFactory {
88
198
  * @param model - Specific model enum value
89
199
  * @returns AIProvider instance
90
200
  */
91
- static createProviderWithModel(provider, model) {
92
- const functionTag = 'AIProviderFactory.createProviderWithModel';
201
+ static async createProviderWithModel(provider, model) {
202
+ const functionTag = "AIProviderFactory.createProviderWithModel";
93
203
  logger.debug(`[${functionTag}] Provider model creation started`, {
94
204
  provider,
95
- model
205
+ model,
96
206
  });
97
207
  try {
98
- const providerInstance = this.createProvider(provider, model);
208
+ const providerInstance = await this.createProvider(provider, model);
99
209
  logger.debug(`[${functionTag}] Provider model creation succeeded`, {
100
210
  provider,
101
211
  model,
102
- providerType: providerInstance.constructor.name
212
+ providerType: providerInstance.constructor.name,
103
213
  });
104
214
  return providerInstance;
105
215
  }
@@ -108,7 +218,7 @@ export class AIProviderFactory {
108
218
  logger.debug(`[${functionTag}] Provider model creation failed`, {
109
219
  provider,
110
220
  model,
111
- error: errorMessage
221
+ error: errorMessage,
112
222
  });
113
223
  throw error;
114
224
  }
@@ -117,24 +227,26 @@ export class AIProviderFactory {
117
227
  * Create the best available provider automatically
118
228
  * @param requestedProvider - Optional preferred provider
119
229
  * @param modelName - Optional model name override
230
+ * @param enableMCP - Optional flag to enable MCP integration (default: true)
120
231
  * @returns AIProvider instance
121
232
  */
122
- static createBestProvider(requestedProvider, modelName) {
123
- const functionTag = 'AIProviderFactory.createBestProvider';
233
+ static async createBestProvider(requestedProvider, modelName, enableMCP = true) {
234
+ const functionTag = "AIProviderFactory.createBestProvider";
124
235
  try {
125
236
  const bestProvider = getBestProvider(requestedProvider);
126
237
  logger.debug(`[${functionTag}] Best provider selected`, {
127
- requestedProvider: requestedProvider || 'auto',
238
+ requestedProvider: requestedProvider || "auto",
128
239
  selectedProvider: bestProvider,
129
- modelName: modelName || 'default'
240
+ modelName: modelName || "default",
241
+ enableMCP,
130
242
  });
131
- return this.createProvider(bestProvider, modelName);
243
+ return await this.createProvider(bestProvider, modelName, enableMCP);
132
244
  }
133
245
  catch (error) {
134
246
  const errorMessage = error instanceof Error ? error.message : String(error);
135
247
  logger.debug(`[${functionTag}] Best provider selection failed`, {
136
- requestedProvider: requestedProvider || 'auto',
137
- error: errorMessage
248
+ requestedProvider: requestedProvider || "auto",
249
+ error: errorMessage,
138
250
  });
139
251
  throw error;
140
252
  }
@@ -144,22 +256,25 @@ export class AIProviderFactory {
144
256
  * @param primaryProvider - Primary provider name
145
257
  * @param fallbackProvider - Fallback provider name
146
258
  * @param modelName - Optional model name override
259
+ * @param enableMCP - Optional flag to enable MCP integration (default: true)
147
260
  * @returns Object with primary and fallback providers
148
261
  */
149
- static createProviderWithFallback(primaryProvider, fallbackProvider, modelName) {
150
- const functionTag = 'AIProviderFactory.createProviderWithFallback';
262
+ static async createProviderWithFallback(primaryProvider, fallbackProvider, modelName, enableMCP = true) {
263
+ const functionTag = "AIProviderFactory.createProviderWithFallback";
151
264
  logger.debug(`[${functionTag}] Fallback provider setup started`, {
152
265
  primaryProvider,
153
266
  fallbackProvider,
154
- modelName: modelName || 'default'
267
+ modelName: modelName || "default",
268
+ enableMCP,
155
269
  });
156
270
  try {
157
- const primary = this.createProvider(primaryProvider, modelName);
158
- const fallback = this.createProvider(fallbackProvider, modelName);
271
+ const primary = await this.createProvider(primaryProvider, modelName, enableMCP);
272
+ const fallback = await this.createProvider(fallbackProvider, modelName, enableMCP);
159
273
  logger.debug(`[${functionTag}] Fallback provider setup succeeded`, {
160
274
  primaryProvider,
161
275
  fallbackProvider,
162
- modelName: modelName || 'default'
276
+ modelName: modelName || "default",
277
+ enableMCP,
163
278
  });
164
279
  return { primary, fallback };
165
280
  }
@@ -168,7 +283,7 @@ export class AIProviderFactory {
168
283
  logger.debug(`[${functionTag}] Fallback provider setup failed`, {
169
284
  primaryProvider,
170
285
  fallbackProvider,
171
- error: errorMessage
286
+ error: errorMessage,
172
287
  });
173
288
  throw error;
174
289
  }
@@ -1,5 +1,5 @@
1
- import type { ZodType, ZodTypeDef } from 'zod';
2
- import type { StreamTextResult, ToolSet, Schema, GenerateTextResult } from 'ai';
1
+ import type { ZodType, ZodTypeDef } from "zod";
2
+ import type { StreamTextResult, ToolSet, Schema, GenerateTextResult, Tool } from "ai";
3
3
  /**
4
4
  * Supported AI Provider Names
5
5
  */
@@ -79,6 +79,7 @@ export interface TextGenerationOptions {
79
79
  maxTokens?: number;
80
80
  systemPrompt?: string;
81
81
  schema?: ZodType<unknown, ZodTypeDef, unknown> | Schema<unknown>;
82
+ tools?: Record<string, Tool>;
82
83
  }
83
84
  /**
84
85
  * Stream text options interface
@@ -90,6 +91,7 @@ export interface StreamTextOptions {
90
91
  maxTokens?: number;
91
92
  systemPrompt?: string;
92
93
  schema?: ZodType<unknown, ZodTypeDef, unknown> | Schema<unknown>;
94
+ tools?: Record<string, Tool>;
93
95
  }
94
96
  /**
95
97
  * AI Provider interface with flexible parameter support