@juspay/neurolink 7.11.1 → 7.12.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 (51) hide show
  1. package/CHANGELOG.md +6 -0
  2. package/README.md +15 -0
  3. package/dist/config/conversationMemoryConfig.d.ts +27 -0
  4. package/dist/config/conversationMemoryConfig.js +39 -0
  5. package/dist/core/baseProvider.js +4 -2
  6. package/dist/core/conversationMemoryManager.d.ts +41 -0
  7. package/dist/core/conversationMemoryManager.js +152 -0
  8. package/dist/core/types.d.ts +2 -0
  9. package/dist/lib/config/conversationMemoryConfig.d.ts +27 -0
  10. package/dist/lib/config/conversationMemoryConfig.js +39 -0
  11. package/dist/lib/core/baseProvider.js +4 -2
  12. package/dist/lib/core/conversationMemoryManager.d.ts +41 -0
  13. package/dist/lib/core/conversationMemoryManager.js +152 -0
  14. package/dist/lib/core/types.d.ts +2 -0
  15. package/dist/lib/neurolink.d.ts +22 -4
  16. package/dist/lib/neurolink.js +67 -5
  17. package/dist/lib/providers/amazonBedrock.js +4 -2
  18. package/dist/lib/providers/anthropic.js +4 -2
  19. package/dist/lib/providers/azureOpenai.js +4 -2
  20. package/dist/lib/providers/googleAiStudio.js +4 -2
  21. package/dist/lib/providers/googleVertex.js +4 -2
  22. package/dist/lib/providers/huggingFace.js +4 -2
  23. package/dist/lib/providers/litellm.js +4 -2
  24. package/dist/lib/providers/mistral.js +3 -2
  25. package/dist/lib/providers/openAI.js +4 -2
  26. package/dist/lib/types/conversationTypes.d.ts +95 -0
  27. package/dist/lib/types/conversationTypes.js +17 -0
  28. package/dist/lib/types/streamTypes.d.ts +2 -0
  29. package/dist/lib/utils/conversationMemoryUtils.d.ts +22 -0
  30. package/dist/lib/utils/conversationMemoryUtils.js +77 -0
  31. package/dist/lib/utils/messageBuilder.d.ts +13 -0
  32. package/dist/lib/utils/messageBuilder.js +48 -0
  33. package/dist/neurolink.d.ts +22 -4
  34. package/dist/neurolink.js +67 -5
  35. package/dist/providers/amazonBedrock.js +4 -2
  36. package/dist/providers/anthropic.js +4 -2
  37. package/dist/providers/azureOpenai.js +4 -2
  38. package/dist/providers/googleAiStudio.js +4 -2
  39. package/dist/providers/googleVertex.js +4 -2
  40. package/dist/providers/huggingFace.js +4 -2
  41. package/dist/providers/litellm.js +4 -2
  42. package/dist/providers/mistral.js +3 -2
  43. package/dist/providers/openAI.js +4 -2
  44. package/dist/types/conversationTypes.d.ts +95 -0
  45. package/dist/types/conversationTypes.js +17 -0
  46. package/dist/types/streamTypes.d.ts +2 -0
  47. package/dist/utils/conversationMemoryUtils.d.ts +22 -0
  48. package/dist/utils/conversationMemoryUtils.js +77 -0
  49. package/dist/utils/messageBuilder.d.ts +13 -0
  50. package/dist/utils/messageBuilder.js +48 -0
  51. package/package.json +1 -1
