# Simbiot Harness Ритмичный агент: живёт тактами, как человек. CQRS + Event Sourcing на спине, Strands Harness SDK как исполнительное ядро, модели через 9router. ## Лестница (v0.1) | Уровень | Интервал | Контекст | Модель | Задачи | |---|---|---|---|---| | sec | 1 с | 0 (без LLM) | — | рефлекс: телеметрия, алерты | | min | 1 мин | ~4K | auto→flash | S-триаж: входящие, быстрые фиксы | | hour | 1 ч | ~32K | auto | S/M-задачи | | day | 1 д | ~128K | auto | M/L-задачи, манифест дня | Принципы: тик идемпотентен (`UNIQUE(level, seq)`); занятый уровень поглощает тик (`TickAbsorbed` + детерминированная заглушка дайджеста, без LLM); запущенная задача не прерывается; наверх идут только дайджесты. ## События (ES-спина) `CycleTicked`, `TickAbsorbed`, `ReflexObserved`, `DigestWritten`, `TaskSubmitted`, `TaskClaimed`, `TaskCompleted`, `TaskFailed`, `TaskPromoted`, `BudgetSpent`, `CycleError`, `HarnessInit`, `PolicySet` — append-only, проекции пересобираются replay'ем, стейт = производное от событий. ## Структура - `harness/es.py` — event store + проекции (checkpoint + replay) - `harness/levels.py` — конфигурация уровней - `harness/scheduler.py` — демон лестницы - `harness/isolated_runner.py` + `_llm_worker.py` — LLM-тик в сабпроцессе (глобальный asyncio-рантайм Strands не переживает 2+ `create_harness`) - `harness/commands.py` — command side - `cli.py` — init/task/tasks/status/events/requeue ## CLI ```bash ./venv/bin/python cli.py init --identity "…" ./venv/bin/python cli.py task "…" -m 240 # -m minutes-to-live estimate: S/M/L ./venv/bin/python cli.py tasks ./venv/bin/python cli.py status ./venv/bin/python cli.py events -n 50 ./venv/bin/python cli.py requeue -r "причина" ./venv/bin/python cli.py promote -r "вне класса уровня" # S→M→L ./venv/bin/python cli.py tg-reply "текст" # ответ на входящее TG ``` ## Запуск ```bash systemctl enable --now simbiot-harness journalctl -u simbiot-harness -f ``` ## Telegram-инбокс Бот @juno42bot → long polling (`simbiot-harness-tg.service`) → `MessageReceived` в стор → минутный уровень видит входящие в контексте → отвечает `cli.py tg-reply` (Telegram-отправка + `ReplySent` закрывает входящее). Белый список чатов в `.env` (`SIMBIOT_TG_ALLOWED`), чужие → `MessageIgnored`. ## Модели 9router (router.cil.by), отдельный ключ `sk-simbiot` в `.env`, комбо `auto`: glm-5.3 → kimi-k3 → deepseek-v4-pro → v4.1-flash → flash. Бюджет виден в событиях `BudgetSpent` (по уровням) и в дашборде 9router по ключу. ## v0.2 (roadmap) - прерывание срочной реакцией / пауза (сейчас absorbed детерминирован) - уровни week/month/quarter/year - инбокс из Telegram/портала