feat(events): внедрить Publisher в Core/Worker/Analyst + шины в app

- Core: setStatus публикует TaskStatusChanged на каждом переходе
  (handleStart/Cancel/Retry/Consent/Edit/Turn, runDecide).
- Worker: setStatus публикует TaskStatusChanged (running/timeout/failed/
  success, failTask), notify остаётся авто-уведомлением.
- Analyst: Decide публикует AgentActivity (stage=decide).
- app: создаёт доменную (256) и логовую (1024) шины, подключает их к
  Core/Worker/Analyst, редиректит log в обе (stderr + логовая шина).
This commit is contained in:
ki.sagidullin
2026-08-20 04:30:29 +05:00
parent 1f7ab9a67e
commit 4957a5552e
4 changed files with 102 additions and 36 deletions

View File

@@ -5,6 +5,7 @@ import (
"context"
"errors"
"fmt"
"io"
"log"
"os"
"os/signal"
@@ -19,6 +20,7 @@ import (
"github.com/kamelion/ratatoskr-go/internal/chat/telegram"
"github.com/kamelion/ratatoskr-go/internal/config"
"github.com/kamelion/ratatoskr-go/internal/core"
"github.com/kamelion/ratatoskr-go/internal/events"
"github.com/kamelion/ratatoskr-go/internal/opencode"
"github.com/kamelion/ratatoskr-go/internal/storage"
"github.com/kamelion/ratatoskr-go/internal/update"
@@ -61,6 +63,10 @@ type App struct {
Updater *update.Updater
tg *telegram.Channel // сохранена для Run
pool *opencode.Pool // пул opencode serve-серверов (API-режим)
// Events — доменная шина UI; LogEvents — шина логов (панель «Логи»).
Events *events.Bus
LogEvents *events.LogBus
}
// New читает конфиг и собирает все зависимости.
@@ -144,6 +150,19 @@ func New(configPath, version, updateToken string) (*App, error) {
CoreCtx: coreCtx,
pool: ocPool,
}
// Шины событий для UI: доменная (статусы/история/трейсы) и логовая
// (сырые строки в панель «Логи»). Издатели подключаются к Core/Worker/
// Analyst; на время headless (--noui) лог дублируется в обе шины, а UI
// просто подписывается на уже существующие.
a.Events = events.New(256)
a.LogEvents = events.NewLogBus(1024)
log.SetOutput(io.MultiWriter(os.Stderr, events.NewLogWriter(a.LogEvents)))
// Подключаем издателей событий к Core/Worker/Analyst.
coreCtx.Events = a.Events
analystCtx.Events = a.Events
router := chat.NewRouter(a.handleIncoming)
// Telegram-канал
@@ -166,6 +185,7 @@ func New(configPath, version, updateToken string) (*App, error) {
GitToken: cfg.Git.Token,
Live: live,
Notify: a, // авто-уведомления владельцу задачи через Router
Events: a.Events,
}
a.Router = router
a.Worker = w