97 lines
2.8 KiB
Python
97 lines
2.8 KiB
Python
import json
|
|
from typing import Any
|
|
|
|
from app.llm.client import LLMClient
|
|
from app.projects.structuring import strip_markdown_json
|
|
|
|
MEAL_PROMPT = """
|
|
Преобразуй описание еды в JSON. Только JSON, без markdown.
|
|
Схема:
|
|
{
|
|
"meal_type": "breakfast|lunch|dinner|snack",
|
|
"description": "краткое описание",
|
|
"calories": 0,
|
|
"protein_g": 0,
|
|
"fat_g": 0,
|
|
"carbs_g": 0,
|
|
"estimated": true
|
|
}
|
|
Правила:
|
|
- Оцени ккал и БЖУ по типичным значениям для России/СНГ.
|
|
- Все числа — float/int, метрическая система (г, ккал).
|
|
- meal_type угадай из контекста или snack.
|
|
- estimated всегда true для LLM-оценки.
|
|
""".strip()
|
|
|
|
WORKOUT_PROMPT = """
|
|
Преобразуй описание тренировки в JSON. Только JSON.
|
|
Формат:
|
|
{
|
|
"title": "название",
|
|
"duration_min": null,
|
|
"active_calories": null,
|
|
"total_calories": null,
|
|
"steps": null,
|
|
"notes": "",
|
|
"exercises": [
|
|
{"name": "имя упраж", "sets": 3, "reps": 8, "weight_kg": 80}
|
|
]
|
|
}
|
|
Правила:
|
|
- weight_kg в кг, округляй разумно.
|
|
- active_calories / total_calories / steps — если упомянуты в тексте, иначе null.
|
|
- Если данных нет — null или пустой массив.
|
|
""".strip()
|
|
|
|
STEPS_PROMPT = """
|
|
Преобразуй запись о шагах в JSON. Только JSON.
|
|
Формат:
|
|
{
|
|
"steps": 0,
|
|
"active_calories": null,
|
|
"notes": ""
|
|
}
|
|
Правила:
|
|
- steps — целое число шагов за день.
|
|
- active_calories — только если явно указаны.
|
|
""".strip()
|
|
|
|
|
|
async def structure_meal(raw_text: str) -> dict[str, Any]:
|
|
llm = LLMClient()
|
|
result = await llm.complete(
|
|
[
|
|
{"role": "system", "content": MEAL_PROMPT},
|
|
{"role": "user", "content": raw_text},
|
|
],
|
|
temperature=0.2,
|
|
)
|
|
raw = strip_markdown_json(result.get("content") or "")
|
|
return json.loads(raw)
|
|
|
|
|
|
async def structure_workout(raw_text: str) -> dict[str, Any]:
|
|
llm = LLMClient()
|
|
result = await llm.complete(
|
|
[
|
|
{"role": "system", "content": WORKOUT_PROMPT},
|
|
{"role": "user", "content": raw_text},
|
|
],
|
|
temperature=0.2,
|
|
)
|
|
raw = strip_markdown_json(result.get("content") or "")
|
|
return json.loads(raw)
|
|
|
|
|
|
async def structure_steps(raw_text: str) -> dict[str, Any]:
|
|
llm = LLMClient()
|
|
result = await llm.complete(
|
|
[
|
|
{"role": "system", "content": STEPS_PROMPT},
|
|
{"role": "user", "content": raw_text},
|
|
],
|
|
temperature=0.2,
|
|
)
|
|
raw = strip_markdown_json(result.get("content") or "")
|
|
return json.loads(raw)
|