@juspay/neurolink 9.51.3 → 9.52.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 +12 -0
- package/dist/artifacts/artifactStore.d.ts +56 -0
- package/dist/artifacts/artifactStore.js +143 -0
- package/dist/browser/neurolink.min.js +311 -298
- package/dist/cli/commands/mcp.d.ts +6 -0
- package/dist/cli/commands/mcp.js +128 -86
- package/dist/cli/loop/optionsSchema.d.ts +1 -1
- package/dist/core/factory.d.ts +2 -2
- package/dist/core/factory.js +4 -4
- package/dist/core/redisConversationMemoryManager.js +20 -0
- package/dist/factories/providerFactory.d.ts +4 -4
- package/dist/factories/providerFactory.js +20 -7
- package/dist/factories/providerRegistry.d.ts +5 -0
- package/dist/factories/providerRegistry.js +45 -26
- package/dist/lib/artifacts/artifactStore.d.ts +56 -0
- package/dist/lib/artifacts/artifactStore.js +144 -0
- package/dist/lib/core/factory.d.ts +2 -2
- package/dist/lib/core/factory.js +4 -4
- package/dist/lib/core/redisConversationMemoryManager.js +20 -0
- package/dist/lib/factories/providerFactory.d.ts +4 -4
- package/dist/lib/factories/providerFactory.js +20 -7
- package/dist/lib/factories/providerRegistry.d.ts +5 -0
- package/dist/lib/factories/providerRegistry.js +45 -26
- package/dist/lib/mcp/externalServerManager.d.ts +6 -0
- package/dist/lib/mcp/externalServerManager.js +9 -0
- package/dist/lib/mcp/mcpOutputNormalizer.d.ts +49 -0
- package/dist/lib/mcp/mcpOutputNormalizer.js +182 -0
- package/dist/lib/mcp/toolDiscoveryService.d.ts +10 -0
- package/dist/lib/mcp/toolDiscoveryService.js +32 -1
- package/dist/lib/memory/memoryRetrievalTools.d.ts +64 -9
- package/dist/lib/memory/memoryRetrievalTools.js +77 -9
- package/dist/lib/neurolink.d.ts +23 -0
- package/dist/lib/neurolink.js +128 -86
- package/dist/lib/providers/amazonBedrock.d.ts +6 -1
- package/dist/lib/providers/amazonBedrock.js +14 -2
- package/dist/lib/providers/amazonSagemaker.d.ts +7 -1
- package/dist/lib/providers/amazonSagemaker.js +21 -3
- package/dist/lib/providers/anthropic.d.ts +4 -1
- package/dist/lib/providers/anthropic.js +18 -5
- package/dist/lib/providers/azureOpenai.d.ts +2 -1
- package/dist/lib/providers/azureOpenai.js +10 -5
- package/dist/lib/providers/googleAiStudio.d.ts +4 -1
- package/dist/lib/providers/googleAiStudio.js +6 -7
- package/dist/lib/providers/googleVertex.d.ts +3 -1
- package/dist/lib/providers/googleVertex.js +96 -17
- package/dist/lib/providers/huggingFace.d.ts +2 -1
- package/dist/lib/providers/huggingFace.js +4 -4
- package/dist/lib/providers/litellm.d.ts +5 -1
- package/dist/lib/providers/litellm.js +14 -9
- package/dist/lib/providers/mistral.d.ts +2 -1
- package/dist/lib/providers/mistral.js +2 -2
- package/dist/lib/providers/ollama.d.ts +3 -1
- package/dist/lib/providers/ollama.js +2 -2
- package/dist/lib/providers/openAI.d.ts +5 -1
- package/dist/lib/providers/openAI.js +15 -5
- package/dist/lib/providers/openRouter.d.ts +5 -1
- package/dist/lib/providers/openRouter.js +17 -5
- package/dist/lib/providers/openaiCompatible.d.ts +4 -1
- package/dist/lib/providers/openaiCompatible.js +15 -3
- package/dist/lib/session/globalSessionState.js +44 -1
- package/dist/lib/types/artifactTypes.d.ts +63 -0
- package/dist/lib/types/artifactTypes.js +11 -0
- package/dist/lib/types/configTypes.d.ts +39 -0
- package/dist/lib/types/conversation.d.ts +7 -0
- package/dist/lib/types/generateTypes.d.ts +13 -0
- package/dist/lib/types/index.d.ts +2 -0
- package/dist/lib/types/mcpOutputTypes.d.ts +40 -0
- package/dist/lib/types/mcpOutputTypes.js +9 -0
- package/dist/lib/types/providers.d.ts +75 -0
- package/dist/lib/types/streamTypes.d.ts +7 -1
- package/dist/mcp/externalServerManager.d.ts +6 -0
- package/dist/mcp/externalServerManager.js +9 -0
- package/dist/mcp/mcpOutputNormalizer.d.ts +49 -0
- package/dist/mcp/mcpOutputNormalizer.js +181 -0
- package/dist/mcp/toolDiscoveryService.d.ts +10 -0
- package/dist/mcp/toolDiscoveryService.js +32 -1
- package/dist/memory/memoryRetrievalTools.d.ts +64 -9
- package/dist/memory/memoryRetrievalTools.js +77 -9
- package/dist/neurolink.d.ts +23 -0
- package/dist/neurolink.js +128 -86
- package/dist/providers/amazonBedrock.d.ts +6 -1
- package/dist/providers/amazonBedrock.js +14 -2
- package/dist/providers/amazonSagemaker.d.ts +7 -1
- package/dist/providers/amazonSagemaker.js +21 -3
- package/dist/providers/anthropic.d.ts +4 -1
- package/dist/providers/anthropic.js +18 -5
- package/dist/providers/azureOpenai.d.ts +2 -1
- package/dist/providers/azureOpenai.js +10 -5
- package/dist/providers/googleAiStudio.d.ts +4 -1
- package/dist/providers/googleAiStudio.js +6 -7
- package/dist/providers/googleVertex.d.ts +3 -1
- package/dist/providers/googleVertex.js +96 -17
- package/dist/providers/huggingFace.d.ts +2 -1
- package/dist/providers/huggingFace.js +4 -4
- package/dist/providers/litellm.d.ts +5 -1
- package/dist/providers/litellm.js +14 -9
- package/dist/providers/mistral.d.ts +2 -1
- package/dist/providers/mistral.js +2 -2
- package/dist/providers/ollama.d.ts +3 -1
- package/dist/providers/ollama.js +2 -2
- package/dist/providers/openAI.d.ts +5 -1
- package/dist/providers/openAI.js +15 -5
- package/dist/providers/openRouter.d.ts +5 -1
- package/dist/providers/openRouter.js +17 -5
- package/dist/providers/openaiCompatible.d.ts +4 -1
- package/dist/providers/openaiCompatible.js +15 -3
- package/dist/session/globalSessionState.js +44 -1
- package/dist/types/artifactTypes.d.ts +63 -0
- package/dist/types/artifactTypes.js +10 -0
- package/dist/types/configTypes.d.ts +39 -0
- package/dist/types/conversation.d.ts +7 -0
- package/dist/types/generateTypes.d.ts +13 -0
- package/dist/types/index.d.ts +2 -0
- package/dist/types/mcpOutputTypes.d.ts +40 -0
- package/dist/types/mcpOutputTypes.js +8 -0
- package/dist/types/providers.d.ts +75 -0
- package/dist/types/streamTypes.d.ts +7 -1
- package/package.json +3 -2
package/dist/lib/neurolink.js
CHANGED
|
@@ -40,6 +40,8 @@ import { ToolCallBatcher } from "./mcp/batching/index.js";
|
|
|
40
40
|
import { ToolResultCache } from "./mcp/caching/index.js";
|
|
41
41
|
import { EnhancedToolDiscovery } from "./mcp/enhancedToolDiscovery.js";
|
|
42
42
|
import { ExternalServerManager } from "./mcp/externalServerManager.js";
|
|
43
|
+
import { McpOutputNormalizer, DEFAULT_MAX_MCP_OUTPUT_BYTES, DEFAULT_WARN_MCP_OUTPUT_BYTES, } from "./mcp/mcpOutputNormalizer.js";
|
|
44
|
+
import { LocalTempArtifactStore } from "./artifacts/artifactStore.js";
|
|
43
45
|
import { ToolRouter } from "./mcp/routing/index.js";
|
|
44
46
|
// Import direct tools server for automatic registration
|
|
45
47
|
import { directToolsServer } from "./mcp/servers/agent/directToolsServer.js";
|
|
@@ -216,6 +218,8 @@ export class NeuroLink {
|
|
|
216
218
|
mcpToolBatcher;
|
|
217
219
|
mcpEnhancedDiscovery;
|
|
218
220
|
mcpToolMiddlewares = [];
|
|
221
|
+
/** Artifact store for externalized MCP tool outputs (set when strategy=externalize). */
|
|
222
|
+
mcpArtifactStore;
|
|
219
223
|
_disableToolCacheForCurrentRequest = false;
|
|
220
224
|
mcpEnhancementsConfig;
|
|
221
225
|
// Enhanced error handling support
|
|
@@ -255,6 +259,60 @@ export class NeuroLink {
|
|
|
255
259
|
authProvider;
|
|
256
260
|
pendingAuthConfig;
|
|
257
261
|
authInitPromise;
|
|
262
|
+
// Per-provider credential overrides (instance-level default)
|
|
263
|
+
credentials;
|
|
264
|
+
/**
|
|
265
|
+
* Merge instance-level credentials with per-call credentials.
|
|
266
|
+
*
|
|
267
|
+
* Semantics: **deep merge at the provider level.** For each provider key
|
|
268
|
+
* present in both `this.credentials` and `callCredentials`, the per-call
|
|
269
|
+
* fields are merged ON TOP of the instance-level fields, so fields not
|
|
270
|
+
* mentioned in the per-call slice are preserved.
|
|
271
|
+
*
|
|
272
|
+
* Example:
|
|
273
|
+
* ```
|
|
274
|
+
* instance: { openai: { apiKey: "key1", baseURL: "url1" } }
|
|
275
|
+
* per-call: { openai: { apiKey: "key2" } }
|
|
276
|
+
* merged: { openai: { apiKey: "key2", baseURL: "url1" } } // baseURL preserved
|
|
277
|
+
* ```
|
|
278
|
+
*
|
|
279
|
+
* Providers present only in one source are carried through unchanged.
|
|
280
|
+
* Unrelated providers (not overridden in callCredentials) are carried through
|
|
281
|
+
* from instance credentials unchanged.
|
|
282
|
+
*/
|
|
283
|
+
resolveCredentials(callCredentials) {
|
|
284
|
+
if (!this.credentials && !callCredentials) {
|
|
285
|
+
return undefined;
|
|
286
|
+
}
|
|
287
|
+
if (!this.credentials) {
|
|
288
|
+
return callCredentials;
|
|
289
|
+
}
|
|
290
|
+
if (!callCredentials) {
|
|
291
|
+
return this.credentials;
|
|
292
|
+
}
|
|
293
|
+
// Per-provider deep merge: for each provider key in the per-call
|
|
294
|
+
// override, merge its fields on top of the instance-level slice so
|
|
295
|
+
// individual fields (e.g. baseURL) are preserved when only apiKey
|
|
296
|
+
// is overridden per-call.
|
|
297
|
+
const merged = { ...this.credentials };
|
|
298
|
+
for (const key of Object.keys(callCredentials)) {
|
|
299
|
+
const instanceSlice = this.credentials[key];
|
|
300
|
+
const callSlice = callCredentials[key];
|
|
301
|
+
if (instanceSlice &&
|
|
302
|
+
callSlice &&
|
|
303
|
+
typeof instanceSlice === "object" &&
|
|
304
|
+
typeof callSlice === "object") {
|
|
305
|
+
merged[key] = {
|
|
306
|
+
...instanceSlice,
|
|
307
|
+
...callSlice,
|
|
308
|
+
};
|
|
309
|
+
}
|
|
310
|
+
else {
|
|
311
|
+
merged[key] = callSlice ?? instanceSlice;
|
|
312
|
+
}
|
|
313
|
+
}
|
|
314
|
+
return merged;
|
|
315
|
+
}
|
|
258
316
|
// HITL (Human-in-the-Loop) support
|
|
259
317
|
hitlManager;
|
|
260
318
|
// Accumulated cost in USD across all generate() calls on this instance
|
|
@@ -595,6 +653,10 @@ export class NeuroLink {
|
|
|
595
653
|
if (config?.auth) {
|
|
596
654
|
this.pendingAuthConfig = config.auth;
|
|
597
655
|
}
|
|
656
|
+
// Store per-provider credential overrides
|
|
657
|
+
if (config?.credentials) {
|
|
658
|
+
this.credentials = config.credentials;
|
|
659
|
+
}
|
|
598
660
|
// Store task config for lazy initialization
|
|
599
661
|
this._taskManagerConfig = config?.tasks;
|
|
600
662
|
// Eagerly create TaskManager and register tools if config is provided
|
|
@@ -818,6 +880,25 @@ export class NeuroLink {
|
|
|
818
880
|
});
|
|
819
881
|
}
|
|
820
882
|
// ToolRouter — lazy-initialized when 2+ external servers exist (see addExternalMCPServer)
|
|
883
|
+
// McpOutputNormalizer — active when mcp.outputLimits is configured
|
|
884
|
+
if (mcpConfig?.outputLimits) {
|
|
885
|
+
const strategy = mcpConfig.outputLimits.strategy ?? "externalize";
|
|
886
|
+
const maxBytes = mcpConfig.outputLimits.maxBytes ?? DEFAULT_MAX_MCP_OUTPUT_BYTES;
|
|
887
|
+
const warnBytes = mcpConfig.outputLimits.warnBytes ?? DEFAULT_WARN_MCP_OUTPUT_BYTES;
|
|
888
|
+
let artifactStore;
|
|
889
|
+
if (strategy === "externalize") {
|
|
890
|
+
artifactStore = new LocalTempArtifactStore();
|
|
891
|
+
this.mcpArtifactStore = artifactStore;
|
|
892
|
+
logger.debug("[NeuroLink] MCP artifact store initialized (local-temp)");
|
|
893
|
+
}
|
|
894
|
+
const normalizer = new McpOutputNormalizer({ strategy, maxBytes, warnBytes }, artifactStore);
|
|
895
|
+
this.externalServerManager.setOutputNormalizer(normalizer);
|
|
896
|
+
logger.debug("[NeuroLink] MCP output normalizer initialized", {
|
|
897
|
+
strategy,
|
|
898
|
+
maxBytes,
|
|
899
|
+
warnBytes,
|
|
900
|
+
});
|
|
901
|
+
}
|
|
821
902
|
}
|
|
822
903
|
/**
|
|
823
904
|
* Register file reference tools with the MCP tool registry.
|
|
@@ -937,90 +1018,46 @@ export class NeuroLink {
|
|
|
937
1018
|
"redis" in memConfig &&
|
|
938
1019
|
!!memConfig.redis) ||
|
|
939
1020
|
process.env.STORAGE_TYPE === "redis";
|
|
940
|
-
|
|
941
|
-
|
|
1021
|
+
const hasArtifactStore = !!this.mcpArtifactStore;
|
|
1022
|
+
// Register when Redis is configured OR when an artifact store exists.
|
|
1023
|
+
// Artifact store alone is sufficient for the artifactId retrieval path —
|
|
1024
|
+
// session history retrieval just returns a clear error when Redis is absent.
|
|
1025
|
+
if ((!memConfig?.enabled || !hasRedisConfig) && !hasArtifactStore) {
|
|
1026
|
+
logger.debug("[NeuroLink] Skipping memory retrieval tools — requires Redis conversation memory or an artifact store");
|
|
942
1027
|
return;
|
|
943
1028
|
}
|
|
944
|
-
|
|
945
|
-
|
|
946
|
-
|
|
947
|
-
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
const errorMsg = hasError
|
|
974
|
-
? result.error
|
|
975
|
-
: undefined;
|
|
976
|
-
return {
|
|
977
|
-
success: !hasError,
|
|
978
|
-
data: result,
|
|
979
|
-
...(errorMsg ? { error: errorMsg } : {}),
|
|
980
|
-
metadata: {
|
|
981
|
-
toolName: "retrieve_context",
|
|
982
|
-
serverId: "direct",
|
|
983
|
-
executionTime: 0,
|
|
984
|
-
},
|
|
985
|
-
};
|
|
986
|
-
},
|
|
1029
|
+
// Extract the canonical tool definition (schema + description) from the
|
|
1030
|
+
// memoryRetrievalTools factory. We pass undefined as the memoryManager here
|
|
1031
|
+
// because we only need the Zod inputSchema and description at registration
|
|
1032
|
+
// time — the actual manager is resolved lazily at execution time.
|
|
1033
|
+
const canonicalTools = createMemoryRetrievalTools(undefined, this.mcpArtifactStore);
|
|
1034
|
+
const retrieveContextDef = canonicalTools.retrieve_context;
|
|
1035
|
+
// Register via this.registerTool() so the tool ends up in the "user-defined"
|
|
1036
|
+
// category inside toolRegistry. getCustomTools() returns that category, which
|
|
1037
|
+
// is what ToolsManager reads to build the tool schema sent to the LLM.
|
|
1038
|
+
// (Tools registered via toolRegistry.registerTool() directly land in the
|
|
1039
|
+
// "built-in" category and are never included in the LLM's tool schema.)
|
|
1040
|
+
this.registerTool("retrieve_context", {
|
|
1041
|
+
name: "retrieve_context",
|
|
1042
|
+
description: retrieveContextDef.description ?? "Retrieve context or artifacts",
|
|
1043
|
+
// Pass the Zod schema so ToolsManager gives the LLM full parameter types.
|
|
1044
|
+
// registerTool() detects isZodSchema on inputSchema and preserves it.
|
|
1045
|
+
inputSchema: retrieveContextDef
|
|
1046
|
+
.inputSchema,
|
|
1047
|
+
execute: async (params) => {
|
|
1048
|
+
// Lazy: conversationMemory is initialized on the first generate() call.
|
|
1049
|
+
// When only an artifact store is present (no Redis), memoryManager is
|
|
1050
|
+
// undefined — createMemoryRetrievalTools handles that via an explicit guard.
|
|
1051
|
+
const memoryManager = this.conversationMemory;
|
|
1052
|
+
const tools = createMemoryRetrievalTools(memoryManager, this.mcpArtifactStore);
|
|
1053
|
+
// Return the result directly so the LLM receives clean output instead
|
|
1054
|
+
// of a nested { success, data, metadata } wrapper.
|
|
1055
|
+
// Bounded by TOOL_TIMEOUTS.EXECUTION_DEFAULT_MS so a stalled Redis or
|
|
1056
|
+
// filesystem backend never hangs the tool call indefinitely.
|
|
1057
|
+
return await withTimeout(tools.retrieve_context.execute(params, { toolCallId: "memory-retrieval", messages: [] }), TOOL_TIMEOUTS.EXECUTION_DEFAULT_MS, ErrorFactory.toolTimeout("retrieve_context", TOOL_TIMEOUTS.EXECUTION_DEFAULT_MS));
|
|
987
1058
|
},
|
|
988
|
-
};
|
|
989
|
-
const registrations = Object.entries(tools).map(async ([toolName, toolDef]) => {
|
|
990
|
-
const toolId = `direct.${toolName}`;
|
|
991
|
-
const toolInfo = {
|
|
992
|
-
name: toolName,
|
|
993
|
-
description: toolDef.description,
|
|
994
|
-
inputSchema: {},
|
|
995
|
-
serverId: "direct",
|
|
996
|
-
category: "built-in",
|
|
997
|
-
};
|
|
998
|
-
await this.toolRegistry.registerTool(toolId, toolInfo, {
|
|
999
|
-
execute: async (params) => {
|
|
1000
|
-
try {
|
|
1001
|
-
return await toolDef.execute(params);
|
|
1002
|
-
}
|
|
1003
|
-
catch (error) {
|
|
1004
|
-
// Known limitation: this non-throwing error path returns
|
|
1005
|
-
// { success: false } without recording errorCategories in
|
|
1006
|
-
// toolExecutionMetrics. These are internal memory-tool failures
|
|
1007
|
-
// (low frequency), so the risk of metric gaps is minimal.
|
|
1008
|
-
// A full fix would require access to the metrics map here,
|
|
1009
|
-
// which is not available in the registration closure.
|
|
1010
|
-
return {
|
|
1011
|
-
success: false,
|
|
1012
|
-
error: error instanceof Error ? error.message : String(error),
|
|
1013
|
-
metadata: { toolName, serverId: "direct", executionTime: 0 },
|
|
1014
|
-
};
|
|
1015
|
-
}
|
|
1016
|
-
},
|
|
1017
|
-
description: toolDef.description,
|
|
1018
|
-
inputSchema: {},
|
|
1019
|
-
});
|
|
1020
|
-
});
|
|
1021
|
-
void Promise.all(registrations).then(() => {
|
|
1022
|
-
logger.info("[NeuroLink] Memory retrieval tools registered");
|
|
1023
1059
|
});
|
|
1060
|
+
logger.info("[NeuroLink] Memory retrieval tools registered");
|
|
1024
1061
|
}
|
|
1025
1062
|
/** Format memory context for prompt inclusion */
|
|
1026
1063
|
formatMemoryContext(memoryContext, currentInput) {
|
|
@@ -2143,6 +2180,7 @@ Current user's request: ${currentInput}`;
|
|
|
2143
2180
|
}
|
|
2144
2181
|
}
|
|
2145
2182
|
logger.debug("[NeuroLink] Graceful shutdown completed");
|
|
2183
|
+
this.credentials = undefined;
|
|
2146
2184
|
}
|
|
2147
2185
|
catch (error) {
|
|
2148
2186
|
logger.error("[NeuroLink] Shutdown failed:", error);
|
|
@@ -2671,6 +2709,7 @@ Current user's request: ${currentInput}`;
|
|
|
2671
2709
|
skipToolPromptInjection: options.skipToolPromptInjection,
|
|
2672
2710
|
middleware: options.middleware,
|
|
2673
2711
|
conversationMessages: options.conversationMessages,
|
|
2712
|
+
credentials: options.credentials,
|
|
2674
2713
|
};
|
|
2675
2714
|
const extraContext = options;
|
|
2676
2715
|
if (extraContext.sessionId || extraContext.userId) {
|
|
@@ -2805,7 +2844,7 @@ Current user's request: ${currentInput}`;
|
|
|
2805
2844
|
const { extractPPTContext, getEffectivePPTProvider } = await import("./features/ppt/utils.js");
|
|
2806
2845
|
// Get provider instance for content planning
|
|
2807
2846
|
const requestedProvider = (options.provider || "vertex");
|
|
2808
|
-
const provider = await AIProviderFactory.createProvider(requestedProvider, options.model, true, this);
|
|
2847
|
+
const provider = await AIProviderFactory.createProvider(requestedProvider, options.model, true, this, undefined, this.resolveCredentials(options.credentials));
|
|
2809
2848
|
// Resolve effective PPT provider (may auto-select if current is not PPT-compatible)
|
|
2810
2849
|
const effectiveProvider = await getEffectivePPTProvider(provider, requestedProvider, options.model || "default", this);
|
|
2811
2850
|
// Extract PPT context from options
|
|
@@ -3839,7 +3878,7 @@ Current user's request: ${currentInput}`;
|
|
|
3839
3878
|
}
|
|
3840
3879
|
async generateWithMCPProvider(context) {
|
|
3841
3880
|
const { options, requestId, functionTag, tryMCPStartTime, providerName, availableTools, enhancedSystemPrompt, conversationMessages, } = context;
|
|
3842
|
-
const provider = await AIProviderFactory.createProvider(providerName, options.model, !options.disableTools, this, options.region);
|
|
3881
|
+
const provider = await AIProviderFactory.createProvider(providerName, options.model, !options.disableTools, this, options.region, this.resolveCredentials(options.credentials));
|
|
3843
3882
|
provider.setTraceContext(this._metricsTraceContext);
|
|
3844
3883
|
this.emitter.emit("connected");
|
|
3845
3884
|
this.emitter.emit("message", `${providerName} provider initialized successfully`);
|
|
@@ -4035,7 +4074,8 @@ Current user's request: ${currentInput}`;
|
|
|
4035
4074
|
}
|
|
4036
4075
|
const provider = await AIProviderFactory.createProvider(providerName, options.model, !options.disableTools, // Pass disableTools as inverse of enableMCP
|
|
4037
4076
|
this, // Pass SDK instance
|
|
4038
|
-
options.region
|
|
4077
|
+
options.region, // Pass region parameter
|
|
4078
|
+
this.resolveCredentials(options.credentials));
|
|
4039
4079
|
// Propagate trace context for parent-child span hierarchy
|
|
4040
4080
|
provider.setTraceContext(this._metricsTraceContext);
|
|
4041
4081
|
// ADD: Emit connection events for successful provider creation (Bedrock-compatible)
|
|
@@ -4783,7 +4823,7 @@ Current user's request: ${currentInput}`;
|
|
|
4783
4823
|
reason: errorMsg,
|
|
4784
4824
|
});
|
|
4785
4825
|
try {
|
|
4786
|
-
const fallbackProvider = await AIProviderFactory.createProvider(fallbackRoute.provider, fallbackRoute.model);
|
|
4826
|
+
const fallbackProvider = await AIProviderFactory.createProvider(fallbackRoute.provider, fallbackRoute.model, true, undefined, undefined, this.resolveCredentials(enhancedOptions.credentials));
|
|
4787
4827
|
// Ensure fallback provider can execute tools
|
|
4788
4828
|
fallbackProvider.setupToolExecutor({
|
|
4789
4829
|
customTools: this.getCustomTools(),
|
|
@@ -4946,7 +4986,8 @@ Current user's request: ${currentInput}`;
|
|
|
4946
4986
|
const providerName = await getBestProvider(options.provider);
|
|
4947
4987
|
const provider = await AIProviderFactory.createProvider(providerName, options.model, !options.disableTools, // Pass disableTools as inverse of enableMCP
|
|
4948
4988
|
this, // Pass SDK instance
|
|
4949
|
-
options.region
|
|
4989
|
+
options.region, // Pass region parameter
|
|
4990
|
+
this.resolveCredentials(options.credentials));
|
|
4950
4991
|
// Propagate trace context for parent-child span hierarchy
|
|
4951
4992
|
provider.setTraceContext(this._metricsTraceContext);
|
|
4952
4993
|
// Enable tool execution for the provider using BaseProvider method
|
|
@@ -5161,7 +5202,7 @@ Current user's request: ${currentInput}`;
|
|
|
5161
5202
|
const originalPrompt = options.input.text;
|
|
5162
5203
|
const responseTime = Date.now() - startTime;
|
|
5163
5204
|
const providerName = await getBestProvider(options.provider);
|
|
5164
|
-
const provider = await AIProviderFactory.createProvider(providerName, options.model);
|
|
5205
|
+
const provider = await AIProviderFactory.createProvider(providerName, options.model, true, undefined, undefined, this.resolveCredentials(options.credentials));
|
|
5165
5206
|
const fallbackStreamResult = await provider.stream({
|
|
5166
5207
|
input: { text: options.input.text },
|
|
5167
5208
|
model: options.model,
|
|
@@ -8523,6 +8564,7 @@ Current user's request: ${currentInput}`;
|
|
|
8523
8564
|
this.mcpInitialized = false;
|
|
8524
8565
|
this.mcpInitPromise = null;
|
|
8525
8566
|
this.conversationMemoryNeedsInit = false;
|
|
8567
|
+
this.credentials = undefined;
|
|
8526
8568
|
logger.debug("[NeuroLink] Initialization state reset successfully");
|
|
8527
8569
|
}
|
|
8528
8570
|
catch (error) {
|
|
@@ -8,7 +8,12 @@ export declare class AmazonBedrockProvider extends BaseProvider {
|
|
|
8
8
|
private bedrockClient;
|
|
9
9
|
private conversationHistory;
|
|
10
10
|
private region;
|
|
11
|
-
constructor(modelName?: string, neurolink?: NeuroLink, region?: string
|
|
11
|
+
constructor(modelName?: string, neurolink?: NeuroLink, region?: string, credentials?: {
|
|
12
|
+
accessKeyId?: string;
|
|
13
|
+
secretAccessKey?: string;
|
|
14
|
+
sessionToken?: string;
|
|
15
|
+
region?: string;
|
|
16
|
+
});
|
|
12
17
|
/**
|
|
13
18
|
* Perform initial health check to catch credential/connectivity issues early
|
|
14
19
|
* This prevents the health check failure we saw in production logs
|
|
@@ -18,9 +18,10 @@ export class AmazonBedrockProvider extends BaseProvider {
|
|
|
18
18
|
bedrockClient;
|
|
19
19
|
conversationHistory = [];
|
|
20
20
|
region;
|
|
21
|
-
constructor(modelName, neurolink, region) {
|
|
21
|
+
constructor(modelName, neurolink, region, credentials) {
|
|
22
22
|
super(modelName, "bedrock", neurolink);
|
|
23
|
-
this.region =
|
|
23
|
+
this.region =
|
|
24
|
+
credentials?.region || region || process.env.AWS_REGION || "us-east-1";
|
|
24
25
|
logger.debug("[AmazonBedrockProvider] Starting constructor with extensive logging for debugging");
|
|
25
26
|
// Log environment variables for debugging
|
|
26
27
|
logger.debug(`[AmazonBedrockProvider] Environment check: AWS_REGION=${process.env.AWS_REGION || "undefined"}, AWS_ACCESS_KEY_ID=${process.env.AWS_ACCESS_KEY_ID ? "SET" : "undefined"}, AWS_SECRET_ACCESS_KEY=${process.env.AWS_SECRET_ACCESS_KEY ? "SET" : "undefined"}`);
|
|
@@ -35,6 +36,17 @@ export class AmazonBedrockProvider extends BaseProvider {
|
|
|
35
36
|
// 2. Environment variables
|
|
36
37
|
// 3. AWS config files
|
|
37
38
|
// 4. Instance metadata
|
|
39
|
+
...(credentials?.accessKeyId && credentials?.secretAccessKey
|
|
40
|
+
? {
|
|
41
|
+
credentials: {
|
|
42
|
+
accessKeyId: credentials.accessKeyId,
|
|
43
|
+
secretAccessKey: credentials.secretAccessKey,
|
|
44
|
+
...(credentials.sessionToken
|
|
45
|
+
? { sessionToken: credentials.sessionToken }
|
|
46
|
+
: {}),
|
|
47
|
+
},
|
|
48
|
+
}
|
|
49
|
+
: {}),
|
|
38
50
|
});
|
|
39
51
|
logger.debug(`[AmazonBedrockProvider] Successfully created BedrockRuntimeClient with model: ${this.modelName}, region: ${this.region}`);
|
|
40
52
|
}
|
|
@@ -17,7 +17,13 @@ export declare class AmazonSageMakerProvider extends BaseProvider {
|
|
|
17
17
|
private sagemakerModel;
|
|
18
18
|
private sagemakerConfig;
|
|
19
19
|
private modelConfig;
|
|
20
|
-
constructor(modelName?: string, endpointName?: string, region?: string, neurolink?: NeuroLink
|
|
20
|
+
constructor(modelName?: string, endpointName?: string, region?: string, neurolink?: NeuroLink, credentials?: {
|
|
21
|
+
accessKeyId?: string;
|
|
22
|
+
secretAccessKey?: string;
|
|
23
|
+
sessionToken?: string;
|
|
24
|
+
region?: string;
|
|
25
|
+
endpoint?: string;
|
|
26
|
+
});
|
|
21
27
|
protected getProviderName(): AIProviderName;
|
|
22
28
|
protected getDefaultModel(): string;
|
|
23
29
|
protected getAISDKModel(): LanguageModel;
|
|
@@ -17,11 +17,29 @@ export class AmazonSageMakerProvider extends BaseProvider {
|
|
|
17
17
|
sagemakerModel;
|
|
18
18
|
sagemakerConfig;
|
|
19
19
|
modelConfig;
|
|
20
|
-
constructor(modelName, endpointName, region, neurolink) {
|
|
20
|
+
constructor(modelName, endpointName, region, neurolink, credentials) {
|
|
21
21
|
super(modelName, "sagemaker", neurolink);
|
|
22
22
|
try {
|
|
23
|
-
// Load and validate configuration
|
|
24
|
-
|
|
23
|
+
// Load and validate configuration, then overlay per-request credentials
|
|
24
|
+
const baseConfig = getSageMakerConfig(credentials?.region ?? region);
|
|
25
|
+
this.sagemakerConfig = {
|
|
26
|
+
...baseConfig,
|
|
27
|
+
...(credentials?.region !== undefined && {
|
|
28
|
+
region: credentials.region,
|
|
29
|
+
}),
|
|
30
|
+
...(credentials?.accessKeyId !== undefined && {
|
|
31
|
+
accessKeyId: credentials.accessKeyId,
|
|
32
|
+
}),
|
|
33
|
+
...(credentials?.secretAccessKey !== undefined && {
|
|
34
|
+
secretAccessKey: credentials.secretAccessKey,
|
|
35
|
+
}),
|
|
36
|
+
...(credentials?.sessionToken !== undefined && {
|
|
37
|
+
sessionToken: credentials.sessionToken,
|
|
38
|
+
}),
|
|
39
|
+
...(credentials?.endpoint !== undefined && {
|
|
40
|
+
endpoint: credentials.endpoint,
|
|
41
|
+
}),
|
|
42
|
+
};
|
|
25
43
|
this.modelConfig = getSageMakerModelConfig(endpointName || getDefaultSageMakerEndpoint());
|
|
26
44
|
// Create the SageMaker LanguageModel implementation.
|
|
27
45
|
// SageMakerLanguageModel implements SageMakerAsLanguageModel which is
|
|
@@ -41,7 +41,10 @@ export declare class AnthropicProvider extends BaseProvider {
|
|
|
41
41
|
* @param sdk - Optional NeuroLink SDK instance
|
|
42
42
|
* @param config - Optional configuration options for auth, subscription tier, and beta features
|
|
43
43
|
*/
|
|
44
|
-
constructor(modelName?: string, sdk?: unknown, config?: AnthropicProviderConfig
|
|
44
|
+
constructor(modelName?: string, sdk?: unknown, config?: AnthropicProviderConfig, credentials?: {
|
|
45
|
+
apiKey?: string;
|
|
46
|
+
oauthToken?: string;
|
|
47
|
+
});
|
|
45
48
|
/**
|
|
46
49
|
* Get authentication headers based on current auth method and configuration.
|
|
47
50
|
*
|
|
@@ -219,14 +219,27 @@ export class AnthropicProvider extends BaseProvider {
|
|
|
219
219
|
* @param sdk - Optional NeuroLink SDK instance
|
|
220
220
|
* @param config - Optional configuration options for auth, subscription tier, and beta features
|
|
221
221
|
*/
|
|
222
|
-
constructor(modelName, sdk, config) {
|
|
223
|
-
// Pre-compute effective model with tier validation before calling super
|
|
224
|
-
|
|
222
|
+
constructor(modelName, sdk, config, credentials) {
|
|
223
|
+
// Pre-compute effective model with tier validation before calling super.
|
|
224
|
+
//
|
|
225
|
+
// When per-request credentials supply an apiKey (without oauthToken),
|
|
226
|
+
// force api_key auth — skip OAuth detection entirely so the caller's
|
|
227
|
+
// key is used rather than a stale OAuth token from ~/.neurolink/.
|
|
228
|
+
const forceApiKey = !!(credentials?.apiKey && !credentials?.oauthToken);
|
|
229
|
+
const oauthToken = forceApiKey
|
|
230
|
+
? null
|
|
231
|
+
: ((credentials?.oauthToken
|
|
232
|
+
? { accessToken: credentials.oauthToken }
|
|
233
|
+
: null) ??
|
|
234
|
+
config?.oauthToken ??
|
|
235
|
+
getOAuthToken());
|
|
225
236
|
// Resolve auth method FIRST so that tier detection uses the chosen method.
|
|
226
237
|
// If ANTHROPIC_AUTH_METHOD=api_key wins over an existing OAuth token, the
|
|
227
238
|
// tier must reflect api_key mode (full model access) rather than the OAuth
|
|
228
239
|
// token's subscription level.
|
|
229
|
-
const authMethod =
|
|
240
|
+
const authMethod = forceApiKey
|
|
241
|
+
? "api_key"
|
|
242
|
+
: (config?.authMethod ?? detectAuthMethod(oauthToken));
|
|
230
243
|
const subscriptionTier = config?.subscriptionTier ??
|
|
231
244
|
(authMethod === "oauth" ? detectSubscriptionTier(oauthToken) : "api");
|
|
232
245
|
const targetModel = modelName || getDefaultAnthropicModel();
|
|
@@ -306,7 +319,7 @@ export class AnthropicProvider extends BaseProvider {
|
|
|
306
319
|
}
|
|
307
320
|
else {
|
|
308
321
|
// Traditional API key authentication
|
|
309
|
-
const apiKeyToUse = config?.apiKey ?? getAnthropicApiKey();
|
|
322
|
+
const apiKeyToUse = credentials?.apiKey ?? config?.apiKey ?? getAnthropicApiKey();
|
|
310
323
|
anthropic = createAnthropic({
|
|
311
324
|
apiKey: apiKeyToUse,
|
|
312
325
|
headers,
|
|
@@ -2,13 +2,14 @@ import { type LanguageModel } from "ai";
|
|
|
2
2
|
import { type AIProviderName } from "../constants/enums.js";
|
|
3
3
|
import { BaseProvider } from "../core/baseProvider.js";
|
|
4
4
|
import type { StreamOptions, StreamResult } from "../types/streamTypes.js";
|
|
5
|
+
import type { NeurolinkCredentials } from "../types/providers.js";
|
|
5
6
|
export declare class AzureOpenAIProvider extends BaseProvider {
|
|
6
7
|
private apiKey;
|
|
7
8
|
private resourceName;
|
|
8
9
|
private deployment;
|
|
9
10
|
private apiVersion;
|
|
10
11
|
private azureProvider;
|
|
11
|
-
constructor(modelName?: string, sdk?: unknown);
|
|
12
|
+
constructor(modelName?: string, sdk?: unknown, _region?: string, credentials?: NeurolinkCredentials["azure"]);
|
|
12
13
|
getProviderName(): AIProviderName;
|
|
13
14
|
getDefaultModel(): string;
|
|
14
15
|
/**
|
|
@@ -14,22 +14,27 @@ export class AzureOpenAIProvider extends BaseProvider {
|
|
|
14
14
|
deployment;
|
|
15
15
|
apiVersion;
|
|
16
16
|
azureProvider;
|
|
17
|
-
constructor(modelName, sdk) {
|
|
17
|
+
constructor(modelName, sdk, _region, credentials) {
|
|
18
18
|
super(modelName, "azure", sdk);
|
|
19
|
-
this.apiKey = process.env.AZURE_OPENAI_API_KEY || "";
|
|
19
|
+
this.apiKey = credentials?.apiKey || process.env.AZURE_OPENAI_API_KEY || "";
|
|
20
20
|
const endpoint = process.env.AZURE_OPENAI_ENDPOINT || "";
|
|
21
|
-
|
|
21
|
+
const envResourceName = endpoint
|
|
22
22
|
.replace("https://", "")
|
|
23
23
|
.replace(/\/+$/, "") // Remove trailing slashes
|
|
24
24
|
.replace(".openai.azure.com", "")
|
|
25
25
|
.replace(".cognitiveservices.azure.com", "");
|
|
26
|
+
this.resourceName = credentials?.resourceName || envResourceName;
|
|
26
27
|
this.deployment =
|
|
27
|
-
|
|
28
|
+
credentials?.deploymentName ||
|
|
29
|
+
modelName ||
|
|
28
30
|
process.env.AZURE_OPENAI_MODEL ||
|
|
29
31
|
process.env.AZURE_OPENAI_DEPLOYMENT ||
|
|
30
32
|
process.env.AZURE_OPENAI_DEPLOYMENT_ID ||
|
|
31
33
|
"gpt-4o";
|
|
32
|
-
this.apiVersion =
|
|
34
|
+
this.apiVersion =
|
|
35
|
+
credentials?.apiVersion ||
|
|
36
|
+
process.env.AZURE_API_VERSION ||
|
|
37
|
+
APIVersions.AZURE_LATEST;
|
|
33
38
|
// Configuration validation - now using consolidated utility
|
|
34
39
|
if (!this.apiKey) {
|
|
35
40
|
validateApiKey(createAzureAPIKeyConfig());
|
|
@@ -36,7 +36,10 @@ import type { ZodUnknownSchema } from "../types/typeAliases.js";
|
|
|
36
36
|
* Solution: Simplify schema or use disableTools: true
|
|
37
37
|
*/
|
|
38
38
|
export declare class GoogleAIStudioProvider extends BaseProvider {
|
|
39
|
-
|
|
39
|
+
private credentials?;
|
|
40
|
+
constructor(modelName?: string, sdk?: unknown, credentials?: {
|
|
41
|
+
apiKey?: string;
|
|
42
|
+
});
|
|
40
43
|
getProviderName(): AIProviderName;
|
|
41
44
|
getDefaultModel(): string;
|
|
42
45
|
/**
|
|
@@ -65,8 +65,10 @@ async function createGoogleGenAIClient(apiKey) {
|
|
|
65
65
|
* Solution: Simplify schema or use disableTools: true
|
|
66
66
|
*/
|
|
67
67
|
export class GoogleAIStudioProvider extends BaseProvider {
|
|
68
|
-
|
|
68
|
+
credentials;
|
|
69
|
+
constructor(modelName, sdk, credentials) {
|
|
69
70
|
super(modelName, "google-ai", sdk);
|
|
71
|
+
this.credentials = credentials;
|
|
70
72
|
logger.debug("GoogleAIStudioProvider initialized", {
|
|
71
73
|
model: this.modelName,
|
|
72
74
|
provider: this.providerName,
|
|
@@ -432,11 +434,6 @@ export class GoogleAIStudioProvider extends BaseProvider {
|
|
|
432
434
|
}
|
|
433
435
|
this.validateStreamOptions(options);
|
|
434
436
|
const startTime = Date.now();
|
|
435
|
-
const apiKey = this.getApiKey();
|
|
436
|
-
// Ensure environment variable is set for @ai-sdk/google
|
|
437
|
-
if (!process.env.GOOGLE_GENERATIVE_AI_API_KEY) {
|
|
438
|
-
process.env.GOOGLE_GENERATIVE_AI_API_KEY = apiKey;
|
|
439
|
-
}
|
|
440
437
|
const model = await this.getAISDKModelWithMiddleware(options);
|
|
441
438
|
const timeout = this.getTimeout(options);
|
|
442
439
|
const timeoutController = createTimeoutController(timeout, this.providerName, "stream");
|
|
@@ -1214,7 +1211,9 @@ export class GoogleAIStudioProvider extends BaseProvider {
|
|
|
1214
1211
|
}
|
|
1215
1212
|
}
|
|
1216
1213
|
getApiKey() {
|
|
1217
|
-
const apiKey =
|
|
1214
|
+
const apiKey = this.credentials?.apiKey ||
|
|
1215
|
+
process.env.GOOGLE_AI_API_KEY ||
|
|
1216
|
+
process.env.GOOGLE_GENERATIVE_AI_API_KEY;
|
|
1218
1217
|
if (!apiKey) {
|
|
1219
1218
|
throw new AuthenticationError("GOOGLE_AI_API_KEY or GOOGLE_GENERATIVE_AI_API_KEY environment variable is not set", this.providerName);
|
|
1220
1219
|
}
|
|
@@ -3,6 +3,7 @@ import type { ZodType } from "zod";
|
|
|
3
3
|
import { type AIProviderName } from "../constants/enums.js";
|
|
4
4
|
import { BaseProvider } from "../core/baseProvider.js";
|
|
5
5
|
import type { EnhancedGenerateResult, TextGenerationOptions } from "../types/generateTypes.js";
|
|
6
|
+
import type { NeurolinkCredentials } from "../types/providers.js";
|
|
6
7
|
import type { StreamOptions, StreamResult } from "../types/streamTypes.js";
|
|
7
8
|
/**
|
|
8
9
|
* Vertex Model Aliases
|
|
@@ -70,13 +71,14 @@ export declare class GoogleVertexProvider extends BaseProvider {
|
|
|
70
71
|
private location;
|
|
71
72
|
private registeredTools;
|
|
72
73
|
private toolContext;
|
|
74
|
+
private credentials;
|
|
73
75
|
private static modelConfigCache;
|
|
74
76
|
private static modelConfigCacheTime;
|
|
75
77
|
private static readonly CACHE_DURATION;
|
|
76
78
|
private static readonly MAX_CACHE_SIZE;
|
|
77
79
|
private static maxTokensCache;
|
|
78
80
|
private static maxTokensCacheTime;
|
|
79
|
-
constructor(modelName?: string, _providerName?: string, sdk?: unknown, region?: string);
|
|
81
|
+
constructor(modelName?: string, _providerName?: string, sdk?: unknown, region?: string, credentials?: NeurolinkCredentials["vertex"]);
|
|
80
82
|
protected getProviderName(): AIProviderName;
|
|
81
83
|
protected getDefaultModel(): string;
|
|
82
84
|
/**
|