67 lines
1.9 KiB
Python
67 lines
1.9 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,
|
|
"notes": "",
|
|
"exercises": [
|
|
{"name": "жим лёжа", "sets": 3, "reps": 8, "weight_kg": 80}
|
|
]
|
|
}
|
|
Правила:
|
|
- weight_kg в кг, метрическая система.
|
|
- Если данных нет — null или пустой массив.
|
|
""".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)
|