UNPKG

@escher-dbai/rag-module

Version:

Enterprise RAG module with chat context storage, vector search, and session management. Complete chat history retrieval and streaming content extraction for Electron apps.

163 lines (140 loc) 5.91 kB
/** * Minimal ContextRetrievalService - Service for retrieving conversation context from local files * This version works directly with local JSON files instead of Qdrant to avoid ES module dependencies */ const fs = require('fs-extra'); const path = require('path'); class ContextRetrievalServiceMinimal { /** * @param {Object} qdrantClient - Mock Qdrant client (for compatibility) * @param {string} collectionName - Collection name (for compatibility) */ constructor(qdrantClient, collectionName = 'chat-collection') { this.qdrantClient = qdrantClient; this.collectionName = collectionName; this.dataFolder = null; // Extract dataFolder from qdrantClient if it's a mock object with dataFolder property if (qdrantClient && qdrantClient.dataFolder) { this.dataFolder = qdrantClient.dataFolder; } } /** * Get organized query-response pairs for a specific context ID * @param {string|Array} contextId - Context ID(s) to retrieve (string or array of strings) * @param {number|Object} [limitOrOptions=100] - Maximum pairs to return OR options object * @param {Object} [options={}] - Additional options (when second param is number) * @returns {Promise<{contextId: string, chatTitle: string, queries: Array, responses: Array, pairs: Array, stats: Object}>} - Organized query-response data */ async getQueryResponsePairs(contextId, limitOrOptions = 100, options = {}) { // Handle flexible parameter formats let actualContextId, actualOptions, actualLimit; if (Array.isArray(contextId)) { actualContextId = contextId[0]; // Take first element if array } else { actualContextId = contextId; } if (typeof limitOrOptions === 'number') { actualLimit = limitOrOptions; actualOptions = options; } else { actualLimit = limitOrOptions.limit || 100; actualOptions = limitOrOptions; } try { console.log('🔍 ContextRetrievalMinimal: Searching for context:', actualContextId); console.log('🔍 ContextRetrievalMinimal: Data folder:', this.dataFolder); // Try to read from local context file let contextData = null; if (this.dataFolder) { const contextFilePath = path.join(this.dataFolder, `${actualContextId}.json`); console.log('🔍 ContextRetrievalMinimal: Looking for file:', contextFilePath); if (await fs.pathExists(contextFilePath)) { console.log('✅ ContextRetrievalMinimal: Found context file'); contextData = await fs.readJson(contextFilePath); } else { console.log('❌ ContextRetrievalMinimal: Context file not found'); } } // Extract conversation pairs from context data let pairs = []; let chatTitle = ''; if (contextData && contextData.final_conversation_context) { const messages = contextData.final_conversation_context.m || []; chatTitle = contextData.final_conversation_context.ct || contextData.chat_title || ''; console.log('🔍 ContextRetrievalMinimal: Found', messages.length, 'messages'); // Convert messages to query-response pairs for (let i = 0; i < messages.length - 1; i += 2) { if (messages[i] && messages[i + 1]) { const query = messages[i]; const response = messages[i + 1]; // Only create pairs if we have both query and response if (query.r === 0 && response.r === 1) { // r=0 is user, r=1 is assistant pairs.push({ query: { content: query.c || '', role: 'user', timestamp: contextData.final_conversation_context.t }, response: { content: response.c || '', role: 'assistant', timestamp: contextData.final_conversation_context.l } }); } } } // Limit the number of pairs returned if (pairs.length > actualLimit) { pairs = pairs.slice(-actualLimit); // Take most recent pairs } } console.log('🔍 ContextRetrievalMinimal: Final results:'); console.log(' - Total pairs:', pairs.length); console.log(' - Chat title:', chatTitle); if (pairs.length > 0) { console.log('🔍 ContextRetrievalMinimal: Sample pair:'); console.log(' - Query:', pairs[0].query.content.substring(0, 100) + '...'); console.log(' - Response:', pairs[0].response.content.substring(0, 100) + '...'); } return { contextId: actualContextId, chatTitle, queries: pairs.map(p => p.query), responses: pairs.map(p => p.response), pairs, stats: { totalMessages: pairs.length * 2, queryCount: pairs.length, responseCount: pairs.length, pairCount: pairs.length, retrievedAt: new Date().toISOString() } }; } catch (error) { console.error('❌ ContextRetrievalMinimal: Error:', error.message); throw new Error(`Failed to retrieve context messages: ${error.message}`); } } /** * Find available context IDs (mock implementation for compatibility) * @param {Object} [options={}] - Search options * @returns {Promise<Array>} - Array of context IDs */ async findContextIds(options = {}) { try { if (!this.dataFolder) { return []; } const files = await fs.readdir(this.dataFolder); const contextIds = files .filter(file => file.endsWith('.json')) .map(file => file.replace('.json', '')); return contextIds; } catch (error) { console.error('❌ ContextRetrievalMinimal: Error finding context IDs:', error.message); return []; } } } module.exports = ContextRetrievalServiceMinimal;