@@ -0,0 +1,48 @@
1
+ /**
2
+ * Message Builder Utility
3
+ * Centralized logic for building message arrays from TextGenerationOptions
4
+ */
5
+ import { CONVERSATION_INSTRUCTIONS } from "../config/conversationMemoryConfig.js";
6
+ /**
7
+ * Build a properly formatted message array for AI providers
8
+ * Combines system prompt, conversation history, and current user prompt
9
+ * Supports both TextGenerationOptions and StreamOptions
10
+ */
11
+ export function buildMessagesArray(options) {
12
+ const messages = [];
13
+ // Check if conversation history exists
14
+ const hasConversationHistory = options.conversationMessages && options.conversationMessages.length > 0;
15
+ // Build enhanced system prompt
16
+ let systemPrompt = options.systemPrompt?.trim() || "";
17
+ // Add conversation-aware instructions when history exists
18
+ if (hasConversationHistory) {
19
+ systemPrompt = `${systemPrompt.trim()}${CONVERSATION_INSTRUCTIONS}`;
20
+ }
21
+ // Add system message if we have one
22
+ if (systemPrompt.trim()) {
23
+ messages.push({
24
+ role: "system",
25
+ content: systemPrompt.trim(),
26
+ });
27
+ }
28
+ // Add conversation history if available
29
+ if (hasConversationHistory && options.conversationMessages) {
30
+ messages.push(...options.conversationMessages);
31
+ }
32
+ // Add current user prompt (required)
33
+ // Handle both TextGenerationOptions (prompt field) and StreamOptions (input.text field)
34
+ let currentPrompt;
35
+ if ("prompt" in options && options.prompt) {
36
+ currentPrompt = options.prompt;
37
+ }
38
+ else if ("input" in options && options.input?.text) {
39
+ currentPrompt = options.input.text;
40
+ }
41
+ if (currentPrompt?.trim()) {
42
+ messages.push({
43
+ role: "user",
44
+ content: currentPrompt.trim(),
45
+ });
46
+ }
47
+ return messages;
48
+ }
@@ -11,6 +11,7 @@ import type { StreamOptions, StreamResult } from "./types/streamTypes.js";
11
11
  import type { SimpleTool } from "./sdk/toolRegistration.js";
12
12
  import type { InMemoryMCPServerConfig } from "./types/mcpTypes.js";
13
13
  import { EventEmitter } from "events";
