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,142 @@
|
||||
"""Руки: какие MCP есть у сетапа и кому из агентов какая рука выдана.
|
||||
|
||||
Секреты MCP - только через env подпроцесса, никогда argv: процесс модели
|
||||
видит `ps` всего контейнера. Рука, чей env не задан, просто не появляется.
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import os
|
||||
from pathlib import Path
|
||||
|
||||
from beaver_gateway.agents.base import ExposedMcp
|
||||
from beaver_gateway.mcp.types import McpServer, McpServerT
|
||||
|
||||
from beaver_agent.hands.calendars import calendars
|
||||
from beaver_agent.hands.homeassistant import HomeAssistant
|
||||
from beaver_agent.hands.komodo import Komodo
|
||||
from beaver_agent.hands.vibegram import Vibegram
|
||||
from beaver_agent.vault import TZ
|
||||
|
||||
env = os.environ.get
|
||||
|
||||
obsidian = McpServer.stdio(
|
||||
name="obsidian-fs",
|
||||
command=["bunx", "-y", "@modelcontextprotocol/server-filesystem", "/vault"],
|
||||
lenient=True,
|
||||
)
|
||||
"""Файловые тулзы для тех, у кого нет своих (Raycast); у Claude vault смонтирован."""
|
||||
|
||||
firefly = (
|
||||
McpServer.stdio(
|
||||
name="firefly",
|
||||
command=["bunx", "-y", "@firefly-iii-mcp/local", "--preset", "default"],
|
||||
env={
|
||||
"FIREFLY_III_PAT": os.environ["FIREFLY_PAT"],
|
||||
"FIREFLY_III_BASE_URL": os.environ["FIREFLY_BASE_URL"],
|
||||
},
|
||||
lenient=True,
|
||||
)
|
||||
if env("FIREFLY_PAT")
|
||||
else None
|
||||
)
|
||||
firefly_exposed = (ExposedMcp(name="firefly", deny=("delete_*",)),) if firefly else ()
|
||||
|
||||
telegram = (
|
||||
McpServer.http(name="telegram", url=os.environ["BEAVERGRAM_MCP"])
|
||||
if env("BEAVERGRAM_MCP")
|
||||
else None
|
||||
)
|
||||
"""beavergram: история чатов Бобра в Telegram."""
|
||||
|
||||
calendar_servers = calendars(env("CALENDAR_MCPS", ""))
|
||||
calendar_exposed = tuple(ExposedMcp(name=m.name) for m in calendar_servers)
|
||||
|
||||
KOMODO = (
|
||||
Komodo(
|
||||
url=os.environ["KOMODO_URL"],
|
||||
key=os.environ["KOMODO_KEY"],
|
||||
secret=os.environ["KOMODO_SECRET"],
|
||||
)
|
||||
if env("KOMODO_URL")
|
||||
else None
|
||||
)
|
||||
"""Флот: перечислимые действия, ключ остаётся в gateway."""
|
||||
komodo = McpServer.python_tool(name="komodo", tools=[KOMODO.komodo]) if KOMODO else None
|
||||
komodo_exposed = (ExposedMcp(name="komodo"),) if KOMODO else ()
|
||||
|
||||
HA = (
|
||||
HomeAssistant(url=os.environ["HA_URL"], token=os.environ["HA_TOKEN"])
|
||||
if env("HA_URL") and env("HA_TOKEN")
|
||||
else None
|
||||
)
|
||||
"""Дом: HA живёт на хосте, из контейнера - host.docker.internal."""
|
||||
ha = McpServer.python_tool(name="ha", tools=[HA.ha]) if HA else None
|
||||
ha_exposed = (ExposedMcp(name="ha"),) if HA else ()
|
||||
|
||||
VIBEGRAM_REPO = Path("/vibegram") / env("VIBEGRAM_REPO", "x/room").split("/")[-1]
|
||||
VIBEGRAM = (
|
||||
Vibegram(
|
||||
hub=env("VIBEGRAM_HUB", "https://vibegram.example.com"),
|
||||
token=os.environ["VIBEGRAM_TOKEN"],
|
||||
nick=env("VIBEGRAM_NICK", "beaver-test"),
|
||||
repo=VIBEGRAM_REPO if VIBEGRAM_REPO.exists() else None,
|
||||
tz=TZ,
|
||||
)
|
||||
if env("VIBEGRAM_TOKEN")
|
||||
else None
|
||||
)
|
||||
"""Комната агентов: диспетчер сидит в ней сам; клон репы комнаты - том `vibegram`."""
|
||||
vibegram = (
|
||||
McpServer.python_tool(name="vibegram", tools=[VIBEGRAM.vibegram])
|
||||
if VIBEGRAM
|
||||
else None
|
||||
)
|
||||
vibegram_exposed = (ExposedMcp(name="vibegram"),) if VIBEGRAM else ()
|
||||
|
||||
t3code = (
|
||||
McpServer.http(name="t3code", url=env("T3CODE_MCP", "http://t3code-mcp:8000/mcp"))
|
||||
if "t3" in env("COMPOSE_PROFILES", "").split(",")
|
||||
else None
|
||||
)
|
||||
"""t3code-mcp - сосед по compose (профиль t3); машины и allowlist в его t3code.toml."""
|
||||
t3code_exposed = (ExposedMcp(name="t3code"),) if t3code else ()
|
||||
|
||||
msos = (
|
||||
McpServer.http(name="msos", url=os.environ["MSOS_MCP"]) if env("MSOS_MCP") else None
|
||||
)
|
||||
"""Таскер рабочих проектов (скилл `задачи`)."""
|
||||
msos_exposed = (ExposedMcp(name="msos"),) if msos else ()
|
||||
|
||||
mcps: list[McpServerT] = [
|
||||
m
|
||||
for m in (
|
||||
obsidian,
|
||||
firefly,
|
||||
telegram,
|
||||
*calendar_servers,
|
||||
komodo,
|
||||
ha,
|
||||
vibegram,
|
||||
t3code,
|
||||
msos,
|
||||
)
|
||||
if m is not None
|
||||
]
|
||||
|
||||
CLAUDE = (
|
||||
*firefly_exposed,
|
||||
ExposedMcp(name="telegram"),
|
||||
*calendar_exposed,
|
||||
*komodo_exposed,
|
||||
*ha_exposed,
|
||||
)
|
||||
"""Руки любого Claude-агента: firefly без delete, телега, календари, флот, дом."""
|
||||
DISPATCHER = (*CLAUDE, *t3code_exposed, *vibegram_exposed, *msos_exposed)
|
||||
"""Диспетчер ещё ходит в код, в комнату агентов и в таскер; глубоким это не даётся."""
|
||||
RAYCAST = (
|
||||
ExposedMcp(name="obsidian-fs"),
|
||||
*firefly_exposed,
|
||||
ExposedMcp(name="telegram"),
|
||||
*calendar_exposed,
|
||||
)
|
||||
Reference in New Issue
Block a user