Commit graph

14 commits

Author SHA1 Message Date
Simbiot Harness
e435289e55 hour берёт L-задачи (t-261002170836): classes S,M,L + мандат; тесты синхронизированы 2026-10-02 16:06:02 +00:00
Simbiot Harness
46a4728c67 fix: /set-tg-bot через портал-канал + race таймаута тика
- portal_channel: команда cmd-settg-* (кнопка TG в UI портала) перехватывается
  в pull() ДО инбокса (токен-секрет не попадает в стор/LLM), апплаер:
  getMe-самотест -> атомарный .env (SIMBIOT_TG_TOKEN+ALLOWED, старый аллоулист
  сохраняется) -> рестарт только simbiot-harness-tg; идемпотентно; отчёт в
  чат портала (push, fallback outbox-файл); TgChannelConfigured в стор.
- isolated_runner: после TimeoutExpired kill процесс-группы воркера и ожидание
  фактической смерти — без этого сабпроцессы продолжали писать BudgetSpent/
  ToolCalled после SchedulerTimeout (burn 9router вхолостую, t-261002090242).
- levels: tick_timeout min 300->480 (занятый мин-уровень штатно поглощает такты;
  эскалация e-261002085000). Контекст-схема не тронута (256k/512k/1M).

Тесты: test_budget_stub_guard / test_inbox_batch / test_delivery_idempotency —
зелёные; e2e на живом канале: cmd-settg consumed=1, стор чист, .env цел.
2026-10-02 09:20:11 +00:00
Simbiot Harness
11a8ccc279 config(levels): контекст-схема min 256k / hour 512k / day 1M (согласована Алексом, e-261001082710); мандат hour: пачку задач брать строго по очереди от старейшей 2026-10-01 08:28:58 +00:00
Simbiot Harness
09a226763b mandate(min): не создавать задачи из служебных сообщений («list», «тест») — отвечать tg-reply; клоны-пустышки засорили доску (e-261001082241) 2026-10-01 08:27:07 +00:00
Simbiot Harness
05555bbf11 feat(levels): day ctx 1M как у hour — симметрия по решению Alex (час-тик t-260930202231-50484f, консолидация правки 20:43) 2026-09-30 21:01:46 +00:00
Simbiot Harness
7efe845f18 feat(levels): часовой контекст 1М по решению Alex (e-260930173121-ed93b5; t-…-4425c3-рядом) 2026-09-30 18:36:49 +00:00
Simbiot Harness
1bc33d5678 fix(delivery): идемпотентная автодоставка артефактов в TG — три атомарных барьера против дублей (t-260930083937)
Инцидент: Alex получал презентацию трижды (m-516173239/241). Две причины:
1) гонка push (тик) vs pull (delivery-демон): оба проходили проверку
   delivery_status != 'sent', пока TG-отправка (до 35с) была в полёте;
2) ad-hoc curl sendDocument из мин-тиков вообще без метки delivered.

Фикс — delivery_ledger (INSERT OR IGNORE: факт доставки раз и навсегда)
+ delivery_locks (атомарный claim ДО отправки, TTL 120с; одно SQLite-
выражение = нет гонок между потоками и процессами). deliver_result /
deliver_artifact: ledger → claim → отправка → запись; сбой → release,
демон досыплет. Requeue сбрасывает ledger (доработка доставляется заново).

Новое: cli.py tg-deliver-file (идемпотентная отправка файлов, --force),
tg-notify -k <ключ>, tg_inbox.send_document (multipart на чистом urllib),
deliver_pending pre-filter по ledger, мандаты уровней: прямые
curl/api.telegram отправки запрещены. DeliverySkipped логирует пропуски.

Тесты: tests/test_delivery_idempotency.py — 49 проверок (гонка потоков,
межпроцессный claim, сбои+ретраи, requeue, CLI). Регрессия: 6/6 тестов ОК.
2026-09-30 13:41:34 +00:00
Simbiot Harness
06be288657 feat(inbox): батч-триаж входящих TG — сводный ответ закрывает все сообщения за один тик (t-260930064924)
Минутный тик отвечал по одному сообщению за тик (m-516173222..228 —
7 тиков подряд на один разговор): контекст показывал все, но мандат
говорил «ответь на него», и главное — нечем было закрыть несколько
входящих одним ответом (tg-reply закрывает одно, «хвосты» снова будили
гейт важности).

- tg_inbox.send_batch_reply: одна TG-отправка → ReplySent на КАЖДОЕ
  входящее батча (полный текст у головного, у хвостовых — ссылка);
  гонки (replied/ignored выпадают, пустой батч → ValueError), разные
  чаты делят батч — каждому своя отправка
- cli tg-reply <id1>,<id2>,… -c: батч-режим; несколько id без -c — отказ
  (защита от случайного закрытия); одиночный режим обратно совместим
- build_context: секция инбокса = «БАТЧ из N» с готовой командой
  (все id через запятую) и инструкцией закрыть ВСЁ за этот тик; кап
  10 → 50 (показываем весь батч, а не хвост)
