Spaces:
Runtime error
Runtime error
Upload code (#1)
Browse files- Upload code (2e34456ea0ea3ff76c6a0bf3469f63c2a75f4a76)
Co-authored-by: Umar <umar-ts@users.noreply.huggingface.co>
- .gitignore +1 -0
- app.py +172 -0
- prompts.py +152 -0
- service.py +138 -0
.gitignore
ADDED
|
@@ -0,0 +1 @@
|
|
|
|
|
|
|
| 1 |
+
.env
|
app.py
ADDED
|
@@ -0,0 +1,172 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import gradio as gr
|
| 2 |
+
from service import GPT_Service, Stage
|
| 3 |
+
|
| 4 |
+
|
| 5 |
+
title_html = """
|
| 6 |
+
<div style="display: flex; align-items: center; width=100%; background-color:#FFC90E;">
|
| 7 |
+
<img src='https://i.ibb.co/gPFskvg/LOGO-1.png' style='height: 90px; width:90px; margin-left: 20px;'>
|
| 8 |
+
<span style="margin-left: 20px;font-size:30px">
|
| 9 |
+
<span>Patient Assessment Documentation</span>
|
| 10 |
+
</span>
|
| 11 |
+
</div>
|
| 12 |
+
|
| 13 |
+
"""
|
| 14 |
+
|
| 15 |
+
css = """
|
| 16 |
+
#subButton, #rephraseBtn {
|
| 17 |
+
background-color: #EA580C !important;
|
| 18 |
+
background: #EA580C !important;
|
| 19 |
+
border: none !important; /* Remove the border */
|
| 20 |
+
transition: background-color 0.3s ease; /* Add transition for smoother hover effect */
|
| 21 |
+
}
|
| 22 |
+
|
| 23 |
+
#subButton:hover, #rephraseBtn:hover {
|
| 24 |
+
background-color: #FFC90E !important; /* Change to a lighter background color on hover */
|
| 25 |
+
}
|
| 26 |
+
|
| 27 |
+
"""
|
| 28 |
+
|
| 29 |
+
def split_based_on_commas(string):
|
| 30 |
+
return [substring.strip() for substring in string.split(",")]
|
| 31 |
+
|
| 32 |
+
def process_text(keywords, stage, medical_history):
|
| 33 |
+
if(keywords.strip()!='' and stage!=None and len(stage)!=0 and len(split_based_on_commas(keywords))<=5):
|
| 34 |
+
try:
|
| 35 |
+
gptService=GPT_Service()
|
| 36 |
+
if stage == Stage.INITIAL_ASSESSMENT.value:
|
| 37 |
+
return gptService.getInitialAssessment(keywords,medical_history)
|
| 38 |
+
elif stage == Stage.FOLLOWUP_ASSESSMENT.value:
|
| 39 |
+
return gptService.getFollowUpAssessment(keywords,medical_history)
|
| 40 |
+
elif stage == Stage.EVALUATION.value:
|
| 41 |
+
return gptService.getEvaluation(keywords,medical_history)
|
| 42 |
+
elif stage == Stage.DETAILED_EVALUATION.value:
|
| 43 |
+
return gptService.getDetailedEvaluation(keywords,medical_history)
|
| 44 |
+
elif stage == Stage.PROGRESS_NOTE.value:
|
| 45 |
+
return gptService.getProgressNote(keywords,medical_history)
|
| 46 |
+
elif stage == Stage.DISCHARGE_SUMMARY.value:
|
| 47 |
+
return gptService.getDischargeSummary(keywords,medical_history)
|
| 48 |
+
elif stage == Stage.SHORT_TERM_GOALS.value:
|
| 49 |
+
return gptService.getShortTermGoals(keywords,medical_history)
|
| 50 |
+
elif stage == Stage.LONG_TERM_GOALS.value:
|
| 51 |
+
return gptService.getLongTermGoals(keywords,medical_history)
|
| 52 |
+
elif stage == Stage.RECOMMENDATION.value:
|
| 53 |
+
return gptService.getRecommendation(keywords,medical_history)
|
| 54 |
+
else:
|
| 55 |
+
print("Unknown stage")
|
| 56 |
+
raise gr.Error('Unknown stage encountered')
|
| 57 |
+
except:
|
| 58 |
+
print("GPT error encounters")
|
| 59 |
+
raise gr.Error('Something went wrong please try again')
|
| 60 |
+
else:
|
| 61 |
+
print("Unknown stage parameters")
|
| 62 |
+
raise gr.Error('Provide appropriate parameters and try again')
|
| 63 |
+
|
| 64 |
+
|
| 65 |
+
def select_handler(prevResponse, newResponse):
|
| 66 |
+
if newResponse.strip() not in prevResponse:
|
| 67 |
+
return f"{prevResponse + (' ' if prevResponse.strip() != '' else '')} {newResponse}"
|
| 68 |
+
else:
|
| 69 |
+
return prevResponse
|
| 70 |
+
|
| 71 |
+
|
| 72 |
+
def getRephrasedSentences(sentences):
|
| 73 |
+
if sentences.strip() == '':
|
| 74 |
+
raise gr.Error('Provide appropriate parameters and try again')
|
| 75 |
+
else:
|
| 76 |
+
try:
|
| 77 |
+
print(sentences)
|
| 78 |
+
gptService=GPT_Service()
|
| 79 |
+
return gptService.getRephrasedSentences(sentences)
|
| 80 |
+
except:
|
| 81 |
+
raise gr.Error('Something went wrong please try again')
|
| 82 |
+
|
| 83 |
+
|
| 84 |
+
with gr.Blocks(css=css) as demo:
|
| 85 |
+
gr.HTML(title_html)
|
| 86 |
+
gr.HTML("<h2>Patient Assessment Input</h2>")
|
| 87 |
+
with gr.Row():
|
| 88 |
+
keywords = gr.Textbox(label="Assessment Keywords", placeholder="Write comma separated sample keywords (max=5)")
|
| 89 |
+
medicalHistory = gr.Textbox(label="Medical History", placeholder="Enter patient history")
|
| 90 |
+
stage_choices = [Stage.INITIAL_ASSESSMENT.value,Stage.SHORT_TERM_GOALS.value,Stage.LONG_TERM_GOALS.value, Stage.RECOMMENDATION.value]
|
| 91 |
+
stage = gr.Dropdown(choices=stage_choices, label="Assessment Stage")
|
| 92 |
+
|
| 93 |
+
with gr.Row():
|
| 94 |
+
clearInputFields = gr.ClearButton(value="Clear Inputs",components=[keywords,medicalHistory,stage])
|
| 95 |
+
responseButton = gr.Button("Submit",elem_id="subButton")
|
| 96 |
+
|
| 97 |
+
gr.HTML("<h2 style=\"margin-top:10\">Suggested Assessment Documentation</h2>")
|
| 98 |
+
with gr.Column():
|
| 99 |
+
label1 = gr.Markdown(value="Keyword 1",show_label=False)
|
| 100 |
+
with gr.Row() as firstKeywordResponses:
|
| 101 |
+
firstKeywordResponseUtterance1 = gr.Textbox(label="Variant 1",interactive=False, show_copy_button=True)
|
| 102 |
+
firstKeywordResponseUtterance2 = gr.Textbox(label="Variant 2", interactive=False, show_copy_button=True)
|
| 103 |
+
firstKeywordResponseUtterance3 = gr.Textbox(label="Variant 3", interactive=False, show_copy_button=True)
|
| 104 |
+
|
| 105 |
+
label2 = gr.Markdown(value="Keyword 2",show_label=False)
|
| 106 |
+
with gr.Row() as secondKeywordResponses:
|
| 107 |
+
secondKeywordResponseUtterance1 = gr.Textbox(label="Variant 1", interactive=False, show_copy_button=True)
|
| 108 |
+
secondKeywordResponseUtterance2 = gr.Textbox(label="Variant 2", interactive=False, show_copy_button=True)
|
| 109 |
+
secondKeywordResponseUtterance3 = gr.Textbox(label="Variant 3", interactive=False, show_copy_button=True)
|
| 110 |
+
|
| 111 |
+
label3 = gr.Markdown(value="Keyword 3",show_label=False)
|
| 112 |
+
with gr.Row() as thirdKeywordResponses:
|
| 113 |
+
thirdKeywordResponseUtterance1 = gr.Textbox(label="Variant 1", interactive=False, show_copy_button=True)
|
| 114 |
+
thirdKeywordResponseUtterance2 = gr.Textbox(label="Variant 2", interactive=False, show_copy_button=True)
|
| 115 |
+
thirdKeywordResponseUtterance3 = gr.Textbox(label="Variant 3", interactive=False, show_copy_button=True)
|
| 116 |
+
|
| 117 |
+
label4 = gr.Markdown(value="Keyword 4",show_label=False)
|
| 118 |
+
with gr.Row() as fourthKeywordResponses:
|
| 119 |
+
fourthKeywordResponseUtterance1 = gr.Textbox(label="Variant 1", interactive=False, show_copy_button=True)
|
| 120 |
+
fourthKeywordResponseUtterance2 = gr.Textbox(label="Variant 2", interactive=False, show_copy_button=True)
|
| 121 |
+
fourthKeywordResponseUtterance3 = gr.Textbox(label="Variant 3", interactive=False, show_copy_button=True)
|
| 122 |
+
|
| 123 |
+
label5 = gr.Markdown(value="Keyword 5",show_label=False)
|
| 124 |
+
with gr.Row() as fifthKeywordResponses:
|
| 125 |
+
fifthKeywordResponseUtterance1 = gr.Textbox(label="Variant 1", interactive=False, show_copy_button=True)
|
| 126 |
+
fifthKeywordResponseUtterance2 = gr.Textbox(label="Variant 2", interactive=False, show_copy_button=True)
|
| 127 |
+
fifthKeywordResponseUtterance3 = gr.Textbox(label="Variant 3", interactive=False, show_copy_button=True)
|
| 128 |
+
|
| 129 |
+
gr.HTML("<h2>Documentation Generator</h2>")
|
| 130 |
+
with gr.Row():
|
| 131 |
+
# clearSelectedSentences = gr.ClearButton(value="Clear Inputs",components=[selectedSentence])
|
| 132 |
+
with gr.Column():
|
| 133 |
+
selectedSentence=gr.Textbox(label="Selected Sentences", show_copy_button=True,lines=5)
|
| 134 |
+
rephraseButton = gr.Button("Generate Documentation",elem_id="rephraseBtn",)
|
| 135 |
+
|
| 136 |
+
rephrasedSentence=gr.Textbox(label="Patient Visit Documentation", interactive=False, show_copy_button=True,lines=7)
|
| 137 |
+
|
| 138 |
+
|
| 139 |
+
# First response event listeners
|
| 140 |
+
firstKeywordResponseUtterance1.select(select_handler,[selectedSentence,firstKeywordResponseUtterance1],selectedSentence)
|
| 141 |
+
firstKeywordResponseUtterance2.select(select_handler,[selectedSentence,firstKeywordResponseUtterance2],selectedSentence)
|
| 142 |
+
firstKeywordResponseUtterance3.select(select_handler,[selectedSentence,firstKeywordResponseUtterance3],selectedSentence)
|
| 143 |
+
|
| 144 |
+
# Second response event listeners
|
| 145 |
+
secondKeywordResponseUtterance1.select(select_handler,[selectedSentence,secondKeywordResponseUtterance1],selectedSentence)
|
| 146 |
+
secondKeywordResponseUtterance2.select(select_handler,[selectedSentence,secondKeywordResponseUtterance2],selectedSentence)
|
| 147 |
+
secondKeywordResponseUtterance3.select(select_handler,[selectedSentence,secondKeywordResponseUtterance3],selectedSentence)
|
| 148 |
+
|
| 149 |
+
# Third response event listeners
|
| 150 |
+
thirdKeywordResponseUtterance1.select(select_handler,[selectedSentence,thirdKeywordResponseUtterance1],selectedSentence)
|
| 151 |
+
thirdKeywordResponseUtterance2.select(select_handler,[selectedSentence,thirdKeywordResponseUtterance2],selectedSentence)
|
| 152 |
+
thirdKeywordResponseUtterance3.select(select_handler,[selectedSentence,thirdKeywordResponseUtterance3],selectedSentence)
|
| 153 |
+
|
| 154 |
+
# Fourth response event listeners
|
| 155 |
+
fourthKeywordResponseUtterance1.select(select_handler,[selectedSentence,fourthKeywordResponseUtterance1],selectedSentence)
|
| 156 |
+
fourthKeywordResponseUtterance2.select(select_handler,[selectedSentence,fourthKeywordResponseUtterance2],selectedSentence)
|
| 157 |
+
fourthKeywordResponseUtterance3.select(select_handler,[selectedSentence,fourthKeywordResponseUtterance3],selectedSentence)
|
| 158 |
+
|
| 159 |
+
# Fifth response event listeners
|
| 160 |
+
fifthKeywordResponseUtterance1.select(select_handler,[selectedSentence,fifthKeywordResponseUtterance1],selectedSentence)
|
| 161 |
+
fifthKeywordResponseUtterance2.select(select_handler,[selectedSentence,fifthKeywordResponseUtterance2],selectedSentence)
|
| 162 |
+
fifthKeywordResponseUtterance3.select(select_handler,[selectedSentence,fifthKeywordResponseUtterance3],selectedSentence)
|
| 163 |
+
|
| 164 |
+
responseButton.click(process_text,[keywords,stage,medicalHistory],[label1,firstKeywordResponseUtterance1,firstKeywordResponseUtterance2,firstKeywordResponseUtterance3,
|
| 165 |
+
label2,secondKeywordResponseUtterance1,secondKeywordResponseUtterance2,secondKeywordResponseUtterance3,
|
| 166 |
+
label3,thirdKeywordResponseUtterance1,thirdKeywordResponseUtterance2,thirdKeywordResponseUtterance3,
|
| 167 |
+
label4,fourthKeywordResponseUtterance1,fourthKeywordResponseUtterance2,fourthKeywordResponseUtterance3,
|
| 168 |
+
label5,fifthKeywordResponseUtterance1,fifthKeywordResponseUtterance2,fifthKeywordResponseUtterance3])
|
| 169 |
+
rephraseButton.click(getRephrasedSentences,selectedSentence,rephrasedSentence)
|
| 170 |
+
|
| 171 |
+
|
| 172 |
+
demo.launch()
|
prompts.py
ADDED
|
@@ -0,0 +1,152 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from enum import Enum
|
| 2 |
+
|
| 3 |
+
class Prompts(Enum):
|
| 4 |
+
INITIAL_ASSESSMENT_PROMPT = """
|
| 5 |
+
"Act as a mental health professional conducting an 'Initial Assessment.'
|
| 6 |
+
User will provide some keywords said by the patient and optionally, the patient's history.
|
| 7 |
+
Respond to the query by considering these keywords and the patient's history (if provided).
|
| 8 |
+
Your response will be crafted three precise variant sentences with numbering for each keyword
|
| 9 |
+
separately by seamlessly integrating that specific mentioned emotional state provided by the patient,
|
| 10 |
+
employing precise related medical terminology. Each keyword should be described separately in it's relevant
|
| 11 |
+
sentence.The objective is to accurately document the patient's mental health status in clear, professional language.
|
| 12 |
+
Your response should directly address the patient's condition without introductory or concluding comments,
|
| 13 |
+
focusing solely on providing a professional yet comprehensible account of the symptoms reported.
|
| 14 |
+
Ensure that the use of medical terms does not compromise the overall accessibility of the text to
|
| 15 |
+
those outside the medical field. Strictly return the below JSON object in response; it must not be a
|
| 16 |
+
JSON string. Use the following structure for your response:
|
| 17 |
+
{\"name of keyword1\" : {\"variant1\": \"...\", \"variant2\": \"...\", \"variant3\": \"...\"}, {\"name of keyword2\" :
|
| 18 |
+
{\"variant1\": \"...\", \"variant2\": \"...\", \"variant3\": \"...\"}, ........}. Don't add any additional ',\n'
|
| 19 |
+
in the JSON object."
|
| 20 |
+
"""
|
| 21 |
+
|
| 22 |
+
RECOMMENDATION_PROMPT = """
|
| 23 |
+
Act as a mental health professional and provide recommendations to patients. User will provide some keywords
|
| 24 |
+
and optionally, the patient's history. Respond to the query by considering these keywords and the patient's history
|
| 25 |
+
(if provided). Your response will be crafted three precise variant sentences with numbering for each keyword separately
|
| 26 |
+
by seamlessly outlining the recommendations based on the provided keyword of user and patient history(if provided).
|
| 27 |
+
Each keyword should be described separately in it's relevant sentence.The objective is to document the recommendation
|
| 28 |
+
of the doctor for the patient based provided kerword and patient history(if provided).Your response should focus solely
|
| 29 |
+
on providing a professional yet comprehensible account of doctor recommendations. Strictly return the below JSON object
|
| 30 |
+
in response; it must not be a JSON string. Use the following structure for your response:
|
| 31 |
+
{\"name of keyword1\" : {\"variant1\": \"...\", \"variant2\": \"...\", \"variant3\": \"...\"}, {\"name of keyword2\" :
|
| 32 |
+
{\"variant1\": \"...\", \"variant2\": \"...\", \"variant3\": \"...\"}, ........}. Don't add any additional ',\n'
|
| 33 |
+
in the JSON object.
|
| 34 |
+
"""
|
| 35 |
+
|
| 36 |
+
SHORT_TERM_GOALS_PROMPT = """
|
| 37 |
+
Act as a mental health professional conducting the second last step of defining 'Short-Term Goals'.
|
| 38 |
+
User will provide some keywords and optionally, the patient's history. Respond to the query by considering
|
| 39 |
+
these keywords and the patient's history (if provided). Your response will be crafted three precise variant
|
| 40 |
+
sentences with numbering for each keyword searately by seamlessly outlining the short term goals based on the
|
| 41 |
+
provided keyword and patient history. Each keyword should be described separately in it's relevant sentence.
|
| 42 |
+
The objective is to document the short term goals of the patient. Your response should focus solely on providing
|
| 43 |
+
a professional yet comprehensible account of patient short term goals. Strictly return the below JSON object in response;
|
| 44 |
+
it must not be a JSON string. Use the following structure for your response:
|
| 45 |
+
{\"name of keyword1\" : {\"variant1\": \"...\", \"variant2\": \"...\", \"variant3\": \"...\"}, {\"name of keyword2\" :
|
| 46 |
+
{\"variant1\": \"...\", \"variant2\": \"...\", \"variant3\": \"...\"}, ........}. Don't add any additional ',\n'
|
| 47 |
+
in the JSON object.
|
| 48 |
+
"""
|
| 49 |
+
|
| 50 |
+
LONG_TERM_GOALS_PROMPT = """
|
| 51 |
+
Act as a mental health professional conducting the second last step of defining
|
| 52 |
+
'Long-Term Goals'.User will provide some keywords and optionally, the patient's history.
|
| 53 |
+
Respond to the query by considering these keywords and the patient's history (if provided).
|
| 54 |
+
Your response will be crafted three precise variant sentences with numbering for each keyword
|
| 55 |
+
separately by seamlessly outlining the Long term goals based on the provided keyword and patient history.
|
| 56 |
+
Each keyword should be described separately in it's relevant sentence.The objective is to document the
|
| 57 |
+
Long term goals of the patient. Your response should focus solely on providing a professional yet comprehensible
|
| 58 |
+
account of patient short term goals. Strictly return the below JSON object in response; it must not be a JSON string.
|
| 59 |
+
Use the following structure for your response:
|
| 60 |
+
{\"name of keyword1\" : {\"variant1\": \"...\", \"variant2\": \"...\", \"variant3\": \"...\"},
|
| 61 |
+
{\"name of keyword2\" : {\"variant1\": \"...\", \"variant2\": \"...\", \"variant3\": \"...\"}, ........}.
|
| 62 |
+
Don't add any additional ',\n' in the JSON object.
|
| 63 |
+
"""
|
| 64 |
+
|
| 65 |
+
REPHRASE_PROMPT = """
|
| 66 |
+
Act as mental Health care provider.Given the following sentences about healthcare patient treatment steps, rephrase
|
| 67 |
+
and combine them into a clear, coherent, and easily understandable paragraph. Aim to improve readability and ensure
|
| 68 |
+
that the essential information and sequence of steps remain accurate and straightforward. Additionally, please adjust
|
| 69 |
+
the tone to be supportive, reassuring for patients and caregivers reading this information. Furthermore,Your response
|
| 70 |
+
must use 'patient' instead of personal pronouns like 'you' to refer to the individual receiving care.
|
| 71 |
+
"""
|
| 72 |
+
|
| 73 |
+
# Not added stages prompts
|
| 74 |
+
|
| 75 |
+
|
| 76 |
+
FOLLOWUP_ASSESSMENT_PROMPT = """
|
| 77 |
+
Act as a mental health professional conducting an 'Follow-up Assessment'. User will provide
|
| 78 |
+
some keywords that reveals the patient's progress since the last evaluation any ongoing issues or
|
| 79 |
+
changes in symptoms and also user can provide patient's history. Respond to the query by considering
|
| 80 |
+
these keywords and the patient's history (if provided). Your response will be crafted three precise variant
|
| 81 |
+
paragraphs with numbering by seamlessly integrating all mentioned emotional states provided by the patient,
|
| 82 |
+
employing precise medical terminology and patient's current status based on their previous assessment, patient history,
|
| 83 |
+
highlighting any improvements, setbacks, or new developments. The objective is to accurately document the patient's
|
| 84 |
+
mental health status in clear, professional language at stage of Follow-up Assessment. Your response should directly
|
| 85 |
+
address the patient's condition without introductory or concluding comments, focusing solely on providing a professional
|
| 86 |
+
yet comprehensible account of the symptoms reported. Ensure that the use of medical terms does not compromise the overall
|
| 87 |
+
accessibility of the text to those outside the medical field. Strictly return the below JSON object in response; it must
|
| 88 |
+
not be a JSON string. Use the following structure for your response:
|
| 89 |
+
{\"variant1\": \"...\", \"variant2\": \"...\", \"variant3\": \"...\"}.
|
| 90 |
+
Don't add any additional ',\n' in the JSON object.
|
| 91 |
+
"""
|
| 92 |
+
|
| 93 |
+
DETAILED_EVALUATION_PROMPT = """
|
| 94 |
+
Act as a mental health professional conducting an 'detailed evaluation.' User will provide some keywords said
|
| 95 |
+
by the patient and optionally, the patient's history. Respond to the query by considering these keywords and
|
| 96 |
+
the patient's history (if provided). Your response will be crafted three precise variant paragraphs with numbering
|
| 97 |
+
by seamlessly writing a detailed paragraph outlining the findings of your evaluation, including observations,
|
| 98 |
+
diagnostic considerations, and preliminary treatment recommendations. The objective is to accurately document
|
| 99 |
+
the patient's mental health status in clear, professional language. Your response should directly address the
|
| 100 |
+
patient's condition without introductory or concluding comments, focusing solely on providing a professional yet
|
| 101 |
+
comprehensible account of patient detail evaluation. Ensure that the use of medical terms does not compromise the
|
| 102 |
+
overall accessibility of the text to those outside the medical field. Strictly return the below JSON object in response;
|
| 103 |
+
it must not be a JSON string. Use the following structure for your response:
|
| 104 |
+
{\"variant1\": \"...\", \"variant2\": \"...\", \"variant3\": \"...\"}.
|
| 105 |
+
Don't add any additional ',\n' in the JSON object."
|
| 106 |
+
"""
|
| 107 |
+
|
| 108 |
+
DISCHARGE_SUMMARY_PROMPT = """
|
| 109 |
+
Act as a mental health professional conducting the 'Discharge Summary' of mental health patient.
|
| 110 |
+
This summary should provides a comprehensive overview of the patient's mental health journey, treatment outcomes,
|
| 111 |
+
and future recommendations. User will provide some keywords and optionally, the patient's history. Respond to the
|
| 112 |
+
query by considering these keywords and the patient's history (if provided). Your response will be crafted three
|
| 113 |
+
detailed variant paragraphs of Discharge summery, summarizing the patient's treatment progress, including improvements,
|
| 114 |
+
relapses, or unresolved issues. Outline post-discharge plans and recommendations for continued care or follow-up.
|
| 115 |
+
Also during crafting consider integrating all mentioned keywords of user and use precise medical terminology.
|
| 116 |
+
The objective is to accurately document the patient's Discharge Summary status in clear, professional language.
|
| 117 |
+
Your response should directly address the patient's Discharge Summary without introductory or concluding comments,
|
| 118 |
+
focusing solely on providing a professional yet comprehensible account of the symptoms reported. Ensure that the use of
|
| 119 |
+
medical terms does not compromise the overall accessibility of the text to those outside the medical field.
|
| 120 |
+
Strictly return the below JSON object in response; it must not be a JSON string. Use the following structure for your
|
| 121 |
+
response: {\"variant1\": \"...\", \"variant2\": \"...\", \"variant3\": \"...\"}. Don't add any additional ',\n' in the JSON object.
|
| 122 |
+
"""
|
| 123 |
+
|
| 124 |
+
PROGRESS_NOTE_PROMPT = """
|
| 125 |
+
Act as a mental health professional conducting an 'Progress Note'
|
| 126 |
+
User will provide some keywords said by the patient and optionally,
|
| 127 |
+
the patient's history. Respond to the query by considering these keywords and the patient's history (if provided).
|
| 128 |
+
Your response will be crafted three precise variant paragraphs with numbering by seamlessly integrating all mentioned
|
| 129 |
+
emotional states provided by the patient, employing precise medical terminology. The objective is to accurately document
|
| 130 |
+
the patient's mental health status in clear, professional language. Your response should directly address the patient's
|
| 131 |
+
condition without introductory or concluding comments, focusing solely on providing a professional yet comprehensible
|
| 132 |
+
account of the symptoms reported. Ensure that the use of medical terms does not compromise the overall accessibility
|
| 133 |
+
of the text to those outside the medical field. Strictly return the below JSON object in response; it must
|
| 134 |
+
not be a JSON string. Use the following structure for your response:
|
| 135 |
+
{\"variant1\": \"...\", \"variant2\": \"...\", \"variant3\": \"...\"}.
|
| 136 |
+
Don't add any additional ',\n' in the JSON object.
|
| 137 |
+
"""
|
| 138 |
+
|
| 139 |
+
EVALUATION_PROMPT = """
|
| 140 |
+
Act as a mental health professional conducting an 'Evaluation'
|
| 141 |
+
User will provide some keywords said by the patient and optionally,
|
| 142 |
+
the patient's history. Respond to the query by considering these keywords and the patient's history (if provided).
|
| 143 |
+
Your response will be crafted three precise variant paragraphs with numbering by seamlessly integrating all mentioned
|
| 144 |
+
emotional states provided by the patient, employing precise medical terminology. The objective is to accurately document
|
| 145 |
+
the patient's mental health status in clear, professional language. Your response should directly address the patient's
|
| 146 |
+
condition without introductory or concluding comments, focusing solely on providing a professional yet comprehensible
|
| 147 |
+
account of the symptoms reported. Ensure that the use of medical terms does not compromise the overall accessibility
|
| 148 |
+
of the text to those outside the medical field. Strictly return the below JSON object in response; it must
|
| 149 |
+
not be a JSON string. Use the following structure for your response:
|
| 150 |
+
{\"variant1\": \"...\", \"variant2\": \"...\", \"variant3\": \"...\"}.
|
| 151 |
+
Don't add any additional ',\n' in the JSON object.
|
| 152 |
+
"""
|
service.py
ADDED
|
@@ -0,0 +1,138 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import os
|
| 2 |
+
import requests
|
| 3 |
+
from enum import Enum
|
| 4 |
+
from dotenv import load_dotenv
|
| 5 |
+
from prompts import Prompts
|
| 6 |
+
import json
|
| 7 |
+
|
| 8 |
+
# Load environment variables from .env file
|
| 9 |
+
load_dotenv()
|
| 10 |
+
|
| 11 |
+
# Access environment variables
|
| 12 |
+
API_KEY = os.environ['CHAT_GPT_KEY']
|
| 13 |
+
|
| 14 |
+
class Stage(Enum):
|
| 15 |
+
INITIAL_ASSESSMENT = "Initial Assessment"
|
| 16 |
+
FOLLOWUP_ASSESSMENT = "Follow Up Assessment"
|
| 17 |
+
EVALUATION = "Evaluation"
|
| 18 |
+
DETAILED_EVALUATION = "Detailed Evaluation"
|
| 19 |
+
PROGRESS_NOTE = "Progress Note"
|
| 20 |
+
RECOMMENDATION="Recommendations"
|
| 21 |
+
DISCHARGE_SUMMARY = "Discharge Summary"
|
| 22 |
+
SHORT_TERM_GOALS = "Short Term Goals"
|
| 23 |
+
LONG_TERM_GOALS = "Long Term Goals"
|
| 24 |
+
|
| 25 |
+
|
| 26 |
+
class GPT_Service:
|
| 27 |
+
def __init__(self):
|
| 28 |
+
self.api_key = API_KEY
|
| 29 |
+
self.base_url = 'https://api.openai.com/v1/chat/completions'
|
| 30 |
+
|
| 31 |
+
def request_gpt_for_response(self, system_prompt, userPrompt):
|
| 32 |
+
headers = {
|
| 33 |
+
'Content-Type': 'application/json',
|
| 34 |
+
'Authorization': f'Bearer {self.api_key}'
|
| 35 |
+
}
|
| 36 |
+
data = {
|
| 37 |
+
'model': 'gpt-3.5-turbo-1106',
|
| 38 |
+
'temperature': 0.3,
|
| 39 |
+
'messages': [
|
| 40 |
+
{
|
| 41 |
+
'role': 'system',
|
| 42 |
+
'content': system_prompt
|
| 43 |
+
},
|
| 44 |
+
{
|
| 45 |
+
'role': 'user',
|
| 46 |
+
'content': userPrompt
|
| 47 |
+
}
|
| 48 |
+
]
|
| 49 |
+
}
|
| 50 |
+
try:
|
| 51 |
+
response = requests.post(
|
| 52 |
+
self.base_url,
|
| 53 |
+
json=data,
|
| 54 |
+
headers=headers,
|
| 55 |
+
)
|
| 56 |
+
response.raise_for_status()
|
| 57 |
+
return response.json()['choices'][0]['message']['content']
|
| 58 |
+
except requests.exceptions.RequestException as e:
|
| 59 |
+
raise ValueError(f"Error: {e}")
|
| 60 |
+
|
| 61 |
+
def formulateUserPrompt(self, assessmentPhase, keywords, medicalHistory):
|
| 62 |
+
patientData= f"""
|
| 63 |
+
Keywords: {keywords}.
|
| 64 |
+
{f"Patient has the following medical history: {medicalHistory}" if medicalHistory is not None and medicalHistory != ""
|
| 65 |
+
else ""}
|
| 66 |
+
"""
|
| 67 |
+
print(patientData)
|
| 68 |
+
return patientData
|
| 69 |
+
|
| 70 |
+
def processOutputResults(self, jsonOutput):
|
| 71 |
+
preprocessed_json_string = jsonOutput.replace('\n', '')
|
| 72 |
+
data = json.loads(preprocessed_json_string)
|
| 73 |
+
dataLength=len(data.keys())
|
| 74 |
+
result_list = []
|
| 75 |
+
|
| 76 |
+
for key, value in data.items():
|
| 77 |
+
result_list.append(key)
|
| 78 |
+
for variant, sentence in value.items():
|
| 79 |
+
result_list.append(sentence)
|
| 80 |
+
|
| 81 |
+
if dataLength < 5:
|
| 82 |
+
additional_keys_needed = 5 - dataLength
|
| 83 |
+
for key in range(additional_keys_needed):
|
| 84 |
+
result_list.append(f"Keyword {dataLength+key+1}") # Empty key
|
| 85 |
+
for _ in range(3):
|
| 86 |
+
result_list.append("") # Empty sentence
|
| 87 |
+
return result_list
|
| 88 |
+
|
| 89 |
+
return result_list
|
| 90 |
+
|
| 91 |
+
def getInitialAssessment(self, keywords,medicalHistory):
|
| 92 |
+
userPrompt= self.formulateUserPrompt(Stage.INITIAL_ASSESSMENT.value,keywords,medicalHistory)
|
| 93 |
+
response= self.request_gpt_for_response(Prompts.INITIAL_ASSESSMENT_PROMPT.value,userPrompt)
|
| 94 |
+
return self.processOutputResults(response)
|
| 95 |
+
|
| 96 |
+
def getFollowUpAssessment(self, keywords, medicalHistory):
|
| 97 |
+
userPrompt= self.formulateUserPrompt(Stage.FOLLOWUP_ASSESSMENT.value,keywords,medicalHistory)
|
| 98 |
+
response= self.request_gpt_for_response(Prompts.FOLLOWUP_ASSESSMENT_PROMPT.value,userPrompt)
|
| 99 |
+
return self.processOutputResults(response)
|
| 100 |
+
|
| 101 |
+
def getEvaluation(self, keywords, medicalHistory):
|
| 102 |
+
userPrompt= self.formulateUserPrompt(Stage.EVALUATION.value,keywords,medicalHistory)
|
| 103 |
+
response= self.request_gpt_for_response(Prompts.EVALUATION_PROMPT.value,userPrompt)
|
| 104 |
+
return self.processOutputResults(response)
|
| 105 |
+
|
| 106 |
+
def getRecommendation(self, keywords, medicalHistory):
|
| 107 |
+
userPrompt= self.formulateUserPrompt(Stage.RECOMMENDATION.value,keywords,medicalHistory)
|
| 108 |
+
response= self.request_gpt_for_response(Prompts.RECOMMENDATION_PROMPT.value,userPrompt)
|
| 109 |
+
return self.processOutputResults(response)
|
| 110 |
+
|
| 111 |
+
def getDetailedEvaluation(self, keywords,medicalHistory):
|
| 112 |
+
userPrompt= self.formulateUserPrompt(Stage.DETAILED_EVALUATION.value,keywords,medicalHistory)
|
| 113 |
+
response= self.request_gpt_for_response(Prompts.DETAILED_EVALUATION_PROMPT.value,userPrompt)
|
| 114 |
+
return self.processOutputResults(response)
|
| 115 |
+
|
| 116 |
+
def getProgressNote(self, keywords,medicalHistory):
|
| 117 |
+
userPrompt= self.formulateUserPrompt(Stage.PROGRESS_NOTE.value,keywords,medicalHistory)
|
| 118 |
+
response = self.request_gpt_for_response(Prompts.PROGRESS_NOTE_PROMPT.value,userPrompt)
|
| 119 |
+
return self.processOutputResults(response)
|
| 120 |
+
|
| 121 |
+
def getDischargeSummary(self, keywords,medicalHistory):
|
| 122 |
+
userPrompt= self.formulateUserPrompt(Stage.DISCHARGE_SUMMARY.value,keywords,medicalHistory)
|
| 123 |
+
response = self.request_gpt_for_response(Prompts.DISCHARGE_SUMMARY_PROMPT.value,userPrompt)
|
| 124 |
+
return self.processOutputResults(response)
|
| 125 |
+
|
| 126 |
+
def getShortTermGoals(self, keywords,medicalHistory):
|
| 127 |
+
userPrompt= self.formulateUserPrompt(Stage.SHORT_TERM_GOALS.value,keywords,medicalHistory)
|
| 128 |
+
response = self.request_gpt_for_response(Prompts.SHORT_TERM_GOALS_PROMPT.value,userPrompt)
|
| 129 |
+
return self.processOutputResults(response)
|
| 130 |
+
|
| 131 |
+
def getLongTermGoals(self, keywords,medicalHistory):
|
| 132 |
+
userPrompt= self.formulateUserPrompt(Stage.LONG_TERM_GOALS.value,keywords,medicalHistory)
|
| 133 |
+
response = self.request_gpt_for_response(Prompts.LONG_TERM_GOALS_PROMPT.value,userPrompt)
|
| 134 |
+
return self.processOutputResults(response)
|
| 135 |
+
|
| 136 |
+
def getRephrasedSentences(self, sentences):
|
| 137 |
+
response = self.request_gpt_for_response(Prompts.REPHRASE_PROMPT.value,sentences)
|
| 138 |
+
return response
|