14
+ import type { ConversationMemoryConfig } from "./types/conversationTypes.js";
14
15
  export interface ProviderStatus {
15
16
  provider: string;
16
17
  status: "working" | "failed" | "not-configured";
@@ -55,7 +56,10 @@ export declare class NeuroLink {
55
56
  * @param success - Whether the tool execution was successful
56
57
  */
57
58
  private emitToolEndEvent;
58
- constructor();
59
+ private conversationMemory?;
60
+ constructor(config?: {
61
+ conversationMemory?: Partial<ConversationMemoryConfig>;
62
+ });
59
63
  /**
60
64
  * Initialize MCP registry with enhanced error handling and resource cleanup
61
65
  * Uses isolated async context to prevent hanging
@@ -75,9 +79,11 @@ export declare class NeuroLink {
75
79
  * REDESIGNED INTERNAL GENERATION - NO CIRCULAR DEPENDENCIES
76
80
  *
77
81
  * This method implements a clean fallback chain:
78
- * 1. Try MCP-enhanced generation if available
79
- * 2. Fall back to direct provider generation
80
- * 3. No recursive calls - each method has a specific purpose
82
+ * 1. Initialize conversation memory if enabled
83
+ * 2. Inject conversation history into prompt
84
+ * 3. Try MCP-enhanced generation if available
85
+ * 4. Fall back to direct provider generation
86
+ * 5. Store conversation turn for future context
81
87
  */
82
88
  private generateTextInternal;
83
89
  /**
@@ -367,6 +373,18 @@ export declare class NeuroLink {
367
373
  recommendations: string[];
368
374
  }>;
369
375
  };
376
+ /**
377
+ * Get conversation memory statistics (public API)
378
+ */
379
+ getConversationStats(): Promise<import("./types/conversationTypes.js").ConversationMemoryStats>;
380
+ /**
381
+ * Clear conversation history for a specific session (public API)
382
+ */
383
+ clearConversationSession(sessionId: string): Promise<boolean>;
384
+ /**
385
+ * Clear all conversation history (public API)
386
+ */
387
+ clearAllConversations(): Promise<void>;
370
388
  }
371
389
  export declare const neurolink: NeuroLink;
372
390
  export default neurolink;
package/dist/neurolink.js CHANGED
@@ -27,6 +27,8 @@ import { processFactoryOptions, enhanceTextGenerationOptions, validateFactoryCon
27
27
  // Enhanced error handling imports
28
28
  import { ErrorFactory, NeuroLinkError, withTimeout, withRetry, isRetriableError, logStructuredError, CircuitBreaker, } from "./utils/errorHandling.js";
29
29
  import { EventEmitter } from "events";
30
+ import { ConversationMemoryManager } from "./core/conversationMemoryManager.js";
31
+ import { applyConversationMemoryDefaults, getConversationMessages, storeConversationTurn, } from "./utils/conversationMemoryUtils.js";
30
32
  // Core types imported from core/types.js
31
33
  export class NeuroLink {
32
34
  mcpInitialized = false;
@@ -52,11 +54,22 @@ export class NeuroLink {
52
54
  timestamp: Date.now(),
53
55
  });
54
56
  }
55
- constructor() {
57
+ // Conversation memory support
58
+ conversationMemory;
59
+ constructor(config) {
56
60
  // SDK always disables manual MCP config for security
57
61
  ProviderRegistry.setOptions({
58
62
  enableManualMCP: false,
59
63
  });
64
+ // Initialize conversation memory if enabled
65
+ if (config?.conversationMemory?.enabled) {
66
+ const memoryConfig = applyConversationMemoryDefaults(config.conversationMemory);
67
+ this.conversationMemory = new ConversationMemoryManager(memoryConfig);
68
+ logger.info("NeuroLink initialized with conversation memory", {
69
+ maxSessions: memoryConfig.maxSessions,
70
+ maxTurnsPerSession: memoryConfig.maxTurnsPerSession,
71
+ });
72
+ }
60
73
  }
61
74
  /**
62
75
  * Initialize MCP registry with enhanced error handling and resource cleanup
@@ -247,9 +260,11 @@ export class NeuroLink {
247
260
  * REDESIGNED INTERNAL GENERATION - NO CIRCULAR DEPENDENCIES
248
261
  *
249
262
  * This method implements a clean fallback chain:
250
- * 1. Try MCP-enhanced generation if available
251
- * 2. Fall back to direct provider generation
252
- * 3. No recursive calls - each method has a specific purpose
263
+ * 1. Initialize conversation memory if enabled
264
+ * 2. Inject conversation history into prompt
265
+ * 3. Try MCP-enhanced generation if available
266
+ * 4. Fall back to direct provider generation
267
+ * 5. Store conversation turn for future context
253
268
  */
254
269
  async generateTextInternal(options) {
255
270
  const startTime = Date.now();
@@ -257,14 +272,21 @@ export class NeuroLink {
257
272
  logger.debug(`[${functionTag}] Starting generation`, {
258
273
  provider: options.provider || "auto",
259
274
  promptLength: options.prompt?.length || 0,
275
+ hasConversationMemory: !!this.conversationMemory,
260
276
  });
261
277
  try {
278
+ // Initialize conversation memory if enabled
279
+ if (this.conversationMemory) {
280
+ await this.conversationMemory.initialize();
281
+ }
262
282
  // Try MCP-enhanced generation first (if not explicitly disabled)
263
283
  if (!options.disableTools) {
264
284
  try {
265
285
  const mcpResult = await this.tryMCPGeneration(options);
266
286
  if (mcpResult && mcpResult.content) {
267
287
  logger.debug(`[${functionTag}] MCP generation successful`);
288
+ // Store conversation turn
289
+ await storeConversationTurn(this.conversationMemory, options, mcpResult);
268
290
  return mcpResult;
269
291
  }
270
292
  }
@@ -277,6 +299,8 @@ export class NeuroLink {
277
299
  // Fall back to direct provider generation
278
300
  const directResult = await this.directProviderGeneration(options);
279
301
  logger.debug(`[${functionTag}] Direct generation successful`);
302
+ // Store conversation turn
303
+ await storeConversationTurn(this.conversationMemory, options, directResult);
280
304
  return directResult;
281
305
  }
282
306
  catch (error) {
@@ -334,6 +358,8 @@ export class NeuroLink {
334
358
  }
335
359
  // Create tool-aware system prompt
336
360
  const enhancedSystemPrompt = this.createToolAwareSystemPrompt(options.systemPrompt, availableTools);
361
+ // Get conversation messages for context
362
+ const conversationMessages = await getConversationMessages(this.conversationMemory, options);
337
363
  // Create provider and generate
338
364
  const provider = await AIProviderFactory.createProvider(providerName, options.model, !options.disableTools, // Pass disableTools as inverse of enableMCP
339
365
  this);
@@ -345,6 +371,7 @@ export class NeuroLink {
345
371
  const result = await provider.generate({
346
372
  ...options,
347
373
  systemPrompt: enhancedSystemPrompt,
374
+ conversationMessages, // Inject conversation history
348
375
  });
349
376
  const responseTime = Date.now() - startTime;
350
377
  // Check if result is meaningful
@@ -413,6 +440,8 @@ export class NeuroLink {
413
440
  for (const providerName of tryProviders) {
414
441
  try {
415
442
  logger.debug(`[${functionTag}] Attempting provider: ${providerName}`);
443
+ // Get conversation messages for context
444
+ const conversationMessages = await getConversationMessages(this.conversationMemory, options);
416
445
  const provider = await AIProviderFactory.createProvider(providerName, options.model, !options.disableTools, // Pass disableTools as inverse of enableMCP
417
446
  this);
418
447
  // Enable tool execution for direct provider generation using BaseProvider method
@@ -420,7 +449,10 @@ export class NeuroLink {
420
449
  customTools: this.customTools,
421
450
  executeTool: this.executeTool.bind(this),
422
451
  }, functionTag);
423
- const result = await provider.generate(options);
452
+ const result = await provider.generate({
453
+ ...options,
454
+ conversationMessages, // Inject conversation history
455
+ });
424
456
  const responseTime = Date.now() - startTime;
425
457
  if (!result) {
426
458
  throw new Error(`Provider ${providerName} returned null result`);
@@ -1577,6 +1609,36 @@ export class NeuroLink {
1577
1609
  tools,
1578
1610
  };
1579
1611
  }
1612
+ // ============================================================================
1613
+ // CONVERSATION MEMORY PUBLIC API
1614
+ // ============================================================================
1615
+ /**
1616
+ * Get conversation memory statistics (public API)
1617
+ */
1618
+ async getConversationStats() {
1619
+ if (!this.conversationMemory) {
1620
+ throw new Error("Conversation memory is not enabled");
1621
+ }
1622
+ return await this.conversationMemory.getStats();
1623
+ }
1624
+ /**
1625
+ * Clear conversation history for a specific session (public API)
1626
+ */
1627
+ async clearConversationSession(sessionId) {
1628
+ if (!this.conversationMemory) {
1629
+ throw new Error("Conversation memory is not enabled");
1630
+ }
1631
+ return await this.conversationMemory.clearSession(sessionId);
1632
+ }
1633
+ /**
1634
+ * Clear all conversation history (public API)
1635
+ */
1636
+ async clearAllConversations() {
1637
+ if (!this.conversationMemory) {
1638
+ throw new Error("Conversation memory is not enabled");
1639
+ }
1640
+ await this.conversationMemory.clearAllSessions();
1641
+ }
1580
1642
  }
1581
1643
  // Create default instance
1582
1644
  export const neurolink = new NeuroLink();
@@ -5,6 +5,7 @@ import { logger } from "../utils/logger.js";
5
5
  import { TimeoutError, } from "../utils/timeout.js";
6
6
  import { DEFAULT_MAX_TOKENS } from "../core/constants.js";
7
7
  import { validateApiKey, createAWSAccessKeyConfig, createAWSSecretConfig, getAWSRegion, getAWSSessionToken, } from "../utils/providerConfig.js";
8
+ import { buildMessagesArray } from "../utils/messageBuilder.js";
8
9
  // Configuration helpers
9
10
  const getBedrockModelId = () => {
10
11
  return (process.env.BEDROCK_MODEL ||
@@ -79,10 +80,11 @@ export class AmazonBedrockProvider extends BaseProvider {
79
80
  async executeStream(options, analysisSchema) {
80
81
  try {
81
82
  this.validateStreamOptions(options);
83
+ // Build message array from options
84
+ const messages = buildMessagesArray(options);
82
85
  const result = await streamText({
83
86
  model: this.model,
84
- prompt: options.input.text,
85
- system: options.systemPrompt,
87
+ messages: messages,
86
88
  maxTokens: options.maxTokens || DEFAULT_MAX_TOKENS,
87
89
  temperature: options.temperature,
88
90
  });
@@ -5,6 +5,7 @@ import { logger } from "../utils/logger.js";
5
5
  import { createTimeoutController, TimeoutError, } from "../utils/timeout.js";
6
6
  import { DEFAULT_MAX_TOKENS, DEFAULT_MAX_STEPS } from "../core/constants.js";
7
7
  import { validateApiKey, createAnthropicConfig, getProviderModel, } from "../utils/providerConfig.js";
8
+ import { buildMessagesArray } from "../utils/messageBuilder.js";
8
9
  // Configuration helpers - now using consolidated utility
9
10
  const getAnthropicApiKey = () => {
10
11
  return validateApiKey(createAnthropicConfig());
@@ -94,10 +95,11 @@ export class AnthropicProvider extends BaseProvider {
94
95
  // ✅ Get tools for streaming (same as generate method)
95
96
  const shouldUseTools = !options.disableTools && this.supportsTools();
96
97
  const tools = shouldUseTools ? await this.getAllTools() : {};
98
+ // Build message array from options
99
+ const messages = buildMessagesArray(options);
97
100
  const result = await streamText({
98
101
  model: this.model,
99
- prompt: options.input.text,
100
- system: options.systemPrompt || undefined,
102
+ messages: messages,
101
103
  temperature: options.temperature,
102
104
  maxTokens: options.maxTokens || DEFAULT_MAX_TOKENS,
103
105
  tools,
@@ -3,6 +3,7 @@ import { streamText } from "ai";
3
3
  import { BaseProvider } from "../core/baseProvider.js";
4
4
  import { validateApiKey, createAzureAPIKeyConfig, createAzureEndpointConfig, } from "../utils/providerConfig.js";
5
5
  import { logger } from "../utils/logger.js";
6
+ import { buildMessagesArray } from "../utils/messageBuilder.js";
6
7
  export class AzureOpenAIProvider extends BaseProvider {
7
8
  apiKey;
8
9
  resourceName;
@@ -69,12 +70,13 @@ export class AzureOpenAIProvider extends BaseProvider {
69
70
  // executeGenerate removed - BaseProvider handles all generation with tools
70
71
  async executeStream(options, analysisSchema) {
71
72
  try {
73
+ // Build message array from options
74
+ const messages = buildMessagesArray(options);
72
75
  const stream = await streamText({
73
76
  model: this.azureProvider(this.deployment),
74
- prompt: options.input?.text || "",
77
+ messages: messages,
75
78
  maxTokens: options.maxTokens || 1000,
76
79
  temperature: options.temperature || 0.7,
77
- system: options.systemPrompt,
78
80
  });
79
81
  return {
80
82
  stream: (async function* () {
@@ -6,6 +6,7 @@ import { logger } from "../utils/logger.js";
6
6
  import { createTimeoutController, TimeoutError, } from "../utils/timeout.js";
7
7
  import { DEFAULT_MAX_TOKENS, DEFAULT_MAX_STEPS } from "../core/constants.js";
8
8
  import { streamAnalyticsCollector } from "../core/streamAnalytics.js";
9
+ import { buildMessagesArray } from "../utils/messageBuilder.js";
9
10
  // Environment variable setup
10
11
  if (!process.env.GOOGLE_GENERATIVE_AI_API_KEY &&
11
12
  process.env.GOOGLE_AI_API_KEY) {
@@ -76,10 +77,11 @@ export class GoogleAIStudioProvider extends BaseProvider {
76
77
  // Get tools consistently with generate method
77
78
  const shouldUseTools = !options.disableTools && this.supportsTools();
78
79
  const tools = shouldUseTools ? await this.getAllTools() : {};
80
+ // Build message array from options
81
+ const messages = buildMessagesArray(options);
79
82
  const result = await streamText({
80
83
  model,
81
- prompt: options.input.text,
82
- system: options.systemPrompt,
84
+ messages: messages,
83
85
  temperature: options.temperature,
84
86
  maxTokens: options.maxTokens || DEFAULT_MAX_TOKENS,
85
87
  tools,
@@ -6,6 +6,7 @@ import { createTimeoutController, TimeoutError, } from "../utils/timeout.js";
6
6
  import { DEFAULT_MAX_TOKENS, DEFAULT_MAX_STEPS } from "../core/constants.js";
7
7
  import { ModelConfigurationManager } from "../core/modelConfiguration.js";
8
8
  import { validateApiKey, createVertexProjectConfig, createGoogleAuthConfig, } from "../utils/providerConfig.js";
9
+ import { buildMessagesArray } from "../utils/messageBuilder.js";
9
10
  // Cache for anthropic module to avoid repeated imports
10
11
  let _createVertexAnthropic = null;
11
12
  let _anthropicImportAttempted = false;
@@ -189,6 +190,8 @@ export class GoogleVertexProvider extends BaseProvider {
189
190
  const timeoutController = createTimeoutController(timeout, this.providerName, "stream");
190
191
  try {
191
192
  this.validateStreamOptions(options);
193
+ // Build message array from options
194
+ const messages = buildMessagesArray(options);
192
195
  logger.debug(`${functionTag}: Starting stream request`, {
193
196
  modelName: this.modelName,
194
197
  promptLength: options.input.text.length,
@@ -209,8 +212,7 @@ export class GoogleVertexProvider extends BaseProvider {
209
212
  // Build complete stream options with proper typing
210
213
  let streamOptions = {
211
214
  model: model,
212
- prompt: options.input.text,
213
- system: options.systemPrompt,
215
+ messages: messages,
214
216
  temperature: options.temperature,
215
217
  ...(maxTokens && { maxTokens }),
216
218
  tools,
@@ -5,6 +5,7 @@ import { logger } from "../utils/logger.js";
5
5
  import { createTimeoutController, TimeoutError } from "../utils/timeout.js";
6
6
  import { DEFAULT_MAX_TOKENS } from "../core/constants.js";
7
7
  import { validateApiKey, createHuggingFaceConfig, getProviderModel, } from "../utils/providerConfig.js";
8
+ import { buildMessagesArray } from "../utils/messageBuilder.js";
8
9
  // Configuration helpers - now using consolidated utility
9
10
  const getHuggingFaceApiKey = () => {
10
11
  return validateApiKey(createHuggingFaceConfig());
@@ -111,10 +112,11 @@ export class HuggingFaceProvider extends BaseProvider {
111
112
  try {
112
113
  // Enhanced tool handling for HuggingFace models
113
114
  const streamOptions = this.prepareStreamOptions(options, analysisSchema);
115
+ // Build message array from options
116
+ const messages = buildMessagesArray(options);
114
117
  const result = await streamText({
115
118
  model: this.model,
116
- prompt: streamOptions.prompt,
117
- system: streamOptions.system,
119
+ messages: messages,
118
120
  temperature: options.temperature,
119
121
  maxTokens: options.maxTokens || DEFAULT_MAX_TOKENS,
120
122
  tools: streamOptions.tools, // Tools format conversion handled by prepareStreamOptions
@@ -6,6 +6,7 @@ import { createTimeoutController, TimeoutError, } from "../utils/timeout.js";
6
6
  import { DEFAULT_MAX_TOKENS } from "../core/constants.js";
7
7
  import { getProviderModel } from "../utils/providerConfig.js";
8
8
  import { streamAnalyticsCollector } from "../core/streamAnalytics.js";
9
+ import { buildMessagesArray } from "../utils/messageBuilder.js";
9
10
  // Configuration helpers
10
11
  const getLiteLLMConfig = () => {
11
12
  return {
@@ -118,10 +119,11 @@ export class LiteLLMProvider extends BaseProvider {
118
119
  const timeout = this.getTimeout(options);
119
120
  const timeoutController = createTimeoutController(timeout, this.providerName, "stream");
120
121
  try {
122
+ // Build message array from options
123
+ const messages = buildMessagesArray(options);
121
124
  const result = await streamText({
122
125
  model: this.model,
123
- prompt: options.input.text,
124
- system: options.systemPrompt,
126
+ messages: messages,
125
127
  temperature: options.temperature,
126
128
  maxTokens: options.maxTokens || DEFAULT_MAX_TOKENS,
127
129
  tools: options.tools,
@@ -6,6 +6,7 @@ import { createTimeoutController, TimeoutError, } from "../utils/timeout.js";
6
6
  import { DEFAULT_MAX_TOKENS, DEFAULT_MAX_STEPS } from "../core/constants.js";
7
7
  import { validateApiKey, createMistralConfig, getProviderModel, } from "../utils/providerConfig.js";
8
8
  import { streamAnalyticsCollector } from "../core/streamAnalytics.js";
9
+ import { buildMessagesArray } from "../utils/messageBuilder.js";
9
10
  // Configuration helpers - now using consolidated utility
10
11
  const getMistralApiKey = () => {
11
12
  return validateApiKey(createMistralConfig());
@@ -46,10 +47,10 @@ export class MistralProvider extends BaseProvider {
46
47
  // Get tools consistently with generate method
47
48
  const shouldUseTools = !options.disableTools && this.supportsTools();
48
49
  const tools = shouldUseTools ? await this.getAllTools() : {};
50
+ const messages = buildMessagesArray(options);
49
51
  const result = await streamText({
50
52
  model: this.model,
51
- prompt: options.input.text,
52
- system: options.systemPrompt,
53
+ messages: messages,
53
54
  temperature: options.temperature,
54
55
  maxTokens: options.maxTokens || DEFAULT_MAX_TOKENS,
55
56
  tools,
@@ -7,6 +7,7 @@ import { createTimeoutController, TimeoutError, } from "../utils/timeout.js";
7
7
  import { DEFAULT_MAX_TOKENS, DEFAULT_MAX_STEPS } from "../core/constants.js";
8
8
  import { validateApiKey, createOpenAIConfig, getProviderModel, } from "../utils/providerConfig.js";
9
9
  import { streamAnalyticsCollector } from "../core/streamAnalytics.js";
10
+ import { buildMessagesArray } from "../utils/messageBuilder.js";
10
11
  // Configuration helpers - now using consolidated utility
11
12
  const getOpenAIApiKey = () => {
12
13
  return validateApiKey(createOpenAIConfig());
@@ -77,10 +78,11 @@ export class OpenAIProvider extends BaseProvider {
77
78
  // Get tools consistently with generate method
78
79
  const shouldUseTools = !options.disableTools && this.supportsTools();
79
80
  const tools = shouldUseTools ? await this.getAllTools() : {};
81
+ // Build message array from options
82
+ const messages = buildMessagesArray(options);
80
83
  const result = await streamText({
81
84
  model: this.model,
82
- prompt: options.input.text,
83
- system: options.systemPrompt,
85
+ messages: messages,
84
86
  temperature: options.temperature,
85
87
  maxTokens: options.maxTokens || DEFAULT_MAX_TOKENS,
86
88
  tools,
@@ -0,0 +1,95 @@
1
+ /**
2
+ * Conversation Memory Types for NeuroLink
3
+ * Provides type-safe conversation storage and context management
4
+ */
5
+ /**
6
+ * Configuration for conversation memory feature
7
+ */
8
+ export interface ConversationMemoryConfig {
9
+ /** Enable conversation memory feature */
10
+ enabled: boolean;
11
+ /** Maximum number of sessions to keep in memory (default: 50) */
12
+ maxSessions?: number;
13
+ /** Maximum number of conversation turns to keep per session (default: 20) */
14
+ maxTurnsPerSession?: number;
15
+ }
16
+ /**
17
+ * Complete memory for a conversation session
18
+ * ULTRA-OPTIMIZED: Direct ChatMessage[] storage - zero conversion overhead
19
+ */
20
+ export interface SessionMemory {
21
+ /** Unique session identifier */
22
+ sessionId: string;
23
+ /** User identifier (optional) */
24
+ userId?: string;
25
+ /** Direct message storage - ready for immediate AI consumption */
26
+ messages: ChatMessage[];
27
+ /** When this session was created */
28
+ createdAt: number;
29
+ /** When this session was last active */
30
+ lastActivity: number;
31
+ /** Optional session metadata */
32
+ metadata?: {
33
+ /** User role or permissions */
34
+ userRole?: string;
35
+ /** Tags for categorizing this session */
36
+ tags?: string[];
37
+ /** Custom data specific to the organization */
38
+ customData?: Record<string, unknown>;
39
+ };
40
+ }
41
+ /**
42
+ * Statistics about conversation memory usage (simplified for pure in-memory storage)
43
+ */
44
+ export interface ConversationMemoryStats {
45
+ /** Total number of active sessions */
46
+ totalSessions: number;
47
+ /** Total number of conversation turns across all sessions */
48
+ totalTurns: number;
49
+ }
50
+ /**
51
+ * Chat message format for conversation history
52
+ */
53
+ export interface ChatMessage {
54
+ /** Role of the message sender */
55
+ role: "user" | "assistant" | "system";
56
+ /** Content of the message */
57
+ content: string;
58
+ }
59
+ /**
60
+ * Events emitted by conversation memory system
61
+ */
62
+ export interface ConversationMemoryEvents {
63
+ /** Emitted when a new session is created */
64
+ "session:created": {
65
+ sessionId: string;
66
+ userId?: string;
67
+ timestamp: number;
68
+ };
69
+ /** Emitted when a conversation turn is stored */
70
+ "turn:stored": {
71
+ sessionId: string;
72
+ turnIndex: number;
73
+ timestamp: number;
74
+ };
75
+ /** Emitted when a session is cleaned up */
76
+ "session:cleanup": {
77
+ sessionId: string;
78
+ reason: "expired" | "limit_exceeded";
79
+ timestamp: number;
80
+ };
81
+ /** Emitted when context is injected */
82
+ "context:injected": {
83
+ sessionId: string;
84
+ turnsIncluded: number;
85
+ timestamp: number;
86
+ };
87
+ }
88
+ /**
89
+ * Error types specific to conversation memory
90
+ */
91
+ export declare class ConversationMemoryError extends Error {
92
+ code: "STORAGE_ERROR" | "CONFIG_ERROR" | "SESSION_NOT_FOUND" | "CLEANUP_ERROR";
93
+ details?: Record<string, unknown> | undefined;
94
+ constructor(message: string, code: "STORAGE_ERROR" | "CONFIG_ERROR" | "SESSION_NOT_FOUND" | "CLEANUP_ERROR", details?: Record<string, unknown> | undefined);
95
+ }
@@ -0,0 +1,17 @@
1
+ /**
2
+ * Conversation Memory Types for NeuroLink
3
+ * Provides type-safe conversation storage and context management
4
+ */
5
+ /**
6
+ * Error types specific to conversation memory
7
+ */
8
+ export class ConversationMemoryError extends Error {
9
+ code;
10
+ details;
11
+ constructor(message, code, details) {
12
+ super(message);
13
+ this.code = code;
14
+ this.details = details;
15
+ this.name = "ConversationMemoryError";
16
+ }
17
+ }
@@ -2,6 +2,7 @@ import type { ZodType, ZodTypeDef } from "zod";
2
2
  import type { Tool, Schema } from "ai";
3
3
  import type { AIProviderName, AnalyticsData, EvaluationData } from "../core/types.js";
4
4
  import type { UnknownRecord, JsonValue } from "./common.js";
5
+ import type { ChatMessage } from "./conversationTypes.js";
5
6
  /**
6
7
  * Interface for tool execution calls (AI SDK compatible)
7
8
  */
@@ -107,6 +108,7 @@ export interface StreamOptions {
107
108
  enableProgress?: boolean;
108
109
  fallbackToGenerate?: boolean;
109
110
  };
111
+ conversationMessages?: ChatMessage[];
110
112
  }
111
113
  /**
112
114
  * Stream function result interface - Primary output format for streaming
@@ -0,0 +1,22 @@
1
+ /**
2
+ * Conversation Memory Utilities
3
+ * Handles configuration merging and conversation memory operations
4
+ */
5
+ import type { ConversationMemoryConfig, ChatMessage } from "../types/conversationTypes.js";
6
+ import type { ConversationMemoryManager } from "../core/conversationMemoryManager.js";
7
+ import type { TextGenerationOptions, TextGenerationResult } from "../core/types.js";
8
+ /**
9
+ * Apply conversation memory defaults to user configuration
10
+ * Merges user config with environment variables and default values
11
+ */
12
+ export declare function applyConversationMemoryDefaults(userConfig?: Partial<ConversationMemoryConfig>): ConversationMemoryConfig;
13
+ /**
14
+ * Get conversation history as message array (PREFERRED METHOD)
15
+ * Returns proper message array format for AI providers
16
+ */
17
+ export declare function getConversationMessages(conversationMemory: ConversationMemoryManager | undefined, options: TextGenerationOptions): Promise<ChatMessage[]>;
18
+ /**
19
+ * Store conversation turn for future context
20
+ * Saves user messages and AI responses for conversation memory
21
+ */
22
+ export declare function storeConversationTurn(conversationMemory: ConversationMemoryManager | undefined, originalOptions: TextGenerationOptions, result: TextGenerationResult): Promise<void>;