diff --git a/config.py b/config.py index 82df494..8724577 100644 --- a/config.py +++ b/config.py @@ -13,6 +13,7 @@ from beaver_gateway.core.conversations import ( SeedContext, ) from beaver_gateway.core.distill import DistillContext, Distiller, LineCap +from beaver_gateway.core.injects import INTERRUPTED_TURN, InjectContext from beaver_gateway.core.prompt import assemble from beaver_gateway.core.registry import Gateway from beaver_gateway.core.rotation import HandoutContext, RotationPolicy @@ -435,7 +436,27 @@ def distill_prompt(ctx: DistillContext) -> str: return DISTILL.format(chat=ctx.chat_name, reason=ctx.reason, day=day, path=path) +# Панель и API - это сам Бобёр (single-user); остальные origin - крон, watch, +# komodo, ротация - не он. +BEAVER_ORIGINS = frozenset({"panel", "api"}) + + +def inject_header(ctx: InjectContext) -> str: + if ctx.origin in BEAVER_ORIGINS: + head = ( + "[инжект из панели: это Бобёр, ответ он видит в панели; " + "в телегу - только через say]" + ) + else: + head = ( + f"[инжект: {ctx.origin} - это не Бобёр, отвечать не нужно, " + "голос не обязателен]" + ) + return f"{head}\n{INTERRUPTED_TURN}" if ctx.interrupted_turn else head + + texts = ConversationTexts( + inject_header=inject_header, merge_prompt=_read(GRANULES / "слив.md") or ConversationTexts().merge_prompt, seed=seed_body, handout=handout_prompt, diff --git a/mcps/komodo.py b/mcps/komodo.py index 5e76b10..d6dc6e4 100644 --- a/mcps/komodo.py +++ b/mcps/komodo.py @@ -46,7 +46,9 @@ class Komodo: secret: str exec_deny: tuple[str, ...] = ("*periphery*", "*komodo*") terminal: str = "beaver" - shell: str = "sh" + shell: str = "env PAGER=cat GIT_PAGER=cat TERM=dumb sh" + """Terminal is a tty: without ``PAGER=cat`` psql/git open a pager and + wait for a key forever, wedging the terminal.""" timeout: float = 120.0 wait: float = 180.0 max_chars: int = 12_000 @@ -77,7 +79,8 @@ class Komodo: - deploy / restart: стек целиком или один service; ждёт исхода до 3 мин. - exec: команда внутри контейнера (container, command; server, если имя контейнера есть на нескольких серверах). Это `docker exec` от - пользователя контейнера. Долгое - запускай в фон с выводом в файл. + пользователя контейнера, свежий шелл на каждый вызов, без tty-пейджера. + Лимит ~2 мин: долгое запускай в фон с выводом в файл и читай файл. Деплой и рестарт - только когда об этом попросили, не «заодно». """ @@ -211,12 +214,9 @@ class Komodo: }, "terminal": self.terminal, "command": command, - "init": {"command": self.shell, "recreate": "Never"}, + "init": {"command": self.shell, "recreate": "Always"}, } status, text = await self._post("terminal/execute", body) - if status != 200: - body["init"]["recreate"] = "Always" - status, text = await self._post("terminal/execute", body) if status != 200: return f"exec {container}: Komodo {status}: {text[:500]}" output, _, code = ANSI.sub("", text).rpartition(EXIT_MARK)