@juspay/neurolink 12.0.3 → 12.0.4

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/dist/neurolink.js CHANGED
@@ -5548,7 +5548,15 @@ Current user's request: ${currentInput}`;
5548
5548
  : "empty",
5549
5549
  hasCustomSystemPrompt: !!options.systemPrompt,
5550
5550
  });
5551
- const conversationMessages = (await getConversationMessages(this.conversationMemory, options));
5551
+ // Caller-supplied conversationMessages win mirroring
5552
+ // directProviderGeneration. getConversationMessages() returns [] whenever
5553
+ // no memory manager / session context is configured, which silently
5554
+ // dropped an inline history on the MCP-first path (the default path for
5555
+ // any bare `new NeuroLink()` with tools enabled) while the direct path
5556
+ // honored it.
5557
+ const conversationMessages = (options.conversationMessages?.length
5558
+ ? options.conversationMessages
5559
+ : await getConversationMessages(this.conversationMemory, options));
5552
5560
  this.logMCPConversationSummary(requestId, conversationMessages);
5553
5561
  logger.debug("[Observability] Available tools for LLM", {
5554
5562
  requestId,
@@ -235,9 +235,47 @@ async function _prepareRAGToolInner(ragConfig, fallbackProvider) {
235
235
  const EMBEDDING_DIMENSION = 128;
236
236
  const vectorStore = new InMemoryVectorStore();
237
237
  const indexName = "rag-index";
238
+ // When the caller configured an embedding provider/model, embed BOTH the
239
+ // index chunks and (below) the queries through that provider — previously
240
+ // those config fields had no runtime effect and retrieval always used the
241
+ // deterministic hash embedding, which is a lexical fingerprint rather than
242
+ // a semantic space. Index and query must share one embedding space, so the
243
+ // provider path replaces the hash path wholesale; any provider failure
244
+ // falls back to the hash for both sides.
245
+ const wantProviderEmbeddings = Boolean(embeddingProvider || embeddingModel);
246
+ const embedProviderName = embeddingProvider || fallbackProvider || "vertex";
247
+ const embedModelName = embeddingModel || "gemini-2.5-flash";
248
+ let embedFn = (text) => Promise.resolve(generateSimpleEmbedding(text, EMBEDDING_DIMENSION));
249
+ if (wantProviderEmbeddings) {
250
+ try {
251
+ const { AIProviderFactory } = await import("../core/factory.js");
252
+ const embedderProvider = (await AIProviderFactory.createProvider(embedProviderName, embedModelName));
253
+ if (typeof embedderProvider.embed === "function") {
254
+ const providerEmbed = embedderProvider.embed.bind(embedderProvider);
255
+ embedFn = (text) => providerEmbed(text, embedModelName);
256
+ }
257
+ else {
258
+ logger.warn(`[RAG] Embedding provider '${embedProviderName}' has no embed(); falling back to hash embeddings`);
259
+ }
260
+ }
261
+ catch (error) {
262
+ logger.warn("[RAG] Failed to create embedding provider; falling back to hash embeddings", { error: error instanceof Error ? error.message : String(error) });
263
+ }
264
+ }
265
+ let chunkVectors;
266
+ try {
267
+ chunkVectors = await Promise.all(allChunks.map((chunk) => embedFn(chunk.text)));
268
+ }
269
+ catch (error) {
270
+ // One failed chunk must not leave a mixed-space index — flip the whole
271
+ // index AND all queries back to the hash space together.
272
+ logger.warn("[RAG] Provider embedding failed mid-index; falling back to hash embeddings for index and queries", { error: error instanceof Error ? error.message : String(error) });
273
+ embedFn = (text) => Promise.resolve(generateSimpleEmbedding(text, EMBEDDING_DIMENSION));
274
+ chunkVectors = allChunks.map((chunk) => generateSimpleEmbedding(chunk.text, EMBEDDING_DIMENSION));
275
+ }
238
276
  const items = allChunks.map((chunk, i) => ({
239
277
  id: `rag-chunk-${i}`,
240
- vector: generateSimpleEmbedding(chunk.text, EMBEDDING_DIMENSION),
278
+ vector: chunkVectors[i],
241
279
  metadata: {
242
280
  text: chunk.text,
243
281
  ...chunk.metadata,
@@ -274,9 +312,9 @@ async function _prepareRAGToolInner(ragConfig, fallbackProvider) {
274
312
  "rag.top_k": topK ?? 5,
275
313
  },
276
314
  }, async (span) => {
277
- // For the in-memory store with simple embeddings,
278
- // generate a query embedding using the same method
279
- const queryEmbedding = generateSimpleEmbedding(query, EMBEDDING_DIMENSION);
315
+ // Query through the same embedding space the index was built in —
316
+ // provider embeddings when configured (and healthy), else the hash.
317
+ const queryEmbedding = await embedFn(query).catch(() => generateSimpleEmbedding(query, EMBEDDING_DIMENSION));
280
318
  // Fetch more candidates than needed so diversity can select across files
281
319
  const fetchK = fileContents.length > 1 ? topK * 3 : topK;
282
320
  const rawResults = await vectorStore.query({
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@juspay/neurolink",
3
- "version": "12.0.3",
3
+ "version": "12.0.4",
4
4
  "packageManager": "pnpm@10.15.1",
5
5
  "description": "TypeScript AI SDK with 24+ LLM providers behind one consistent API. MCP-native (connect any MCP server), voice TTS/STT/realtime, RAG, agents, memory, context compaction. OpenAI · Anthropic · Gemini · Bedrock · Azure · Ollama · DeepSeek · NVIDIA NIM and more.",
6
6
  "author": {