ziggycross
commited on
Commit
•
caeec0f
1
Parent(s):
ca9ba38
Added basic assessment service to chatbot.
Browse files- Dockerfile +1 -1
- app.py +19 -30
- questionnaires.py +35 -0
- static/questionnaires/index.json +7 -0
- static/questionnaires/questionnaire_asrs-5.json +93 -0
- static/questionnaires/questionnaire_gad-7.json +113 -0
- static/questionnaires/questionnaire_pc-ptsd.json +73 -0
- static/questionnaires/questionnaire_phq-9.json +144 -0
- static/questionnaires/questionnaire_zf-ocs.json +72 -0
- therapist.py +106 -0
Dockerfile
CHANGED
@@ -1,6 +1,6 @@
|
|
1 |
# syntax=docker/dockerfile:1
|
2 |
|
3 |
-
FROM python:3.
|
4 |
|
5 |
WORKDIR /code
|
6 |
|
|
|
1 |
# syntax=docker/dockerfile:1
|
2 |
|
3 |
+
FROM python:3.10
|
4 |
|
5 |
WORKDIR /code
|
6 |
|
app.py
CHANGED
@@ -1,13 +1,16 @@
|
|
1 |
-
from datetime import datetime
|
2 |
from flask import Flask, request, jsonify, make_response
|
3 |
from flask_cors import CORS
|
4 |
from datetime import datetime
|
5 |
import openai
|
6 |
import os
|
|
|
|
|
7 |
|
8 |
### VARIABLES
|
9 |
|
10 |
INITIAL_MESSAGE = "Hi! I'm Brainy, a virtual assistant who can guide you through the mental health screening process. Can you start by telling me a bit about the problems you are experiencing?"
|
|
|
11 |
|
12 |
#### SET UP ENVIRONMENT
|
13 |
openai.api_key = os.getenv("OPENAI_API_KEY")
|
@@ -18,20 +21,6 @@ CORS(app)
|
|
18 |
users = {}
|
19 |
message_history = {}
|
20 |
|
21 |
-
### RESPONSE FUNCTIONS
|
22 |
-
|
23 |
-
def generate_response(prompt):
|
24 |
-
completions = openai.Completion.create(
|
25 |
-
engine = "text-davinci-003",
|
26 |
-
prompt = prompt,
|
27 |
-
max_tokens = 1024,
|
28 |
-
n = 1,
|
29 |
-
stop = None,
|
30 |
-
temperature=0.5,
|
31 |
-
)
|
32 |
-
message = completions.choices[0].text.strip()
|
33 |
-
return message
|
34 |
-
|
35 |
### UTILITY FUNCTIONS
|
36 |
|
37 |
def clean_users(users=users, message_history=message_history):
|
@@ -48,33 +37,33 @@ def index():
|
|
48 |
|
49 |
@app.route('/get_initial', methods=['GET'])
|
50 |
def get_initial():
|
51 |
-
response =
|
52 |
|
53 |
connect_time = datetime.now()
|
54 |
-
user_id = str(
|
55 |
|
56 |
-
users[user_id] =
|
57 |
-
|
|
|
|
|
|
|
58 |
|
59 |
clean_users() # Remove old user IDs and messages from our system
|
60 |
|
61 |
return jsonify({"response": response, "user_id":user_id})
|
62 |
|
63 |
-
@app.route('/reset_cookie', methods=['GET'])
|
64 |
-
def reset_cookie():
|
65 |
-
# Set cookie value to an empty string
|
66 |
-
resp = make_response("Cookie reset")
|
67 |
-
resp.set_cookie('last_index', '', expires=datetime.now() - timedelta(days=1))
|
68 |
-
return resp
|
69 |
-
|
70 |
@app.route('/get_response', methods=['GET'])
|
71 |
def get_response():
|
72 |
message = request.args.get("message")
|
73 |
user_id = request.args.get("user_id")
|
74 |
-
|
75 |
-
|
76 |
-
|
77 |
-
|
|
|
|
|
|
|
|
|
78 |
|
79 |
return jsonify({"response": response})
|
80 |
|
|
|
1 |
+
from datetime import datetime
|
2 |
from flask import Flask, request, jsonify, make_response
|
3 |
from flask_cors import CORS
|
4 |
from datetime import datetime
|
5 |
import openai
|
6 |
import os
|
7 |
+
import random
|
8 |
+
import therapist
|
9 |
|
10 |
### VARIABLES
|
11 |
|
12 |
INITIAL_MESSAGE = "Hi! I'm Brainy, a virtual assistant who can guide you through the mental health screening process. Can you start by telling me a bit about the problems you are experiencing?"
|
13 |
+
HASH_LENGTH = 12
|
14 |
|
15 |
#### SET UP ENVIRONMENT
|
16 |
openai.api_key = os.getenv("OPENAI_API_KEY")
|
|
|
21 |
users = {}
|
22 |
message_history = {}
|
23 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
24 |
### UTILITY FUNCTIONS
|
25 |
|
26 |
def clean_users(users=users, message_history=message_history):
|
|
|
37 |
|
38 |
@app.route('/get_initial', methods=['GET'])
|
39 |
def get_initial():
|
40 |
+
response = therapist.initial_message
|
41 |
|
42 |
connect_time = datetime.now()
|
43 |
+
user_id = str("%030x" % random.randrange(16 ** HASH_LENGTH))[-HASH_LENGTH:]
|
44 |
|
45 |
+
users[user_id] = {
|
46 |
+
"user_id": user_id,
|
47 |
+
"connect_time": connect_time,
|
48 |
+
"state": ["initial"],
|
49 |
+
"message_history": [therapist.initial_message]}
|
50 |
|
51 |
clean_users() # Remove old user IDs and messages from our system
|
52 |
|
53 |
return jsonify({"response": response, "user_id":user_id})
|
54 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
55 |
@app.route('/get_response', methods=['GET'])
|
56 |
def get_response():
|
57 |
message = request.args.get("message")
|
58 |
user_id = request.args.get("user_id")
|
59 |
+
user = users[user_id]
|
60 |
+
|
61 |
+
if not message.strip():
|
62 |
+
response = "Please enter a message."
|
63 |
+
else:
|
64 |
+
state, response = therapist.generate_response(user, message)
|
65 |
+
user["state"] = state
|
66 |
+
user["message_history"].extend([message, response])
|
67 |
|
68 |
return jsonify({"response": response})
|
69 |
|
questionnaires.py
ADDED
@@ -0,0 +1,35 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import json
|
2 |
+
|
3 |
+
FILE_PATH = "static/questionnaires/"
|
4 |
+
END = "<end>"
|
5 |
+
|
6 |
+
with open(FILE_PATH+"index.json", "r") as fh:
|
7 |
+
index = json.load(fh)
|
8 |
+
|
9 |
+
topics = list(index.keys())
|
10 |
+
|
11 |
+
questionnaires = {}
|
12 |
+
for topic, filename in index.items():
|
13 |
+
with open(FILE_PATH+filename, "r") as fh:
|
14 |
+
questionnaires[topic] = json.load(fh)
|
15 |
+
|
16 |
+
numbers = {
|
17 |
+
topic: [question["number"] for question in questionnaires[topic]["questions"]] + [END]
|
18 |
+
for topic
|
19 |
+
in topics
|
20 |
+
}
|
21 |
+
sections = {
|
22 |
+
topic: [question["section"] for question in questionnaires[topic]["questions"]] + [END]
|
23 |
+
for topic
|
24 |
+
in topics
|
25 |
+
}
|
26 |
+
questions = {
|
27 |
+
topic: [question["text"] for question in questionnaires[topic]["questions"]] + [END]
|
28 |
+
for topic
|
29 |
+
in topics
|
30 |
+
}
|
31 |
+
scales = {
|
32 |
+
topic: [question["scale"] for question in questionnaires[topic]["questions"]] + [END]
|
33 |
+
for topic
|
34 |
+
in topics
|
35 |
+
}
|
static/questionnaires/index.json
ADDED
@@ -0,0 +1,7 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
{
|
2 |
+
"depression": "questionnaire_phq-9.json",
|
3 |
+
"anxiety": "questionnaire_gad-7.json",
|
4 |
+
"adhd": "questionnaire_asrs-5.json",
|
5 |
+
"ocd": "questionnaire_zf-ocs.json",
|
6 |
+
"ptsd": "questionnaire_pc-ptsd.json"
|
7 |
+
}
|
static/questionnaires/questionnaire_asrs-5.json
ADDED
@@ -0,0 +1,93 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
{
|
2 |
+
"name": "ASRS-5",
|
3 |
+
"description": null,
|
4 |
+
"questions": [
|
5 |
+
{
|
6 |
+
"number": 1,
|
7 |
+
"section": 1,
|
8 |
+
"text": "Over the past six months, how often have you had difficulty concentrating on what people are saying to you even when they are speaking to you directly?",
|
9 |
+
"scale": {
|
10 |
+
"Never": 0,
|
11 |
+
"Rarely": 1,
|
12 |
+
"Sometimes": 2,
|
13 |
+
"Often": 3,
|
14 |
+
"Very Often": 4
|
15 |
+
}
|
16 |
+
},
|
17 |
+
{
|
18 |
+
"number": 2,
|
19 |
+
"section": 1,
|
20 |
+
"text": "Over the past six months, how often have you left your seat in meetings or other situations in which you are expected to remain seated?",
|
21 |
+
"scale": {
|
22 |
+
"Never": 0,
|
23 |
+
"Rarely": 1,
|
24 |
+
"Sometimes": 2,
|
25 |
+
"Often": 3,
|
26 |
+
"Very Often": 4
|
27 |
+
}
|
28 |
+
},
|
29 |
+
{
|
30 |
+
"number": 3,
|
31 |
+
"section": 1,
|
32 |
+
"text": "Over the past six months, how often have you had difficulty unwinding and relaxing when you have time to yourself?",
|
33 |
+
"scale": {
|
34 |
+
"Never": 0,
|
35 |
+
"Rarely": 1,
|
36 |
+
"Sometimes": 2,
|
37 |
+
"Often": 3,
|
38 |
+
"Very Often": 4
|
39 |
+
}
|
40 |
+
},
|
41 |
+
{
|
42 |
+
"number": 4,
|
43 |
+
"section": 1,
|
44 |
+
"text": "Over the past six months, how often have you found yourself finishing the sentences of the people you are talking to before they can finish them themselves when you're in a conversation?",
|
45 |
+
"scale": {
|
46 |
+
"Never": 0,
|
47 |
+
"Rarely": 1,
|
48 |
+
"Sometimes": 2,
|
49 |
+
"Often": 3,
|
50 |
+
"Very Often": 4
|
51 |
+
}
|
52 |
+
},
|
53 |
+
{
|
54 |
+
"number": 5,
|
55 |
+
"section": 1,
|
56 |
+
"text": "Over the past six months, how often have you put things off until the last minute?",
|
57 |
+
"scale": {
|
58 |
+
"Never": 0,
|
59 |
+
"Rarely": 1,
|
60 |
+
"Sometimes": 2,
|
61 |
+
"Often": 3,
|
62 |
+
"Very Often": 4
|
63 |
+
}
|
64 |
+
},
|
65 |
+
{
|
66 |
+
"number": 6,
|
67 |
+
"section": 1,
|
68 |
+
"text": "Over the past six months, how often have you depended on others to keep your life in order and attend to details?",
|
69 |
+
"scale": {
|
70 |
+
"Never": 0,
|
71 |
+
"Rarely": 1,
|
72 |
+
"Sometimes": 2,
|
73 |
+
"Often": 3,
|
74 |
+
"Very Often": 4
|
75 |
+
}
|
76 |
+
}
|
77 |
+
],
|
78 |
+
"scoring": [
|
79 |
+
{
|
80 |
+
"section": 1,
|
81 |
+
"ranges": [
|
82 |
+
[0,14],
|
83 |
+
[14,25]
|
84 |
+
],
|
85 |
+
"severity": [
|
86 |
+
"Does not screen positive",
|
87 |
+
"Screens positive"
|
88 |
+
]
|
89 |
+
}
|
90 |
+
],
|
91 |
+
"source": "https://www.hcp.med.harvard.edu/ncs/ftpdir/adhd/ASRS-5_English.pdf",
|
92 |
+
"accessed": "2023-03-25"
|
93 |
+
}
|
static/questionnaires/questionnaire_gad-7.json
ADDED
@@ -0,0 +1,113 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
{
|
2 |
+
"name": "GAD-7",
|
3 |
+
"description": null,
|
4 |
+
"questions": [
|
5 |
+
{
|
6 |
+
"number": 1,
|
7 |
+
"section": 1,
|
8 |
+
"text": "Over the last two weeks, how often have you been bothered by feeling nervous, anxious, or on edge?",
|
9 |
+
"scale": {
|
10 |
+
"Not at all": 0,
|
11 |
+
"Several days": 1,
|
12 |
+
"More than half the days": 2,
|
13 |
+
"Nearly every day": 3
|
14 |
+
}
|
15 |
+
},
|
16 |
+
{
|
17 |
+
"number": 2,
|
18 |
+
"section": 1,
|
19 |
+
"text": "Over the last two weeks, how often have you been bothered by not being able to stop or control worrying?",
|
20 |
+
"scale": {
|
21 |
+
"Not at all": 0,
|
22 |
+
"Several days": 1,
|
23 |
+
"More than half the days": 2,
|
24 |
+
"Nearly every day": 3
|
25 |
+
}
|
26 |
+
},
|
27 |
+
{
|
28 |
+
"number": 3,
|
29 |
+
"section": 1,
|
30 |
+
"text": "Over the last two weeks, how often have you been bothered by worrying too much about different things?",
|
31 |
+
"scale": {
|
32 |
+
"Not at all": 0,
|
33 |
+
"Several days": 1,
|
34 |
+
"More than half the days": 2,
|
35 |
+
"Nearly every day": 3
|
36 |
+
}
|
37 |
+
},
|
38 |
+
{
|
39 |
+
"number": 4,
|
40 |
+
"section": 1,
|
41 |
+
"text": "Over the last two weeks, how often have you been bothered by trouble relaxing?",
|
42 |
+
"scale": {
|
43 |
+
"Not at all": 0,
|
44 |
+
"Several days": 1,
|
45 |
+
"More than half the days": 2,
|
46 |
+
"Nearly every day": 3
|
47 |
+
}
|
48 |
+
},
|
49 |
+
{
|
50 |
+
"number": 5,
|
51 |
+
"section": 1,
|
52 |
+
"text": "Over the last two weeks, how often have you been bothered by being so restless that it is hard to sit still?",
|
53 |
+
"scale": {
|
54 |
+
"Not at all": 0,
|
55 |
+
"Several days": 1,
|
56 |
+
"More than half the days": 2,
|
57 |
+
"Nearly every day": 3
|
58 |
+
}
|
59 |
+
},
|
60 |
+
{
|
61 |
+
"number": 6,
|
62 |
+
"section": 1,
|
63 |
+
"text": "Over the last two weeks, how often have you been bothered by becoming easily annoyed or irritable?",
|
64 |
+
"scale": {
|
65 |
+
"Not at all": 0,
|
66 |
+
"Several days": 1,
|
67 |
+
"More than half the days": 2,
|
68 |
+
"Nearly every day": 3
|
69 |
+
}
|
70 |
+
},
|
71 |
+
{
|
72 |
+
"number": 7,
|
73 |
+
"section": 1,
|
74 |
+
"text": "Over the last two weeks, how often have you been bothered by feeling afraid, as if something awful might happen?",
|
75 |
+
"scale": {
|
76 |
+
"Not at all": 0,
|
77 |
+
"Several days": 1,
|
78 |
+
"More than half the days": 2,
|
79 |
+
"Nearly every day": 3
|
80 |
+
}
|
81 |
+
},
|
82 |
+
{
|
83 |
+
"number": 8,
|
84 |
+
"section": 2,
|
85 |
+
"text": "How difficult have these problems made it for you to do your work, take care of things at home, or get along with other people?",
|
86 |
+
"scale": {
|
87 |
+
"Not difficult at all": 0,
|
88 |
+
"Somewhat difficult": 1,
|
89 |
+
"Very difficult": 2,
|
90 |
+
"Extremely difficult": 3
|
91 |
+
}
|
92 |
+
}
|
93 |
+
],
|
94 |
+
"scoring": [
|
95 |
+
{
|
96 |
+
"section": 1,
|
97 |
+
"ranges": [
|
98 |
+
[0,5],
|
99 |
+
[5,10],
|
100 |
+
[10,15],
|
101 |
+
[15,22]
|
102 |
+
],
|
103 |
+
"severity": [
|
104 |
+
"Minimal",
|
105 |
+
"Mild",
|
106 |
+
"Moderate",
|
107 |
+
"Severe"
|
108 |
+
]
|
109 |
+
}
|
110 |
+
],
|
111 |
+
"source": "https://adaa.org/sites/default/files/GAD-7_Anxiety-updated_0.pdf",
|
112 |
+
"accessed": "2023-03-25"
|
113 |
+
}
|
static/questionnaires/questionnaire_pc-ptsd.json
ADDED
@@ -0,0 +1,73 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
{
|
2 |
+
"name": "ZF-OCS",
|
3 |
+
"description": null,
|
4 |
+
"questions": [
|
5 |
+
{
|
6 |
+
"number": 1,
|
7 |
+
"section": 1,
|
8 |
+
"text": "Sometimes things happen to people that are unusually or especially frightening, horrible, or traumatic. For example:, a serious accident or fire, a physical or sexual assault or abuse, an earthquake or flood, a war, seeing someone be killed or seriously injured, having a loved one die through homicide or suicide. Have you ever experienced this kind of event?",
|
9 |
+
"scale": {
|
10 |
+
"No": 0,
|
11 |
+
"Yes": 1
|
12 |
+
}
|
13 |
+
},
|
14 |
+
{
|
15 |
+
"number": 2,
|
16 |
+
"section": 2,
|
17 |
+
"text": "In the past month, have you had nightmares about the event or thought about the event when you did not want to?",
|
18 |
+
"scale": {
|
19 |
+
"No": 0,
|
20 |
+
"Yes": 1
|
21 |
+
}
|
22 |
+
},
|
23 |
+
{
|
24 |
+
"number": 3,
|
25 |
+
"section": 2,
|
26 |
+
"text": "In the past month, have you tried hard not to think about the event or went out of your way to avoid situations that reminded you of the event?",
|
27 |
+
"scale": {
|
28 |
+
"No": 0,
|
29 |
+
"Yes": 1
|
30 |
+
}
|
31 |
+
},
|
32 |
+
{
|
33 |
+
"number": 4,
|
34 |
+
"section": 2,
|
35 |
+
"text": "In the past month, have you been constantly on guard, watchful, or easily startled?",
|
36 |
+
"scale": {
|
37 |
+
"No": 0,
|
38 |
+
"Yes": 1
|
39 |
+
}
|
40 |
+
},
|
41 |
+
{
|
42 |
+
"number": 5,
|
43 |
+
"section": 2,
|
44 |
+
"text": "In the past month, have you felt numb or detached from people, activities, or your surroundings?",
|
45 |
+
"scale": {
|
46 |
+
"No": 0,
|
47 |
+
"Yes": 1
|
48 |
+
}
|
49 |
+
},
|
50 |
+
{
|
51 |
+
"number": 6,
|
52 |
+
"section": 2,
|
53 |
+
"text": "In the past month, have you felt guilty or unable to stop blaming yourself or others for the event(s) or any problems the event(s) may have caused?",
|
54 |
+
"scale": {
|
55 |
+
"No": 0,
|
56 |
+
"Yes": 1
|
57 |
+
}
|
58 |
+
}
|
59 |
+
],
|
60 |
+
"scoring": [
|
61 |
+
{
|
62 |
+
"section": 2,
|
63 |
+
"ranges": [
|
64 |
+
[0,1]
|
65 |
+
],
|
66 |
+
"severity": [
|
67 |
+
"Positive for PTSD symptoms"
|
68 |
+
]
|
69 |
+
}
|
70 |
+
],
|
71 |
+
"source": "https://www.ptsd.va.gov/professional/assessment/screens/pc-ptsd.asp",
|
72 |
+
"accessed": "2023-03-25"
|
73 |
+
}
|
static/questionnaires/questionnaire_phq-9.json
ADDED
@@ -0,0 +1,144 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
{
|
2 |
+
"name": "PHQ-9",
|
3 |
+
"description": null,
|
4 |
+
"questions": [
|
5 |
+
{
|
6 |
+
"number": 1,
|
7 |
+
"section": 1,
|
8 |
+
"text": "Over the last two weeks, how often have you been bothered by having little interest or pleasure in doing things?",
|
9 |
+
"scale": {
|
10 |
+
"Not at all": 0,
|
11 |
+
"Several days": 1,
|
12 |
+
"More than half the days": 2,
|
13 |
+
"Nearly every day": 3
|
14 |
+
}
|
15 |
+
},
|
16 |
+
{
|
17 |
+
"number": 2,
|
18 |
+
"section": 1,
|
19 |
+
"text": "Over the last two weeks, how often have you been bothered by feeling down, depressed, or hopeless?",
|
20 |
+
"scale": {
|
21 |
+
"Not at all": 0,
|
22 |
+
"Several days": 1,
|
23 |
+
"More than half the days": 2,
|
24 |
+
"Nearly every day": 3
|
25 |
+
}
|
26 |
+
},
|
27 |
+
{
|
28 |
+
"number": 3,
|
29 |
+
"section": 1,
|
30 |
+
"text": "Over the last two weeks, how often have you been bothered by having trouble falling or staying asleep, or sleeping too much?",
|
31 |
+
"scale": {
|
32 |
+
"Not at all": 0,
|
33 |
+
"Several days": 1,
|
34 |
+
"More than half the days": 2,
|
35 |
+
"Nearly every day": 3
|
36 |
+
}
|
37 |
+
},
|
38 |
+
{
|
39 |
+
"number": 4,
|
40 |
+
"section": 1,
|
41 |
+
"text": "Over the last two weeks, how often have you been bothered by feeling tired or having little energy?",
|
42 |
+
"scale": {
|
43 |
+
"Not at all": 0,
|
44 |
+
"Several days": 1,
|
45 |
+
"More than half the days": 2,
|
46 |
+
"Nearly every day": 3
|
47 |
+
}
|
48 |
+
},
|
49 |
+
{
|
50 |
+
"number": 5,
|
51 |
+
"section": 1,
|
52 |
+
"text": "Over the last two weeks, how often have you been bothered by having poor appetite or overeating?",
|
53 |
+
"scale": {
|
54 |
+
"Not at all": 0,
|
55 |
+
"Several days": 1,
|
56 |
+
"More than half the days": 2,
|
57 |
+
"Nearly every day": 3
|
58 |
+
}
|
59 |
+
},
|
60 |
+
{
|
61 |
+
"number": 6,
|
62 |
+
"section": 1,
|
63 |
+
"text": "Over the last two weeks, how often have you been bothered by feeling bad about yourself - or that you are a failure or have let yourself or your family down?",
|
64 |
+
"scale": {
|
65 |
+
"Not at all": 0,
|
66 |
+
"Several days": 1,
|
67 |
+
"More than half the days": 2,
|
68 |
+
"Nearly every day": 3
|
69 |
+
}
|
70 |
+
},
|
71 |
+
{
|
72 |
+
"number": 7,
|
73 |
+
"section": 1,
|
74 |
+
"text": "Over the last two weeks, how often have you been bothered by having trouble concentrating on things, such as reading the newspaper or watching television?",
|
75 |
+
"scale": {
|
76 |
+
"Not at all": 0,
|
77 |
+
"Several days": 1,
|
78 |
+
"More than half the days": 2,
|
79 |
+
"Nearly every day": 3
|
80 |
+
}
|
81 |
+
},
|
82 |
+
{
|
83 |
+
"number": 8,
|
84 |
+
"section": 1,
|
85 |
+
"text": "Over the last two weeks, how often have you been bothered by moving or speaking so slowly that other people could have noticed? Or the opposite - being so fidgety or restless that you have been moving around a lot more than usual?",
|
86 |
+
"scale": {
|
87 |
+
"Not at all": 0,
|
88 |
+
"Several days": 1,
|
89 |
+
"More than half the days": 2,
|
90 |
+
"Nearly every day": 3
|
91 |
+
}
|
92 |
+
},
|
93 |
+
{
|
94 |
+
"number": 9,
|
95 |
+
"section": 1,
|
96 |
+
"text": "Over the last two weeks, how often have you been bothered by having thoughts that you would be better off dead or of hurting yourself in some way?",
|
97 |
+
"scale": {
|
98 |
+
"Not at all": 0,
|
99 |
+
"Several days": 1,
|
100 |
+
"More than half the days": 2,
|
101 |
+
"Nearly every day": 3
|
102 |
+
}
|
103 |
+
},
|
104 |
+
{
|
105 |
+
"number": 10,
|
106 |
+
"section": 1,
|
107 |
+
"text": "How difficult have these problems made it for you to do your work, take care of things at home, or get along with other people?",
|
108 |
+
"scale": {
|
109 |
+
"Not difficult at all": 0,
|
110 |
+
"Somewhat difficult": 1,
|
111 |
+
"Very difficult": 2,
|
112 |
+
"Extremely difficult": 3
|
113 |
+
}
|
114 |
+
}
|
115 |
+
],
|
116 |
+
"scoring": [
|
117 |
+
{
|
118 |
+
"section": 1,
|
119 |
+
"ranges": [
|
120 |
+
[0,5],
|
121 |
+
[5,10],
|
122 |
+
[10,15],
|
123 |
+
[15,20],
|
124 |
+
[20,28]
|
125 |
+
],
|
126 |
+
"severity": [
|
127 |
+
"None-minimal",
|
128 |
+
"Mild",
|
129 |
+
"Moderate",
|
130 |
+
"Moderately severe",
|
131 |
+
"Severe"
|
132 |
+
],
|
133 |
+
"action": [
|
134 |
+
"Patient may not need depression treatment",
|
135 |
+
"Use clinical judgment about treatment, based on patient's duration of symptoms and functional impairment",
|
136 |
+
"Use clinical judgment about treatment, based on patient's duration of symptoms and functional impairment",
|
137 |
+
"Treat using antidepressants, psychotherapy or a combination of treatment",
|
138 |
+
"Treat using antidepressants with or without psychotherapy"
|
139 |
+
]
|
140 |
+
}
|
141 |
+
],
|
142 |
+
"source": "https://www2.gov.bc.ca/assets/gov/health/practitioner-pro/bc-guidelines/depression_patient_health_questionnaire.pdf",
|
143 |
+
"accessed": "2023-03-25"
|
144 |
+
}
|
static/questionnaires/questionnaire_zf-ocs.json
ADDED
@@ -0,0 +1,72 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
{
|
2 |
+
"name": "ZF-OCS",
|
3 |
+
"description": null,
|
4 |
+
"questions": [
|
5 |
+
{
|
6 |
+
"number": 1,
|
7 |
+
"section": 1,
|
8 |
+
"text": "Do you wash or clean a lot?",
|
9 |
+
"scale": {
|
10 |
+
"No": 0,
|
11 |
+
"Yes": 1
|
12 |
+
}
|
13 |
+
},
|
14 |
+
{
|
15 |
+
"number": 2,
|
16 |
+
"section": 1,
|
17 |
+
"text": "Do you check things a lot?",
|
18 |
+
"scale": {
|
19 |
+
"No": 0,
|
20 |
+
"Yes": 1
|
21 |
+
}
|
22 |
+
},
|
23 |
+
{
|
24 |
+
"number": 3,
|
25 |
+
"section": 1,
|
26 |
+
"text": "Is there any thought that keeps bothering you that you would like to get rid of, but can't?",
|
27 |
+
"scale": {
|
28 |
+
"No": 0,
|
29 |
+
"Yes": 1
|
30 |
+
}
|
31 |
+
},
|
32 |
+
{
|
33 |
+
"number": 4,
|
34 |
+
"section": 1,
|
35 |
+
"text": "Do your daily activities take a long time to finish?",
|
36 |
+
"scale": {
|
37 |
+
"No": 0,
|
38 |
+
"Yes": 1
|
39 |
+
}
|
40 |
+
},
|
41 |
+
{
|
42 |
+
"number": 5,
|
43 |
+
"section": 1,
|
44 |
+
"text": "Are you concerned about orderliness or symmetry?",
|
45 |
+
"scale": {
|
46 |
+
"No": 0,
|
47 |
+
"Yes": 1
|
48 |
+
}
|
49 |
+
},
|
50 |
+
{
|
51 |
+
"number": 6,
|
52 |
+
"section": 1,
|
53 |
+
"text": "Have you depended on others to keep your life in order and attend to details?",
|
54 |
+
"scale": {
|
55 |
+
"No": 0,
|
56 |
+
"Yes": 1
|
57 |
+
}
|
58 |
+
},
|
59 |
+
{
|
60 |
+
"number": 7,
|
61 |
+
"section": 2,
|
62 |
+
"text": "Do these problems trouble you?",
|
63 |
+
"scale": {
|
64 |
+
"No": 0,
|
65 |
+
"Yes": 1
|
66 |
+
}
|
67 |
+
}
|
68 |
+
],
|
69 |
+
"scoring": null,
|
70 |
+
"source": "https://www.ementalhealth.ca/index.php?m=survey&ID=13",
|
71 |
+
"accessed": "2023-03-25"
|
72 |
+
}
|
therapist.py
ADDED
@@ -0,0 +1,106 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import openai
|
2 |
+
import os
|
3 |
+
import questionnaires
|
4 |
+
|
5 |
+
initial_message = "Hi! I'm Brainy, a virtual assistant who can help you through the mental health screening process. Can you start by telling me a bit about the problems you are experiencing?"
|
6 |
+
services = "https://www.canada.ca/en/public-health/topics/mental-health-wellness.html"
|
7 |
+
|
8 |
+
openai.api_key = os.getenv("OPENAI_API_KEY")
|
9 |
+
|
10 |
+
available_questionnaires = list(questionnaires.topics)
|
11 |
+
|
12 |
+
def listify(options: list, lower=True):
|
13 |
+
if len(options) > 1: options[-1] = "and " + options[-1]
|
14 |
+
if lower is True: options = list(map(str.lower, options))
|
15 |
+
return ", ".join(options) if len(options) > 2 else " ".join(options)
|
16 |
+
|
17 |
+
def content_summarizer():
|
18 |
+
pass
|
19 |
+
|
20 |
+
def assess_response(question: str, response:str, options: list, uses_scale=True, context="a psychological evaluation"):
|
21 |
+
context_prompt = "" if context=="" else f"The context of this discussion is {context}. "
|
22 |
+
if uses_scale is True:
|
23 |
+
prompt = context_prompt + f"""
|
24 |
+
Given the question '{question}' and this response to the question '{response}', rate the response on the following scale: {", ".join(map("'{}'".format, options))}.
|
25 |
+
Return only the corresponding scale item and nothing else.
|
26 |
+
"""
|
27 |
+
else:
|
28 |
+
prompt = context_prompt + f"""
|
29 |
+
Given the question '{question}' and this response to the question '{response}', which of the following is the response most similar to? {", ".join(map("'{}'".format, options))}.
|
30 |
+
Return only the most similar item and nothing else.
|
31 |
+
"""
|
32 |
+
response = openai.Completion.create(
|
33 |
+
model="text-davinci-003",
|
34 |
+
prompt=prompt,
|
35 |
+
temperature=0.1,
|
36 |
+
max_tokens=10
|
37 |
+
)
|
38 |
+
return response.choices[0].text.strip()
|
39 |
+
|
40 |
+
def yes_no(message):
|
41 |
+
return assess_response(question="Yes or No?", response=message, options=["Yes", "No"], context="", uses_scale=False)
|
42 |
+
|
43 |
+
def questionnaire_chooser(message):
|
44 |
+
topic = assess_response(
|
45 |
+
question = initial_message,
|
46 |
+
response = message,
|
47 |
+
options = available_questionnaires + ["Suicidal", "None of the previously mentioned options"],
|
48 |
+
uses_scale = False
|
49 |
+
)
|
50 |
+
|
51 |
+
match topic.lower():
|
52 |
+
case "suicidal":
|
53 |
+
state = ["initial"]
|
54 |
+
response = f"""
|
55 |
+
It sounds like you are in a crisis, or require immediate assistance. If this is the case, please call 911.
|
56 |
+
If would like to know more, resources can be found here: {services}.
|
57 |
+
"""
|
58 |
+
case "none of the previously mentioned options":
|
59 |
+
state = ["initial"]
|
60 |
+
response = f"""
|
61 |
+
At the moment I can only help with {listify(available_questionnaires)}.
|
62 |
+
If you are in a crisis, or require immediate assistance, please call 911.
|
63 |
+
If you are looking for help with another mental health topic, more resources can be found here: {services}.
|
64 |
+
"""
|
65 |
+
case _:
|
66 |
+
state = ["potential", topic.lower()]
|
67 |
+
response = f"It sounds like you're having trouble with {topic.lower()}. Is that correct?"
|
68 |
+
|
69 |
+
return state, response
|
70 |
+
|
71 |
+
def bot_response(next_question=None):
|
72 |
+
pass
|
73 |
+
|
74 |
+
def get_question(questionnaire, number):
|
75 |
+
print(questionnaire, number)
|
76 |
+
return questionnaires.questions[questionnaire][number]
|
77 |
+
|
78 |
+
def generate_response(user, message):
|
79 |
+
|
80 |
+
user_id, state = user["user_id"], user["state"]
|
81 |
+
|
82 |
+
match state[0]:
|
83 |
+
case "initial":
|
84 |
+
state, response = questionnaire_chooser(message)
|
85 |
+
|
86 |
+
case "potential":
|
87 |
+
if yes_no(message) == "Yes":
|
88 |
+
state = ["screening", state[1], 1]
|
89 |
+
response = get_question(state[1], 0)
|
90 |
+
else:
|
91 |
+
state, response = ["initial"], "I think I misunderstood you. Let's try again... can you please tell me about the problems you are experiencing?"
|
92 |
+
|
93 |
+
case "screening":
|
94 |
+
state, question = state, get_question(state[1], state[2])
|
95 |
+
|
96 |
+
if question == questionnaires.END:
|
97 |
+
state = ["finished"]
|
98 |
+
response = f"I have finished my evaluation, and that is all I can do for you today. Please refresh my page if you would like to start again. If you would like to give your clinician access to my assessment, please give them reference number #{user_id}."
|
99 |
+
else:
|
100 |
+
state[2] += 1
|
101 |
+
response = question
|
102 |
+
|
103 |
+
case "finished":
|
104 |
+
state, response = state, None
|
105 |
+
|
106 |
+
return state, response
|