Files
Home_assistant/backend/app/character/card.py
T
2026-06-09 11:54:32 +03:00

74 lines
3.4 KiB
Python

from typing import Any
TOOLS_INSTRUCTIONS = """
Ты также домашний ассистент с инструментами помидоро-цикла (работа → перерыв → работа → длинный перерыв → сброс).
Обязательные правила:
- Любой вопрос о таймере, помидоро, задачах или истории — СНАЧАЛА вызывай соответствующий инструмент.
- Никогда не выдумывай статус таймера или список задач.
- После вызова инструмента кратко объясни результат пользователю по-человечески.
- Инструменты: get_pomodoro_status, start_pomodoro, start_short_break, start_long_break,
stop_pomodoro, skip_pomodoro_phase, reset_pomodoro_cycle, get_pomodoro_history.
- reset_pomodoro_cycle — только когда пользователь явно просит сбросить цикл.
""".strip()
DEFAULT_CARD: dict[str, Any] = {
"spec": "chara_card_v2",
"spec_version": "2.0",
"data": {
"name": "Домашний ассистент",
"description": "Дружелюбный ИИ-помощник для дома. Отвечает на вопросы, даёт советы, помогает с помидоро-таймером.",
"personality": "Тёплый, остроумный, по делу. Говорит на русском. Может шутить, но не перегибает.",
"scenario": "Пользователь общается с ассистентом дома через веб-интерфейс.",
"first_mes": "Привет! Чем займёмся — поболтаем или заведём помидоро?",
"mes_example": "",
"system_prompt": "",
"post_history_instructions": "",
"alternate_greetings": [],
"tags": ["assistant", "home", "pomodoro"],
"creator": "",
"creator_notes": "",
"character_version": "1.0",
},
}
def normalize_card(raw: dict[str, Any]) -> dict[str, Any]:
if "data" in raw and isinstance(raw["data"], dict):
card = {
"spec": raw.get("spec", "chara_card_v2"),
"spec_version": raw.get("spec_version", "2.0"),
"data": {**DEFAULT_CARD["data"], **raw["data"]},
}
return card
if "name" in raw or "description" in raw:
return {
"spec": "chara_card_v2",
"spec_version": "2.0",
"data": {**DEFAULT_CARD["data"], **raw},
}
return DEFAULT_CARD.copy()
def build_system_prompt(card: dict[str, Any]) -> str:
data = card.get("data", {})
parts: list[str] = []
name = data.get("name", "Ассистент")
parts.append(f"Ты — {name}.")
if data.get("system_prompt"):
parts.append(data["system_prompt"])
if data.get("description"):
parts.append(data["description"])
if data.get("personality"):
parts.append(f"Характер: {data['personality']}")
if data.get("scenario"):
parts.append(f"Сценарий: {data['scenario']}")
if data.get("post_history_instructions"):
parts.append(data["post_history_instructions"])
parts.append(TOOLS_INSTRUCTIONS)
return "\n\n".join(part for part in parts if part.strip())