@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
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Artifact Store Types (canonical location)
|
|
3
|
+
*
|
|
4
|
+
* Types for the MCP large-output artifact storage system.
|
|
5
|
+
* When mcp.outputLimits.strategy = "externalize", oversized MCP tool outputs
|
|
6
|
+
* are stored as artifacts and the model receives a compact surrogate instead.
|
|
7
|
+
*
|
|
8
|
+
* @module types/artifactTypes
|
|
9
|
+
*/
|
|
10
|
+
/** Metadata recorded alongside a stored artifact. */
|
|
11
|
+
export type ArtifactMeta = {
|
|
12
|
+
/** Tool name that produced the output. */
|
|
13
|
+
toolName: string;
|
|
14
|
+
/** MCP server ID. */
|
|
15
|
+
serverId: string;
|
|
16
|
+
/** Session that triggered the tool call (optional). */
|
|
17
|
+
sessionId?: string;
|
|
18
|
+
/** Serialized byte size of the full payload. */
|
|
19
|
+
sizeBytes: number;
|
|
20
|
+
/** Whether the payload is valid JSON or plain text. */
|
|
21
|
+
contentType: "json" | "text";
|
|
22
|
+
/** Unix epoch ms when the artifact was created. */
|
|
23
|
+
createdAt: number;
|
|
24
|
+
};
|
|
25
|
+
/** Lightweight descriptor returned after a successful ArtifactStore.store(). */
|
|
26
|
+
export type ArtifactRef = {
|
|
27
|
+
/** UUID v4 — stable identifier used in surrogate results and metadata. */
|
|
28
|
+
id: string;
|
|
29
|
+
/** First N characters of the payload (for surrogate headers). */
|
|
30
|
+
preview: string;
|
|
31
|
+
/** Full serialized byte size. */
|
|
32
|
+
sizeBytes: number;
|
|
33
|
+
/** Stored metadata. */
|
|
34
|
+
meta: ArtifactMeta;
|
|
35
|
+
};
|
|
36
|
+
/**
|
|
37
|
+
* Pluggable storage contract for externalized MCP tool outputs.
|
|
38
|
+
*
|
|
39
|
+
* Default backend: LocalTempArtifactStore (filesystem, single-process).
|
|
40
|
+
* Future backends can implement this interface for S3, Redis blobs, etc.
|
|
41
|
+
*/
|
|
42
|
+
export interface ArtifactStore {
|
|
43
|
+
/**
|
|
44
|
+
* Persist a payload and return a lightweight reference.
|
|
45
|
+
* @param payload Serialized tool output (JSON string or plain text).
|
|
46
|
+
* @param meta Descriptor without `createdAt` (assigned internally).
|
|
47
|
+
*/
|
|
48
|
+
store(payload: string, meta: Omit<ArtifactMeta, "createdAt">): Promise<ArtifactRef>;
|
|
49
|
+
/**
|
|
50
|
+
* Retrieve the full payload by artifact ID.
|
|
51
|
+
* Returns `null` if the artifact is not found or has been cleaned up.
|
|
52
|
+
*/
|
|
53
|
+
retrieve(id: string): Promise<string | null>;
|
|
54
|
+
/** Delete a single artifact. No-op if the ID does not exist. */
|
|
55
|
+
delete(id: string): Promise<void>;
|
|
56
|
+
/**
|
|
57
|
+
* Delete all artifacts older than `olderThanMs` milliseconds.
|
|
58
|
+
* Returns the number of artifacts deleted.
|
|
59
|
+
*/
|
|
60
|
+
cleanup(olderThanMs: number): Promise<number>;
|
|
61
|
+
/** Generate a short preview string from a serialized payload. */
|
|
62
|
+
generatePreview(payload: string): string;
|
|
63
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Artifact Store Types (canonical location)
|
|
3
|
+
*
|
|
4
|
+
* Types for the MCP large-output artifact storage system.
|
|
5
|
+
* When mcp.outputLimits.strategy = "externalize", oversized MCP tool outputs
|
|
6
|
+
* are stored as artifacts and the model receives a compact surrogate instead.
|
|
7
|
+
*
|
|
8
|
+
* @module types/artifactTypes
|
|
9
|
+
*/
|
|
10
|
+
export {};
|
|
11
|
+
//# sourceMappingURL=artifactTypes.js.map
|
|
@@ -11,6 +11,7 @@ import type { RoutingStrategy } from "../mcp/routing/index.js";
|
|
|
11
11
|
import type { CacheStrategy } from "../mcp/caching/index.js";
|
|
12
12
|
import type { ToolMiddleware } from "../mcp/toolIntegration.js";
|
|
13
13
|
import type { MastraAuthProvider, AuthProviderType, AuthProviderConfig, Auth0Config, ClerkConfig, FirebaseConfig, SupabaseConfig, WorkOSConfig, BetterAuthConfig, JWTConfig, OAuth2Config, CognitoConfig, KeycloakConfig, AuthenticatedContext } from "./authTypes.js";
|
|
14
|
+
import type { NeurolinkCredentials } from "./providers.js";
|
|
14
15
|
/**
|
|
15
16
|
* Main NeuroLink configuration type
|
|
16
17
|
*/
|
|
@@ -39,6 +40,12 @@ export type NeurolinkConstructorConfig = {
|
|
|
39
40
|
auth?: NeuroLinkAuthConfig;
|
|
40
41
|
/** TaskManager configuration (scheduled and self-running tasks) */
|
|
41
42
|
tasks?: TaskManagerConfig;
|
|
43
|
+
/**
|
|
44
|
+
* Per-provider credential overrides.
|
|
45
|
+
* When set here, applies as the default for all generate()/stream() calls
|
|
46
|
+
* from this NeuroLink instance. Per-call credentials override these.
|
|
47
|
+
*/
|
|
48
|
+
credentials?: NeurolinkCredentials;
|
|
42
49
|
};
|
|
43
50
|
/**
|
|
44
51
|
* Configuration for MCP enhancement modules wired into generate()/stream() paths.
|
|
@@ -90,6 +97,38 @@ export type MCPEnhancementsConfig = {
|
|
|
90
97
|
};
|
|
91
98
|
/** Global tool middleware applied to every tool execution. Default: empty. */
|
|
92
99
|
middleware?: ToolMiddleware[];
|
|
100
|
+
/**
|
|
101
|
+
* Large MCP tool output handling.
|
|
102
|
+
*
|
|
103
|
+
* MCP servers can return arbitrarily large payloads. Without limits these
|
|
104
|
+
* are loaded entirely into memory, cached in full, stored whole in Redis, and
|
|
105
|
+
* injected into the LLM context window — all of which silently fail at scale.
|
|
106
|
+
*
|
|
107
|
+
* When configured, NeuroLink intercepts oversized outputs at the tool boundary
|
|
108
|
+
* (before caching and before memory persistence) and applies the chosen
|
|
109
|
+
* strategy so the model receives a compact surrogate instead of a firehose.
|
|
110
|
+
*
|
|
111
|
+
* Two strategies:
|
|
112
|
+
* - "inline" Keep sending the full payload to the model regardless of
|
|
113
|
+
* size. A warning is emitted above warnBytes.
|
|
114
|
+
* - "externalize" Store the full payload on disk as an artifact and return a
|
|
115
|
+
* compact surrogate with a head/tail preview and an artifact
|
|
116
|
+
* ID. The model uses `retrieve_context` with that ID to read
|
|
117
|
+
* the full output on demand, with offset/limit pagination.
|
|
118
|
+
*
|
|
119
|
+
* Defaults (when `outputLimits` is set):
|
|
120
|
+
* strategy = "externalize"
|
|
121
|
+
* maxBytes = 100 KB (100 * 1024)
|
|
122
|
+
* warnBytes = 50 KB (50 * 1024)
|
|
123
|
+
*/
|
|
124
|
+
outputLimits?: {
|
|
125
|
+
/** What to do when output exceeds maxBytes. Default: "externalize". */
|
|
126
|
+
strategy?: "inline" | "externalize";
|
|
127
|
+
/** Byte ceiling above which the strategy fires. Default: 102400 (100 KB). */
|
|
128
|
+
maxBytes?: number;
|
|
129
|
+
/** Bytes at which a warning is emitted even when still inline. Default: 51200 (50 KB). */
|
|
130
|
+
warnBytes?: number;
|
|
131
|
+
};
|
|
93
132
|
};
|
|
94
133
|
/**
|
|
95
134
|
* Authentication configuration for NeuroLink SDK
|
|
@@ -231,6 +231,13 @@ export type ChatMessageMetadata = {
|
|
|
231
231
|
toolOutputPreview?: string;
|
|
232
232
|
/** Original byte size of the full tool output before any truncation */
|
|
233
233
|
originalSize?: number;
|
|
234
|
+
/**
|
|
235
|
+
* Artifact store ID for an externalized MCP tool output.
|
|
236
|
+
* Set when `mcp.outputLimits.strategy = "externalize"` and the tool output
|
|
237
|
+
* exceeded `maxBytes`. Use retrieve_context with this ID to fetch the full
|
|
238
|
+
* payload from the local artifact store.
|
|
239
|
+
*/
|
|
240
|
+
artifactId?: string;
|
|
234
241
|
};
|
|
235
242
|
/**
|
|
236
243
|
* Chat message format for conversation history
|
|
@@ -11,6 +11,7 @@ import type { DirectorModeOptions, DirectorSegment, VideoGenerationResult, Video
|
|
|
11
11
|
import type { PPTGenerationResult, PPTOutputOptions } from "./pptTypes.js";
|
|
12
12
|
import type { TTSOptions, TTSResult } from "./ttsTypes.js";
|
|
13
13
|
import type { StandardRecord, ValidationSchema, ZodUnknownSchema } from "./typeAliases.js";
|
|
14
|
+
import type { NeurolinkCredentials } from "./providers.js";
|
|
14
15
|
/**
|
|
15
16
|
* Generate function options type - Primary method for content generation
|
|
16
17
|
* Supports multimodal content while maintaining backward compatibility
|
|
@@ -424,6 +425,12 @@ export type GenerateOptions = {
|
|
|
424
425
|
auth?: {
|
|
425
426
|
token: string;
|
|
426
427
|
};
|
|
428
|
+
/**
|
|
429
|
+
* Per-provider credential overrides for this request.
|
|
430
|
+
* Overrides instance-level credentials set in `new NeuroLink({ credentials })`.
|
|
431
|
+
* Unset providers fall through to instance credentials, then environment variables.
|
|
432
|
+
*/
|
|
433
|
+
credentials?: NeurolinkCredentials;
|
|
427
434
|
/**
|
|
428
435
|
* Per-call memory control.
|
|
429
436
|
*
|
|
@@ -942,6 +949,12 @@ export type TextGenerationOptions = {
|
|
|
942
949
|
/** Thinking level (Gemini 3: minimal|low|medium|high). Ignored for Anthropic. */
|
|
943
950
|
thinkingLevel?: "minimal" | "low" | "medium" | "high";
|
|
944
951
|
};
|
|
952
|
+
/**
|
|
953
|
+
* Per-provider credential overrides for this request.
|
|
954
|
+
* Overrides instance-level credentials set in `new NeuroLink({ credentials })`.
|
|
955
|
+
* Unset providers fall through to instance credentials, then environment variables.
|
|
956
|
+
*/
|
|
957
|
+
credentials?: NeurolinkCredentials;
|
|
945
958
|
/**
|
|
946
959
|
* Optional request identifier for observability and log correlation.
|
|
947
960
|
* When provided, this ID is forwarded to spans, logs, and telemetry so
|
|
@@ -6,6 +6,8 @@ export * from "./cli.js";
|
|
|
6
6
|
export * from "./common.js";
|
|
7
7
|
export type { AnalyticsConfig, BackupInfo, BackupMetadata, CacheConfig, ConfigUpdateOptions, ConfigValidationResult, FallbackConfig, MCPEnhancementsConfig, NeuroLinkConfig, PerformanceConfig, RetryConfig, ToolConfig, } from "./configTypes.js";
|
|
8
8
|
export type { ExternalMCPConfigValidation, ExternalMCPManagerConfig, ExternalMCPOperationResult, ExternalMCPServerEvents, ExternalMCPServerHealth, ExternalMCPServerInstance, ExternalMCPServerStatus, ExternalMCPToolContext, ExternalMCPToolInfo, ExternalMCPToolResult, } from "./externalMcp.js";
|
|
9
|
+
export type { ArtifactMeta, ArtifactRef, ArtifactStore, } from "./artifactTypes.js";
|
|
10
|
+
export type { McpOutputContext, McpOutputNormalizerConfig, McpOutputStrategy, NormalizedMcpOutput, } from "./mcpOutputTypes.js";
|
|
9
11
|
export type { AuthorizationUrlResult, CircuitBreakerConfig, CircuitBreakerEvents, CircuitBreakerState, CircuitBreakerStats, DiscoveredMcp, ExternalToolExecutionOptions, FlexibleValidationResult, HTTPRetryConfig, MCPClientResult, MCPConnectedServer, MCPDiscoveredServer, MCPExecutableTool, MCPOAuthConfig, MCPServerCategory, MCPServerConfig, MCPServerConnectionStatus, MCPServerInfo, MCPServerMetadata, MCPServerRegistryEntry, MCPServerStatus, MCPStatus, MCPToolInfo, MCPToolMetadata, MCPTransportType, McpMetadata, McpRegistry, NeuroLinkExecutionContext, NeuroLinkMCPServer, NeuroLinkMCPTool, OAuthClientInformation, OAuthTokens as McpOAuthTokens, RateLimitConfig, TokenBucketRateLimitConfig, TokenExchangeRequest, TokenStorage, ToolDiscoveryResult, ToolRegistryEvents, ToolValidationResult, } from "./mcpTypes.js";
|
|
10
12
|
export type { ModelCapability, ModelFilter, ModelPricing, ModelResolutionContext, ModelStats, ModelUseCase, } from "./providers.js";
|
|
11
13
|
export * from "./providers.js";
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MCP Output Normalizer Types (canonical location)
|
|
3
|
+
*
|
|
4
|
+
* Types for the large MCP response handling system.
|
|
5
|
+
*
|
|
6
|
+
* @module types/mcpOutputTypes
|
|
7
|
+
*/
|
|
8
|
+
/**
|
|
9
|
+
* Two honest strategies for oversized MCP tool outputs:
|
|
10
|
+
* - "inline" Full payload always sent to the model (warning logged above warnBytes).
|
|
11
|
+
* - "externalize" Full payload stored as an artifact; model receives a compact
|
|
12
|
+
* surrogate with head/tail preview and an artifact ID it can
|
|
13
|
+
* resolve via retrieve_context with offset/limit pagination.
|
|
14
|
+
*/
|
|
15
|
+
export type McpOutputStrategy = "inline" | "externalize";
|
|
16
|
+
/** Configuration for McpOutputNormalizer. */
|
|
17
|
+
export type McpOutputNormalizerConfig = {
|
|
18
|
+
strategy: McpOutputStrategy;
|
|
19
|
+
/** Byte ceiling above which the strategy fires. */
|
|
20
|
+
maxBytes: number;
|
|
21
|
+
/** Bytes at which a warning is emitted while still inline. */
|
|
22
|
+
warnBytes: number;
|
|
23
|
+
};
|
|
24
|
+
/** Contextual info passed alongside the raw MCP callResult. */
|
|
25
|
+
export type McpOutputContext = {
|
|
26
|
+
toolName: string;
|
|
27
|
+
serverId: string;
|
|
28
|
+
sessionId?: string;
|
|
29
|
+
};
|
|
30
|
+
/** Value returned by McpOutputNormalizer.normalize(). */
|
|
31
|
+
export type NormalizedMcpOutput = {
|
|
32
|
+
/** The result to substitute for the raw callResult. May be a surrogate. */
|
|
33
|
+
result: unknown;
|
|
34
|
+
/** Whether the full payload was written to the artifact store. */
|
|
35
|
+
isExternalized: boolean;
|
|
36
|
+
/** Artifact ID when isExternalized === true. */
|
|
37
|
+
artifactId?: string;
|
|
38
|
+
/** Serialized byte size of the original payload. */
|
|
39
|
+
originalBytes: number;
|
|
40
|
+
};
|
|
@@ -71,6 +71,81 @@ export type AWSCredentialConfig = {
|
|
|
71
71
|
/** Optional service endpoint override (e.g., VPC/Gov endpoints) */
|
|
72
72
|
endpoint?: string;
|
|
73
73
|
};
|
|
74
|
+
/**
|
|
75
|
+
* Per-provider credential overrides for generate() / stream() calls.
|
|
76
|
+
*
|
|
77
|
+
* When set on `NeurolinkConstructorConfig.credentials`, applies as the default
|
|
78
|
+
* for all calls from that NeuroLink instance. When set on
|
|
79
|
+
* `GenerateOptions.credentials` or `StreamOptions.credentials`, overrides the
|
|
80
|
+
* instance default for that single call.
|
|
81
|
+
*
|
|
82
|
+
* Unset providers fall through to environment variables (existing behaviour).
|
|
83
|
+
*/
|
|
84
|
+
export type NeurolinkCredentials = {
|
|
85
|
+
openai?: {
|
|
86
|
+
apiKey?: string;
|
|
87
|
+
baseURL?: string;
|
|
88
|
+
};
|
|
89
|
+
anthropic?: {
|
|
90
|
+
apiKey?: string;
|
|
91
|
+
oauthToken?: string;
|
|
92
|
+
};
|
|
93
|
+
googleAiStudio?: {
|
|
94
|
+
apiKey?: string;
|
|
95
|
+
};
|
|
96
|
+
vertex?: {
|
|
97
|
+
projectId?: string;
|
|
98
|
+
location?: string;
|
|
99
|
+
/** Vertex Express Mode — simplified API-key auth */
|
|
100
|
+
apiKey?: string;
|
|
101
|
+
/** Full service-account JSON string */
|
|
102
|
+
serviceAccountKey?: string;
|
|
103
|
+
/** Inline service-account fields (alternative to serviceAccountKey) */
|
|
104
|
+
clientEmail?: string;
|
|
105
|
+
privateKey?: string;
|
|
106
|
+
};
|
|
107
|
+
bedrock?: {
|
|
108
|
+
accessKeyId?: string;
|
|
109
|
+
secretAccessKey?: string;
|
|
110
|
+
sessionToken?: string;
|
|
111
|
+
region?: string;
|
|
112
|
+
};
|
|
113
|
+
sagemaker?: {
|
|
114
|
+
accessKeyId?: string;
|
|
115
|
+
secretAccessKey?: string;
|
|
116
|
+
sessionToken?: string;
|
|
117
|
+
region?: string;
|
|
118
|
+
endpoint?: string;
|
|
119
|
+
};
|
|
120
|
+
azure?: {
|
|
121
|
+
apiKey?: string;
|
|
122
|
+
resourceName?: string;
|
|
123
|
+
deploymentName?: string;
|
|
124
|
+
apiVersion?: string;
|
|
125
|
+
};
|
|
126
|
+
mistral?: {
|
|
127
|
+
apiKey?: string;
|
|
128
|
+
};
|
|
129
|
+
huggingFace?: {
|
|
130
|
+
apiKey?: string;
|
|
131
|
+
baseURL?: string;
|
|
132
|
+
};
|
|
133
|
+
openrouter?: {
|
|
134
|
+
apiKey?: string;
|
|
135
|
+
baseURL?: string;
|
|
136
|
+
};
|
|
137
|
+
litellm?: {
|
|
138
|
+
apiKey?: string;
|
|
139
|
+
baseURL?: string;
|
|
140
|
+
};
|
|
141
|
+
openaiCompatible?: {
|
|
142
|
+
apiKey?: string;
|
|
143
|
+
baseURL?: string;
|
|
144
|
+
};
|
|
145
|
+
ollama?: {
|
|
146
|
+
baseURL?: string;
|
|
147
|
+
};
|
|
148
|
+
};
|
|
74
149
|
/**
|
|
75
150
|
* AWS Credential Validation Result
|
|
76
151
|
*/
|
|
@@ -9,7 +9,7 @@ import type { JsonValue, UnknownRecord } from "./common.js";
|
|
|
9
9
|
import type { Content, ImageWithAltText } from "./content.js";
|
|
10
10
|
import type { ChatMessage } from "./conversation.js";
|
|
11
11
|
import type { AdditionalMemoryUser } from "./generateTypes.js";
|
|
12
|
-
import type { AIModelProviderConfig } from "./providers.js";
|
|
12
|
+
import type { AIModelProviderConfig, NeurolinkCredentials } from "./providers.js";
|
|
13
13
|
import type { TTSChunk, TTSOptions } from "./ttsTypes.js";
|
|
14
14
|
import type { StandardRecord, ValidationSchema } from "./typeAliases.js";
|
|
15
15
|
/**
|
|
@@ -444,6 +444,12 @@ export type StreamOptions = {
|
|
|
444
444
|
auth?: {
|
|
445
445
|
token: string;
|
|
446
446
|
};
|
|
447
|
+
/**
|
|
448
|
+
* Per-provider credential overrides for this request.
|
|
449
|
+
* Overrides instance-level credentials set in `new NeuroLink({ credentials })`.
|
|
450
|
+
* Unset providers fall through to instance credentials, then environment variables.
|
|
451
|
+
*/
|
|
452
|
+
credentials?: NeurolinkCredentials;
|
|
447
453
|
/**
|
|
448
454
|
* Per-call memory control.
|
|
449
455
|
*
|
|
@@ -27,6 +27,12 @@ export declare class ExternalServerManager extends EventEmitter {
|
|
|
27
27
|
constructor(config?: ExternalMCPManagerConfig, options?: {
|
|
28
28
|
enableMainRegistryIntegration?: boolean;
|
|
29
29
|
});
|
|
30
|
+
/**
|
|
31
|
+
* Attach a McpOutputNormalizer to the underlying ToolDiscoveryService.
|
|
32
|
+
* All tool outputs will be measured and (if oversized) replaced with compact
|
|
33
|
+
* surrogates before being returned to callers.
|
|
34
|
+
*/
|
|
35
|
+
setOutputNormalizer(normalizer: import("./mcpOutputNormalizer.js").McpOutputNormalizer): void;
|
|
30
36
|
/**
|
|
31
37
|
* Set HITL manager for human-in-the-loop safety mechanisms
|
|
32
38
|
* @param hitlManager - HITL manager instance (optional, can be undefined to disable)
|
|
@@ -210,6 +210,15 @@ export class ExternalServerManager extends EventEmitter {
|
|
|
210
210
|
process.on("SIGTERM", () => this.shutdown());
|
|
211
211
|
process.on("beforeExit", () => this.shutdown());
|
|
212
212
|
}
|
|
213
|
+
/**
|
|
214
|
+
* Attach a McpOutputNormalizer to the underlying ToolDiscoveryService.
|
|
215
|
+
* All tool outputs will be measured and (if oversized) replaced with compact
|
|
216
|
+
* surrogates before being returned to callers.
|
|
217
|
+
*/
|
|
218
|
+
setOutputNormalizer(normalizer) {
|
|
219
|
+
this.toolDiscovery.setOutputNormalizer(normalizer);
|
|
220
|
+
mcpLogger.debug("[ExternalServerManager] MCP output normalizer attached to ToolDiscoveryService");
|
|
221
|
+
}
|
|
213
222
|
/**
|
|
214
223
|
* Set HITL manager for human-in-the-loop safety mechanisms
|
|
215
224
|
* @param hitlManager - HITL manager instance (optional, can be undefined to disable)
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MCP Output Normalizer
|
|
3
|
+
*
|
|
4
|
+
* Single responsibility: intercept a raw MCP `CallToolResult`, measure it,
|
|
5
|
+
* and apply the configured strategy so that oversized payloads never reach
|
|
6
|
+
* caches, Redis, or LLM context windows raw.
|
|
7
|
+
*
|
|
8
|
+
* Two strategies:
|
|
9
|
+
* - "inline" Pass through unchanged. The full payload enters the LLM
|
|
10
|
+
* context as-is. Emit a warning above warnBytes.
|
|
11
|
+
* - "externalize" Write the full payload to the ArtifactStore, return a
|
|
12
|
+
* compact surrogate with a head/tail preview and an artifact
|
|
13
|
+
* ID. The model uses `retrieve_context` with that ID to read
|
|
14
|
+
* the full output on demand, with offset/limit pagination.
|
|
15
|
+
*
|
|
16
|
+
* The surrogate result is shaped as an MCP `CallToolResult` so it passes
|
|
17
|
+
* transparently through any downstream code that expects that format.
|
|
18
|
+
* A `_meta` extension carries the artifact ID for structured extraction in
|
|
19
|
+
* `redisConversationMemoryManager`.
|
|
20
|
+
*
|
|
21
|
+
* @module mcp/mcpOutputNormalizer
|
|
22
|
+
*/
|
|
23
|
+
import type { ArtifactStore } from "../artifacts/artifactStore.js";
|
|
24
|
+
import type { McpOutputNormalizerConfig, McpOutputContext, NormalizedMcpOutput } from "../types/mcpOutputTypes.js";
|
|
25
|
+
export type { McpOutputStrategy, McpOutputNormalizerConfig, McpOutputContext, NormalizedMcpOutput, } from "../types/mcpOutputTypes.js";
|
|
26
|
+
/** Default byte ceiling above which externalize fires (100 KB). */
|
|
27
|
+
export declare const DEFAULT_MAX_MCP_OUTPUT_BYTES: number;
|
|
28
|
+
/** Default byte threshold for emitting a warning while still inline (50 KB). */
|
|
29
|
+
export declare const DEFAULT_WARN_MCP_OUTPUT_BYTES: number;
|
|
30
|
+
/** Metadata key embedded in surrogate `_meta` and used by memory manager. */
|
|
31
|
+
export declare const NEUROLINK_ARTIFACT_ID_KEY = "neurolinkArtifactId";
|
|
32
|
+
/**
|
|
33
|
+
* Stateless normalizer (state lives in the injected ArtifactStore).
|
|
34
|
+
*
|
|
35
|
+
* Construct once per NeuroLink instance and set via
|
|
36
|
+
* `ToolDiscoveryService.setOutputNormalizer()`.
|
|
37
|
+
*/
|
|
38
|
+
export declare class McpOutputNormalizer {
|
|
39
|
+
private readonly config;
|
|
40
|
+
private readonly artifactStore?;
|
|
41
|
+
constructor(config: McpOutputNormalizerConfig, artifactStore?: ArtifactStore | undefined);
|
|
42
|
+
/**
|
|
43
|
+
* Measure `callResult`, apply strategy if oversized, return normalized output.
|
|
44
|
+
*
|
|
45
|
+
* Never throws: on any internal failure the raw result is returned unchanged
|
|
46
|
+
* with a warning log so tool execution is never broken by the normalizer.
|
|
47
|
+
*/
|
|
48
|
+
normalize(callResult: unknown, context: McpOutputContext): Promise<NormalizedMcpOutput>;
|
|
49
|
+
}
|
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MCP Output Normalizer
|
|
3
|
+
*
|
|
4
|
+
* Single responsibility: intercept a raw MCP `CallToolResult`, measure it,
|
|
5
|
+
* and apply the configured strategy so that oversized payloads never reach
|
|
6
|
+
* caches, Redis, or LLM context windows raw.
|
|
7
|
+
*
|
|
8
|
+
* Two strategies:
|
|
9
|
+
* - "inline" Pass through unchanged. The full payload enters the LLM
|
|
10
|
+
* context as-is. Emit a warning above warnBytes.
|
|
11
|
+
* - "externalize" Write the full payload to the ArtifactStore, return a
|
|
12
|
+
* compact surrogate with a head/tail preview and an artifact
|
|
13
|
+
* ID. The model uses `retrieve_context` with that ID to read
|
|
14
|
+
* the full output on demand, with offset/limit pagination.
|
|
15
|
+
*
|
|
16
|
+
* The surrogate result is shaped as an MCP `CallToolResult` so it passes
|
|
17
|
+
* transparently through any downstream code that expects that format.
|
|
18
|
+
* A `_meta` extension carries the artifact ID for structured extraction in
|
|
19
|
+
* `redisConversationMemoryManager`.
|
|
20
|
+
*
|
|
21
|
+
* @module mcp/mcpOutputNormalizer
|
|
22
|
+
*/
|
|
23
|
+
import { generateToolOutputPreview } from "../context/toolOutputLimits.js";
|
|
24
|
+
import { logger } from "../utils/logger.js";
|
|
25
|
+
import { withTimeout } from "../utils/errorHandling.js";
|
|
26
|
+
// ---------------------------------------------------------------------------
|
|
27
|
+
// Public constants
|
|
28
|
+
// ---------------------------------------------------------------------------
|
|
29
|
+
/** Default byte ceiling above which externalize fires (100 KB). */
|
|
30
|
+
export const DEFAULT_MAX_MCP_OUTPUT_BYTES = 100 * 1024;
|
|
31
|
+
/** Default byte threshold for emitting a warning while still inline (50 KB). */
|
|
32
|
+
export const DEFAULT_WARN_MCP_OUTPUT_BYTES = 50 * 1024;
|
|
33
|
+
/** Metadata key embedded in surrogate `_meta` and used by memory manager. */
|
|
34
|
+
export const NEUROLINK_ARTIFACT_ID_KEY = "neurolinkArtifactId";
|
|
35
|
+
// ---------------------------------------------------------------------------
|
|
36
|
+
// McpOutputNormalizer
|
|
37
|
+
// ---------------------------------------------------------------------------
|
|
38
|
+
/**
|
|
39
|
+
* Stateless normalizer (state lives in the injected ArtifactStore).
|
|
40
|
+
*
|
|
41
|
+
* Construct once per NeuroLink instance and set via
|
|
42
|
+
* `ToolDiscoveryService.setOutputNormalizer()`.
|
|
43
|
+
*/
|
|
44
|
+
export class McpOutputNormalizer {
|
|
45
|
+
config;
|
|
46
|
+
artifactStore;
|
|
47
|
+
constructor(config, artifactStore) {
|
|
48
|
+
this.config = config;
|
|
49
|
+
this.artifactStore = artifactStore;
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Measure `callResult`, apply strategy if oversized, return normalized output.
|
|
53
|
+
*
|
|
54
|
+
* Never throws: on any internal failure the raw result is returned unchanged
|
|
55
|
+
* with a warning log so tool execution is never broken by the normalizer.
|
|
56
|
+
*/
|
|
57
|
+
async normalize(callResult, context) {
|
|
58
|
+
const serialized = serialize(callResult);
|
|
59
|
+
const originalBytes = Buffer.byteLength(serialized, "utf-8");
|
|
60
|
+
// Fast path: below warn threshold — always inline, no logging
|
|
61
|
+
if (originalBytes <= this.config.warnBytes) {
|
|
62
|
+
return { result: callResult, isExternalized: false, originalBytes };
|
|
63
|
+
}
|
|
64
|
+
// Between warn and max: emit a warning but keep inline regardless of strategy
|
|
65
|
+
if (originalBytes <= this.config.maxBytes) {
|
|
66
|
+
logger.warn(`[McpOutputNormalizer] Large MCP output from "${context.toolName}" on ` +
|
|
67
|
+
`"${context.serverId}" (${formatBytes(originalBytes)}). ` +
|
|
68
|
+
`Approaching limit of ${formatBytes(this.config.maxBytes)}.`, {
|
|
69
|
+
toolName: context.toolName,
|
|
70
|
+
serverId: context.serverId,
|
|
71
|
+
originalBytes,
|
|
72
|
+
});
|
|
73
|
+
return { result: callResult, isExternalized: false, originalBytes };
|
|
74
|
+
}
|
|
75
|
+
// Above max — apply strategy
|
|
76
|
+
logger.warn(`[McpOutputNormalizer] MCP output from "${context.toolName}" on ` +
|
|
77
|
+
`"${context.serverId}" exceeds limit ` +
|
|
78
|
+
`(${formatBytes(originalBytes)} > ${formatBytes(this.config.maxBytes)}). ` +
|
|
79
|
+
`Applying strategy "${this.config.strategy}".`, { toolName: context.toolName, serverId: context.serverId, originalBytes });
|
|
80
|
+
if (this.config.strategy === "inline") {
|
|
81
|
+
// Caller explicitly opted in to inline regardless of size
|
|
82
|
+
return { result: callResult, isExternalized: false, originalBytes };
|
|
83
|
+
}
|
|
84
|
+
// strategy === "externalize"
|
|
85
|
+
if (!this.artifactStore) {
|
|
86
|
+
// Misconfiguration: externalize was chosen but no store was provided.
|
|
87
|
+
// Pass through inline so execution is never broken, but log loudly.
|
|
88
|
+
logger.error(`[McpOutputNormalizer] strategy="externalize" but no ArtifactStore ` +
|
|
89
|
+
`configured — passing through raw result for "${context.toolName}". ` +
|
|
90
|
+
`Set mcp.outputLimits.strategy="externalize" and ensure the NeuroLink ` +
|
|
91
|
+
`constructor creates a LocalTempArtifactStore.`);
|
|
92
|
+
return { result: callResult, isExternalized: false, originalBytes };
|
|
93
|
+
}
|
|
94
|
+
let ref;
|
|
95
|
+
try {
|
|
96
|
+
ref = await withTimeout(this.artifactStore.store(serialized, {
|
|
97
|
+
toolName: context.toolName,
|
|
98
|
+
serverId: context.serverId,
|
|
99
|
+
sessionId: context.sessionId,
|
|
100
|
+
sizeBytes: originalBytes,
|
|
101
|
+
contentType: isJsonLike(callResult) ? "json" : "text",
|
|
102
|
+
}), 10_000, new Error(`ArtifactStore.store() timed out for "${context.toolName}"`));
|
|
103
|
+
}
|
|
104
|
+
catch (err) {
|
|
105
|
+
// Storage failure or timeout — pass through inline so the call doesn't break.
|
|
106
|
+
logger.error(`[McpOutputNormalizer] ArtifactStore.store() failed for ` +
|
|
107
|
+
`"${context.toolName}": ${err instanceof Error ? err.message : String(err)} ` +
|
|
108
|
+
`— passing through raw result.`);
|
|
109
|
+
return { result: callResult, isExternalized: false, originalBytes };
|
|
110
|
+
}
|
|
111
|
+
// Generate a compact head/tail preview for the surrogate.
|
|
112
|
+
// Cap at warnBytes so the surrogate itself is always well within limits.
|
|
113
|
+
const { preview } = generateToolOutputPreview(serialized, {
|
|
114
|
+
maxBytes: Math.min(this.config.warnBytes, DEFAULT_WARN_MCP_OUTPUT_BYTES),
|
|
115
|
+
});
|
|
116
|
+
return {
|
|
117
|
+
result: buildSurrogate(preview, ref.id, context, originalBytes),
|
|
118
|
+
isExternalized: true,
|
|
119
|
+
artifactId: ref.id,
|
|
120
|
+
originalBytes,
|
|
121
|
+
};
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
// ---------------------------------------------------------------------------
|
|
125
|
+
// Helpers
|
|
126
|
+
// ---------------------------------------------------------------------------
|
|
127
|
+
/**
|
|
128
|
+
* Build a compact MCP-shaped surrogate the LLM receives instead of the
|
|
129
|
+
* raw oversized payload.
|
|
130
|
+
*
|
|
131
|
+
* Shape mirrors `CallToolResult` so downstream code that inspects
|
|
132
|
+
* `result.content` keeps working unchanged.
|
|
133
|
+
* `_meta` carries the artifact ID for structured extraction in
|
|
134
|
+
* `redisConversationMemoryManager`.
|
|
135
|
+
*/
|
|
136
|
+
function buildSurrogate(preview, artifactId, context, originalBytes) {
|
|
137
|
+
const text = `[MCP Tool Output — ${context.toolName} | ${context.serverId}]\n` +
|
|
138
|
+
`Original size: ${formatBytes(originalBytes)} | ` +
|
|
139
|
+
`Externalized — use retrieve_context with artifactId="${artifactId}" ` +
|
|
140
|
+
`to read the full output (supports offset + limit pagination)\n` +
|
|
141
|
+
`\n--- Preview (head + tail) ---\n` +
|
|
142
|
+
preview +
|
|
143
|
+
`\n--- End Preview ---\n` +
|
|
144
|
+
`[${NEUROLINK_ARTIFACT_ID_KEY}=${artifactId}]`;
|
|
145
|
+
return {
|
|
146
|
+
content: [{ type: "text", text }],
|
|
147
|
+
_meta: {
|
|
148
|
+
[NEUROLINK_ARTIFACT_ID_KEY]: artifactId,
|
|
149
|
+
originalBytes,
|
|
150
|
+
toolName: context.toolName,
|
|
151
|
+
serverId: context.serverId,
|
|
152
|
+
},
|
|
153
|
+
};
|
|
154
|
+
}
|
|
155
|
+
function serialize(value) {
|
|
156
|
+
if (typeof value === "string") {
|
|
157
|
+
return value;
|
|
158
|
+
}
|
|
159
|
+
try {
|
|
160
|
+
// Compact JSON keeps byte measurement accurate and size enforcement honest.
|
|
161
|
+
// Pretty-printing with null, 2 inflates every object by ~30–50 % and would
|
|
162
|
+
// shift the externalization threshold relative to what the LLM actually
|
|
163
|
+
// receives if the payload is ever inlined.
|
|
164
|
+
return JSON.stringify(value);
|
|
165
|
+
}
|
|
166
|
+
catch {
|
|
167
|
+
return String(value);
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
function isJsonLike(value) {
|
|
171
|
+
return typeof value === "object" && value !== null;
|
|
172
|
+
}
|
|
173
|
+
function formatBytes(bytes) {
|
|
174
|
+
if (bytes < 1024) {
|
|
175
|
+
return `${bytes} B`;
|
|
176
|
+
}
|
|
177
|
+
if (bytes < 1024 * 1024) {
|
|
178
|
+
return `${(bytes / 1024).toFixed(1)} KB`;
|
|
179
|
+
}
|
|
180
|
+
return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;
|
|
181
|
+
}
|
|
@@ -8,6 +8,7 @@ import type { Client } from "@modelcontextprotocol/sdk/client/index.js";
|
|
|
8
8
|
import type { ExternalMCPToolInfo, ExternalMCPToolResult } from "../types/externalMcp.js";
|
|
9
9
|
import type { ToolDiscoveryResult, ExternalToolExecutionOptions } from "../types/mcpTypes.js";
|
|
10
10
|
import type { JsonObject } from "../types/common.js";
|
|
11
|
+
import type { McpOutputNormalizer } from "./mcpOutputNormalizer.js";
|
|
11
12
|
/**
|
|
12
13
|
* ToolDiscoveryService
|
|
13
14
|
* Handles automatic tool discovery and registration from external MCP servers
|
|
@@ -17,7 +18,16 @@ export declare class ToolDiscoveryService extends EventEmitter {
|
|
|
17
18
|
private toolRegistry;
|
|
18
19
|
private serverTools;
|
|
19
20
|
private discoveryInProgress;
|
|
21
|
+
/** Optional normalizer applied to every tool output before it is returned. */
|
|
22
|
+
private outputNormalizer?;
|
|
20
23
|
constructor();
|
|
24
|
+
/**
|
|
25
|
+
* Attach a McpOutputNormalizer.
|
|
26
|
+
* When set, every raw callTool() result is passed through the normalizer
|
|
27
|
+
* before being returned. Oversized outputs are replaced with compact
|
|
28
|
+
* surrogates according to the configured strategy.
|
|
29
|
+
*/
|
|
30
|
+
setOutputNormalizer(normalizer: McpOutputNormalizer): void;
|
|
21
31
|
/**
|
|
22
32
|
* Discover tools from an external MCP server
|
|
23
33
|
*/
|