Spaces:
Running
Running
Add functionality for handling empty responses in AI workflows
Browse filesEnhanced AI response generation to handle cases where no suitable clinics are found by providing relevant suggestions. Updated database handling and utility functions to support tracking and managing changes in entity data, ensuring better user feedback.
- trauma/api/data/db_requests.py +17 -0
- trauma/api/message/ai/engine.py +14 -7
- trauma/api/message/ai/openai_request.py +15 -0
- trauma/api/message/ai/prompts.py +13 -8
- trauma/api/message/utils.py +164 -0
- trauma/api/message/views.py +2 -3
trauma/api/data/db_requests.py
CHANGED
@@ -1,4 +1,5 @@
|
|
1 |
import asyncio
|
|
|
2 |
import re
|
3 |
|
4 |
from fastapi import HTTPException
|
@@ -35,3 +36,19 @@ async def search_facilities_obj(data: SearchRequest) -> tuple[list[EntityModel],
|
|
35 |
settings.DB_CLIENT.entities.count_documents(regex_filter)
|
36 |
)
|
37 |
return [EntityModel.from_mongo(ent) for ent in objects], total_count
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
import asyncio
|
2 |
+
import json
|
3 |
import re
|
4 |
|
5 |
from fastapi import HTTPException
|
|
|
36 |
settings.DB_CLIENT.entities.count_documents(regex_filter)
|
37 |
)
|
38 |
return [EntityModel.from_mongo(ent) for ent in objects], total_count
|
39 |
+
|
40 |
+
|
41 |
+
async def check_instructions():
|
42 |
+
pipeline = [
|
43 |
+
{"$unwind": "$contactDetails.postalCode"},
|
44 |
+
{"$group": {"_id": None, "uniqueTreatmentMethods": {"$addToSet": "$contactDetails.postalCode"}}}
|
45 |
+
]
|
46 |
+
result = await settings.DB_CLIENT.entities.aggregate(pipeline).to_list(length=1)
|
47 |
+
if result:
|
48 |
+
t = result[0]["uniqueTreatmentMethods"]
|
49 |
+
with open('test.json', 'w') as f:
|
50 |
+
f.write(json.dumps({"t": t}, indent=2))
|
51 |
+
return []
|
52 |
+
|
53 |
+
if __name__ == "__main__":
|
54 |
+
asyncio.run(check_instructions())
|
trauma/api/message/ai/engine.py
CHANGED
@@ -14,19 +14,21 @@ from trauma.api.message.ai.openai_request import (update_entity_data_with_ai,
|
|
14 |
choose_closest_treatment_area,
|
15 |
check_is_valid_request,
|
16 |
generate_invalid_response,
|
17 |
-
set_entity_score)
|
18 |
from trauma.api.message.db_requests import (save_assistant_user_message,
|
19 |
filter_entities_by_age_location,
|
20 |
update_entity_data_obj, get_entities_bulk)
|
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,
|
|
|
|
|
30 |
from trauma.core.config import settings
|
31 |
|
32 |
|
@@ -40,7 +42,7 @@ async def search_entities(
|
|
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'))
|
@@ -62,9 +64,14 @@ async def search_entities(
|
|
62 |
)
|
63 |
final_entities = await search_semantic_entities(search_request, entity_data, possible_entity_indexes)
|
64 |
final_entities_str = prepare_final_entities_str(final_entities)
|
65 |
-
|
66 |
-
|
67 |
-
|
|
|
|
|
|
|
|
|
|
|
68 |
|
69 |
user_message = MessageModel(chatId=chat.id, author=Author.User, text=decoded_message)
|
70 |
assistant_message = MessageModel(chatId=chat.id, author=Author.Assistant, text=response, entities=final_entities)
|
|
|
14 |
choose_closest_treatment_area,
|
15 |
check_is_valid_request,
|
16 |
generate_invalid_response,
|
17 |
+
set_entity_score, generate_empty_final_response)
|
18 |
from trauma.api.message.db_requests import (save_assistant_user_message,
|
19 |
filter_entities_by_age_location,
|
20 |
update_entity_data_obj, get_entities_bulk)
|
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,
|
30 |
+
find_matching_age_group,
|
31 |
+
search_changed_field_inst)
|
32 |
from trauma.core.config import settings
|
33 |
|
34 |
|
|
|
42 |
update_entity_data_with_ai(chat.entityData, decoded_message, messages[-1].text),
|
43 |
check_is_valid_request(decoded_message, message_history_str)
|
44 |
)
|
45 |
+
final_entities, fields_changed_inst = None, search_changed_field_inst(entity_data, chat.entityData)
|
46 |
|
47 |
if not is_valid:
|
48 |
empty_field = retrieve_empty_field_from_entity_data(chat.entityData.model_dump(mode='json'))
|
|
|
64 |
)
|
65 |
final_entities = await search_semantic_entities(search_request, entity_data, possible_entity_indexes)
|
66 |
final_entities_str = prepare_final_entities_str(final_entities)
|
67 |
+
if final_entities:
|
68 |
+
response = await generate_final_response(
|
69 |
+
final_entities_str, decoded_message, message_history_str, empty_field_instructions
|
70 |
+
)
|
71 |
+
else:
|
72 |
+
response = await generate_empty_final_response(
|
73 |
+
decoded_message, message_history_str, fields_changed_inst
|
74 |
+
)
|
75 |
|
76 |
user_message = MessageModel(chatId=chat.id, author=Author.User, text=decoded_message)
|
77 |
assistant_message = MessageModel(chatId=chat.id, author=Author.Assistant, text=response, entities=final_entities)
|
trauma/api/message/ai/openai_request.py
CHANGED
@@ -71,6 +71,21 @@ async def generate_final_response(
|
|
71 |
]
|
72 |
return messages
|
73 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
74 |
|
75 |
async def convert_value_to_embeddings(value: str, dimensions: int = 1536) -> list[float]:
|
76 |
embeddings = await settings.OPENAI_CLIENT.embeddings.create(
|
|
|
71 |
]
|
72 |
return messages
|
73 |
|
74 |
+
@openai_wrapper(temperature=0.8)
|
75 |
+
async def generate_empty_final_response(
|
76 |
+
user_message: str, message_history_str: str, empty_field_instructions: dict
|
77 |
+
):
|
78 |
+
messages = [
|
79 |
+
{
|
80 |
+
"role": "system",
|
81 |
+
"content": TraumaPrompts.generate_empty_recommendations
|
82 |
+
.replace("{message_history}", message_history_str)
|
83 |
+
.replace("{user_message}", user_message)
|
84 |
+
.replace("{instructions}", json.dumps(empty_field_instructions, indent=2))
|
85 |
+
}
|
86 |
+
]
|
87 |
+
return messages
|
88 |
+
|
89 |
|
90 |
async def convert_value_to_embeddings(value: str, dimensions: int = 1536) -> list[float]:
|
91 |
embeddings = await settings.OPENAI_CLIENT.embeddings.create(
|
trauma/api/message/ai/prompts.py
CHANGED
@@ -242,29 +242,34 @@ Stel op een beleefde manier enkele medische instellingen voor op basis van de in
|
|
242 |
|
243 |
generate_empty_recommendations = """## Taak
|
244 |
|
245 |
-
Je moet de gebruiker op een empathische en ondersteunende manier informeren dat er geen geschikte klinieken voor de patiënt zijn gevonden
|
246 |
|
247 |
## Context
|
248 |
|
249 |
-
De gebruiker zoekt
|
250 |
|
251 |
-
##
|
252 |
|
253 |
-
**
|
254 |
```
|
255 |
{user_message}
|
256 |
```
|
257 |
|
258 |
-
**
|
259 |
```
|
260 |
{message_history}
|
261 |
```
|
262 |
|
|
|
|
|
|
|
|
|
|
|
263 |
## Belangrijke opmerkingen
|
264 |
|
265 |
-
- Gebruik een vriendelijke en
|
266 |
-
-
|
267 |
-
- Stel open vragen om de gebruiker te
|
268 |
generate_searched_entity = """## Taak
|
269 |
|
270 |
Je moet de gevraagde faciliteit beschrijven, waarvan de informatie wordt gegeven in de sectie `## Data`. Analyseer de gebruikersvraag en de informatie over de faciliteit, en geef een beknopt en bondig antwoord.
|
|
|
242 |
|
243 |
generate_empty_recommendations = """## Taak
|
244 |
|
245 |
+
Je moet de gebruiker op een empathische en ondersteunende manier informeren dat er geen geschikte klinieken voor de patiënt zijn gevonden, en je moet de gebruiker voorstellen om te zoeken door de meest relevante mogelijke opties uit `Possible values` te geven.
|
246 |
|
247 |
## Context
|
248 |
|
249 |
+
De gebruiker zoekt een geschikte kliniek voor een patiënt en deelt details zoals de ziekte, leeftijd en behandelingsmethoden, evenals informatie over de kliniek. In het laatste bericht heeft de gebruiker echter informatie verstrekt waaruit geen klinieken zijn gevonden. Je moet op een empathische en beleefde toon de meest semantisch vergelijkbare opties uit `Possible values` voorstellen waarvoor klinieken beschikbaar zijn.
|
250 |
|
251 |
+
## Gegevens
|
252 |
|
253 |
+
**Gebruikersverzoek**:
|
254 |
```
|
255 |
{user_message}
|
256 |
```
|
257 |
|
258 |
+
**Gespreksgeschiedenis**:
|
259 |
```
|
260 |
{message_history}
|
261 |
```
|
262 |
|
263 |
+
**Mogelijke varianten**:
|
264 |
+
```
|
265 |
+
{instructions}
|
266 |
+
```
|
267 |
+
|
268 |
## Belangrijke opmerkingen
|
269 |
|
270 |
+
- Gebruik een vriendelijke en rustgevende toon.
|
271 |
+
- Stel de meest semantisch vergelijkbare voorbeelden voor uit `Possible variants` om een geschikte kliniek te vinden.
|
272 |
+
- Stel open vragen om de gebruiker te helpen de gegevens te verduidelijken, bijvoorbeeld: "Zijn er andere belangrijke punten die we kunnen toevoegen?\""""
|
273 |
generate_searched_entity = """## Taak
|
274 |
|
275 |
Je moet de gevraagde faciliteit beschrijven, waarvan de informatie wordt gegeven in de sectie `## Data`. Analyseer de gebruikersvraag en de informatie over de faciliteit, en geef een beknopt en bondig antwoord.
|
trauma/api/message/utils.py
CHANGED
@@ -1,6 +1,7 @@
|
|
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
|
@@ -104,3 +105,166 @@ def decode_treatment_letters(user_message: str) -> str:
|
|
104 |
for short, full in replacements.items():
|
105 |
user_message = re.sub(rf'\b{short}\b', full, user_message, flags=re.IGNORECASE)
|
106 |
return user_message
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
import json
|
2 |
import re
|
3 |
|
4 |
+
from trauma.api.chat.dto import EntityData
|
5 |
from trauma.api.data.dto import AgeGroup
|
6 |
from trauma.api.data.model import EntityModel
|
7 |
from trauma.api.message.dto import Author
|
|
|
105 |
for short, full in replacements.items():
|
106 |
user_message = re.sub(rf'\b{short}\b', full, user_message, flags=re.IGNORECASE)
|
107 |
return user_message
|
108 |
+
|
109 |
+
|
110 |
+
def search_changed_field_inst(entity_data: dict, old_entity_data: EntityData) -> dict[str, str]:
|
111 |
+
changed_fields = {}
|
112 |
+
instruction_map = {
|
113 |
+
"age": {'ageMinSupported': 0, "ageMaxSupported": 23},
|
114 |
+
"treatmentMethod": [
|
115 |
+
"Hypnose",
|
116 |
+
"Hypnotherapie",
|
117 |
+
"eclectisch",
|
118 |
+
"Schematherapie",
|
119 |
+
"BEPP (Beknopte Eclectische Psychotherapie bij PTSS",
|
120 |
+
"Muziektherapie, klankbehandeling",
|
121 |
+
"FITT, family based intensive trauma treatment",
|
122 |
+
"systeemtherapie & schematherapie",
|
123 |
+
"Narratieve Exposure Therapie (NET)",
|
124 |
+
"Ouder-kindtraumatherapie",
|
125 |
+
"Lichaamsgerichte therapie",
|
126 |
+
"integratieve therapie",
|
127 |
+
"Havening, hypnose",
|
128 |
+
"Psychotherapie",
|
129 |
+
"TIST",
|
130 |
+
"Words and pictures",
|
131 |
+
"Integratieve Kindertherapie",
|
132 |
+
"Buitenpsychologie",
|
133 |
+
"systeemtherapie gericht op scheidingsproblematiek",
|
134 |
+
"NET",
|
135 |
+
"Eigen methodiek, SSP, Focustherapie",
|
136 |
+
"Systeemtherapie",
|
137 |
+
"BEPP (beknopte eclectische psychotherapie voor PTSS), BEP-TG (beknopte eclectische psychotherapie voor traumatische rouw), NET (narratieve exposure therapie), schematherapie",
|
138 |
+
"Narratieve Exposure therapie",
|
139 |
+
"Writejunior",
|
140 |
+
"Tem Je Draak",
|
141 |
+
"EMDR voor ouders",
|
142 |
+
"Methodes vanuit de systeemtherapie",
|
143 |
+
"CGT (oa exposure)",
|
144 |
+
"Horizonmethodiek",
|
145 |
+
"TF-CBT",
|
146 |
+
"BEPP protocol",
|
147 |
+
"Speltherapie",
|
148 |
+
"ouder-kind therapie (vanuit de IMH visie)",
|
149 |
+
"IGT-K",
|
150 |
+
"medicamenteus",
|
151 |
+
"Verwerken en versterken",
|
152 |
+
"Pre-verbale EMDR",
|
153 |
+
"Kortdurende Intensieve traumabehandeling",
|
154 |
+
"aantal bovenstaande nog in ontwikkeling, deze niet aangevinkt nu",
|
155 |
+
"Drakentemmers",
|
156 |
+
"BEPP",
|
157 |
+
"schematherapie",
|
158 |
+
"Hypno-regressie therapie",
|
159 |
+
"ImRS",
|
160 |
+
"Beeldende therapie",
|
161 |
+
"sensorimotor psychotherapie",
|
162 |
+
"Cref-methode /paarde coaching",
|
163 |
+
"KINGS",
|
164 |
+
"KINGS in voorbereiding",
|
165 |
+
"systeemtherapie",
|
166 |
+
"EMDR",
|
167 |
+
"Ouder Kind Trauma Therapie",
|
168 |
+
"BEPP, NET",
|
169 |
+
"IEMT",
|
170 |
+
"Bokstherapie",
|
171 |
+
"babytherapie",
|
172 |
+
"sensorimotorpsychotherapie",
|
173 |
+
"Dramatherapie",
|
174 |
+
"BEPP / Sensorimotor Psychotherapie",
|
175 |
+
"Psychomotorische Therapie",
|
176 |
+
"Slapende honden",
|
177 |
+
"Nika, psycho-educatie",
|
178 |
+
"Basic Trust-methode, schematherapie, behandeling gericht op rouw en verlies",
|
179 |
+
"Intensieve Ambulante Gezinstherapie",
|
180 |
+
"EFFT / EFIT en ABFT",
|
181 |
+
"DDP, ABFT, EFFT, AFFT, Theraplay, schematherapie",
|
182 |
+
"Imaginaire Exposure",
|
183 |
+
"Bokspsychotherapie",
|
184 |
+
"ABFT",
|
185 |
+
"Lichaamsgerichte, innerlijk bronnen en systemische traumatherapie",
|
186 |
+
"NET (Narratieve Exposure Therapie)"
|
187 |
+
],
|
188 |
+
"treatmentArea": [
|
189 |
+
"Geen beschikking nodig",
|
190 |
+
"Normaal begaafd",
|
191 |
+
"langdurig pesten behandelen wij ook, waarbij wel wordt gekeken of het niet gaat om complex trauma, dan wordt veelal verwezen naar de S-GGZ, wij bieden GB-GGZ. Een verstandelijke beperking is niet perse een contra, maar schatten dit per casus in. Wanneer het gaat om een licht verstandelijke beperkt niveau tot zwakbegaafd is het vaak wel mogelijk.",
|
192 |
+
"automutilatie, geen acute suicidaliteit/crisis",
|
193 |
+
"Trauma in het systeem",
|
194 |
+
"Visuele beperking",
|
195 |
+
"Vluchtelingenproblematiek",
|
196 |
+
"Taalontwikkelingsstoornis",
|
197 |
+
"ASS",
|
198 |
+
"vaak is het comorbiditeit en niet de hoofddiagnose. Ik doe vaak traumatherapie/combi EMDR bij persoonlijkheidsproblematiek",
|
199 |
+
"als er sprake is van een VB dan ook bij ASS, ADHD etc",
|
200 |
+
"Geen onderscheid",
|
201 |
+
"intergenerationeel trauma",
|
202 |
+
"Genderproblematiek",
|
203 |
+
"Hoogbegaafd",
|
204 |
+
"misbruik, grote somberte, bij suicidaliteit en/of automutilatie altijd contact met arts of psychiater",
|
205 |
+
"deelbehandeling in samenwerking met andere behandelsetting",
|
206 |
+
"(Lichte) Verstandelijke Beperking",
|
207 |
+
"Auditieve beperking",
|
208 |
+
"Transcultureel",
|
209 |
+
"ouder-kind relatieproblematiek",
|
210 |
+
"Verslaving",
|
211 |
+
"generationeel trauma ivm systemische problematiek",
|
212 |
+
"Meervoudig trauma",
|
213 |
+
"loyaliteitsproblematiek/ouderverstoting/oudervervreemding",
|
214 |
+
"Als er sprake is van een indicatie, dan pakken wij dit als wijkteam in het voorveld niet op",
|
215 |
+
"Bijna alle psychische aandoening waar ambulante behandeling van toepassing is",
|
216 |
+
"Sucidaliteit en/of automutilatie",
|
217 |
+
"Comorbiditeit is geen contra voor traumabehandeling. Middelengebruik moet gestopt zijn voor de traumabehandeling kan starten.",
|
218 |
+
"Eetstoornis",
|
219 |
+
"overbrugging wachtlijst",
|
220 |
+
"Enkelvoudig trauma"
|
221 |
+
],
|
222 |
+
"location": [
|
223 |
+
"Aalsmeer",
|
224 |
+
"Alkmaar",
|
225 |
+
"Amstelveen",
|
226 |
+
"Amsterdam",
|
227 |
+
"Badhoevedorp",
|
228 |
+
"Beverwijk",
|
229 |
+
"Bergen NH",
|
230 |
+
"Broek op Langedijk",
|
231 |
+
"Bussum",
|
232 |
+
"Callantsoog",
|
233 |
+
"Castricum",
|
234 |
+
"Cruquiusweg 32",
|
235 |
+
"Den Helder",
|
236 |
+
"Diemen",
|
237 |
+
"Edam",
|
238 |
+
"Enkhuizen",
|
239 |
+
"Heemstede",
|
240 |
+
"Heerhugowaard",
|
241 |
+
"Heiloo",
|
242 |
+
"Hilversum",
|
243 |
+
"Hoofddorp",
|
244 |
+
"Hoorn",
|
245 |
+
"Huizen",
|
246 |
+
"Janmaat Psychotherapie Haarlem",
|
247 |
+
"Krommenie",
|
248 |
+
"Laren NH",
|
249 |
+
"Monnickendam",
|
250 |
+
"Naarden",
|
251 |
+
"Noord-Scharwoude",
|
252 |
+
"Purmerend",
|
253 |
+
"Schagen",
|
254 |
+
"Spierdijk",
|
255 |
+
"Velsen",
|
256 |
+
"Vondelstraat 100",
|
257 |
+
"Weesp",
|
258 |
+
"Wormerland",
|
259 |
+
"Zaanstad",
|
260 |
+
"Zaandam",
|
261 |
+
"Zuid-Kennemerland/ IJmond"
|
262 |
+
],
|
263 |
+
"postalCode": None,
|
264 |
+
}
|
265 |
+
old_entity_data = old_entity_data.model_dump(mode='json')
|
266 |
+
for key, value in entity_data.items():
|
267 |
+
if key in old_entity_data and old_entity_data[key] != value:
|
268 |
+
real_key = key if key!="treatmentArea" else "traumaType"
|
269 |
+
changed_fields[real_key] = instruction_map[key]
|
270 |
+
return changed_fields
|
trauma/api/message/views.py
CHANGED
@@ -10,9 +10,7 @@ from trauma.api.message.dto import Feedback
|
|
10 |
from trauma.api.message.model import MessageModel
|
11 |
from trauma.api.message.schemas import (AllMessageWrapper,
|
12 |
AllMessageResponse,
|
13 |
-
CreateMessageRequest
|
14 |
-
CreateMessageResponse)
|
15 |
-
from trauma.api.message.utils import transform_messages_to_openai
|
16 |
from trauma.core.security import PermissionDependency
|
17 |
from trauma.core.wrappers import TraumaResponseWrapper
|
18 |
|
@@ -49,3 +47,4 @@ async def create_feedback(
|
|
49 |
) -> TraumaResponseWrapper[MessageModel]:
|
50 |
message = await update_message_feedback_obj(messageId, feedback_data)
|
51 |
return TraumaResponseWrapper(data=message)
|
|
|
|
10 |
from trauma.api.message.model import MessageModel
|
11 |
from trauma.api.message.schemas import (AllMessageWrapper,
|
12 |
AllMessageResponse,
|
13 |
+
CreateMessageRequest)
|
|
|
|
|
14 |
from trauma.core.security import PermissionDependency
|
15 |
from trauma.core.wrappers import TraumaResponseWrapper
|
16 |
|
|
|
47 |
) -> TraumaResponseWrapper[MessageModel]:
|
48 |
message = await update_message_feedback_obj(messageId, feedback_data)
|
49 |
return TraumaResponseWrapper(data=message)
|
50 |
+
|