refactor: split config.py into the beaver_agent package (vault, prompts, skills, policy, hands, agents, frontends, texts, memory, jobs)
This commit is contained in:
@@ -0,0 +1,185 @@
|
||||
"""Всё, что gateway говорит модели и Бобру, по-русски."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
from beaver_gateway.conversations.texts import ConversationTexts, EnvelopeTexts
|
||||
from beaver_gateway.frontends.telegram import TelegramTexts
|
||||
|
||||
from beaver_agent.memory.handouts import (
|
||||
distill_prompt,
|
||||
handout_prompt,
|
||||
new_day,
|
||||
seed_body,
|
||||
)
|
||||
from beaver_agent.vault import GRANULES, read
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from beaver_gateway.conversations.injects import InjectContext
|
||||
|
||||
BEAVER_ORIGINS = frozenset({"panel", "api"})
|
||||
"""Панель и API - это сам Бобёр; крон, watch, komodo, ротация - нет."""
|
||||
|
||||
ORIGINS = {
|
||||
"merge": "слив",
|
||||
"digest": "выжимка",
|
||||
"rotation": "ротация",
|
||||
"cap": "потолок",
|
||||
"system": "система",
|
||||
"agent": "агент",
|
||||
}
|
||||
|
||||
INTERRUPTED_TURN = (
|
||||
"[этот инжект прервал предыдущий тёрн: «Request interrupted» выше - "
|
||||
"прерывание, не отказ от тулзы]"
|
||||
)
|
||||
|
||||
|
||||
def inject_header(ctx: InjectContext) -> str:
|
||||
if ctx.origin in BEAVER_ORIGINS:
|
||||
head = (
|
||||
"[инжект из панели: это Бобёр, ответ он видит в панели; "
|
||||
"в телегу - только через say]"
|
||||
)
|
||||
else:
|
||||
origin = ORIGINS.get(ctx.origin, ctx.origin)
|
||||
head = (
|
||||
f"[инжект: {origin} - это не Бобёр, отвечать не нужно, голос не обязателен]"
|
||||
)
|
||||
return f"{head}\n{INTERRUPTED_TURN}" if ctx.interrupted_turn else head
|
||||
|
||||
|
||||
ENVELOPE = EnvelopeTexts(
|
||||
header=(
|
||||
"[конверт - фоновый сигнал, не обращение; "
|
||||
"реагируй, только если относится к вопросу]"
|
||||
),
|
||||
time="время: {stamp} ({zone})",
|
||||
changed="vault, изменено {since}: {names}",
|
||||
since="с {time}",
|
||||
since_start="со старта",
|
||||
truncated="… (потолок конверта)",
|
||||
file_header="--- {path}, только добавленное ---",
|
||||
more_lines="+ … ещё {count}",
|
||||
)
|
||||
|
||||
MERGE_PROMPT = read(GRANULES / "слив.md") or (
|
||||
"Ветка закрывается. Напиши слив для мастера: что решили, что сделано, "
|
||||
"что не сделано и почему, открытые вопросы. Идентификаторы и ссылки - "
|
||||
"дословно. Коротко, прошедшее время."
|
||||
)
|
||||
|
||||
CONVERSATIONS = ConversationTexts(
|
||||
merge_prompt=MERGE_PROMPT,
|
||||
inject_header=inject_header,
|
||||
bundle_header="[инжекты, накопившиеся с {since}; это не Бобёр]",
|
||||
interrupted="прервано",
|
||||
answered="Пользователь ответил: {answer}",
|
||||
unanswered=(
|
||||
"Пользователь не ответил за {minutes} мин. Вопрос ему показан текстом; "
|
||||
"заверши тёрн сейчас, ответ придёт следующим сообщением."
|
||||
),
|
||||
seed=seed_body,
|
||||
seed_head="[сид: {seed}] {kind}{title}, {stamp}.",
|
||||
seed_copy="История родителя скопирована ({scope}); продолжай в ней.",
|
||||
seed_copy_window="последние {window} тёрнов",
|
||||
seed_copy_all="вся история",
|
||||
seed_morning_missing="Хендаут не приехал.",
|
||||
handout=handout_prompt,
|
||||
new_day=new_day,
|
||||
moved_injects=" Инжектов переехало из старого мастера: {moved}.",
|
||||
distill=distill_prompt,
|
||||
closed="Закрыт глубокий чат [[{chat}]]{digest}.\n{text}",
|
||||
closed_digest=", выжимка [[{digest}]]",
|
||||
digest_missing="файл выжимки не появился",
|
||||
too_long=(
|
||||
"`{name}`: {lines} строк при потолке {max_lines}. Запись отбита, файл "
|
||||
"возвращён к прежней версии. Сократи и перепиши."
|
||||
),
|
||||
cut_by_restart="тёрн {turn_id} оборван рестартом gateway",
|
||||
repaired_tools=(
|
||||
"; {fixed} незакрытых тул-коллов получили tool_result «{interrupted}»"
|
||||
),
|
||||
envelope=ENVELOPE,
|
||||
)
|
||||
|
||||
TELEGRAM = TelegramTexts(
|
||||
commands=(
|
||||
("merge", "слить ветку в мастер"),
|
||||
("new", "новая ветка: в General - новый топик, в топике - заново на нём"),
|
||||
("chat", "открыть глубокий чат в vault: /chat тема"),
|
||||
("status", "что с этим разговором"),
|
||||
("help", "команды"),
|
||||
),
|
||||
help_head="General - мастер, любой другой топик - ветка.",
|
||||
branch="ветка",
|
||||
waiting="⏳ думаю",
|
||||
thinking="🤔 думаю",
|
||||
writing="✍️ пишу",
|
||||
tool_labels={
|
||||
"Read": "читаю vault",
|
||||
"Glob": "ищу файлы",
|
||||
"Grep": "ищу в vault",
|
||||
"Edit": "правлю файл",
|
||||
"Write": "пишу файл",
|
||||
"MultiEdit": "правлю файлы",
|
||||
"Bash": "выполняю команду",
|
||||
"WebSearch": "ищу в сети",
|
||||
"WebFetch": "читаю страницу",
|
||||
"Task": "запустил сабагента",
|
||||
"Agent": "запустил сабагента",
|
||||
"AskUserQuestion": "спрашиваю",
|
||||
"TodoWrite": "планирую",
|
||||
"Skill": "открываю скилл",
|
||||
"mcp__gateway__spawn": "открываю разговор",
|
||||
"mcp__gateway__read_conversation": "читаю разговор",
|
||||
"mcp__gateway__say": "говорю",
|
||||
"mcp__gateway__schedule": "ставлю напоминание",
|
||||
"mcp__gateway__inject": "передаю в другой разговор",
|
||||
},
|
||||
attachment_sticker="[вложение: стикер - не поддерживается]",
|
||||
attachment_animation="[вложение: анимация - не поддерживается]",
|
||||
attachment_kinds={
|
||||
"photo": "фото",
|
||||
"document": "файл",
|
||||
"voice": "голосовое",
|
||||
"audio": "аудио",
|
||||
"video": "видео",
|
||||
"video_note": "кружок",
|
||||
},
|
||||
attachment_too_big=(
|
||||
"[вложение: {kind} {name}, {mb} МБ - больше 20 МБ, Telegram не отдаёт ботам]"
|
||||
),
|
||||
attachment_failed="[вложение: {kind} {name} - не скачалось: {error}]",
|
||||
attachment_size=", {kb} КБ",
|
||||
attachment="[вложение: {kind} {path}{size}]",
|
||||
attachment_kept=(
|
||||
"[вложение: {kind} {path}{size}; хранится {days} дн., "
|
||||
"перенеси в vault, если нужно]"
|
||||
),
|
||||
merge_nothing="сливать нечего: это не открытая ветка",
|
||||
merging="🔀 сливаю в мастер",
|
||||
merged="✅ слито в мастер",
|
||||
merge_failed="⚠️ слив не удался: {error}",
|
||||
new_branch_topic="🌿 ветка «{title}» - в новом топике",
|
||||
new_branch_here="🌿 новая ветка на этом топике",
|
||||
chat_usage="/chat <тема>",
|
||||
chat_failed="не вышло: {error}",
|
||||
chat_opened="💬 глубокий чат: {where}",
|
||||
status_unbound="этот топик ни к чему не привязан - напиши, и откроется ветка",
|
||||
status_line="сессия: {live} · тёрн: {turn} · в очереди: {queued}",
|
||||
status_live="живая",
|
||||
status_dead="нет",
|
||||
status_running="идёт",
|
||||
status_idle="нет",
|
||||
status_question="❓ ждёт ответа на вопрос",
|
||||
status_pool="пул: {sessions} сессий, rss {mb} МБ",
|
||||
status_outbox="outbox: {pending} в очереди",
|
||||
turn_failed="⚠️ тёрн упал, смотри логи gateway",
|
||||
background_failed="⚠️ фоновый тёрн ({origin}) упал, смотри логи gateway",
|
||||
question_closed="вопрос уже закрыт",
|
||||
question_timeout="⌛ время вышло - ответь текстом",
|
||||
done_button="✅ готово",
|
||||
mirrored="📝 из панели:\n{text}",
|
||||
)
|
||||
Reference in New Issue
Block a user