- мандат min: батч-семантика (сводный ответ по смыслу разговора)
- тесты tests/test_inbox_batch.py: 32 проверки (hermetic), все зелёные
2026-09-30 10:12:47 +00:00
Simbiot Harness
34df7f3d72 feat(rag)+fix(timeout): RAG-инструмент в тиках + хард-кап шагов воркера
RAG (t-260929212316): каждому LLM-тику доступен rag_lookup — семантический
поиск по базе кооператива (/root/rag, fastembed+sqlite). Лимиты зашиты в
инструмент: 1 запрос/тик, k<=5, таймаут 20с, сабпроцесс rag-venv, мёртвый
вендор не валит тик. Трейс RagQueried в сторе. CLI: rag-query.

Хард-кап шагов (e-260930031800): мин-воркер тонул в 90+ tool-вызовах и
умирал по таймауту 300с. До: 3 CycleError за 2 часа, эскалации min→hour.
Фикс: cancel_tool на вызовы сверх лимита + end_turn (AfterToolsEvent)
останавливает цикл после партии + limits.turns (нативный механизм SDK).
e2e: 20 параллельных вызовов при лимите 3 → ровно 3 исполнения, цикл
остановлен, тик завершён текстом за ~12с (было: таймаут 300с).

Мандат мин-уровня: про rag_lookup и приоритет RAG для вопросов про кооператив.

Тесты: tests/test_rag_lookup.py (29 PASS), tests/test_tool_budget.py (12 PASS).
2026-09-30 04:16:46 +00:00
Simbiot Harness
7f4db9f085 feat(delivery): автодоставка готовых артефактов в TG + orphan-requeue сирот рестартов (t-260929205927-8c20ea)
- события TaskAwaitDelivery / DeliverySent: флаг 'результат доставить в чат'
  на задаче, доставка идемпотентна (один раз sent — повторов нет)
- commands.mark_awaiting_delivery / deliver_result (единственный путь отправки) /
  complete_task_with_delivery: завершение и отправка идут парой —
  «сделал и промолчал» больше не случается
- scheduler: push после TaskCompleted + delivery-демон (pull каждые 15с —
  досылает, если тик умер между завершением и отправкой); requeue сбрасывает
  доставку — доработка снова уйдёт в чат
- orphan_requeue: running-задачи с мёртвым воркером (рестарт демона убивает
  воркеров, TaskCompleted не пишется) возвращаются в очередь автоматически;
  корень эскалации e-260929234911: 'повторный таймаут часового воркера'
  был убийством живого воркера рестартом в 23:12/00:03, не таймаутом
  (трейс и BudgetSpent шли вплоть до секунды рестарта)
- cli: task -a (подать с доставкой) + task-await (пометить существующую);
  мин-уровень помечает задачи-просьбы из TG
- 18 тестов на копии БД: submit→await→complete→deliver→idempotency→
  requeue→re-deliver→pull→orphan→rebuild
2026-09-30 01:31:03 +00:00
Simbiot Harness
413ee7a14d fix(min): запрет research исходников харнеса в мандате мин-уровня (рут-кейс таймаутов 16:27-16:59) 2026-09-29 17:06:21 +00:00
simbiot-min
ed502650f4 feat: эскалации (min→hour→day) + фикс хвоста событий в CLI
Часть 1 (часовой уровень, задача t-260929155421-9f7bff):
- EscalationRaised/Acknowledged в ES-спину, проекция escalations
- CLI: escalate / escalations / escalation-ack
- уровни видят открытые эскалации в контексте; scheduler перезапускает
  критическую эскалацию сразу (не дожидаясь границы такта)

Часть 2 (минутный, этот тик):
- fix(cli): 'events -n N' показывал первые N событий вместо хвоста стора
  (README обещает хвост) — теперь хвост; --after N — от id N вперёд
- + es.count_events()
2026-09-29 16:13:23 +00:00
Simbiot Harness
94cc921ccd feat: Telegram-инбокс — сообщения Алекса как события
- harness/tg_inbox.py: long-polling поллер (@juno42bot) + send_reply
- события MessageReceived/ReplySent/MessageIgnored (агрегат inbox)
- проекция inbox в read model (кап 100)
- контекст минутного тика: входящие ждущие ответа + мандат триажа
- cli.py tg-reply: Telegram-отправка + ReplySent закрывает входящее
- systemd simbiot-harness-tg.service
- E2E: «йоу» от Алекса → минутный тик ответил в TG + дайджест в сторе
2026-09-29 15:52:46 +00:00
Simbiot Harness
b60439152b Simbiot Harness v0.1: тактовая лестница на Strands + CQRS/ES-спина
- harness/es.py: append-only event store + проекции (образец — кооп-портал)
- harness/levels.py: уровни 1с/1м/1ч/1д, контекст ∝ масштабу
- harness/scheduler.py: уровневые потоки, идемпотентные тики, absorbed-стабы
- harness/isolated_runner.py + _llm_worker.py: LLM-тик в сабпроцессе
  (глобальный asyncio-рантайм Strands не переживает 2+ create_harness)
- cli.py: init/task/tasks/status/events + requeue (написан самим минутным агентом)
- 9router: отдельный ключ sk-simbiot, модель auto (glm-5.3 первым)
2026-09-29 15:28:50 +00:00