Spaces:
Running
Running
Refactor message handling and AI prompts for clarity.
Browse filesStreamlined AI prompt generation by replacing list-based message history with a structured string representation. Simplified assistant-user message saving and updated related utility methods for better readability. Enhanced context in invalid and recommendation responses.
- trauma/api/message/ai/engine.py +25 -10
- trauma/api/message/ai/openai_request.py +16 -20
- trauma/api/message/ai/prompts.py +72 -19
- trauma/api/message/db_requests.py +2 -4
- trauma/api/message/utils.py +45 -6
- trauma/api/message/views.py +2 -3
trauma/api/message/ai/engine.py
CHANGED
@@ -18,8 +18,12 @@ from trauma.api.message.ai.openai_request import (update_entity_data_with_ai,
|
|
18 |
from trauma.api.message.db_requests import (save_assistant_user_message,
|
19 |
filter_entities_by_age_location,
|
20 |
update_entity_data_obj, get_entity_by_index)
|
|
|
|
|
21 |
from trauma.api.message.schemas import CreateMessageResponse
|
22 |
-
from trauma.api.message.utils import (
|
|
|
|
|
23 |
prepare_user_messages_str,
|
24 |
prepare_final_entities_str,
|
25 |
pick_empty_field_instructions, find_matching_age_group)
|
@@ -27,33 +31,44 @@ from trauma.core.config import settings
|
|
27 |
|
28 |
|
29 |
async def search_entities(
|
30 |
-
user_message: str, messages: list[
|
31 |
) -> CreateMessageResponse:
|
|
|
|
|
|
|
32 |
entity_data, is_valid = await asyncio.gather(
|
33 |
-
update_entity_data_with_ai(chat.entityData,
|
34 |
-
check_is_valid_request(
|
35 |
)
|
36 |
final_entities = None
|
|
|
37 |
if not is_valid:
|
38 |
-
|
|
|
|
|
|
|
39 |
else:
|
40 |
asyncio.create_task(update_entity_data_obj(entity_data, chat.id))
|
41 |
empty_field = retrieve_empty_field_from_entity_data(entity_data)
|
|
|
42 |
if empty_field:
|
43 |
empty_field_instructions = pick_empty_field_instructions(empty_field)
|
44 |
-
response = await generate_next_question(empty_field, empty_field_instructions,
|
|
|
45 |
else:
|
46 |
-
user_messages_str = prepare_user_messages_str(
|
47 |
possible_entity_indexes, search_request = await asyncio.gather(
|
48 |
filter_entities_by_age_location(entity_data),
|
49 |
generate_search_request(user_messages_str, entity_data)
|
50 |
)
|
51 |
final_entities = await search_semantic_entities(search_request, entity_data, possible_entity_indexes)
|
52 |
final_entities_str = prepare_final_entities_str(final_entities)
|
53 |
-
response = await generate_final_response(final_entities_str,
|
54 |
|
55 |
-
|
56 |
-
|
|
|
|
|
57 |
|
58 |
|
59 |
async def search_semantic_entities(
|
|
|
18 |
from trauma.api.message.db_requests import (save_assistant_user_message,
|
19 |
filter_entities_by_age_location,
|
20 |
update_entity_data_obj, get_entity_by_index)
|
21 |
+
from trauma.api.message.dto import Author
|
22 |
+
from trauma.api.message.model import MessageModel
|
23 |
from trauma.api.message.schemas import CreateMessageResponse
|
24 |
+
from trauma.api.message.utils import (decode_treatment_letters,
|
25 |
+
prepare_message_history_str,
|
26 |
+
retrieve_empty_field_from_entity_data,
|
27 |
prepare_user_messages_str,
|
28 |
prepare_final_entities_str,
|
29 |
pick_empty_field_instructions, find_matching_age_group)
|
|
|
31 |
|
32 |
|
33 |
async def search_entities(
|
34 |
+
user_message: str, messages: list[MessageModel], chat: ChatModel
|
35 |
) -> CreateMessageResponse:
|
36 |
+
decoded_message = decode_treatment_letters(user_message)
|
37 |
+
message_history_str = prepare_message_history_str(messages, decoded_message)
|
38 |
+
|
39 |
entity_data, is_valid = await asyncio.gather(
|
40 |
+
update_entity_data_with_ai(chat.entityData, decoded_message, messages[-1].text),
|
41 |
+
check_is_valid_request(decoded_message, message_history_str)
|
42 |
)
|
43 |
final_entities = None
|
44 |
+
|
45 |
if not is_valid:
|
46 |
+
empty_field = retrieve_empty_field_from_entity_data(chat.entityData.model_dump(mode='json'))
|
47 |
+
response = await generate_invalid_response(decoded_message, message_history_str, empty_field)
|
48 |
+
final_entities = messages[-1].entities if messages else None
|
49 |
+
|
50 |
else:
|
51 |
asyncio.create_task(update_entity_data_obj(entity_data, chat.id))
|
52 |
empty_field = retrieve_empty_field_from_entity_data(entity_data)
|
53 |
+
|
54 |
if empty_field:
|
55 |
empty_field_instructions = pick_empty_field_instructions(empty_field)
|
56 |
+
response = await generate_next_question(empty_field, empty_field_instructions, message_history_str)
|
57 |
+
|
58 |
else:
|
59 |
+
user_messages_str = prepare_user_messages_str(decoded_message, messages)
|
60 |
possible_entity_indexes, search_request = await asyncio.gather(
|
61 |
filter_entities_by_age_location(entity_data),
|
62 |
generate_search_request(user_messages_str, entity_data)
|
63 |
)
|
64 |
final_entities = await search_semantic_entities(search_request, entity_data, possible_entity_indexes)
|
65 |
final_entities_str = prepare_final_entities_str(final_entities)
|
66 |
+
response = await generate_final_response(final_entities_str, decoded_message, message_history_str)
|
67 |
|
68 |
+
user_message = MessageModel(chatId=chat.id, author=Author.User, text=decoded_message)
|
69 |
+
assistant_message = MessageModel(chatId=chat.id, author=Author.Assistant, text=response, entities=final_entities)
|
70 |
+
asyncio.create_task(save_assistant_user_message(user_message, assistant_message))
|
71 |
+
return assistant_message
|
72 |
|
73 |
|
74 |
async def search_semantic_entities(
|
trauma/api/message/ai/openai_request.py
CHANGED
@@ -23,18 +23,14 @@ async def update_entity_data_with_ai(entity_data: EntityData, user_message: str,
|
|
23 |
|
24 |
|
25 |
@openai_wrapper(temperature=0.8)
|
26 |
-
async def generate_next_question(empty_field: str, instructions: str,
|
27 |
messages = [
|
28 |
{
|
29 |
"role": "system",
|
30 |
"content": TraumaPrompts.generate_next_question
|
31 |
.replace("{empty_field}", empty_field)
|
32 |
.replace("{instructions}", instructions)
|
33 |
-
|
34 |
-
*message_history,
|
35 |
-
{
|
36 |
-
"role": "user",
|
37 |
-
"content": user_message
|
38 |
}
|
39 |
]
|
40 |
return messages
|
@@ -54,7 +50,7 @@ async def generate_search_request(user_messages_str: str, entity_data: dict):
|
|
54 |
|
55 |
|
56 |
@openai_wrapper(temperature=0.8)
|
57 |
-
async def generate_final_response(final_entities: str, user_message: str,
|
58 |
if not json.loads(final_entities)['klinieken']:
|
59 |
prompt = TraumaPrompts.generate_empty_recommendations
|
60 |
else:
|
@@ -63,12 +59,8 @@ async def generate_final_response(final_entities: str, user_message: str, messag
|
|
63 |
{
|
64 |
"role": "system",
|
65 |
"content": prompt
|
66 |
-
|
67 |
-
|
68 |
-
*message_history,
|
69 |
-
{
|
70 |
-
"role": "user",
|
71 |
-
"content": user_message
|
72 |
}
|
73 |
]
|
74 |
return messages
|
@@ -123,16 +115,20 @@ async def check_is_valid_request(user_message: str, message_history: str):
|
|
123 |
|
124 |
|
125 |
@openai_wrapper(temperature=0.9)
|
126 |
-
async def generate_invalid_response(user_message: str,
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
127 |
messages = [
|
128 |
{
|
129 |
"role": "system",
|
130 |
-
"content":
|
131 |
-
|
132 |
-
|
133 |
-
{
|
134 |
-
"role": "user",
|
135 |
-
"content": user_message
|
136 |
}
|
137 |
]
|
138 |
return messages
|
|
|
23 |
|
24 |
|
25 |
@openai_wrapper(temperature=0.8)
|
26 |
+
async def generate_next_question(empty_field: str, instructions: str, message_history_str: str):
|
27 |
messages = [
|
28 |
{
|
29 |
"role": "system",
|
30 |
"content": TraumaPrompts.generate_next_question
|
31 |
.replace("{empty_field}", empty_field)
|
32 |
.replace("{instructions}", instructions)
|
33 |
+
.replace("{message_history}", message_history_str)
|
|
|
|
|
|
|
|
|
34 |
}
|
35 |
]
|
36 |
return messages
|
|
|
50 |
|
51 |
|
52 |
@openai_wrapper(temperature=0.8)
|
53 |
+
async def generate_final_response(final_entities: str, user_message: str, message_history_str: str):
|
54 |
if not json.loads(final_entities)['klinieken']:
|
55 |
prompt = TraumaPrompts.generate_empty_recommendations
|
56 |
else:
|
|
|
59 |
{
|
60 |
"role": "system",
|
61 |
"content": prompt
|
62 |
+
.replace("{message_history}", message_history_str)
|
63 |
+
.replace("{user_message}", user_message)
|
|
|
|
|
|
|
|
|
64 |
}
|
65 |
]
|
66 |
return messages
|
|
|
115 |
|
116 |
|
117 |
@openai_wrapper(temperature=0.9)
|
118 |
+
async def generate_invalid_response(user_message: str, message_history_str: str, empty_field: str | None):
|
119 |
+
from trauma.api.message.utils import pick_empty_field_instructions
|
120 |
+
|
121 |
+
if empty_field:
|
122 |
+
empty_field_instructions = pick_empty_field_instructions(empty_field)
|
123 |
+
prompt = TraumaPrompts.generate_invalid_response.replace("{empty_field}", empty_field_instructions)
|
124 |
+
else:
|
125 |
+
prompt = TraumaPrompts.generate_invalid_response_with_recs
|
126 |
messages = [
|
127 |
{
|
128 |
"role": "system",
|
129 |
+
"content": prompt
|
130 |
+
.replace("{message_history}", message_history_str)
|
131 |
+
.replace("{user_message}", user_message)
|
|
|
|
|
|
|
132 |
}
|
133 |
]
|
134 |
return messages
|
trauma/api/message/ai/prompts.py
CHANGED
@@ -28,9 +28,9 @@ Je verzamelt informatie over een patiënt, hun ziekte en de behandelmethode zoda
|
|
28 |
|
29 |
```json
|
30 |
{
|
31 |
-
|
32 |
-
|
33 |
-
|
34 |
"location": "string",
|
35 |
"postalCode": "string",
|
36 |
}
|
@@ -40,7 +40,7 @@ Je verzamelt informatie over een patiënt, hun ziekte en de behandelmethode zoda
|
|
40 |
- **treatmentArea**: Het type mentale of fysieke ziekte/stoornis.
|
41 |
- **treatmentMethod**: Een methode voor het behandelen van de ziekte of stoornis.
|
42 |
- **location**: Stad of adres waar de facility zich bevindt
|
43 |
-
- **postalCode**: Postcode van de facility
|
44 |
|
45 |
## Regels voor het bijwerken van Entity Data
|
46 |
|
@@ -49,11 +49,12 @@ Je verzamelt informatie over een patiënt, hun ziekte en de behandelmethode zoda
|
|
49 |
- Werk alleen de velden bij die expliciet door de gebruiker zijn genoemd."""
|
50 |
generate_next_question = """## Taak
|
51 |
|
52 |
-
Stel een
|
53 |
|
54 |
## Context
|
55 |
|
56 |
-
Je bent een
|
|
|
57 |
## Gegevens
|
58 |
|
59 |
**Gemist veld**:
|
@@ -61,12 +62,16 @@ Je bent een informatieanalist die gegevens verzamelt van een verpleegkundige ove
|
|
61 |
{empty_field}
|
62 |
```
|
63 |
|
64 |
-
- {
|
|
|
|
|
|
|
|
|
|
|
65 |
|
66 |
-
## Belangrijke
|
67 |
|
68 |
-
- De
|
69 |
-
- Gebruik een empathische toon, bijvoorbeeld: "Kun je me iets meer vertellen over [Gemist veld]? Dit helpt me om je beter te helpen."""
|
70 |
generate_search_request = """## Taak
|
71 |
|
72 |
Je moet een beknopte zoekopdracht genereren op basis van de berichten van de gebruiker [berichtgeschiedenis] en de verzamelde patiëntgegevens [patiëntgegevens].
|
@@ -113,7 +118,7 @@ Je moet een antwoord genereren aan de gebruiker waarin je aangeeft dat je geschi
|
|
113 |
- Geweldig nieuws! Ik heb klinieken gevonden die perfect passen bij de aangegeven behoeften. Deze klinieken zijn gespecialiseerd in [treatmentMethod] en werken met patiënten in de leeftijd van [ageMin] tot [ageMax]."""
|
114 |
decide_is_valid_request = """## Task
|
115 |
|
116 |
-
You must determine whether the user's request
|
117 |
|
118 |
## Data
|
119 |
|
@@ -139,21 +144,57 @@ You must determine whether the user's request is valid. Provide your answer in t
|
|
139 |
|
140 |
## Instructions for Filling JSON
|
141 |
|
142 |
-
|
143 |
-
- The user describes the patient,
|
144 |
-
- The user
|
145 |
-
- The user's request is a valid response to the assistant's question.
|
146 |
-
- The user's request describes desired facility.
|
147 |
|
148 |
[/INST]"""
|
149 |
generate_invalid_response = """## Taak
|
150 |
|
151 |
-
Je moet
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
152 |
|
153 |
## Belangrijke opmerkingen
|
154 |
|
155 |
-
- Je antwoord moet
|
156 |
-
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
157 |
generate_empty_recommendations = """## Taak
|
158 |
|
159 |
Je moet de gebruiker op een empathische en ondersteunende manier informeren dat er geen geschikte klinieken voor de patiënt zijn gevonden. Moedig de gebruiker aan om de informatie opnieuw in te voeren met aanvullende details om betere zoekresultaten te genereren. Geef hierbij een voorbeeld van een geschikte invoer, zoals: 'jongen van 16 jaar met LVB waarvoor ik EMDR zoek'.
|
@@ -162,6 +203,18 @@ Je moet de gebruiker op een empathische en ondersteunende manier informeren dat
|
|
162 |
|
163 |
De gebruiker zoekt naar een geschikte kliniek voor een patiënt en deelt hierbij details zoals ziekte, leeftijd en behandelmethoden. Ondanks deze informatie heeft het systeem geen geschikte kliniek kunnen vinden die voldoet aan de eisen. Het is jouw taak om dit op een vriendelijke manier te communiceren en suggesties te geven voor het herzien of aanvullen van de ingevoerde gegevens.
|
164 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
165 |
## Belangrijke opmerkingen
|
166 |
|
167 |
- Gebruik een vriendelijke en geruststellende toon, bijvoorbeeld: "Ik heb op basis van de ingevoerde gegevens geen kliniek kunnen vinden. Kunnen we samen kijken of we de informatie iets kunnen aanpassen om betere resultaten te krijgen?"
|
|
|
28 |
|
29 |
```json
|
30 |
{
|
31 |
+
"age": integer,
|
32 |
+
"treatmentArea": "string",
|
33 |
+
"treatmentMethod": "string",
|
34 |
"location": "string",
|
35 |
"postalCode": "string",
|
36 |
}
|
|
|
40 |
- **treatmentArea**: Het type mentale of fysieke ziekte/stoornis.
|
41 |
- **treatmentMethod**: Een methode voor het behandelen van de ziekte of stoornis.
|
42 |
- **location**: Stad of adres waar de facility zich bevindt
|
43 |
+
- **postalCode**: Postcode van de facility.
|
44 |
|
45 |
## Regels voor het bijwerken van Entity Data
|
46 |
|
|
|
49 |
- Werk alleen de velden bij die expliciet door de gebruiker zijn genoemd."""
|
50 |
generate_next_question = """## Taak
|
51 |
|
52 |
+
Stel de gebruiker vriendelijk een gerichte vraag over het gemiste veld (`Gemist veld`) om de noodzakelijke informatie te verkrijgen voor het aanbevelen van een medische instelling.
|
53 |
|
54 |
## Context
|
55 |
|
56 |
+
Je bent een informaticus die gegevens verzamelt over de patiënt en de gewenste kliniek. Deze gegevens worden door het systeem gebruikt om een geschikte kliniek aan te bevelen.
|
57 |
+
|
58 |
## Gegevens
|
59 |
|
60 |
**Gemist veld**:
|
|
|
62 |
{empty_field}
|
63 |
```
|
64 |
|
65 |
+
- {instructies}
|
66 |
+
|
67 |
+
**Gespreksgeschiedenis**:
|
68 |
+
```
|
69 |
+
{message_history}
|
70 |
+
```
|
71 |
|
72 |
+
## Belangrijke opmerking
|
73 |
|
74 |
+
- De geformuleerde vraag moet beknopt zijn en een empathische toon hebben."""
|
|
|
75 |
generate_search_request = """## Taak
|
76 |
|
77 |
Je moet een beknopte zoekopdracht genereren op basis van de berichten van de gebruiker [berichtgeschiedenis] en de verzamelde patiëntgegevens [patiëntgegevens].
|
|
|
118 |
- Geweldig nieuws! Ik heb klinieken gevonden die perfect passen bij de aangegeven behoeften. Deze klinieken zijn gespecialiseerd in [treatmentMethod] en werken met patiënten in de leeftijd van [ageMin] tot [ageMax]."""
|
119 |
decide_is_valid_request = """## Task
|
120 |
|
121 |
+
You must determine whether the user's request pertains to the topic of medical facility recommendations or not. Use `User Request` to determine and `Message History` as context for making the decision.
|
122 |
|
123 |
## Data
|
124 |
|
|
|
144 |
|
145 |
## Instructions for Filling JSON
|
146 |
|
147 |
+
`User Request` pertains to the topic of medical facility recommendations (`is_valid = true`), if:
|
148 |
+
- The user describes the patient, for example, age, illness, treatment method, etc.
|
149 |
+
- The user describes the medical facility, for example, its location, postal code, treatment methods, supported age groups, etc.
|
|
|
|
|
150 |
|
151 |
[/INST]"""
|
152 |
generate_invalid_response = """## Taak
|
153 |
|
154 |
+
Je moet de gebruiker vriendelijk laten weten dat hun verzoek (`Gebruikersquery`) niet betrekking heeft op het onderwerp van medische instellingen aanbevelingen, en empathisch doorverwijzen zodat ze de verplichte informatie (`Required field`) kunnen delen. Gebruik (`Gesprekshistorie`) om de toon en stijl van communicatie te behouden.
|
155 |
+
|
156 |
+
## Gegevens
|
157 |
+
|
158 |
+
**Gebruikersquery**:
|
159 |
+
```
|
160 |
+
{user_message}
|
161 |
+
```
|
162 |
+
|
163 |
+
**Gesprekshistorie**:
|
164 |
+
```
|
165 |
+
{message_history}
|
166 |
+
```
|
167 |
+
|
168 |
+
**Verplichte veld**:
|
169 |
+
```
|
170 |
+
{empty_field}
|
171 |
+
```
|
172 |
|
173 |
## Belangrijke opmerkingen
|
174 |
|
175 |
+
- Je antwoord moet beknopt, empathisch en vriendelijk zijn.
|
176 |
+
- Je antwoord moet in twee zinnen worden gepresenteerd."""
|
177 |
+
generate_invalid_response_with_recs = """## Taak
|
178 |
+
|
179 |
+
Je moet op een beleefde manier verschillende medische instellingen voorstellen op basis van de informatie die de gebruiker heeft verstrekt, en ook toevoegen dat als er aanvullende informatie is, de gebruiker altijd kan terugkomen om zijn behoeften verder te verduidelijken en nieuwe aanbevelingen te krijgen.
|
180 |
+
|
181 |
+
## Gegevens
|
182 |
+
|
183 |
+
**Gebruikersquery**:
|
184 |
+
```
|
185 |
+
{user_message}
|
186 |
+
```
|
187 |
+
|
188 |
+
**Gesprekshistorie**:
|
189 |
+
```
|
190 |
+
{message_history}
|
191 |
+
```
|
192 |
+
|
193 |
+
## Belangrijke notities
|
194 |
+
|
195 |
+
- Je antwoord moet beknopt, empathisch en vriendelijk zijn.
|
196 |
+
- Gebruik de `Gesprekshistorie` om de toon en stijl van de communicatie te behouden.
|
197 |
+
- Je antwoord moet in twee zinnen zijn."""
|
198 |
generate_empty_recommendations = """## Taak
|
199 |
|
200 |
Je moet de gebruiker op een empathische en ondersteunende manier informeren dat er geen geschikte klinieken voor de patiënt zijn gevonden. Moedig de gebruiker aan om de informatie opnieuw in te voeren met aanvullende details om betere zoekresultaten te genereren. Geef hierbij een voorbeeld van een geschikte invoer, zoals: 'jongen van 16 jaar met LVB waarvoor ik EMDR zoek'.
|
|
|
203 |
|
204 |
De gebruiker zoekt naar een geschikte kliniek voor een patiënt en deelt hierbij details zoals ziekte, leeftijd en behandelmethoden. Ondanks deze informatie heeft het systeem geen geschikte kliniek kunnen vinden die voldoet aan de eisen. Het is jouw taak om dit op een vriendelijke manier te communiceren en suggesties te geven voor het herzien of aanvullen van de ingevoerde gegevens.
|
205 |
|
206 |
+
## Data
|
207 |
+
|
208 |
+
**Gebruikersquery**:
|
209 |
+
```
|
210 |
+
{user_message}
|
211 |
+
```
|
212 |
+
|
213 |
+
**Gesprekshistorie**:
|
214 |
+
```
|
215 |
+
{message_history}
|
216 |
+
```
|
217 |
+
|
218 |
## Belangrijke opmerkingen
|
219 |
|
220 |
- Gebruik een vriendelijke en geruststellende toon, bijvoorbeeld: "Ik heb op basis van de ingevoerde gegevens geen kliniek kunnen vinden. Kunnen we samen kijken of we de informatie iets kunnen aanpassen om betere resultaten te krijgen?"
|
trauma/api/message/db_requests.py
CHANGED
@@ -54,10 +54,8 @@ async def update_entity_data_obj(entity_data: dict, chat_id: str) -> None:
|
|
54 |
|
55 |
@background_task()
|
56 |
async def save_assistant_user_message(
|
57 |
-
user_message:
|
58 |
) -> None:
|
59 |
-
user_message = MessageModel(chatId=chat_id, author=Author.User, entities=final_entities, text=user_message)
|
60 |
-
assistant_message = MessageModel(chatId=chat_id, author=Author.Assistant, text=assistant_message)
|
61 |
await settings.DB_CLIENT.messages.insert_one(user_message.to_mongo())
|
62 |
await settings.DB_CLIENT.messages.insert_one(assistant_message.to_mongo())
|
63 |
|
@@ -99,4 +97,4 @@ async def update_message_feedback_obj(message_id: str, feedback_data: Feedback)
|
|
99 |
message.feedback = feedback_data
|
100 |
await settings.DB_CLIENT.messages.update_one({"id": message_id},
|
101 |
{"$set": {"feedback": feedback_data.model_dump(mode='json')}})
|
102 |
-
return message
|
|
|
54 |
|
55 |
@background_task()
|
56 |
async def save_assistant_user_message(
|
57 |
+
user_message: MessageModel, assistant_message: MessageModel
|
58 |
) -> None:
|
|
|
|
|
59 |
await settings.DB_CLIENT.messages.insert_one(user_message.to_mongo())
|
60 |
await settings.DB_CLIENT.messages.insert_one(assistant_message.to_mongo())
|
61 |
|
|
|
97 |
message.feedback = feedback_data
|
98 |
await settings.DB_CLIENT.messages.update_one({"id": message_id},
|
99 |
{"$set": {"feedback": feedback_data.model_dump(mode='json')}})
|
100 |
+
return message
|
trauma/api/message/utils.py
CHANGED
@@ -1,7 +1,9 @@
|
|
1 |
import json
|
|
|
2 |
|
3 |
from trauma.api.data.dto import AgeGroup
|
4 |
from trauma.api.data.model import EntityModel
|
|
|
5 |
from trauma.api.message.model import MessageModel
|
6 |
|
7 |
|
@@ -19,16 +21,24 @@ def transform_messages_to_openai(messages: list[MessageModel]) -> list[dict]:
|
|
19 |
|
20 |
def retrieve_empty_field_from_entity_data(entity_data: dict) -> str | None:
|
21 |
for k, v in entity_data.items():
|
22 |
-
if k not in ('
|
23 |
return k
|
24 |
return None
|
25 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
26 |
|
27 |
-
|
|
|
28 |
user_message_str = ''
|
29 |
for message in messages:
|
30 |
-
if message
|
31 |
-
user_message_str += f"- {message
|
32 |
user_message_str += f'- {user_message}'
|
33 |
return user_message_str
|
34 |
|
@@ -45,10 +55,10 @@ def prepare_final_entities_str(entities: list[EntityModel]) -> str:
|
|
45 |
def pick_empty_field_instructions(empty_field: str) -> str:
|
46 |
if empty_field == "age":
|
47 |
return "Leeftijd van de patiënt."
|
48 |
-
elif empty_field == "treatmentArea":
|
49 |
-
return "Het type psychische of lichamelijke ziekte / stoornis."
|
50 |
elif empty_field == "treatmentMethod":
|
51 |
return "Een methode om de ziekte of stoornis te behandelen."
|
|
|
|
|
52 |
|
53 |
|
54 |
def find_matching_age_group(entity: EntityModel, entity_data: dict) -> AgeGroup:
|
@@ -61,3 +71,32 @@ def find_matching_age_group(entity: EntityModel, entity_data: dict) -> AgeGroup:
|
|
61 |
if best_match is None or age_group.ageMax > best_match.ageMax:
|
62 |
best_match = age_group
|
63 |
return best_match
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
import json
|
2 |
+
import re
|
3 |
|
4 |
from trauma.api.data.dto import AgeGroup
|
5 |
from trauma.api.data.model import EntityModel
|
6 |
+
from trauma.api.message.dto import Author
|
7 |
from trauma.api.message.model import MessageModel
|
8 |
|
9 |
|
|
|
21 |
|
22 |
def retrieve_empty_field_from_entity_data(entity_data: dict) -> str | None:
|
23 |
for k, v in entity_data.items():
|
24 |
+
if k not in ('treatmentArea', 'postalCode') and not v:
|
25 |
return k
|
26 |
return None
|
27 |
|
28 |
+
def prepare_message_history_str(messages: list[MessageModel], user_message: str) -> str:
|
29 |
+
results = ""
|
30 |
+
shorted_message_history = messages[-8:]
|
31 |
+
for message in shorted_message_history:
|
32 |
+
results += f"[{message.author.value}] {message.text}\n"
|
33 |
+
results += f"[User] {user_message}"
|
34 |
+
return results
|
35 |
|
36 |
+
|
37 |
+
def prepare_user_messages_str(user_message: str, messages: list[MessageModel]) -> str:
|
38 |
user_message_str = ''
|
39 |
for message in messages:
|
40 |
+
if message.author == Author.User:
|
41 |
+
user_message_str += f"- {message.text}\n"
|
42 |
user_message_str += f'- {user_message}'
|
43 |
return user_message_str
|
44 |
|
|
|
55 |
def pick_empty_field_instructions(empty_field: str) -> str:
|
56 |
if empty_field == "age":
|
57 |
return "Leeftijd van de patiënt."
|
|
|
|
|
58 |
elif empty_field == "treatmentMethod":
|
59 |
return "Een methode om de ziekte of stoornis te behandelen."
|
60 |
+
elif empty_field == "location":
|
61 |
+
return "Stad of adres waar de facility zich bevindt."
|
62 |
|
63 |
|
64 |
def find_matching_age_group(entity: EntityModel, entity_data: dict) -> AgeGroup:
|
|
|
71 |
if best_match is None or age_group.ageMax > best_match.ageMax:
|
72 |
best_match = age_group
|
73 |
return best_match
|
74 |
+
|
75 |
+
def decode_treatment_letters(user_message: str) -> str:
|
76 |
+
replacements = {
|
77 |
+
"lvb": "Licht Verstandelijke Beperking",
|
78 |
+
"emdr": "Eye Movement Desensitization and Reprocessing",
|
79 |
+
"ptss": "Posttraumatische Stress Stoornis",
|
80 |
+
"cgt": "Cognitieve Gedragstherapie",
|
81 |
+
"ass": "Autisme Spectrum Stoornis",
|
82 |
+
"adhd": "Attention Deficit Hyperactivity Disorder",
|
83 |
+
"add": "Attention Deficit Disorder",
|
84 |
+
"bps": "Borderline Persoonlijkheidsstoornis",
|
85 |
+
"gad": "Gegeneraliseerde Angststoornis",
|
86 |
+
"ocd": "Obsessieve-Compulsieve Stoornis",
|
87 |
+
"an": "Anorexia Nervosa",
|
88 |
+
"bed": "Eetbuistoornis",
|
89 |
+
"solk": "Somatisch Onvoldoende verklaarde Lichamelijke Klachten",
|
90 |
+
"dis": "Dissociatieve Identiteitsstoornis",
|
91 |
+
"nah": "Niet Aangeboren Hersenletsel",
|
92 |
+
"sas": "Stemmings-, angst- en somatoforme stoornissen",
|
93 |
+
"epa": "Ernstige Psychiatrische Aandoeningen",
|
94 |
+
"net": "Narratieve Exposure Therapie",
|
95 |
+
"bepp": "Beknopte Eclectische Psychotherapie voor PTSS",
|
96 |
+
"dbt": "Dialectische Gedragstherapie",
|
97 |
+
"act": "Acceptance and Commitment Therapy",
|
98 |
+
"iht": "Intensive Home Treatment"
|
99 |
+
}
|
100 |
+
for short, full in replacements.items():
|
101 |
+
user_message = re.sub(rf'\b{short}\b', full, user_message, flags=re.IGNORECASE)
|
102 |
+
return user_message
|
trauma/api/message/views.py
CHANGED
@@ -35,10 +35,9 @@ async def create_message(
|
|
35 |
chatId: str,
|
36 |
message_data: CreateMessageRequest,
|
37 |
account: AccountModel = Depends(PermissionDependency([AccountType.Admin, AccountType.User]))
|
38 |
-
) -> TraumaResponseWrapper[
|
39 |
messages, chat = await get_all_chat_messages_obj(chatId, account)
|
40 |
-
|
41 |
-
response = await search_entities(message_data.text, message_history, chat)
|
42 |
return TraumaResponseWrapper(data=response)
|
43 |
|
44 |
|
|
|
35 |
chatId: str,
|
36 |
message_data: CreateMessageRequest,
|
37 |
account: AccountModel = Depends(PermissionDependency([AccountType.Admin, AccountType.User]))
|
38 |
+
) -> TraumaResponseWrapper[MessageModel]:
|
39 |
messages, chat = await get_all_chat_messages_obj(chatId, account)
|
40 |
+
response = await search_entities(message_data.text, messages, chat)
|
|
|
41 |
return TraumaResponseWrapper(data=response)
|
42 |
|
43 |
|