@juspay/neurolink 7.30.0 → 7.31.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/core/baseProvider.d.ts +6 -6
- package/dist/core/baseProvider.js +30 -34
- package/dist/core/conversationMemoryManager.js +15 -9
- package/dist/core/types.d.ts +2 -0
- package/dist/factories/providerRegistry.js +1 -1
- package/dist/index.d.ts +3 -1
- package/dist/index.js +2 -0
- package/dist/lib/core/baseProvider.d.ts +6 -6
- package/dist/lib/core/baseProvider.js +30 -34
- package/dist/lib/core/conversationMemoryManager.js +15 -9
- package/dist/lib/core/types.d.ts +2 -0
- package/dist/lib/factories/providerRegistry.js +1 -1
- package/dist/lib/index.d.ts +3 -1
- package/dist/lib/index.js +2 -0
- package/dist/lib/middleware/builtin/analytics.d.ts +1 -1
- package/dist/lib/middleware/builtin/guardrails.d.ts +1 -1
- package/dist/lib/middleware/factory.d.ts +1 -1
- package/dist/lib/middleware/index.d.ts +1 -1
- package/dist/lib/middleware/registry.d.ts +1 -1
- package/dist/lib/providers/amazonBedrock.d.ts +28 -59
- package/dist/lib/providers/amazonBedrock.js +913 -330
- package/dist/lib/types/streamTypes.d.ts +2 -0
- package/dist/lib/utils/conversationMemoryUtils.js +1 -1
- package/dist/lib/utils/logger.d.ts +164 -4
- package/dist/lib/utils/logger.js +163 -10
- package/dist/lib/utils/providerUtils.js +9 -6
- package/dist/middleware/builtin/analytics.d.ts +1 -1
- package/dist/middleware/builtin/guardrails.d.ts +1 -1
- package/dist/middleware/factory.d.ts +1 -1
- package/dist/middleware/index.d.ts +1 -1
- package/dist/middleware/registry.d.ts +1 -1
- package/dist/providers/amazonBedrock.d.ts +28 -59
- package/dist/providers/amazonBedrock.js +913 -330
- package/dist/types/streamTypes.d.ts +2 -0
- package/dist/utils/conversationMemoryUtils.js +1 -1
- package/dist/utils/logger.d.ts +164 -4
- package/dist/utils/logger.js +163 -10
- package/dist/utils/providerUtils.js +9 -6
- package/package.json +2 -3
- package/dist/lib/providers/aws/credentialProvider.d.ts +0 -58
- package/dist/lib/providers/aws/credentialProvider.js +0 -267
- package/dist/lib/providers/aws/credentialTester.d.ts +0 -49
- package/dist/lib/providers/aws/credentialTester.js +0 -394
- package/dist/providers/aws/credentialProvider.d.ts +0 -58
- package/dist/providers/aws/credentialProvider.js +0 -267
- package/dist/providers/aws/credentialTester.d.ts +0 -49
- package/dist/providers/aws/credentialTester.js +0 -394
- /package/dist/lib/{middleware/types.d.ts → types/middlewareTypes.d.ts} +0 -0
- /package/dist/lib/{middleware/types.js → types/middlewareTypes.js} +0 -0
- /package/dist/{middleware/types.d.ts → types/middlewareTypes.d.ts} +0 -0
- /package/dist/{middleware/types.js → types/middlewareTypes.js} +0 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,15 @@
|
|
|
1
|
+
## [7.31.0](https://github.com/juspay/neurolink/compare/v7.30.1...v7.31.0) (2025-09-01)
|
|
2
|
+
|
|
3
|
+
### Features
|
|
4
|
+
|
|
5
|
+
- **(core):** implement global middleware architecture ([8eb711a](https://github.com/juspay/neurolink/commit/8eb711ae827773c3fbc5339402d6cbee4e0bc8d4))
|
|
6
|
+
|
|
7
|
+
## [7.30.1](https://github.com/juspay/neurolink/compare/v7.30.0...v7.30.1) (2025-08-31)
|
|
8
|
+
|
|
9
|
+
### Bug Fixes
|
|
10
|
+
|
|
11
|
+
- **(bedrock):** migrate from ai-sdk to native AWS SDK implementation ([e5d8a4c](https://github.com/juspay/neurolink/commit/e5d8a4c85144ed558167f5083abd89d125576ab0))
|
|
12
|
+
|
|
1
13
|
## [7.30.0](https://github.com/juspay/neurolink/compare/v7.29.3...v7.30.0) (2025-08-29)
|
|
2
14
|
|
|
3
15
|
### Features
|
|
@@ -2,6 +2,7 @@ import type { ValidationSchema } from "../types/typeAliases.js";
|
|
|
2
2
|
import type { Tool, LanguageModelV1 } from "ai";
|
|
3
3
|
import type { AIProvider, TextGenerationOptions, TextGenerationResult, EnhancedGenerateResult, AnalyticsData, AIProviderName } from "../core/types.js";
|
|
4
4
|
import type { EvaluationData } from "../index.js";
|
|
5
|
+
import type { MiddlewareFactoryOptions } from "../types/middlewareTypes.js";
|
|
5
6
|
import type { StreamOptions, StreamResult } from "../types/streamTypes.js";
|
|
6
7
|
import type { UnknownRecord } from "../types/common.js";
|
|
7
8
|
import type { NeuroLink } from "../neurolink.js";
|
|
@@ -13,6 +14,7 @@ export declare abstract class BaseProvider implements AIProvider {
|
|
|
13
14
|
protected readonly modelName: string;
|
|
14
15
|
protected readonly providerName: AIProviderName;
|
|
15
16
|
protected readonly defaultTimeout: number;
|
|
17
|
+
protected middlewareOptions?: MiddlewareFactoryOptions;
|
|
16
18
|
protected readonly directTools: {};
|
|
17
19
|
protected mcpTools?: Record<string, Tool>;
|
|
18
20
|
protected customTools?: Map<string, unknown>;
|
|
@@ -20,7 +22,7 @@ export declare abstract class BaseProvider implements AIProvider {
|
|
|
20
22
|
protected sessionId?: string;
|
|
21
23
|
protected userId?: string;
|
|
22
24
|
protected neurolink?: NeuroLink;
|
|
23
|
-
constructor(modelName?: string, providerName?: AIProviderName, neurolink?: NeuroLink);
|
|
25
|
+
constructor(modelName?: string, providerName?: AIProviderName, neurolink?: NeuroLink, middleware?: MiddlewareFactoryOptions);
|
|
24
26
|
/**
|
|
25
27
|
* Check if this provider supports tool/function calling
|
|
26
28
|
* Override in subclasses to disable tools for specific providers or models
|
|
@@ -67,16 +69,14 @@ export declare abstract class BaseProvider implements AIProvider {
|
|
|
67
69
|
/**
|
|
68
70
|
* Get AI SDK model with middleware applied
|
|
69
71
|
* This method wraps the base model with any configured middleware
|
|
72
|
+
* TODO: Implement global level middlewares that can be used
|
|
70
73
|
*/
|
|
71
74
|
protected getAISDKModelWithMiddleware(options?: TextGenerationOptions | StreamOptions): Promise<LanguageModelV1>;
|
|
72
75
|
/**
|
|
73
|
-
* Extract middleware options from generation options
|
|
76
|
+
* Extract middleware options from generation options. This is the single
|
|
77
|
+
* source of truth for deciding if middleware should be applied.
|
|
74
78
|
*/
|
|
75
79
|
private extractMiddlewareOptions;
|
|
76
|
-
/**
|
|
77
|
-
* Determine if middleware should be skipped for this request
|
|
78
|
-
*/
|
|
79
|
-
private shouldSkipMiddleware;
|
|
80
80
|
/**
|
|
81
81
|
* Check if a schema is a Zod schema
|
|
82
82
|
*/
|
|
@@ -18,6 +18,7 @@ export class BaseProvider {
|
|
|
18
18
|
modelName;
|
|
19
19
|
providerName;
|
|
20
20
|
defaultTimeout = 30000; // 30 seconds
|
|
21
|
+
middlewareOptions; // TODO: Implement global level middlewares that can be used
|
|
21
22
|
// Tools are conditionally included based on centralized configuration
|
|
22
23
|
directTools = shouldDisableBuiltinTools()
|
|
23
24
|
? {}
|
|
@@ -28,10 +29,11 @@ export class BaseProvider {
|
|
|
28
29
|
sessionId;
|
|
29
30
|
userId;
|
|
30
31
|
neurolink; // Reference to actual NeuroLink instance for MCP tools
|
|
31
|
-
constructor(modelName, providerName, neurolink) {
|
|
32
|
+
constructor(modelName, providerName, neurolink, middleware) {
|
|
32
33
|
this.modelName = modelName || this.getDefaultModel();
|
|
33
34
|
this.providerName = providerName || this.getProviderName();
|
|
34
35
|
this.neurolink = neurolink;
|
|
36
|
+
this.middlewareOptions = middleware;
|
|
35
37
|
}
|
|
36
38
|
/**
|
|
37
39
|
* Check if this provider supports tool/function calling
|
|
@@ -170,8 +172,7 @@ export class BaseProvider {
|
|
|
170
172
|
totalTools: getKeyCount(tools),
|
|
171
173
|
totalToolNames: getKeysAsString(tools),
|
|
172
174
|
});
|
|
173
|
-
|
|
174
|
-
const model = await this.getAISDKModel(); // This method is now REQUIRED
|
|
175
|
+
const model = await this.getAISDKModelWithMiddleware(options);
|
|
175
176
|
// Build proper message array with conversation history
|
|
176
177
|
const messages = buildMessagesArray(options);
|
|
177
178
|
const result = await generateText({
|
|
@@ -402,13 +403,14 @@ export class BaseProvider {
|
|
|
402
403
|
/**
|
|
403
404
|
* Get AI SDK model with middleware applied
|
|
404
405
|
* This method wraps the base model with any configured middleware
|
|
406
|
+
* TODO: Implement global level middlewares that can be used
|
|
405
407
|
*/
|
|
406
408
|
async getAISDKModelWithMiddleware(options = {}) {
|
|
407
409
|
// Get the base model
|
|
408
410
|
const baseModel = await this.getAISDKModel();
|
|
409
411
|
// Check if middleware should be applied
|
|
410
412
|
const middlewareOptions = this.extractMiddlewareOptions(options);
|
|
411
|
-
if (!middlewareOptions
|
|
413
|
+
if (!middlewareOptions) {
|
|
412
414
|
return baseModel;
|
|
413
415
|
}
|
|
414
416
|
try {
|
|
@@ -437,47 +439,41 @@ export class BaseProvider {
|
|
|
437
439
|
}
|
|
438
440
|
}
|
|
439
441
|
/**
|
|
440
|
-
* Extract middleware options from generation options
|
|
442
|
+
* Extract middleware options from generation options. This is the single
|
|
443
|
+
* source of truth for deciding if middleware should be applied.
|
|
441
444
|
*/
|
|
442
445
|
extractMiddlewareOptions(options) {
|
|
443
|
-
//
|
|
444
|
-
const
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
const disabledMiddleware = optionsRecord.disabledMiddleware;
|
|
448
|
-
const preset = optionsRecord.middlewarePreset;
|
|
449
|
-
// If no middleware configuration is present, return null
|
|
450
|
-
if (!middlewareConfig &&
|
|
451
|
-
!enabledMiddleware &&
|
|
452
|
-
!disabledMiddleware &&
|
|
453
|
-
!preset) {
|
|
446
|
+
// 1. Determine effective middleware config: per-request overrides global.
|
|
447
|
+
const middlewareOpts = options.middleware ??
|
|
448
|
+
this.middlewareOptions;
|
|
449
|
+
if (!middlewareOpts) {
|
|
454
450
|
return null;
|
|
455
451
|
}
|
|
452
|
+
// 2. The middleware property must be an object with configuration.
|
|
453
|
+
if (typeof middlewareOpts !== "object" || middlewareOpts === null) {
|
|
454
|
+
return null;
|
|
455
|
+
}
|
|
456
|
+
// 3. Check if the middleware object has any actual configuration keys.
|
|
457
|
+
const fullOpts = middlewareOpts;
|
|
458
|
+
const hasArray = (arr) => Array.isArray(arr) && arr.length > 0;
|
|
459
|
+
const hasConfig = !!fullOpts.middlewareConfig ||
|
|
460
|
+
hasArray(fullOpts.enabledMiddleware) ||
|
|
461
|
+
hasArray(fullOpts.disabledMiddleware) ||
|
|
462
|
+
!!fullOpts.preset ||
|
|
463
|
+
hasArray(fullOpts.middleware);
|
|
464
|
+
if (!hasConfig) {
|
|
465
|
+
return null;
|
|
466
|
+
}
|
|
467
|
+
// 4. Return the formatted options if configuration is present.
|
|
456
468
|
return {
|
|
457
|
-
|
|
458
|
-
enabledMiddleware,
|
|
459
|
-
disabledMiddleware,
|
|
460
|
-
preset,
|
|
469
|
+
...fullOpts,
|
|
461
470
|
global: {
|
|
462
471
|
collectStats: true,
|
|
463
472
|
continueOnError: true,
|
|
473
|
+
...(fullOpts.global || {}),
|
|
464
474
|
},
|
|
465
475
|
};
|
|
466
476
|
}
|
|
467
|
-
/**
|
|
468
|
-
* Determine if middleware should be skipped for this request
|
|
469
|
-
*/
|
|
470
|
-
shouldSkipMiddleware(options) {
|
|
471
|
-
// Skip middleware if explicitly disabled
|
|
472
|
-
if (options.disableMiddleware === true) {
|
|
473
|
-
return true;
|
|
474
|
-
}
|
|
475
|
-
// Skip middleware for tool-disabled requests to avoid conflicts
|
|
476
|
-
if (options.disableTools === true) {
|
|
477
|
-
return true;
|
|
478
|
-
}
|
|
479
|
-
return false;
|
|
480
|
-
}
|
|
481
477
|
// ===================
|
|
482
478
|
// TOOL MANAGEMENT
|
|
483
479
|
// ===================
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
* Handles in-memory conversation storage, session management, and context injection
|
|
4
4
|
*/
|
|
5
5
|
import { ConversationMemoryError } from "../types/conversationTypes.js";
|
|
6
|
-
import { DEFAULT_MAX_TURNS_PER_SESSION, DEFAULT_MAX_SESSIONS, MESSAGES_PER_TURN } from "../config/conversationMemoryConfig.js";
|
|
6
|
+
import { DEFAULT_MAX_TURNS_PER_SESSION, DEFAULT_MAX_SESSIONS, MESSAGES_PER_TURN, } from "../config/conversationMemoryConfig.js";
|
|
7
7
|
import { logger } from "../utils/logger.js";
|
|
8
8
|
import { NeuroLink } from "../neurolink.js";
|
|
9
9
|
export class ConversationMemoryManager {
|
|
@@ -49,13 +49,15 @@ export class ConversationMemoryManager {
|
|
|
49
49
|
session.messages.push({ role: "user", content: userMessage }, { role: "assistant", content: aiResponse });
|
|
50
50
|
session.lastActivity = Date.now();
|
|
51
51
|
if (this.config.enableSummarization) {
|
|
52
|
-
const
|
|
53
|
-
|
|
52
|
+
const userAssistantCount = session.messages.filter((msg) => msg.role === "user" || msg.role === "assistant").length;
|
|
53
|
+
const currentTurnCount = Math.floor(userAssistantCount / MESSAGES_PER_TURN);
|
|
54
|
+
if (currentTurnCount >= (this.config.summarizationThresholdTurns || 20)) {
|
|
54
55
|
await this._summarizeSession(session);
|
|
55
56
|
}
|
|
56
57
|
}
|
|
57
58
|
else {
|
|
58
|
-
const maxMessages = (this.config.maxTurnsPerSession || DEFAULT_MAX_TURNS_PER_SESSION) *
|
|
59
|
+
const maxMessages = (this.config.maxTurnsPerSession || DEFAULT_MAX_TURNS_PER_SESSION) *
|
|
60
|
+
MESSAGES_PER_TURN;
|
|
59
61
|
if (session.messages.length > maxMessages) {
|
|
60
62
|
session.messages = session.messages.slice(-maxMessages);
|
|
61
63
|
}
|
|
@@ -96,13 +98,15 @@ export class ConversationMemoryManager {
|
|
|
96
98
|
return;
|
|
97
99
|
}
|
|
98
100
|
const summarizationPrompt = this._createSummarizationPrompt(messagesToSummarize);
|
|
99
|
-
const summarizer = new NeuroLink({
|
|
101
|
+
const summarizer = new NeuroLink({
|
|
102
|
+
conversationMemory: { enabled: false },
|
|
103
|
+
});
|
|
100
104
|
try {
|
|
101
105
|
const providerName = this.config.summarizationProvider;
|
|
102
106
|
// Map provider names to correct format
|
|
103
107
|
let mappedProvider = providerName;
|
|
104
|
-
if (providerName ===
|
|
105
|
-
mappedProvider =
|
|
108
|
+
if (providerName === "vertex") {
|
|
109
|
+
mappedProvider = "googlevertex";
|
|
106
110
|
}
|
|
107
111
|
if (!mappedProvider) {
|
|
108
112
|
logger.error(`[ConversationMemory] Missing summarization provider`);
|
|
@@ -118,7 +122,7 @@ export class ConversationMemoryManager {
|
|
|
118
122
|
if (summaryResult.content) {
|
|
119
123
|
session.messages = [
|
|
120
124
|
this.createSummarySystemMessage(summaryResult.content),
|
|
121
|
-
...recentMessages
|
|
125
|
+
...recentMessages,
|
|
122
126
|
];
|
|
123
127
|
logger.info(`[ConversationMemory] Summarization complete for session ${session.sessionId}.`);
|
|
124
128
|
}
|
|
@@ -131,7 +135,9 @@ export class ConversationMemoryManager {
|
|
|
131
135
|
}
|
|
132
136
|
}
|
|
133
137
|
_createSummarizationPrompt(history) {
|
|
134
|
-
const formattedHistory = history
|
|
138
|
+
const formattedHistory = history
|
|
139
|
+
.map((msg) => `${msg.role}: ${msg.content}`)
|
|
140
|
+
.join("\n\n");
|
|
135
141
|
return `
|
|
136
142
|
You are a context summarization AI. Your task is to condense the following conversation history for another AI assistant.
|
|
137
143
|
The summary must be a concise, third-person narrative that retains all critical information, including key entities, technical details, decisions made, and any specific dates or times mentioned.
|
package/dist/core/types.d.ts
CHANGED
|
@@ -7,6 +7,7 @@ import type { ChatMessage, ConversationMemoryConfig } from "../types/conversatio
|
|
|
7
7
|
import type { TokenUsage, AnalyticsData } from "../types/providers.js";
|
|
8
8
|
import type { EvaluationData } from "../index.js";
|
|
9
9
|
export type { EvaluationData };
|
|
10
|
+
import type { MiddlewareFactoryOptions } from "../types/middlewareTypes.js";
|
|
10
11
|
export interface TextGenerationResult {
|
|
11
12
|
content: string;
|
|
12
13
|
provider?: string;
|
|
@@ -157,6 +158,7 @@ export interface TextGenerationOptions {
|
|
|
157
158
|
conversationMessages?: ChatMessage[];
|
|
158
159
|
conversationMemoryConfig?: Partial<ConversationMemoryConfig>;
|
|
159
160
|
originalPrompt?: string;
|
|
161
|
+
middleware?: MiddlewareFactoryOptions;
|
|
160
162
|
expectedOutcome?: string;
|
|
161
163
|
evaluationCriteria?: string[];
|
|
162
164
|
}
|
|
@@ -41,7 +41,7 @@ export class ProviderRegistry {
|
|
|
41
41
|
// Register Amazon Bedrock provider
|
|
42
42
|
ProviderFactory.registerProvider(AIProviderName.BEDROCK, async (modelName, _providerName, sdk) => {
|
|
43
43
|
const { AmazonBedrockProvider } = await import("../providers/amazonBedrock.js");
|
|
44
|
-
return new AmazonBedrockProvider(modelName,
|
|
44
|
+
return new AmazonBedrockProvider(modelName, sdk);
|
|
45
45
|
}, undefined, // Let provider read BEDROCK_MODEL from .env
|
|
46
46
|
["bedrock", "aws"]);
|
|
47
47
|
// Register Azure OpenAI provider
|
package/dist/index.d.ts
CHANGED
|
@@ -15,10 +15,12 @@ export { validateTool } from "./sdk/toolRegistration.js";
|
|
|
15
15
|
export type { ToolResult, ToolDefinition } from "./types/tools.js";
|
|
16
16
|
export { BedrockModels, OpenAIModels, VertexModels, DEFAULT_PROVIDER_CONFIGS, } from "./core/types.js";
|
|
17
17
|
export { getBestProvider, getAvailableProviders, isValidProvider, } from "./utils/providerUtils.js";
|
|
18
|
+
export { dynamicModelProvider } from "./core/dynamicModels.js";
|
|
19
|
+
export type { ModelConfig, ModelRegistry } from "./core/dynamicModels.js";
|
|
18
20
|
export { NeuroLink } from "./neurolink.js";
|
|
19
21
|
export type { ProviderStatus, MCPStatus } from "./neurolink.js";
|
|
20
22
|
export type { MCPServerInfo } from "./types/mcpTypes.js";
|
|
21
|
-
export type { NeuroLinkMiddleware, MiddlewareContext, MiddlewareFactoryOptions, MiddlewarePreset, MiddlewareConfig, } from "./
|
|
23
|
+
export type { NeuroLinkMiddleware, MiddlewareContext, MiddlewareFactoryOptions, MiddlewarePreset, MiddlewareConfig, } from "./types/middlewareTypes.js";
|
|
22
24
|
export { MiddlewareFactory } from "./middleware/factory.js";
|
|
23
25
|
export declare const VERSION = "1.0.0";
|
|
24
26
|
/**
|
package/dist/index.js
CHANGED
|
@@ -14,6 +14,8 @@ export { validateTool } from "./sdk/toolRegistration.js";
|
|
|
14
14
|
export { BedrockModels, OpenAIModels, VertexModels, DEFAULT_PROVIDER_CONFIGS, } from "./core/types.js";
|
|
15
15
|
// Utility exports
|
|
16
16
|
export { getBestProvider, getAvailableProviders, isValidProvider, } from "./utils/providerUtils.js";
|
|
17
|
+
// Dynamic Models exports
|
|
18
|
+
export { dynamicModelProvider } from "./core/dynamicModels.js";
|
|
17
19
|
// Main NeuroLink wrapper class and diagnostic types
|
|
18
20
|
export { NeuroLink } from "./neurolink.js";
|
|
19
21
|
export { MiddlewareFactory } from "./middleware/factory.js";
|
|
@@ -2,6 +2,7 @@ import type { ValidationSchema } from "../types/typeAliases.js";
|
|
|
2
2
|
import type { Tool, LanguageModelV1 } from "ai";
|
|
3
3
|
import type { AIProvider, TextGenerationOptions, TextGenerationResult, EnhancedGenerateResult, AnalyticsData, AIProviderName } from "../core/types.js";
|
|
4
4
|
import type { EvaluationData } from "../index.js";
|
|
5
|
+
import type { MiddlewareFactoryOptions } from "../types/middlewareTypes.js";
|
|
5
6
|
import type { StreamOptions, StreamResult } from "../types/streamTypes.js";
|
|
6
7
|
import type { UnknownRecord } from "../types/common.js";
|
|
7
8
|
import type { NeuroLink } from "../neurolink.js";
|
|
@@ -13,6 +14,7 @@ export declare abstract class BaseProvider implements AIProvider {
|
|
|
13
14
|
protected readonly modelName: string;
|
|
14
15
|
protected readonly providerName: AIProviderName;
|
|
15
16
|
protected readonly defaultTimeout: number;
|
|
17
|
+
protected middlewareOptions?: MiddlewareFactoryOptions;
|
|
16
18
|
protected readonly directTools: {};
|
|
17
19
|
protected mcpTools?: Record<string, Tool>;
|
|
18
20
|
protected customTools?: Map<string, unknown>;
|
|
@@ -20,7 +22,7 @@ export declare abstract class BaseProvider implements AIProvider {
|
|
|
20
22
|
protected sessionId?: string;
|
|
21
23
|
protected userId?: string;
|
|
22
24
|
protected neurolink?: NeuroLink;
|
|
23
|
-
constructor(modelName?: string, providerName?: AIProviderName, neurolink?: NeuroLink);
|
|
25
|
+
constructor(modelName?: string, providerName?: AIProviderName, neurolink?: NeuroLink, middleware?: MiddlewareFactoryOptions);
|
|
24
26
|
/**
|
|
25
27
|
* Check if this provider supports tool/function calling
|
|
26
28
|
* Override in subclasses to disable tools for specific providers or models
|
|
@@ -67,16 +69,14 @@ export declare abstract class BaseProvider implements AIProvider {
|
|
|
67
69
|
/**
|
|
68
70
|
* Get AI SDK model with middleware applied
|
|
69
71
|
* This method wraps the base model with any configured middleware
|
|
72
|
+
* TODO: Implement global level middlewares that can be used
|
|
70
73
|
*/
|
|
71
74
|
protected getAISDKModelWithMiddleware(options?: TextGenerationOptions | StreamOptions): Promise<LanguageModelV1>;
|
|
72
75
|
/**
|
|
73
|
-
* Extract middleware options from generation options
|
|
76
|
+
* Extract middleware options from generation options. This is the single
|
|
77
|
+
* source of truth for deciding if middleware should be applied.
|
|
74
78
|
*/
|
|
75
79
|
private extractMiddlewareOptions;
|
|
76
|
-
/**
|
|
77
|
-
* Determine if middleware should be skipped for this request
|
|
78
|
-
*/
|
|
79
|
-
private shouldSkipMiddleware;
|
|
80
80
|
/**
|
|
81
81
|
* Check if a schema is a Zod schema
|
|
82
82
|
*/
|
|
@@ -18,6 +18,7 @@ export class BaseProvider {
|
|
|
18
18
|
modelName;
|
|
19
19
|
providerName;
|
|
20
20
|
defaultTimeout = 30000; // 30 seconds
|
|
21
|
+
middlewareOptions; // TODO: Implement global level middlewares that can be used
|
|
21
22
|
// Tools are conditionally included based on centralized configuration
|
|
22
23
|
directTools = shouldDisableBuiltinTools()
|
|
23
24
|
? {}
|
|
@@ -28,10 +29,11 @@ export class BaseProvider {
|
|
|
28
29
|
sessionId;
|
|
29
30
|
userId;
|
|
30
31
|
neurolink; // Reference to actual NeuroLink instance for MCP tools
|
|
31
|
-
constructor(modelName, providerName, neurolink) {
|
|
32
|
+
constructor(modelName, providerName, neurolink, middleware) {
|
|
32
33
|
this.modelName = modelName || this.getDefaultModel();
|
|
33
34
|
this.providerName = providerName || this.getProviderName();
|
|
34
35
|
this.neurolink = neurolink;
|
|
36
|
+
this.middlewareOptions = middleware;
|
|
35
37
|
}
|
|
36
38
|
/**
|
|
37
39
|
* Check if this provider supports tool/function calling
|
|
@@ -170,8 +172,7 @@ export class BaseProvider {
|
|
|
170
172
|
totalTools: getKeyCount(tools),
|
|
171
173
|
totalToolNames: getKeysAsString(tools),
|
|
172
174
|
});
|
|
173
|
-
|
|
174
|
-
const model = await this.getAISDKModel(); // This method is now REQUIRED
|
|
175
|
+
const model = await this.getAISDKModelWithMiddleware(options);
|
|
175
176
|
// Build proper message array with conversation history
|
|
176
177
|
const messages = buildMessagesArray(options);
|
|
177
178
|
const result = await generateText({
|
|
@@ -402,13 +403,14 @@ export class BaseProvider {
|
|
|
402
403
|
/**
|
|
403
404
|
* Get AI SDK model with middleware applied
|
|
404
405
|
* This method wraps the base model with any configured middleware
|
|
406
|
+
* TODO: Implement global level middlewares that can be used
|
|
405
407
|
*/
|
|
406
408
|
async getAISDKModelWithMiddleware(options = {}) {
|
|
407
409
|
// Get the base model
|
|
408
410
|
const baseModel = await this.getAISDKModel();
|
|
409
411
|
// Check if middleware should be applied
|
|
410
412
|
const middlewareOptions = this.extractMiddlewareOptions(options);
|
|
411
|
-
if (!middlewareOptions
|
|
413
|
+
if (!middlewareOptions) {
|
|
412
414
|
return baseModel;
|
|
413
415
|
}
|
|
414
416
|
try {
|
|
@@ -437,47 +439,41 @@ export class BaseProvider {
|
|
|
437
439
|
}
|
|
438
440
|
}
|
|
439
441
|
/**
|
|
440
|
-
* Extract middleware options from generation options
|
|
442
|
+
* Extract middleware options from generation options. This is the single
|
|
443
|
+
* source of truth for deciding if middleware should be applied.
|
|
441
444
|
*/
|
|
442
445
|
extractMiddlewareOptions(options) {
|
|
443
|
-
//
|
|
444
|
-
const
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
const disabledMiddleware = optionsRecord.disabledMiddleware;
|
|
448
|
-
const preset = optionsRecord.middlewarePreset;
|
|
449
|
-
// If no middleware configuration is present, return null
|
|
450
|
-
if (!middlewareConfig &&
|
|
451
|
-
!enabledMiddleware &&
|
|
452
|
-
!disabledMiddleware &&
|
|
453
|
-
!preset) {
|
|
446
|
+
// 1. Determine effective middleware config: per-request overrides global.
|
|
447
|
+
const middlewareOpts = options.middleware ??
|
|
448
|
+
this.middlewareOptions;
|
|
449
|
+
if (!middlewareOpts) {
|
|
454
450
|
return null;
|
|
455
451
|
}
|
|
452
|
+
// 2. The middleware property must be an object with configuration.
|
|
453
|
+
if (typeof middlewareOpts !== "object" || middlewareOpts === null) {
|
|
454
|
+
return null;
|
|
455
|
+
}
|
|
456
|
+
// 3. Check if the middleware object has any actual configuration keys.
|
|
457
|
+
const fullOpts = middlewareOpts;
|
|
458
|
+
const hasArray = (arr) => Array.isArray(arr) && arr.length > 0;
|
|
459
|
+
const hasConfig = !!fullOpts.middlewareConfig ||
|
|
460
|
+
hasArray(fullOpts.enabledMiddleware) ||
|
|
461
|
+
hasArray(fullOpts.disabledMiddleware) ||
|
|
462
|
+
!!fullOpts.preset ||
|
|
463
|
+
hasArray(fullOpts.middleware);
|
|
464
|
+
if (!hasConfig) {
|
|
465
|
+
return null;
|
|
466
|
+
}
|
|
467
|
+
// 4. Return the formatted options if configuration is present.
|
|
456
468
|
return {
|
|
457
|
-
|
|
458
|
-
enabledMiddleware,
|
|
459
|
-
disabledMiddleware,
|
|
460
|
-
preset,
|
|
469
|
+
...fullOpts,
|
|
461
470
|
global: {
|
|
462
471
|
collectStats: true,
|
|
463
472
|
continueOnError: true,
|
|
473
|
+
...(fullOpts.global || {}),
|
|
464
474
|
},
|
|
465
475
|
};
|
|
466
476
|
}
|
|
467
|
-
/**
|
|
468
|
-
* Determine if middleware should be skipped for this request
|
|
469
|
-
*/
|
|
470
|
-
shouldSkipMiddleware(options) {
|
|
471
|
-
// Skip middleware if explicitly disabled
|
|
472
|
-
if (options.disableMiddleware === true) {
|
|
473
|
-
return true;
|
|
474
|
-
}
|
|
475
|
-
// Skip middleware for tool-disabled requests to avoid conflicts
|
|
476
|
-
if (options.disableTools === true) {
|
|
477
|
-
return true;
|
|
478
|
-
}
|
|
479
|
-
return false;
|
|
480
|
-
}
|
|
481
477
|
// ===================
|
|
482
478
|
// TOOL MANAGEMENT
|
|
483
479
|
// ===================
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
* Handles in-memory conversation storage, session management, and context injection
|
|
4
4
|
*/
|
|
5
5
|
import { ConversationMemoryError } from "../types/conversationTypes.js";
|
|
6
|
-
import { DEFAULT_MAX_TURNS_PER_SESSION, DEFAULT_MAX_SESSIONS, MESSAGES_PER_TURN } from "../config/conversationMemoryConfig.js";
|
|
6
|
+
import { DEFAULT_MAX_TURNS_PER_SESSION, DEFAULT_MAX_SESSIONS, MESSAGES_PER_TURN, } from "../config/conversationMemoryConfig.js";
|
|
7
7
|
import { logger } from "../utils/logger.js";
|
|
8
8
|
import { NeuroLink } from "../neurolink.js";
|
|
9
9
|
export class ConversationMemoryManager {
|
|
@@ -49,13 +49,15 @@ export class ConversationMemoryManager {
|
|
|
49
49
|
session.messages.push({ role: "user", content: userMessage }, { role: "assistant", content: aiResponse });
|
|
50
50
|
session.lastActivity = Date.now();
|
|
51
51
|
if (this.config.enableSummarization) {
|
|
52
|
-
const
|
|
53
|
-
|
|
52
|
+
const userAssistantCount = session.messages.filter((msg) => msg.role === "user" || msg.role === "assistant").length;
|
|
53
|
+
const currentTurnCount = Math.floor(userAssistantCount / MESSAGES_PER_TURN);
|
|
54
|
+
if (currentTurnCount >= (this.config.summarizationThresholdTurns || 20)) {
|
|
54
55
|
await this._summarizeSession(session);
|
|
55
56
|
}
|
|
56
57
|
}
|
|
57
58
|
else {
|
|
58
|
-
const maxMessages = (this.config.maxTurnsPerSession || DEFAULT_MAX_TURNS_PER_SESSION) *
|
|
59
|
+
const maxMessages = (this.config.maxTurnsPerSession || DEFAULT_MAX_TURNS_PER_SESSION) *
|
|
60
|
+
MESSAGES_PER_TURN;
|
|
59
61
|
if (session.messages.length > maxMessages) {
|
|
60
62
|
session.messages = session.messages.slice(-maxMessages);
|
|
61
63
|
}
|
|
@@ -96,13 +98,15 @@ export class ConversationMemoryManager {
|
|
|
96
98
|
return;
|
|
97
99
|
}
|
|
98
100
|
const summarizationPrompt = this._createSummarizationPrompt(messagesToSummarize);
|
|
99
|
-
const summarizer = new NeuroLink({
|
|
101
|
+
const summarizer = new NeuroLink({
|
|
102
|
+
conversationMemory: { enabled: false },
|
|
103
|
+
});
|
|
100
104
|
try {
|
|
101
105
|
const providerName = this.config.summarizationProvider;
|
|
102
106
|
// Map provider names to correct format
|
|
103
107
|
let mappedProvider = providerName;
|
|
104
|
-
if (providerName ===
|
|
105
|
-
mappedProvider =
|
|
108
|
+
if (providerName === "vertex") {
|
|
109
|
+
mappedProvider = "googlevertex";
|
|
106
110
|
}
|
|
107
111
|
if (!mappedProvider) {
|
|
108
112
|
logger.error(`[ConversationMemory] Missing summarization provider`);
|
|
@@ -118,7 +122,7 @@ export class ConversationMemoryManager {
|
|
|
118
122
|
if (summaryResult.content) {
|
|
119
123
|
session.messages = [
|
|
120
124
|
this.createSummarySystemMessage(summaryResult.content),
|
|
121
|
-
...recentMessages
|
|
125
|
+
...recentMessages,
|
|
122
126
|
];
|
|
123
127
|
logger.info(`[ConversationMemory] Summarization complete for session ${session.sessionId}.`);
|
|
124
128
|
}
|
|
@@ -131,7 +135,9 @@ export class ConversationMemoryManager {
|
|
|
131
135
|
}
|
|
132
136
|
}
|
|
133
137
|
_createSummarizationPrompt(history) {
|
|
134
|
-
const formattedHistory = history
|
|
138
|
+
const formattedHistory = history
|
|
139
|
+
.map((msg) => `${msg.role}: ${msg.content}`)
|
|
140
|
+
.join("\n\n");
|
|
135
141
|
return `
|
|
136
142
|
You are a context summarization AI. Your task is to condense the following conversation history for another AI assistant.
|
|
137
143
|
The summary must be a concise, third-person narrative that retains all critical information, including key entities, technical details, decisions made, and any specific dates or times mentioned.
|
package/dist/lib/core/types.d.ts
CHANGED
|
@@ -7,6 +7,7 @@ import type { ChatMessage, ConversationMemoryConfig } from "../types/conversatio
|
|
|
7
7
|
import type { TokenUsage, AnalyticsData } from "../types/providers.js";
|
|
8
8
|
import type { EvaluationData } from "../index.js";
|
|
9
9
|
export type { EvaluationData };
|
|
10
|
+
import type { MiddlewareFactoryOptions } from "../types/middlewareTypes.js";
|
|
10
11
|
export interface TextGenerationResult {
|
|
11
12
|
content: string;
|
|
12
13
|
provider?: string;
|
|
@@ -157,6 +158,7 @@ export interface TextGenerationOptions {
|
|
|
157
158
|
conversationMessages?: ChatMessage[];
|
|
158
159
|
conversationMemoryConfig?: Partial<ConversationMemoryConfig>;
|
|
159
160
|
originalPrompt?: string;
|
|
161
|
+
middleware?: MiddlewareFactoryOptions;
|
|
160
162
|
expectedOutcome?: string;
|
|
161
163
|
evaluationCriteria?: string[];
|
|
162
164
|
}
|
|
@@ -41,7 +41,7 @@ export class ProviderRegistry {
|
|
|
41
41
|
// Register Amazon Bedrock provider
|
|
42
42
|
ProviderFactory.registerProvider(AIProviderName.BEDROCK, async (modelName, _providerName, sdk) => {
|
|
43
43
|
const { AmazonBedrockProvider } = await import("../providers/amazonBedrock.js");
|
|
44
|
-
return new AmazonBedrockProvider(modelName,
|
|
44
|
+
return new AmazonBedrockProvider(modelName, sdk);
|
|
45
45
|
}, undefined, // Let provider read BEDROCK_MODEL from .env
|
|
46
46
|
["bedrock", "aws"]);
|
|
47
47
|
// Register Azure OpenAI provider
|
package/dist/lib/index.d.ts
CHANGED
|
@@ -15,10 +15,12 @@ export { validateTool } from "./sdk/toolRegistration.js";
|
|
|
15
15
|
export type { ToolResult, ToolDefinition } from "./types/tools.js";
|
|
16
16
|
export { BedrockModels, OpenAIModels, VertexModels, DEFAULT_PROVIDER_CONFIGS, } from "./core/types.js";
|
|
17
17
|
export { getBestProvider, getAvailableProviders, isValidProvider, } from "./utils/providerUtils.js";
|
|
18
|
+
export { dynamicModelProvider } from "./core/dynamicModels.js";
|
|
19
|
+
export type { ModelConfig, ModelRegistry } from "./core/dynamicModels.js";
|
|
18
20
|
export { NeuroLink } from "./neurolink.js";
|
|
19
21
|
export type { ProviderStatus, MCPStatus } from "./neurolink.js";
|
|
20
22
|
export type { MCPServerInfo } from "./types/mcpTypes.js";
|
|
21
|
-
export type { NeuroLinkMiddleware, MiddlewareContext, MiddlewareFactoryOptions, MiddlewarePreset, MiddlewareConfig, } from "./
|
|
23
|
+
export type { NeuroLinkMiddleware, MiddlewareContext, MiddlewareFactoryOptions, MiddlewarePreset, MiddlewareConfig, } from "./types/middlewareTypes.js";
|
|
22
24
|
export { MiddlewareFactory } from "./middleware/factory.js";
|
|
23
25
|
export declare const VERSION = "1.0.0";
|
|
24
26
|
/**
|
package/dist/lib/index.js
CHANGED
|
@@ -14,6 +14,8 @@ export { validateTool } from "./sdk/toolRegistration.js";
|
|
|
14
14
|
export { BedrockModels, OpenAIModels, VertexModels, DEFAULT_PROVIDER_CONFIGS, } from "./core/types.js";
|
|
15
15
|
// Utility exports
|
|
16
16
|
export { getBestProvider, getAvailableProviders, isValidProvider, } from "./utils/providerUtils.js";
|
|
17
|
+
// Dynamic Models exports
|
|
18
|
+
export { dynamicModelProvider } from "./core/dynamicModels.js";
|
|
17
19
|
// Main NeuroLink wrapper class and diagnostic types
|
|
18
20
|
export { NeuroLink } from "./neurolink.js";
|
|
19
21
|
export { MiddlewareFactory } from "./middleware/factory.js";
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { NeuroLinkMiddleware } from "
|
|
1
|
+
import type { NeuroLinkMiddleware } from "../../types/middlewareTypes.js";
|
|
2
2
|
/**
|
|
3
3
|
* Create analytics middleware for tracking AI model usage
|
|
4
4
|
* Collects metrics on token usage, response times, and model performance
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { LanguageModelV1 } from "ai";
|
|
2
|
-
import type { MiddlewareContext, MiddlewareConfig, MiddlewareFactoryOptions, MiddlewareChainStats, MiddlewarePreset, NeuroLinkMiddleware, MiddlewareRegistrationOptions } from "
|
|
2
|
+
import type { MiddlewareContext, MiddlewareConfig, MiddlewareFactoryOptions, MiddlewareChainStats, MiddlewarePreset, NeuroLinkMiddleware, MiddlewareRegistrationOptions } from "../types/middlewareTypes.js";
|
|
3
3
|
import { MiddlewareRegistry } from "./registry.js";
|
|
4
4
|
/**
|
|
5
5
|
* Middleware factory for creating and applying middleware chains.
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
* of language models with features like analytics, guardrails, caching, and more.
|
|
7
7
|
*/
|
|
8
8
|
import { MiddlewareFactory } from "./factory.js";
|
|
9
|
-
export type { NeuroLinkMiddleware, MiddlewareConfig, MiddlewareContext, MiddlewareConditions, MiddlewareRegistrationOptions, MiddlewareExecutionResult, MiddlewareChainStats, MiddlewarePreset, MiddlewareFactoryOptions, BuiltInMiddlewareType, } from "
|
|
9
|
+
export type { NeuroLinkMiddleware, MiddlewareConfig, MiddlewareContext, MiddlewareConditions, MiddlewareRegistrationOptions, MiddlewareExecutionResult, MiddlewareChainStats, MiddlewarePreset, MiddlewareFactoryOptions, BuiltInMiddlewareType, } from "../types/middlewareTypes.js";
|
|
10
10
|
export type { LanguageModelV1Middleware } from "ai";
|
|
11
11
|
export { MiddlewareFactory };
|
|
12
12
|
export default MiddlewareFactory;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { LanguageModelV1Middleware } from "ai";
|
|
2
|
-
import type { NeuroLinkMiddleware, MiddlewareConfig, MiddlewareContext, MiddlewareRegistrationOptions, MiddlewareExecutionResult } from "
|
|
2
|
+
import type { NeuroLinkMiddleware, MiddlewareConfig, MiddlewareContext, MiddlewareRegistrationOptions, MiddlewareExecutionResult } from "../types/middlewareTypes.js";
|
|
3
3
|
/**
|
|
4
4
|
* Manages the registration, configuration, and execution of middleware for a single factory instance.
|
|
5
5
|
*/
|