diff --git a/Confido/src/GenAICore.ts b/Confido/src/GenAICore.ts new file mode 100644 index 00000000..a1cf3894 --- /dev/null +++ b/Confido/src/GenAICore.ts @@ -0,0 +1,120 @@ +import { + fetchAllPatientAppointmentsFromFb, + fetchClinicDetailsFromFb, + fetchPatientAssignedWorkflowFromFb, + fetchPatientFromFb, +} from '../Utilities/FirestoreServices'; +import { + Variable, + WorkflowTask, + defaultClinicDetails, + defaultPatient, + defaultWorkflow, +} from '../shared/FirestoreInterfaces'; +import { ChatOpenAI } from 'langchain/chat_models/openai'; +import { OpenAIEmbeddings } from 'langchain/embeddings/openai'; +import { Document } from 'langchain/document'; +import { HNSWLib } from 'langchain/vectorstores/hnswlib'; +import { RetrievalQAChain, loadQAStuffChain } from 'langchain/chains'; +import { defineString } from 'firebase-functions/v2/params'; + +export const replyToPatientWithContext = async ( + patientUid: string, + incomingMessage: string +) => { + const openAiApiKey = defineString('OPENAI_API', { default: '' }); + + if (!openAiApiKey.value()) { + return ''; + } + + // Fetch all relevant data + let clinicDetails = await fetchClinicDetailsFromFb(); + if (!clinicDetails) { + clinicDetails = { ...defaultClinicDetails }; + } + + let patient = await fetchPatientFromFb(patientUid); + if (!patient) { + patient = { ...defaultPatient }; + } + + let appointments = await fetchAllPatientAppointmentsFromFb(patientUid); + if (!appointments) { + appointments = []; + } + + let currentAssignedWorkflows = null; + const surgeryTasks: any[] = []; + const surgeryDetails = new Map(); + if (patient.currentAssignedWorkflowUid) { + currentAssignedWorkflows = await fetchPatientAssignedWorkflowFromFb( + patientUid, + patient.currentAssignedWorkflowUid + ); + } + if (!currentAssignedWorkflows) { + currentAssignedWorkflows = { ...defaultWorkflow }; + } + + currentAssignedWorkflows.surgeryDetails.variables.forEach( + (variable: Variable) => surgeryDetails.set(variable.name, variable.value) + ); + + currentAssignedWorkflows.workflowTasks.forEach((task: WorkflowTask) => { + surgeryTasks.push({ + name: task.name, + timeline: task.timeline, + message: task.patientMessageContent, + }); + }); + + // Build document array + const docs = [ + new Document({ pageContent: JSON.stringify(clinicDetails) }), + new Document({ pageContent: JSON.stringify(patient) }), + ...currentAssignedWorkflows.surgeryDetails.variables.map( + (variable: Variable) => { + return new Document({ pageContent: JSON.stringify(variable) }); + } + ), + ...appointments.map((appointment) => { + return new Document({ pageContent: JSON.stringify(appointment) }); + }), + ...surgeryTasks.map((task: any) => { + return new Document({ pageContent: JSON.stringify(task) }); + }), + ]; + + // Convert to Vector store + const embeddingsModel = new OpenAIEmbeddings({ + openAIApiKey: openAiApiKey.value(), + }); + const vectorStore = await HNSWLib.fromDocuments(docs, embeddingsModel); + console.log(vectorStore); + + const retreiver = vectorStore.asRetriever(40); + console.log(retreiver); + + // Initialize LLM + const llm = new ChatOpenAI({ + openAIApiKey: openAiApiKey.value(), + temperature: 0, + modelName: 'gpt-3.5-turbo', + }); + console.log(llm); + + // Setup retreival chain + const retreivalChain = new RetrievalQAChain({ + retriever: retreiver, + combineDocumentsChain: loadQAStuffChain(llm), + verbose: true, + }); + console.log(retreivalChain); + + // Run the input message through the chain + const reply = await retreivalChain.run(incomingMessage); + console.log(reply); + + return reply; +}; diff --git a/README.md b/README.md index 9d3f4a24..f2b38b62 100644 --- a/README.md +++ b/README.md @@ -1,26 +1,26 @@ -# Gen-Ai-Rush-Buildathon +Team Name - Confido Health +Problem Statement - Virtual Nurse AI to automate patient communication in complex treatments like surgeries +Team Leader Email - vichar@confido.health -## Submission Instruction: - 1. Fork this repository - 2. Create a folder with your Team Name - 3. Upload all the code and necessary files in the created folder - 4. Upload a **README.md** file in your folder with the below mentioned informations. - 5. Generate a Pull Request with your Team Name. (Example: submission-XYZ_team) +A Brief of the Prototype: +Live prototype: https://clinical-workflow-demo.web.app/ [vichar@confido.health/VIchar1995] +Link: +https://www.loom.com/share/d915cf751d56409ebd4516965c0b6243?sid=27c7322e-ae0a-44c9-b4e8-35d7813ccd36 -## README.md must consist of the following information: +OpenAI LLM -> Retraining on Patient Context, Medical Record Data and Surgical Data -> Clinic Dashboard built on ReactJS -> Patient SMS via Twilio -#### Team Name - -#### Problem Statement - -#### Team Leader Email - +Tech Stack: + +GenAI Stack: +OpenAI +Langchain + +Prototype Stack: +Firebase, Firestore +ReactJS +NodeJS +Twilio API for SMS + +What I Learned: +- How to retrain an LLM on unstructured datasets like medical record data, patient context -## A Brief of the Prototype: - This section must include UML Diagrams and prototype description - -## Tech Stack: - List Down all technologies used to Build the prototype - -## Step-by-Step Code Execution Instructions: - This Section must contain a set of instructions required to clone and run the prototype so that it can be tested and deeply analyzed - -## What I Learned: - Write about the biggest learning you had while developing the prototype