ivanm151 commited on
Commit
1833177
·
1 Parent(s): f831d3d

qwen new promt 1

Browse files
Files changed (2) hide show
  1. app.py +21 -18
  2. utils.py +214 -272
app.py CHANGED
@@ -18,40 +18,43 @@ async def health_check():
18
  "model_loaded": llm is not None
19
  }
20
 
 
 
21
  @app.post("/api/v1/generate_plantuml", response_model=DiagramResponse)
22
  async def generate_plantuml(req: DiagramRequest):
23
  global llm
24
  if llm is None:
25
- raise HTTPException(503, "Модель ещё не загружена или ошибка при загрузке")
26
 
27
  desc = preprocess_description(req.description)
28
  if not desc:
29
  raise HTTPException(400, "Description cannot be empty")
30
 
31
- prompt = get_prompt(desc) # твой промпт с примерами
32
-
33
- output = llm(
34
- prompt=prompt,
35
- max_tokens=1200,
36
- temperature=0.65,
37
- top_p=0.92,
38
- top_k=40,
39
- repeat_penalty=1.1,
40
- stop=["</s>", "@enduml", "\n\n"], # чтобы не генерил лишнего
41
- echo=False
42
  )
43
 
44
- generated_text = output["choices"][0]["text"].strip()
45
 
46
- # Пытаемся аккуратно извлечь PlantUML
47
  start_marker = "@startuml"
48
  end_marker = "@enduml"
49
  if start_marker in generated_text and end_marker in generated_text:
50
  start_idx = generated_text.find(start_marker)
51
- end_idx = generated_text.find(end_marker, start_idx) + len(end_marker)
52
  plantuml_code = generated_text[start_idx:end_idx]
53
  else:
54
- # fallback весь текст, если маркеры потерялись
55
- plantuml_code = generated_text
 
 
56
 
57
- return {"plantuml_code": plantuml_code.strip()}
 
18
  "model_loaded": llm is not None
19
  }
20
 
21
+ # ... (остальное без изменений)
22
+
23
  @app.post("/api/v1/generate_plantuml", response_model=DiagramResponse)
24
  async def generate_plantuml(req: DiagramRequest):
25
  global llm
26
  if llm is None:
27
+ raise HTTPException(503, "Модель ещё не загружена")
28
 
29
  desc = preprocess_description(req.description)
30
  if not desc:
31
  raise HTTPException(400, "Description cannot be empty")
32
 
33
+ messages = get_prompt(desc) # теперь list[dict]
34
+
35
+ output = llm.create_chat_completion(
36
+ messages,
37
+ max_tokens=1500, # чуть больше — примеры длинные
38
+ temperature=0.6, # ниже — меньше креатива, строже синтаксис
39
+ top_p=0.9,
40
+ top_k=35,
41
+ repeat_penalty=1.15, # меньше повторений
42
+ stop=["</s>", "<|im_end|>", "@enduml\n\n", "```"], # стоп на конце
 
43
  )
44
 
45
+ generated_text = output["choices"][0]["message"]["content"].strip()
46
 
47
+ # Извлечение только кода (на всякий случай)
48
  start_marker = "@startuml"
49
  end_marker = "@enduml"
50
  if start_marker in generated_text and end_marker in generated_text:
51
  start_idx = generated_text.find(start_marker)
52
+ end_idx = generated_text.rfind(end_marker) + len(end_marker)
53
  plantuml_code = generated_text[start_idx:end_idx]
54
  else:
55
+ plantuml_code = generated_text # fallback
56
+
57
+ # Финальная чистка: убираем лишние пустые строки внутри
58
+ plantuml_code = re.sub(r'\n\s*\n', '\n', plantuml_code).strip()
59
 
60
+ return {"plantuml_code": plantuml_code}
utils.py CHANGED
@@ -1,308 +1,250 @@
1
  from pydantic import BaseModel
 
 
2
 
3
  class DiagramRequest(BaseModel):
4
  description: str
5
 
 
6
  class DiagramResponse(BaseModel):
7
  plantuml_code: str
8
 
