File size: 3,512 Bytes
cd5e33d
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
import { generateResponse } from './llmClient.js';
import { vectorService } from './vectorService.js';
import dotenv from 'dotenv';

dotenv.config();

class RAGService {
  constructor() {
    this.vectorService = vectorService;
  }
  
  async retrievePatientContext(patientId, query, nResults = 5) {
    const patientResults = await this.vectorService.searchPatientRecords(
      query,
      patientId,
      nResults
    );
    return { patient_records: patientResults };
  }
  
  async retrieveResearchContext(query, nResults = 3) {
    return await this.vectorService.searchResearchPapers(query, nResults);
  }
  
  formatContextForLLM(patientContext, researchContext) {
    const contextParts = [];
    
    contextParts.push('=== PATIENT MEDICAL RECORDS ===');
    if (patientContext.patient_records && patientContext.patient_records.length > 0) {
      patientContext.patient_records.forEach((record, idx) => {
        contextParts.push(`\n${idx + 1}. ${record.document}`);
        contextParts.push(`   Type: ${record.metadata.type || 'unknown'}`);
      });
    } else {
      contextParts.push('No patient records found.');
    }
    
    contextParts.push('\n\n=== RELEVANT MEDICAL RESEARCH ===');
    if (researchContext && researchContext.length > 0) {
      researchContext.forEach((paper, idx) => {
        contextParts.push(`\n${idx + 1}. Title: ${paper.metadata.title || 'Unknown'}`);
        contextParts.push(`   Content: ${paper.document}`);
      });
    } else {
      contextParts.push('No relevant research found.');
    }
    
    return contextParts.join('\n');
  }
  
  async generateRAGResponse(patientId, patientData, query) {
    const patientContext = await this.retrievePatientContext(patientId, query, 5);
    const researchContext = await this.retrieveResearchContext(query, 3);
    const formattedContext = this.formatContextForLLM(patientContext, researchContext);
    
    const prompt = `
You are an expert medical AI assistant.

PATIENT:
- Name: ${patientData.name}
- Age: ${patientData.age}
- Gender: ${patientData.gender}

CONTEXT:
${formattedContext}

DOCTOR'S QUESTION:
${query}

Please give a medically accurate, evidence-based answer.
`;
    
    try {
      const text = await generateResponse(prompt);
      
      return {
        text,
        patient_records_used: (patientContext.patient_records || []).length,
        research_papers_used: researchContext.length,
        sources: {
          patient_records: (patientContext.patient_records || []).map(r => ({
            type: r.metadata.type,
            content: r.document.substring(0, 200) + '...'
          })),
          research_papers: researchContext.map(r => ({
            title: r.metadata.title,
            excerpt: r.document.substring(0, 200) + '...'
          }))
        }
      };
    } catch (error) {
      return { text: `Error generating AI response: ${error.message}`, error: true };
    }
  }
  
  async suggestTreatments(patientId, patientData, condition) {
    const query = `Treatment options for ${condition}`;
    return await this.generateRAGResponse(patientId, patientData, query);
  }
  
  async analyzeDrugInteractions(patientId, patientData, newMedication) {
    const currentMeds = (patientData.medications || []).map(m => m.name).join(', ');
    const query = `Drug interactions between ${newMedication} and current medications: ${currentMeds}`;
    return await this.generateRAGResponse(patientId, patientData, query);
  }
}

export const ragService = new RAGService();