@juspay/neurolink 7.29.3 → 7.30.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (38) hide show
  1. package/CHANGELOG.md +6 -0
  2. package/dist/config/conversationMemoryConfig.js +5 -0
  3. package/dist/core/conversationMemoryManager.d.ts +9 -15
  4. package/dist/core/conversationMemoryManager.js +98 -57
  5. package/dist/core/types.d.ts +3 -1
  6. package/dist/lib/config/conversationMemoryConfig.js +5 -0
  7. package/dist/lib/core/conversationMemoryManager.d.ts +9 -15
  8. package/dist/lib/core/conversationMemoryManager.js +98 -57
  9. package/dist/lib/core/types.d.ts +3 -1
  10. package/dist/lib/neurolink.d.ts +0 -9
  11. package/dist/lib/neurolink.js +7 -39
  12. package/dist/lib/types/conversationTypes.d.ts +10 -0
  13. package/dist/lib/types/generateTypes.d.ts +1 -2
  14. package/dist/lib/utils/conversationMemoryUtils.d.ts +1 -2
  15. package/dist/lib/utils/conversationMemoryUtils.js +6 -7
  16. package/dist/neurolink.d.ts +0 -9
  17. package/dist/neurolink.js +7 -39
  18. package/dist/types/conversationTypes.d.ts +10 -0
  19. package/dist/types/generateTypes.d.ts +1 -2
  20. package/dist/utils/conversationMemoryUtils.d.ts +1 -2
  21. package/dist/utils/conversationMemoryUtils.js +6 -7
  22. package/package.json +1 -1
  23. package/dist/context/ContextManager.d.ts +0 -28
  24. package/dist/context/ContextManager.js +0 -113
  25. package/dist/context/config.d.ts +0 -5
  26. package/dist/context/config.js +0 -42
  27. package/dist/context/types.d.ts +0 -20
  28. package/dist/context/types.js +0 -1
  29. package/dist/context/utils.d.ts +0 -7
  30. package/dist/context/utils.js +0 -8
  31. package/dist/lib/context/ContextManager.d.ts +0 -28
  32. package/dist/lib/context/ContextManager.js +0 -113
  33. package/dist/lib/context/config.d.ts +0 -5
  34. package/dist/lib/context/config.js +0 -42
  35. package/dist/lib/context/types.d.ts +0 -20
  36. package/dist/lib/context/types.js +0 -1
  37. package/dist/lib/context/utils.d.ts +0 -7
  38. package/dist/lib/context/utils.js +0 -8