9
- # Простой препроцесс: чистим текст, добавляем маркеры если нужно
10
- def preprocess_description(desc: str) -> str:
11
- return desc.strip().replace("\n", " ").replace("\r", "")
12
-
13
- # Шаблон промпта (few-shot с твоими примерами + инструкция)
14
- def get_prompt(description: str) -> str:
15
- return f"""You are an expert in generating PlantUML code from diagram descriptions. Detect the diagram type (BPMN, UML, C4, flowchart) based on the text.
16
-
17
- - For BPMN-like processes with actors/pools and branches: Use @startuml with activity diagram, partitions for pools (e.g., partition Client { ... }), start, end, if/else for gateways.
18
- - For UML: Use class/object/sequence diagrams as appropriate.
19
- - For C4 models (systems/containers/relations): Include !include <C4/C4_Container> and use macros like System, Container, Rel.
20
- - For flowcharts/tables of steps: Use activity diagram with sequential actions.
21
-
22
- Output ONLY the PlantUML code inside @startuml ... @enduml. No explanations.
23
-
24
- Examples:
25
-
26
- Description: Клиент: (start Потребность оформить заказ)
27
-
28
- Клиент: Адрес и способ доставки
29
-
30
- Система Додо: Проверка адреса и доступности доставки
31
-
32
- Клиент: Выбор блюд и акций
33
-
34
- Система Додо: Расчёт стоимости и ETA
35
-
36
- Клиент: Выбор способа оплаты (онлайн)
37
-
38
- Система Додо: Инициация онлайн-оплаты
39
-
40
- Платёжный провайдер: Авторизация платежа
41
-
42
- Система Додо: Обработка результата авторизации
43
-
44
- Система Додо: Оплата успешна
45
-
46
- Система Додо: Создать заказ и присвоить ETA
47
-
48
- Система Додо: Уведомление клиенту: заказ принят
49
-
50
- Ресторан: Печать чек-листа / стикера
51
-
52
- Ресторан: Приготовление заказа
53
-
54
- Ресторан: Фото-верификация и упаковка
55
-
56
- Ресторан: Готовность заказа
57
-
58
- Система Додо: Автоназначение курьера
59
-
60
- Система Додо: Построение маршрута
61
-
62
- Ресторан: Передача заказа курьеру
63
-
64
- Курьер: Доставка к адресу клиента
65
-
66
- Курьер: Клиент доступен
67
-
68
- Курьер: Вручение заказа
69
-
70
- Система Додо: Закрыть заказ (доставлен)
71
-
72
- (finish Заказ получен)
73
-
74
- Клиент: (start Потребность оформить заказ)
75
-
76
- Клиент: Адрес и способ доставки
77
-
78
- Система Додо: Проверка адреса и доступности доставки
79
-
80
- Клиент: Выбор блюд и акций
81
-
82
- Система Додо: Расчёт стоимости и ETA
83
-
84
- Клиент: Выбор способа оплаты (онлайн)
85
-
86
- Система Додо: Инициация онлайн-оплаты
87
-
88
- Платёжный провайдер: Авторизация платежа
89
-
90
- Система Додо: Обработка результата авторизации
91
-
92
- Система Додо: Оплата успешна
93
-
94
- Система Додо: Создать заказ и присвоить ETA
95
-
96
- Система Додо: Уведомление клиенту: заказ принят
97
-
98
- Ресторан: Печать чек-листа / стикера
99
-
100
- Ресторан: Приготовление заказа
101
-
102
- Ресторан: Фото-верификация и упаковка
103
-
104
- Ресторан: Готовность заказа
105
-
106
- Система Додо: Автоназначение курьера
107
-
108
- Система Додо: Построение маршрута
109
-
110
- Ресторан: Передача заказа курьеру
111
-
112
- Курьер: Доставка к адресу клиента
113
-
114
- Курьер: Клиент недоступен
115
-
116
- Курьер: Ожидание по политике (15 минут)
117
-
118
- Курьер: Повторная попытка / процедура по политике
119
-
120
- Система Додо: Закрыть заказ (клиент недоступен, заказ отменён)
121
-
122
- (finish Клиент недоступен, заказ отменён)
123
-
124
- Клиент: (start Потребность оформить заказ)
125
-
126
- Клиент: Адрес и способ доставки
127
-
128
- Система Додо: Проверка адреса и доступности доставки
129
-
130
- Клиент: Выбор блюд и акций
131
-
132
- Система Додо: Расчёт стоимости и ETA
133
-
134
- Клиент: Выбор способа оплаты (онлайн)
135
-
136
- Система Додо: Инициация онлайн-оплаты
137
-
138
- Платёжный провайдер: Авторизация платежа
139
-
140
- Система Додо: Обработка результата авторизации
141
-
142
- Система Додо: Оплата неуспешна
143
-
144
- Система Додо: Ретраи / каскад по платежу
145
 
146
- Система Додо: Предложить альтернативный способ оплаты
147
-
148
- Клиент: Выбор альтернативного способа оплаты
149
-
150
- Система Додо: Инициация онлайнплаты
151
-
152
- Платёжный провайдер: Авторизация платежа
153
-
154
- Система Додо: Обработка результата авторизации
155
-
156
- Система Додо: Оплата успешна
157
-
158
- Система Додо: Создать заказ и присвоить ETA
159
-
160
- Система Додо: Уведомление клиенту: заказ принят
161
-
162
- Ресторан: Печать чек-листа / стикера
163
-
164
- Ресторан: Приготовление заказа
165
-
166
- Ресторан: Фото-верификация и упаковка
167
-
168
- Ресторан: Готовность заказа
169
-
170
- Система Додо: Автоназначение курьера
171
-
172
- Система Додо: Построение маршрута
173
-
174
- Ресторан: Передача заказа курьеру
175
-
176
- Курьер: Доставка к адресу клиента
177
-
178
- Курьер: Клиент доступен
179
-
180
- Курьер: Вручение заказа
181
-
182
- Система Додо: Закрыть заказ (доставлен)
183
-
184
- (finish Заказ получен)
185
-
186
- Клиент: (start Потребность оформить заказ)
187
-
188
- Клиент: Адрес и способ доставки
189
-
190
- Система Додо: Проверка адреса и доступности доставки
191
-
192
- Клиент: Выбор блюд и акций
193
-
194
- Система Додо: Расчёт стоимости и ETA
195
-
196
- Клиент: Выбор способа оплаты (онлайн)
197
-
198
- Система Додо: Инициация онлайн-оплаты
199
-
200
- Платёжный провайдер: Авторизация платежа
201
-
202
- Система Додо: Обработка результата авторизации
203
-
204
- Система Додо: Оплата неуспешна
205
-
206
- Система Додо: Ретраи / каскад по платежу
207
-
208
- Система Додо: Предложить альтернативный способ оплаты
209
-
210
- Клиент: Отказаться от альтернативного спосо
211
-
212
- ба оплаты
213
-
214
- Система Додо: Отменить заказ (не оплачен)
215
-
216
- (finish Заказ отменён, не оплачен)
217
- PlantUML:
218
- @startuml
219
- partition Client {{
220
- start
221
- :Потребность оформить заказ;
222
- :Адрес и способ доставки;
223
- :Выбор блюд и акций;
224
- :Выбор способа оплаты (онлайн);
225
- }}
226
- partition "Система Додо" {{
227
- :Проверка адреса и доступности доставки;
228
- :Расчёт стоимости и ETA;
229
- :Инициация онлайн-оплаты;
230
- if (Оплата успешна?) then (yes)
231
- :Создать заказ и присвоить ETA;
232
- :Уведомление клиенту: заказ принят;
233
- else (no)
234
- :Ретраи / каскад по платежу;
235
- :Предложить альтернативный способ оплаты;
236
- endif
237
- }}
238
- partition "Платёжный провайдер" {{
239
- :Авторизация платежа;
240
- }}
241
- ' ... continue with branches and ends
242
- stop
243
- @enduml
244
-
245
- Description: Шаг | Роль
246
 
247
  1. Создание запроса | Инициатор
248
-
249
  2. Внесение технологии в тех. стек в статусе "Consideration" | Координатор
250
-
251
  3. Оценка по техническим критериям | Инициатор
252
-
253
  4. Уточнение требований к технологии | Совет по технологиям, Координатор, Владелец продукта
254
-
255
  5. Оценка ограничений и рисков принятия новой мажорной версии | Координатор
256
-
257
  6. Презентация новой мажорной версии | Инициатор
258
-
259
  7. Принятие решения | Главный корпоративный архитектор, Совет по технологиям
260
-
261
  8. Внесение записи в тех. стек, оповещение | Координатор
262
-
263
  9. Перевод прошлой мажорной версии в статус Deprecated | Координатор
 
 
 
 
 
 
 
 
 
 
 
264
 
265
- 10.Оповещение | Координатор
 
266
 
267
- 11.Планирование обновления продукта, в рамках которого поставляется технология | Координатор
 
268
 
269
- 12.Планирование автоматизации ресурсов на стороне ДИТ | Координатор
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
270
 
271
- 13.Изменение атрибутов технологии в технологическом стеке | Координатор
272
- PlantUML:
273
- @startuml
274
- start
275
- :1. Создание запроса; <<Инициатор>>
276
- :2. Внесение технологии в тех. стек в статусе "Consideration"; <<Координатор>>
277
- ' ... sequential
278
  stop
279
- @enduml
 
280
 
281
- Description: Шаг
 
 
282
 
283
- 1. Выполнить сценарий выбора СФЛ при назначени роли
 
 
 
 
 
 
 
 
 
 
 
 
 
284
 
285
- 2. Выдать сообщение о невозможности совмещения ролей
 
286
 
287
- 3. Сохранить скан документа,удостоверяющего полномочия
 
 
288
 
289
- 4. Выбрать все нужные полномочия из списка
 
290
 
291
- 5. Запросить информацию о праве передоверие
 
292
 
293
- 6. Запросить срок действия документа, удостоверяющего полномочия
 
294
 
295
- 7. Запросить прочие атрибуты роли "Доверенное лицо"
 
296
 
297
- 8. Запросить все обязательные атрибуты роли # Третий
298
- PlantUML:
299
- @startuml
 
 
 
 
 
 
 
 
 
 
 
 
300
  start
301
- :1. Выполнить сценарий выбора СФЛ при назначени роли;
302
- :2. Выдать сообщение о невозможности совмещения ролей;
303
- ' ...
 
 
 
304
  stop
305
- @enduml
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
306
 
307
- Now, generate for this description: {description}
308
- """
 
