diff --git a/backend/chatbot.py b/backend/chatbot.py index bdf5f9b7..a0a8761e 100644 --- a/backend/chatbot.py +++ b/backend/chatbot.py @@ -9,43 +9,34 @@ - - # 1) Configure your API key client = genai.Client(api_key=api_key) - +def get_system_prompt(combined_plans_text, user_experience, question, user_info): + prompt = f"""You are a healthcare plan assistant. Only use the text provided to answer user questions. + Below is the text for multiple plans: + {combined_plans_text} + The user experience level is with healthcare plans is {user_experience}. + Use the associated score to justify each plan and its ranking. + The user experience level is {user_experience} and there info is {user_info} + Answer the following question ONLY from the text above: + Question: {question} + """ + return prompt def get_chatbot_response(question: str, history: dict) -> str: client = genai.Client(api_key=api_key) - # Combine plan textract stuff - - combined_plans_text = "" - - for key, value in history.items(): - combined_plans_text += f"---\nPlan: {key}\n\n{value['text']}\n" - - - - # Prompting type - prompt = f"""You are a healthcare plan assistant. Only use the text provided to answer user questions. - Below is the text for multiple plans: - {combined_plans_text} - - Answer the following question ONLY from the text above: - - Question: {question} - """ + prompt = get_system_prompt(history["combined_plan_text"], history["experience"], question, str(history["user_info"])) response = client.models.generate_content( model="gemini-2.0-flash", contents=[prompt], ) - # 5) Return the text response + # Return the text response return response.text diff --git a/backend/insurance_databases.py b/backend/insurance_databases.py deleted file mode 100644 index feecad34..00000000 --- a/backend/insurance_databases.py +++ /dev/null @@ -1,52 +0,0 @@ -import pandas as pd -import numpy as np - -ma_benefits = pd.read_csv('backend/CSVs/MassachusettsSBEPUF2024/MABenefits05102024.csv') -ma_business_rules = pd.read_csv('backend/CSVs/MassachusettsSBEPUF2024/MABusinessRules05102024.csv') -ma_networks = pd.read_csv('backend/CSVs/MassachusettsSBEPUF2024/MANetworks05102024.csv') -ma_plans = pd.read_csv('backend/CSVs/MassachusettsSBEPUF2024/MAPlans05102024.csv') -ma_rates = pd.read_csv('backend/CSVs/MassachusettsSBEPUF2024/MARates05102024.csv') -ma_service_areas = pd.read_csv('backend/CSVs/MassachusettsSBEPUF2024/MAServiceAreas05102024.csv') - -ct_benefits = pd.read_csv('backend/CSVs/ConnecticutSBEPUF2024/CTBenefits05102024.csv') -ct_business_rules = pd.read_csv('backend/CSVs/ConnecticutSBEPUF2024/CTBusinessRules05102024.csv') -ct_networks = pd.read_csv('backend/CSVs/ConnecticutSBEPUF2024/CTNetworks05102024.csv') -ct_plans = pd.read_csv('backend/CSVs/ConnecticutSBEPUF2024/CTPlans05102024.csv') -ct_rates = pd.read_csv('backend/CSVs/ConnecticutSBEPUF2024/CTRates05102024.csv') -ct_service_areas = pd.read_csv('backend/CSVs/ConnecticutSBEPUF2024/CTServiceAreas05102024.csv') - -me_benefits = pd.read_csv('backend/CSVs/MaineSBEPUF2024/MEBenefits05102024.csv') -me_business_rules = pd.read_csv('backend/CSVs/MaineSBEPUF2024/MEBusinessRules05102024.csv') -me_networks = pd.read_csv('backend/CSVs/MaineSBEPUF2024/MENetworks05102024.csv') -me_plans = pd.read_csv('backend/CSVs/MaineSBEPUF2024/MEPlans05102024.csv') -me_rates = pd.read_csv('backend/CSVs/MaineSBEPUF2024/MERates05102024.csv') -me_service_areas = pd.read_csv('backend/CSVs/MaineSBEPUF2024/MEServiceAreas05102024.csv') - -vt_benefits = pd.read_csv('backend/CSVs/VermontSBEPUF2024/VTBenefits05102024.csv') -vt_business_rules = pd.read_csv('backend/CSVs/VermontSBEPUF2024/VTBusinessRules05102024.csv') -vt_networks = pd.read_csv('backend/CSVs/VermontSBEPUF2024/VTNetworks05102024.csv') -vt_plans = pd.read_csv('backend/CSVs/VermontSBEPUF2024/VTPlans05102024.csv') -vt_service_areas = pd.read_csv('backend/CSVs/VermontSBEPUF2024/VTServiceAreas05102024.csv') - -ri_benefits = pd.read_csv('backend/CSVs/RhodeIslandSBEPUF2024/RIBenefits05102024.csv') -ri_business_rules = pd.read_csv('backend/CSVs/RhodeIslandSBEPUF2024/RIBusinessRules05102024.csv') -ri_networks = pd.read_csv('backend/CSVs/RhodeIslandSBEPUF2024/RINetworks05102024.csv') -ri_plans = pd.read_csv('backend/CSVs/RhodeIslandSBEPUF2024/RIPlans05102024.csv') -ri_service_areas = pd.read_csv('backend/CSVs/RhodeIslandSBEPUF2024/RIServiceAreas05102024.csv') - - -new_england_benefits = pd.concat([ma_benefits, ct_benefits, me_benefits, vt_benefits, ri_benefits], ignore_index= True) -new_england_business_rules = pd.concat([ma_business_rules, ct_business_rules, me_business_rules, vt_business_rules], ignore_index= True) -new_england_networks = pd.concat([ma_networks, ct_networks, me_networks, vt_networks, ri_networks], ignore_index= True) -new_england_insurance_plans = pd.concat([ma_plans, ct_plans, me_plans, vt_plans, ri_plans], ignore_index=True) -new_england_service_areas = pd.concat([ma_service_areas, ct_service_areas, me_service_areas, vt_service_areas, ri_service_areas], ignore_index= True) - -print(new_england_benefits.isnull().sum()) -print('next null\n') -print(new_england_business_rules.isnull().sum()) -print('next null\n') -print(new_england_networks.isnull().sum()) -print('next null\n') -print(new_england_insurance_plans.isnull().sum()) -print('next null\n') -print(new_england_service_areas.isnull().sum()) \ No newline at end of file diff --git a/backend/models.py b/backend/models.py index 013eeae7..d54d191d 100644 --- a/backend/models.py +++ b/backend/models.py @@ -43,3 +43,4 @@ class UserInputForm(BaseModel): address: Address weights: Weights premium: List[float] + user_experience: str diff --git a/backend/root.py b/backend/root.py index 0bb3588e..61dba497 100644 --- a/backend/root.py +++ b/backend/root.py @@ -28,7 +28,7 @@ # cd backend # fastapi dev root.py -history = {} +history = {"user_info": "","combined_plan_text": None, "experience": None, "chat_history" : []} @@ -64,11 +64,10 @@ async def upload_pdfs(form_data: str = Form(...), for i, j in zip(premiums, files): plans[j] = i - - # upload to s3 and textract # { "name": filename, "text": "TEXT RESULTS " } - results = await upload_and_extract(plans) + textract_results = await upload_and_extract(plans) + # The weights: @@ -95,27 +94,28 @@ async def process_plan(plan_name: str, plan_content: str, plan_premium: float): total_score = ranking_instance.total_scores() return plan_name, unweighted_scores, weighted_scores, total_score, plan_content - tasks = [process_plan(name, content[0], content[1]) for name, content in results.items()] + tasks = [process_plan(name, content[0], content[1]) for name, content in textract_results.items()] # Run all tasks concurrently results = await asyncio.gather(*tasks) to_frontend = [] + combined_plan_text = "" # Store the results in the history for name, unweighted_scores, weighted_scores, total_score, plan_content in results: # {'file_name': 'weighted_scores: dict, 'total_score': float, 'text': str} - history[name] = { - "weighted_scores": weighted_scores, - "total_score": total_score, - "text": plan_content - } - to_frontend.append({ "name" : name, "weightedScores": weighted_scores, "totalScore": total_score, }) + combined_plan_text += f"Plan Name: {name}(associated score: {total_score}), content: {plan_content}\n\n" + + history["combined_plan_text"] = combined_plan_text + history["experience"] = user_input['user_experience'] + history["user_info"] = str(user_input) + return to_frontend diff --git a/backend/upload_extract.py b/backend/upload_extract.py index bd0a3550..a239b42b 100644 --- a/backend/upload_extract.py +++ b/backend/upload_extract.py @@ -24,6 +24,7 @@ def start_textract_job(bucket: str, key: str) -> str: # GET TEXTRACT RESULTS def get_textract_result(job_id: str) -> str: + time.sleep(5) while True: response = textract.get_document_text_detection(JobId=job_id) status = response["JobStatus"] @@ -46,19 +47,25 @@ async def upload_and_extract(files: dict): job_map = {} upload_jobs = [] # start all s3 jobs and wait till they finish + s3_start = time.time(); + print('STARTING S3 UPLOAD') for file, premium in files.items(): job_map[file.filename] = premium job = asyncio.to_thread(upload_to_s3, file, S3_BUCKET_NAME, file.filename); upload_jobs.append(job) await asyncio.gather(*upload_jobs) - + print('S3 UPLOAD COMPLETE: '+str(time.time()-s3_start)) textract_jobs = {} + textract_start = time.time() + print('STARTING TEXTRACT UPLOAD: ') for file, premium in files.items(): job_id = await asyncio.to_thread(start_textract_job, S3_BUCKET_NAME, file.filename) textract_jobs[file.filename] = (job_id, premium) - results = {} + print('TEXTRACT DONE STARTING JOBS: '+str(time.time()-textract_start)) for filename, (job_id, premium) in textract_jobs.items(): result = await asyncio.to_thread(get_textract_result, job_id) results[filename] = [result, premium] + print('TEXTRACT FINISHED: '+str(time.time()-textract_start)) return results + diff --git a/frontend/src/pages/Ranking/Rankings.tsx b/frontend/src/pages/Ranking/Rankings.tsx index c3a9840b..8293eb69 100644 --- a/frontend/src/pages/Ranking/Rankings.tsx +++ b/frontend/src/pages/Ranking/Rankings.tsx @@ -13,7 +13,7 @@ import {SelectChangeEvent} from "@mui/material/Select"; import {ResultsProps} from "../../App"; import {sendInputData} from "../sendInputAPI.ts"; -import {getResults} from "../resultsAPI.ts"; + import styles from "./rankings.module.css"; import {useFlow} from "../../context/FlowContext.tsx"; @@ -93,7 +93,7 @@ const Rankings: React.FC = ({results, setResults}) => { setLoading(true) // success = true, if form upload worked someone handle that.. - const results = await sendInputData(fullUserData, files, planCost); + const results = await sendInputData(fullUserData, files, planCost, selectedOption); setLoading(false); diff --git a/frontend/src/pages/resultsAPI.ts b/frontend/src/pages/resultsAPI.ts deleted file mode 100644 index 6cb02497..00000000 --- a/frontend/src/pages/resultsAPI.ts +++ /dev/null @@ -1,21 +0,0 @@ -import axios from "axios"; - -export async function getResults() { - try { - const response = await axios.get("http://127.0.0.1:8000/results", { - headers: { "Content-Type": "application/json" } - }); - console.log('RESULTS:'); - console.log(response); - console.log(response.data); - return response.data; - } catch (error) { - console.error("Get error:", error); - - if (axios.isAxiosError(error) && error.response) { - alert(`Error: ${error.response.data.detail || "Failed to get results"}`); - } else { - alert("Failed to connect to the server."); - } - } -} diff --git a/frontend/src/pages/sendInputAPI.ts b/frontend/src/pages/sendInputAPI.ts index 624d97eb..be33dbcc 100644 --- a/frontend/src/pages/sendInputAPI.ts +++ b/frontend/src/pages/sendInputAPI.ts @@ -16,7 +16,7 @@ interface FormDataInput { [key: string]: any; } -function structureToJSON(data: FormDataInput, planCost: number[]) { +function structureToJSON(data: FormDataInput, planCost: number[], userExperience) { return { "first_name": data.firstName || "", @@ -48,7 +48,8 @@ function structureToJSON(data: FormDataInput, planCost: number[]) { "convenience_of_coverage": parseFloat(data["Convenience of Accessing Benefits"]) || 0, "geographic_coverage": parseFloat(data["Geographic coverage"]) || 0, }, - "premium" : planCost + "premium" : planCost, + "user_experience" : userExperience }; } @@ -57,12 +58,12 @@ function structureToJSON(data: FormDataInput, planCost: number[]) { * @param data the user's filled out form data * @param files the uploaded pdfs of the insurance plans */ -async function sendInputData(data: FormDataInput, files: File[], planCost: number[]) { +async function sendInputData(data: FormDataInput, files: File[], planCost: number[], userExperience: string) { console.log("Post request"); try { const formData = new FormData(); // add the user form data - const jsonData = structureToJSON(data, planCost); + const jsonData = structureToJSON(data, planCost, userExperience); formData.append("form_data", JSON.stringify(jsonData)); // add all the uploaded files files.forEach((file) => {