package/CHANGELOG.md CHANGED
@@ -1,3 +1,9 @@
1
+ ## [7.30.0](https://github.com/juspay/neurolink/compare/v7.29.3...v7.30.0) (2025-08-29)
2
+
3
+ ### Features
4
+
5
+ - **(SDK):** Integrate context summarization with conversation memory BZ-43344 ([a2316ff](https://github.com/juspay/neurolink/commit/a2316ff6df55107316892d33365455e6ebdcbbd9))
6
+
1
7
  ## [7.29.3](https://github.com/juspay/neurolink/compare/v7.29.2...v7.29.3) (2025-08-29)
2
8
 
3
9
  ### Bug Fixes
@@ -36,5 +36,10 @@ export function getConversationMemoryDefaults() {
36
36
  maxSessions: Number(process.env.NEUROLINK_MEMORY_MAX_SESSIONS) || DEFAULT_MAX_SESSIONS,
37
37
  maxTurnsPerSession: Number(process.env.NEUROLINK_MEMORY_MAX_TURNS_PER_SESSION) ||
38
38
  DEFAULT_MAX_TURNS_PER_SESSION,
39
+ enableSummarization: process.env.NEUROLINK_SUMMARIZATION_ENABLED === "true",
40
+ summarizationThresholdTurns: Number(process.env.NEUROLINK_SUMMARIZATION_THRESHOLD_TURNS) || 20,
41
+ summarizationTargetTurns: Number(process.env.NEUROLINK_SUMMARIZATION_TARGET_TURNS) || 10,
42
+ summarizationProvider: process.env.NEUROLINK_SUMMARIZATION_PROVIDER || "vertex",
43
+ summarizationModel: process.env.NEUROLINK_SUMMARIZATION_MODEL || "gemini-2.5-flash",
39
44
  };
40
45
  }
@@ -2,10 +2,10 @@
2
2
  * Conversation Memory Manager for NeuroLink
3
3
  * Handles in-memory conversation storage, session management, and context injection
4
4
  */
5
- import type { ConversationMemoryConfig, ConversationMemoryStats, ChatMessage } from "../types/conversationTypes.js";
5
+ import type { ConversationMemoryConfig, SessionMemory, ConversationMemoryStats, ChatMessage } from "../types/conversationTypes.js";
6
6
  export declare class ConversationMemoryManager {
7
7
  private sessions;
8
- private config;
8
+ config: ConversationMemoryConfig;
9
9
  private isInitialized;
10
10
  constructor(config: ConversationMemoryConfig);
11
11
  /**
@@ -22,20 +22,14 @@ export declare class ConversationMemoryManager {
22
22
  * Returns pre-stored message array with zero conversion overhead
23
23
  */
24
24
  buildContextMessages(sessionId: string): ChatMessage[];
25
- /**
26
- * Get memory statistics (simplified for pure in-memory storage)
27
- * ULTRA-OPTIMIZED: Calculate turns from message count (each turn = MESSAGES_PER_TURN messages)
28
- */
29
- getStats(): Promise<ConversationMemoryStats>;
30
- /**
31
- * Clear all conversations for a specific session
32
- */
33
- clearSession(sessionId: string): Promise<boolean>;
34
- /**
35
- * Clear all conversations (reset memory)
36
- */
37
- clearAllSessions(): Promise<void>;
25
+ getSession(sessionId: string): SessionMemory | undefined;
26
+ createSummarySystemMessage(content: string): ChatMessage;
27
+ private _summarizeSession;
28
+ private _createSummarizationPrompt;
38
29
  private ensureInitialized;
39
30
  private createNewSession;
40
31
  private enforceSessionLimit;
32
+ getStats(): Promise<ConversationMemoryStats>;
33
+ clearSession(sessionId: string): Promise<boolean>;
34
+ clearAllSessions(): Promise<void>;
41
35
  }
@@ -3,14 +3,14 @@
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
+ import { NeuroLink } from "../neurolink.js";
8
9
  export class ConversationMemoryManager {
9
10
  sessions = new Map();
10
11
  config;
11
12
  isInitialized = false;
12
13
  constructor(config) {
13
- // Trust that config is already complete from applyConversationMemoryDefaults()
14
14
  this.config = config;
15
15
  }
16
16
  /**
@@ -48,21 +48,19 @@ export class ConversationMemoryManager {
48
48
  // ULTRA-OPTIMIZED: Direct message storage - no intermediate objects
49
49
  session.messages.push({ role: "user", content: userMessage }, { role: "assistant", content: aiResponse });
50
50
  session.lastActivity = Date.now();
51
- // Enforce per-session turn limit (each turn = MESSAGES_PER_TURN messages: user + assistant)
52
- const maxMessages = (this.config.maxTurnsPerSession || DEFAULT_MAX_TURNS_PER_SESSION) *
53
- MESSAGES_PER_TURN;
54
- if (session.messages.length > maxMessages) {
55
- session.messages = session.messages.slice(-maxMessages);
51
+ if (this.config.enableSummarization) {
52
+ const currentTurnCount = session.messages.length / MESSAGES_PER_TURN;
53
+ if (currentTurnCount > (this.config.summarizationThresholdTurns || 20)) {
54
+ await this._summarizeSession(session);
55
+ }
56
+ }
57
+ else {
58
+ const maxMessages = (this.config.maxTurnsPerSession || DEFAULT_MAX_TURNS_PER_SESSION) * MESSAGES_PER_TURN;
59
+ if (session.messages.length > maxMessages) {
60
+ session.messages = session.messages.slice(-maxMessages);
61
+ }
56
62
  }
57
- // Enforce global session limit
58
63
  this.enforceSessionLimit();
59
- logger.debug("Conversation turn stored", {
60
- sessionId,
61
- messageCount: session.messages.length,
62
- turnCount: session.messages.length / MESSAGES_PER_TURN, // Each turn = MESSAGES_PER_TURN messages
63
- userMessageLength: userMessage.length,
64
- aiResponseLength: aiResponse.length,
65
- });
66
64
  }
67
65
  catch (error) {
68
66
  throw new ConversationMemoryError(`Failed to store conversation turn for session ${sessionId}`, "STORAGE_ERROR", {
@@ -77,48 +75,74 @@ export class ConversationMemoryManager {
77
75
  */
78
76
  buildContextMessages(sessionId) {
79
77
  const session = this.sessions.get(sessionId);
80
- if (!session || session.messages.length === 0) {
81
- return [];
82
- }
83
- // ULTRA-OPTIMIZED: Direct return - no processing needed!
84
- return session.messages;
78
+ return session ? session.messages : [];
85
79
  }
86
- /**
87
- * Get memory statistics (simplified for pure in-memory storage)
88
- * ULTRA-OPTIMIZED: Calculate turns from message count (each turn = MESSAGES_PER_TURN messages)
89
- */
90
- async getStats() {
91
- await this.ensureInitialized();
92
- const sessions = Array.from(this.sessions.values());
93
- const totalTurns = sessions.reduce((sum, session) => sum + session.messages.length / MESSAGES_PER_TURN, 0);
80
+ getSession(sessionId) {
81
+ return this.sessions.get(sessionId);
82
+ }
83
+ createSummarySystemMessage(content) {
94
84
  return {
95
- totalSessions: sessions.length,
96
- totalTurns,
85
+ role: "system",
86
+ content: `Summary of previous conversation turns:\n\n${content}`,
97
87
  };
98
88
  }
99
- /**
100
- * Clear all conversations for a specific session
101
- */
102
- async clearSession(sessionId) {
103
- const session = this.sessions.get(sessionId);
104
- if (!session) {
105
- return false;
89
+ async _summarizeSession(session) {
90
+ logger.info(`[ConversationMemory] Summarizing session ${session.sessionId}...`);
91
+ const targetTurns = this.config.summarizationTargetTurns || 10;
92
+ const splitIndex = Math.max(0, session.messages.length - targetTurns * MESSAGES_PER_TURN);
93
+ const messagesToSummarize = session.messages.slice(0, splitIndex);
94
+ const recentMessages = session.messages.slice(splitIndex);
95
+ if (messagesToSummarize.length === 0) {
96
+ return;
97
+ }
98
+ const summarizationPrompt = this._createSummarizationPrompt(messagesToSummarize);
99
+ const summarizer = new NeuroLink({ conversationMemory: { enabled: false } });
100
+ try {
101
+ const providerName = this.config.summarizationProvider;
102
+ // Map provider names to correct format
103
+ let mappedProvider = providerName;
104
+ if (providerName === 'vertex') {
105
+ mappedProvider = 'googlevertex';
106
+ }
107
+ if (!mappedProvider) {
108
+ logger.error(`[ConversationMemory] Missing summarization provider`);
109
+ return;
110
+ }
111
+ logger.debug(`[ConversationMemory] Using provider: ${mappedProvider} for summarization`);
112
+ const summaryResult = await summarizer.generate({
113
+ input: { text: summarizationPrompt },
114
+ provider: mappedProvider,
115
+ model: this.config.summarizationModel,
116
+ disableTools: true,
117
+ });
118
+ if (summaryResult.content) {
119
+ session.messages = [
120
+ this.createSummarySystemMessage(summaryResult.content),
121
+ ...recentMessages
122
+ ];
123
+ logger.info(`[ConversationMemory] Summarization complete for session ${session.sessionId}.`);
124
+ }
125
+ else {
126
+ logger.warn(`[ConversationMemory] Summarization failed for session ${session.sessionId}. History not modified.`);
127
+ }
128
+ }
129
+ catch (error) {
130
+ logger.error(`[ConversationMemory] Error during summarization for session ${session.sessionId}`, { error });
106
131
  }
107
- // Remove from memory
108
- this.sessions.delete(sessionId);
109
- logger.info("Session cleared", { sessionId });
110
- return true;
111
132
  }
112
- /**
113
- * Clear all conversations (reset memory)
114
- */
115
- async clearAllSessions() {
116
- const sessionIds = Array.from(this.sessions.keys());
117
- // Clear memory
118
- this.sessions.clear();
119
- logger.info("All sessions cleared", { clearedCount: sessionIds.length });
133
+ _createSummarizationPrompt(history) {
134
+ const formattedHistory = history.map(msg => `${msg.role}: ${msg.content}`).join('\n\n');
135
+ return `
136
+ You are a context summarization AI. Your task is to condense the following conversation history for another AI assistant.
137
+ 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.
138
+ Ensure the summary flows logically and is ready to be used as context for the next turn in the conversation.
139
+
140
+ Conversation History to Summarize:
141
+ ---
142
+ ${formattedHistory}
143
+ ---
144
+ `.trim();
120
145
  }
121
- // Private methods
122
146
  async ensureInitialized() {
123
147
  if (!this.isInitialized) {
124
148
  await this.initialize();
@@ -138,16 +162,33 @@ export class ConversationMemoryManager {
138
162
  if (this.sessions.size <= maxSessions) {
139
163
  return;
140
164
  }
141
- // Sort sessions by last activity (oldest first)
142
165
  const sessions = Array.from(this.sessions.entries()).sort(([, a], [, b]) => a.lastActivity - b.lastActivity);
143
- // Remove oldest sessions
144
- const sessionsToRemove = sessions.slice(0, sessions.length - maxSessions);
166
+ const sessionsToRemove = sessions.slice(0, this.sessions.size - maxSessions);
145
167
  for (const [sessionId] of sessionsToRemove) {
146
168
  this.sessions.delete(sessionId);
147
169
  }
148
- logger.debug("Session limit enforced", {
149
- removedSessions: sessionsToRemove.length,
150
- remainingSessions: this.sessions.size,
151
- });
170
+ }
171
+ async getStats() {
172
+ await this.ensureInitialized();
173
+ const sessions = Array.from(this.sessions.values());
174
+ const totalTurns = sessions.reduce((sum, session) => sum + session.messages.length / MESSAGES_PER_TURN, 0);
175
+ return {
176
+ totalSessions: sessions.length,
177
+ totalTurns,
178
+ };
179
+ }
180
+ async clearSession(sessionId) {
181
+ const session = this.sessions.get(sessionId);
182
+ if (!session) {
183
+ return false;
184
+ }
185
+ this.sessions.delete(sessionId);
186
+ logger.info("Session cleared", { sessionId });
187
+ return true;
188
+ }
189
+ async clearAllSessions() {
190
+ const sessionIds = Array.from(this.sessions.keys());
191
+ this.sessions.clear();
192
+ logger.info("All sessions cleared", { clearedCount: sessionIds.length });
152
193
  }
153
194
  }
@@ -3,7 +3,7 @@ import type { ZodUnknownSchema, ValidationSchema } from "../types/typeAliases.js
3
3
  import type { GenerateResult } from "../types/generateTypes.js";
4
4
  import type { StreamOptions, StreamResult } from "../types/streamTypes.js";
5
5
  import type { JsonValue } from "../types/common.js";
6
- import type { ChatMessage } from "../types/conversationTypes.js";
6
+ import type { ChatMessage, ConversationMemoryConfig } from "../types/conversationTypes.js";
7
7
  import type { TokenUsage, AnalyticsData } from "../types/providers.js";
8
8
  import type { EvaluationData } from "../index.js";
9
9
  export type { EvaluationData };
@@ -155,6 +155,8 @@ export interface TextGenerationOptions {
155
155
  content: string;
156
156
  }>;
157
157
  conversationMessages?: ChatMessage[];
158
+ conversationMemoryConfig?: Partial<ConversationMemoryConfig>;
159
+ originalPrompt?: string;
158
160
  expectedOutcome?: string;
159
161
  evaluationCriteria?: string[];
160
162
  }
@@ -36,5 +36,10 @@ export function getConversationMemoryDefaults() {
36
36
  maxSessions: Number(process.env.NEUROLINK_MEMORY_MAX_SESSIONS) || DEFAULT_MAX_SESSIONS,
37
37
  maxTurnsPerSession: Number(process.env.NEUROLINK_MEMORY_MAX_TURNS_PER_SESSION) ||
38
38
  DEFAULT_MAX_TURNS_PER_SESSION,
39
+ enableSummarization: process.env.NEUROLINK_SUMMARIZATION_ENABLED === "true",
40
+ summarizationThresholdTurns: Number(process.env.NEUROLINK_SUMMARIZATION_THRESHOLD_TURNS) || 20,
41
+ summarizationTargetTurns: Number(process.env.NEUROLINK_SUMMARIZATION_TARGET_TURNS) || 10,
42
+ summarizationProvider: process.env.NEUROLINK_SUMMARIZATION_PROVIDER || "vertex",
43
+ summarizationModel: process.env.NEUROLINK_SUMMARIZATION_MODEL || "gemini-2.5-flash",
39
44
  };
40
45
  }
@@ -2,10 +2,10 @@
2
2
  * Conversation Memory Manager for NeuroLink
3
3
  * Handles in-memory conversation storage, session management, and context injection
4
4
  */
5
- import type { ConversationMemoryConfig, ConversationMemoryStats, ChatMessage } from "../types/conversationTypes.js";
5
+ import type { ConversationMemoryConfig, SessionMemory, ConversationMemoryStats, ChatMessage } from "../types/conversationTypes.js";
6
6
  export declare class ConversationMemoryManager {
7
7
  private sessions;
8
- private config;
8
+ config: ConversationMemoryConfig;
9
9
  private isInitialized;
10
10
  constructor(config: ConversationMemoryConfig);
11
11
  /**
@@ -22,20 +22,14 @@ export declare class ConversationMemoryManager {
22
22
  * Returns pre-stored message array with zero conversion overhead
23
23
  */
24
24
  buildContextMessages(sessionId: string): ChatMessage[];
25
- /**
26
- * Get memory statistics (simplified for pure in-memory storage)
27
- * ULTRA-OPTIMIZED: Calculate turns from message count (each turn = MESSAGES_PER_TURN messages)
28
- */
29
- getStats(): Promise<ConversationMemoryStats>;
30
- /**
31
- * Clear all conversations for a specific session
32
- */
33
- clearSession(sessionId: string): Promise<boolean>;
34
- /**
35
- * Clear all conversations (reset memory)
36
- */
37
- clearAllSessions(): Promise<void>;
25
+ getSession(sessionId: string): SessionMemory | undefined;
26
+ createSummarySystemMessage(content: string): ChatMessage;
27
+ private _summarizeSession;
28
+ private _createSummarizationPrompt;
38
29
  private ensureInitialized;
39
30
  private createNewSession;
40
31
  private enforceSessionLimit;
32
+ getStats(): Promise<ConversationMemoryStats>;
33
+ clearSession(sessionId: string): Promise<boolean>;
34
+ clearAllSessions(): Promise<void>;
41
35
  }
@@ -3,14 +3,14 @@
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
+ import { NeuroLink } from "../neurolink.js";
8
9
  export class ConversationMemoryManager {
9
10
  sessions = new Map();
10
11
  config;
11
12
  isInitialized = false;
12
13
  constructor(config) {
13
- // Trust that config is already complete from applyConversationMemoryDefaults()
14
14
  this.config = config;
15
15
  }
16
16
  /**
@@ -48,21 +48,19 @@ export class ConversationMemoryManager {
48
48
  // ULTRA-OPTIMIZED: Direct message storage - no intermediate objects
49
49
  session.messages.push({ role: "user", content: userMessage }, { role: "assistant", content: aiResponse });
50
50
  session.lastActivity = Date.now();
51
- // Enforce per-session turn limit (each turn = MESSAGES_PER_TURN messages: user + assistant)
52
- const maxMessages = (this.config.maxTurnsPerSession || DEFAULT_MAX_TURNS_PER_SESSION) *
53
- MESSAGES_PER_TURN;
54
- if (session.messages.length > maxMessages) {
55
- session.messages = session.messages.slice(-maxMessages);
51
+ if (this.config.enableSummarization) {
52
+ const currentTurnCount = session.messages.length / MESSAGES_PER_TURN;
53
+ if (currentTurnCount > (this.config.summarizationThresholdTurns || 20)) {
54
+ await this._summarizeSession(session);
55
+ }
56
+ }
57
+ else {
58
+ const maxMessages = (this.config.maxTurnsPerSession || DEFAULT_MAX_TURNS_PER_SESSION) * MESSAGES_PER_TURN;
59
+ if (session.messages.length > maxMessages) {
60
+ session.messages = session.messages.slice(-maxMessages);
61
+ }
56
62
  }
57
- // Enforce global session limit
58
63
  this.enforceSessionLimit();
59
- logger.debug("Conversation turn stored", {
60
- sessionId,
61
- messageCount: session.messages.length,
62
- turnCount: session.messages.length / MESSAGES_PER_TURN, // Each turn = MESSAGES_PER_TURN messages
63
- userMessageLength: userMessage.length,
64
- aiResponseLength: aiResponse.length,
65
- });
66
64
  }
67
65
  catch (error) {
68
66
  throw new ConversationMemoryError(`Failed to store conversation turn for session ${sessionId}`, "STORAGE_ERROR", {
@@ -77,48 +75,74 @@ export class ConversationMemoryManager {
77
75
  */
78
76
  buildContextMessages(sessionId) {
79
77
  const session = this.sessions.get(sessionId);
80
- if (!session || session.messages.length === 0) {
81
- return [];
82
- }
83
- // ULTRA-OPTIMIZED: Direct return - no processing needed!
84
- return session.messages;
78
+ return session ? session.messages : [];
85
79
  }
86
- /**
87
- * Get memory statistics (simplified for pure in-memory storage)
88
- * ULTRA-OPTIMIZED: Calculate turns from message count (each turn = MESSAGES_PER_TURN messages)
89
- */
90
- async getStats() {
91
- await this.ensureInitialized();
92
- const sessions = Array.from(this.sessions.values());
93
- const totalTurns = sessions.reduce((sum, session) => sum + session.messages.length / MESSAGES_PER_TURN, 0);
80
+ getSession(sessionId) {
81
+ return this.sessions.get(sessionId);
82
+ }
83
+ createSummarySystemMessage(content) {
94
84
  return {
95
- totalSessions: sessions.length,
96
- totalTurns,
85
+ role: "system",
86
+ content: `Summary of previous conversation turns:\n\n${content}`,
97
87
  };
98
88
  }
99
- /**
100
- * Clear all conversations for a specific session
101
- */
102
- async clearSession(sessionId) {
103
- const session = this.sessions.get(sessionId);
104
- if (!session) {
105
- return false;
89
+ async _summarizeSession(session) {
90
+ logger.info(`[ConversationMemory] Summarizing session ${session.sessionId}...`);
91
+ const targetTurns = this.config.summarizationTargetTurns || 10;
92
+ const splitIndex = Math.max(0, session.messages.length - targetTurns * MESSAGES_PER_TURN);
93
+ const messagesToSummarize = session.messages.slice(0, splitIndex);
94
+ const recentMessages = session.messages.slice(splitIndex);
95
+ if (messagesToSummarize.length === 0) {
96
+ return;
97
+ }
98
+ const summarizationPrompt = this._createSummarizationPrompt(messagesToSummarize);
99
+ const summarizer = new NeuroLink({ conversationMemory: { enabled: false } });
100
+ try {
101
+ const providerName = this.config.summarizationProvider;
102
+ // Map provider names to correct format
103
+ let mappedProvider = providerName;
104
+ if (providerName === 'vertex') {
105
+ mappedProvider = 'googlevertex';
106
+ }
107
+ if (!mappedProvider) {
108
+ logger.error(`[ConversationMemory] Missing summarization provider`);
109
+ return;
110
+ }
111
+ logger.debug(`[ConversationMemory] Using provider: ${mappedProvider} for summarization`);
112
+ const summaryResult = await summarizer.generate({
113
+ input: { text: summarizationPrompt },
114
+ provider: mappedProvider,
115
+ model: this.config.summarizationModel,
116
+ disableTools: true,
117
+ });
118
+ if (summaryResult.content) {
119
+ session.messages = [
120
+ this.createSummarySystemMessage(summaryResult.content),
121
+ ...recentMessages
122
+ ];
123
+ logger.info(`[ConversationMemory] Summarization complete for session ${session.sessionId}.`);
124
+ }
125
+ else {
126
+ logger.warn(`[ConversationMemory] Summarization failed for session ${session.sessionId}. History not modified.`);
127
+ }
128
+ }
129
+ catch (error) {
130
+ logger.error(`[ConversationMemory] Error during summarization for session ${session.sessionId}`, { error });
106
131
  }
107
- // Remove from memory
108
- this.sessions.delete(sessionId);
109
- logger.info("Session cleared", { sessionId });
110
- return true;
111
132
  }
112
- /**
113
- * Clear all conversations (reset memory)
114
- */
115
- async clearAllSessions() {
116
- const sessionIds = Array.from(this.sessions.keys());
117
- // Clear memory
118
- this.sessions.clear();
119
- logger.info("All sessions cleared", { clearedCount: sessionIds.length });
133
+ _createSummarizationPrompt(history) {
134
+ const formattedHistory = history.map(msg => `${msg.role}: ${msg.content}`).join('\n\n');
135
+ return `
136
+ You are a context summarization AI. Your task is to condense the following conversation history for another AI assistant.
137
+ 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.
138
+ Ensure the summary flows logically and is ready to be used as context for the next turn in the conversation.
139
+
140
+ Conversation History to Summarize:
141
+ ---
142
+ ${formattedHistory}
143
+ ---
144
+ `.trim();
120
145
  }
121
- // Private methods
122
146
  async ensureInitialized() {
123
147
  if (!this.isInitialized) {
124
148
  await this.initialize();
@@ -138,16 +162,33 @@ export class ConversationMemoryManager {
138
162
  if (this.sessions.size <= maxSessions) {
139
163
  return;
140
164
  }
141
- // Sort sessions by last activity (oldest first)
142
165
  const sessions = Array.from(this.sessions.entries()).sort(([, a], [, b]) => a.lastActivity - b.lastActivity);
143
- // Remove oldest sessions
144
- const sessionsToRemove = sessions.slice(0, sessions.length - maxSessions);
166
+ const sessionsToRemove = sessions.slice(0, this.sessions.size - maxSessions);
145
167
  for (const [sessionId] of sessionsToRemove) {
146
168
  this.sessions.delete(sessionId);
147
169
  }
148
- logger.debug("Session limit enforced", {
149
- removedSessions: sessionsToRemove.length,
150
- remainingSessions: this.sessions.size,
151
- });
170
+ }
171
+ async getStats() {
172
+ await this.ensureInitialized();
173
+ const sessions = Array.from(this.sessions.values());
174
+ const totalTurns = sessions.reduce((sum, session) => sum + session.messages.length / MESSAGES_PER_TURN, 0);
175
+ return {
176
+ totalSessions: sessions.length,
177
+ totalTurns,
178
+ };
179
+ }
180
+ async clearSession(sessionId) {
181
+ const session = this.sessions.get(sessionId);
182
+ if (!session) {
183
+ return false;
184
+ }
185
+ this.sessions.delete(sessionId);
186
+ logger.info("Session cleared", { sessionId });
187
+ return true;
188
+ }
189
+ async clearAllSessions() {
190
+ const sessionIds = Array.from(this.sessions.keys());
191
+ this.sessions.clear();
192
+ logger.info("All sessions cleared", { clearedCount: sessionIds.length });
152
193
  }
153
194
  }
@@ -3,7 +3,7 @@ import type { ZodUnknownSchema, ValidationSchema } from "../types/typeAliases.js
3
3
  import type { GenerateResult } from "../types/generateTypes.js";
4
4
  import type { StreamOptions, StreamResult } from "../types/streamTypes.js";
5
5
  import type { JsonValue } from "../types/common.js";
6
- import type { ChatMessage } from "../types/conversationTypes.js";
6
+ import type { ChatMessage, ConversationMemoryConfig } from "../types/conversationTypes.js";
7
7
  import type { TokenUsage, AnalyticsData } from "../types/providers.js";
8
8
  import type { EvaluationData } from "../index.js";
9
9
  export type { EvaluationData };
@@ -155,6 +155,8 @@ export interface TextGenerationOptions {
155
155
  content: string;
156
156
  }>;
157
157
  conversationMessages?: ChatMessage[];
158
+ conversationMemoryConfig?: Partial<ConversationMemoryConfig>;
159
+ originalPrompt?: string;
158
160
  expectedOutcome?: string;
159
161
  evaluationCriteria?: string[];
160
162
  }
@@ -39,11 +39,9 @@ export interface MCPStatus {
39
39
  error?: string;
40
40
  [key: string]: unknown;
41
41
  }
42
- import type { ContextManagerConfig } from "./context/types.js";
43
42
  export declare class NeuroLink {
44
43
  private mcpInitialized;
45
44
  private emitter;
46
- private contextManager;
47
45
  private autoDiscoveredServerInfos;
48
46
  private externalServerManager;
49
47
  private toolCircuitBreakers;
@@ -167,13 +165,6 @@ export declare class NeuroLink {
167
165
  * @returns The original prompt text as a string.
168
166
  */
169
167
  private _extractOriginalPrompt;
170
- /**
171
- * Enables automatic context summarization for the NeuroLink instance.
172
- * Once enabled, the instance will maintain conversation history and
173
- * automatically summarize it when it exceeds token limits.
174
- * @param config Optional configuration to override default summarization settings.
175
- */
176
- enableContextSummarization(config?: Partial<ContextManagerConfig>): void;
177
168
  /**
178
169
  * Generate AI content using the best available provider with MCP tool integration.
179
170
  * This is the primary method for text generation with full feature support.