1
  from pydantic import BaseModel
2
+ import re
3
+
4
 
5
  class DiagramRequest(BaseModel):
6
  description: str
7
 
8
+
9
  class DiagramResponse(BaseModel):
10
  plantuml_code: str
11
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
12
 
13
+ def preprocess_description(desc: str) -> str:
14
+ """
15
+ Улучшенный препроцессинг:
16
+ - Убираем лишние пустые строки в начале/конце
17
+ - Нормализуем множественные пробелы и табы
18
+ - Сохраняем \n внутри — это важно для таблиц "Шаг | Роль" и списков
19
+ - Убираем только trailing/leading whitespace
20
+ """
21
+ # Удаляем BOM, если есть
22
+ desc = desc.strip().lstrip('\ufeff')
23
+
24
+ # Заменяем множественные пробелы/табы на один, но сохраняем строки
25
+ desc = re.sub(r'[ \t]+', ' ', desc)
26
+
27
+ # Убираем пустые строки в начале и конце, но оставляем внутри
28
+ lines = [line.rstrip() for line in desc.splitlines() if line.strip()]
29
+ desc = '\n'.join(lines).strip()
30
+
31
+ return desc
32
+
33
+
34
+ def get_prompt(description: str) -> list[dict]:
35
+ """
36
+ Возвращает список сообщений в формате ChatML для Qwen2.5-Instruct.
37
+ Это сильно улучшает качество по сравнению с plain text.
38
+ """
39
+ system_prompt = """You are an expert PlantUML diagram generator. Your ONLY task is to convert the given process description into a valid, complete PlantUML activity diagram.
40
+
41
+ Rules you MUST follow strictly:
42
+ - Always output ONLY the PlantUML code: from @startuml to @enduml inclusive.
43
+ - NEVER add explanations, comments, markdown, extra text, apologies or anything else.
44
+ - Use the new activity diagram syntax (beta).
45
+ - Use swimlanes/partitions (|Actor|) for different roles or actors when mentioned (Шаг | Роль, Actor: action, etc.).
46
+ - Use start / stop / (*) / (*) for begin/end.
47
+ - Use :action; for steps.
48
+ - Use if (Condition?) then (yes) ... else (no) ... endif for decisions.
49
+ - Use -> [label]; for arrows with conditions if needed.
50
+ - Make diagrams clean, logical and complete — close all branches, ifs, etc.
51
+ - Detect type: simple sequence → linear; table Шаг/Роль → swimlanes; branches (Найдена?, Автоматически?) → if/else.
52
+
53
+ Examples follow. Follow their style and completeness exactly."""
54
+
55
+ messages = [
56
+ {"role": "system", "content": system_prompt},
57
+ ]
58
+
59
+ # Few-shot примеры (полные, без '...', валидные)
60
+ examples = [
61
+ # Пример 1: Таблица с ролями (тех. стек)
62
+ {
63
+ "user": """Шаг | Роль
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
64
 
65
  1. Создание запроса | Инициатор
 
66
  2. Внесение технологии в тех. стек в статусе "Consideration" | Координатор
 
67
  3. Оценка по техническим критериям | Инициатор
 
68
  4. Уточнение требований к технологии | Совет по технологиям, Координатор, Владелец продукта
 
69
  5. Оценка ограничений и рисков принятия новой мажорной версии | Координатор
 
70
  6. Презентация новой мажорной версии | Инициатор
 
71
  7. Принятие решения | Главный корпоративный архитектор, Совет по технологиям
 
72
  8. Внесение записи в тех. стек, оповещение | Координатор
 
73
  9. Перевод прошлой мажорной версии в статус Deprecated | Координатор
74
+ 10. Оповещение | Координатор
75
+ 11. Планирование обновления продукта | Координатор
76
+ 12. Планирование автоматизации ресурсов | Координатор
77
+ 13. Изменение атрибутов технологии в стеке | Координатор""",
78
+ "assistant": """@startuml
79
+ skinparam shadowing false
80
+ skinparam monochrome true
81
+
82
+ |Инициатор|
83
+ start
84
+ :Создание запроса;
85
 
86
+ |Координатор|
87
+ :Внесение технологии в тех. стек (Consideration);
88
 
89
+ нициатор|
90
+ :Оценка по техническим критериям;
91
 
92
+ овет по технологиям, Координатор, Владелец продукта|
93
+ :Уточнение требований к технологии;
94
+
95
+ |Координатор|
96
+ :Оценка ограничений и рисков;
97
+
98
+ |Инициатор|
99
+ :Презентация новой мажорной версии;
100
+
101
+ |Главный корпоративный архитектор, Совет по технологиям|
102
+ :Принятие решения;
103
+
104
+ |Координатор|
105
+ :Внесение записи в тех. стек;
106
+ :Оповещение;
107
+ :Перевод прошлой версии в Deprecated;
108
+ :Оповещение;
109
+ :Планирование обновления продукта;
110
+ :Планирование автоматизации ресурсов;
111
+
112
+ :Изменение атрибутов технологии;
113
 
 
 
 
 
 
 
 
114
  stop
115
+ @enduml"""
116
+ },
117
 
118
+ # Пример 2: Ещё одна таблица с ролями
119
+ {
120
+ "user": """Шаг | Роль
121
 
122
+ 1. Создание запроса | Инициатор
123
+ 2. Подтверждение потребности в изменении условий использования | Координатор
124
+ 3. Определение пользователей технологии | Совет по технологиям
125
+ 4. Оценка трудозатрат | Совет по технологиям
126
+ 5. Принятие решения | Главный корпоративный архитектор, Совет по технологиям
127
+ 6. Изменение статуса технологии | Координатор
128
+ 7. Оповещение клиентов | Команда разработки
129
+ 8. Выполнение работ | ДЭиС""",
130
+ "assistant": """@startuml
131
+ skinparam shadowing false
132
+
133
+ |Инициатор|
134
+ start
135
+ :Создание запроса;
136
 
137
+ оординатор|
138
+ :Подтверждение потребности в изменении;
139
 
140
+ |Совет по технологиям|
141
+ :Определение пользователей технологии;
142
+ :Оценка трудозатрат;
143
 
144
+ |Главный корпоративный архитектор, Совет по технологиям|
145
+ :Принятие решения;
146
 
147
+ оординатор|
148
+ :Изменение статуса технологии;
149
 
150
+ оманда разработки|
151
+ :Оповещение клиентов;
152
 
153
+ |ДЭиС|
154
+ :Выполнение работ;
155
 
156
+ stop
157
+ @enduml"""
158
+ },
159
+
160
+ # Пример 3: Простая последовательность без ролей
161
+ {
162
+ "user": """Шаг
163
+
164
+ 1. Создание запроса
165
+ 2. Рассмотрение запроса
166
+ 3. Анализ запроса
167
+ 4. Принятие решения о реализации изменения
168
+ 5. Реализация улучшений и исправление несоответствий
169
+ 6. Оценка результатов""",
170
+ "assistant": """@startuml
171
  start
172
+ :Создание запроса;
173
+ :Рассмотрение запроса;
174
+ :Анализ запроса;
175
+ :Принятие решения о реализации;
176
+ :Реализация улучшений и исправлений;
177
+ :Оценка результатов;
178
  stop
179
+ @enduml"""
180
+ },
181
+
182
+ # Пример 4: Чайник с событием и ветвлением
183
+ {
184
+ "user": """Шаг
185
+
186
+ 1. Начало
187
+ 2. Наполнить чайник
188
+ 3. Включить чайник
189
+ 4. Ждать закипания
190
+ 5. Событие: Чайник закипел
191
+ 6. Таймер: 30 секунд
192
+ 7. Автовыключение
193
+ 8. Ручное выключение
194
+ 9. Чай готов""",
195
+ "assistant": """@startuml
196
+ start
197
+ :Наполнить чайник;
198
+ :Включить чайник;
199
+ :Ждать закипания;
200
+ note right: Событие: Чайник закипел
201
+ :Таймер: 30 секунд;
202
+ if (Выключен автоматически?) then (да)
203
+ :Автовыключение;
204
+ else (нет)
205
+ :Ручное выключение;
206
+ endif
207
+ :Чай готов;
208
+ stop
209
+ @enduml"""
210
+ },
211
+
212
+ # Пример 5: Решение с ветвлением (работа/учёба)
213
+ {
214
+ "user": """Шаг
215
+
216
+ 1. Зачисление
217
+ 2. Обновить резюме
218
+ 3. Искать гибкую работу
219
+ 4. Решение: Найдена?
220
+ 5. Договориться о графике
221
+ 6. Совмещение работы и учебы
222
+ 7. Фокус на учебе
223
+ 8. Только учеба""",
224
+ "assistant": """@startuml
225
+ start
226
+ :Зачисление;
227
+ :Обновить резюме;
228
+ :Искать гибкую работу;
229
+ if (Работа найдена?) then (да)
230
+ :Договориться о графике;
231
+ :Совмещение работы и учебы;
232
+ else (нет)
233
+ :Фокус на учебе;
234
+ :Только учеба;
235
+ endif
236
+ stop
237
+ @enduml"""
238
+ },
239
+ ]
240
+
241
+ # Добавляем все few-shot
242
+ for ex in examples:
243
+ messages.append({"role": "user", "content": ex["user"]})
244
+ messages.append({"role": "assistant", "content": ex["assistant"]})
245
+
246
+ # Финальный запрос
247
+ messages.append(
248
+ {"role": "user", "content": f"Generate PlantUML activity diagram for this description:\n\n{description}"})
249
 
250
+ return messages