From 76ec7d21f1e6e55f5d44dbcb26801b6c2603e6e9 Mon Sep 17 00:00:00 2001 From: Hermes Date: Sun, 16 Aug 2026 23:21:30 +0500 Subject: [PATCH] =?UTF-8?q?fix:=20=D0=B1=D0=BB=D0=BE=D0=BA=D0=B8=D1=80?= =?UTF-8?q?=D0=BE=D0=B2=D0=B0=D1=82=D1=8C=20=D0=B2=D0=B2=D0=BE=D0=B4=20?= =?UTF-8?q?=D0=B2=20running-=D0=B7=D0=B0=D0=B4=D0=B0=D1=87=D1=83=20(S3:=20?= =?UTF-8?q?=D0=BD=D0=B5=D0=BB=D1=8C=D0=B7=D1=8F=20running=E2=86=92collecti?= =?UTF-8?q?ng);=20=D1=80=D0=B0=D0=B7=D1=80=D0=B5=D1=88=D0=B5=D0=BD=D1=8B?= =?UTF-8?q?=20/cancel=20=D0=B8=20/status=20N?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- internal/app/app.go | 31 +++++++++++++++++++++++-------- 1 file changed, 23 insertions(+), 8 deletions(-) diff --git a/internal/app/app.go b/internal/app/app.go index 0b5c72c..27c3c04 100644 --- a/internal/app/app.go +++ b/internal/app/app.go @@ -83,14 +83,14 @@ func New(configPath, version, updateToken string) (*App, error) { // OpenCode runner — один на аналитика и воркер ocRunner := &opencode.Runner{ - Bin: cfg.OpenCode.Bin, - DBPath: cfg.OpenCode.DBPath, - Config: cfg.OpenCode.Config, - ConfigDir: cfg.OpenCode.ConfigDir, - IdleTimeout: cfg.OpenCode.IdleTimeout.Duration(), - HardTimeout: cfg.OpenCode.HardTimeout.Duration(), + Bin: cfg.OpenCode.Bin, + DBPath: cfg.OpenCode.DBPath, + Config: cfg.OpenCode.Config, + ConfigDir: cfg.OpenCode.ConfigDir, + IdleTimeout: cfg.OpenCode.IdleTimeout.Duration(), + HardTimeout: cfg.OpenCode.HardTimeout.Duration(), PollInterval: cfg.OpenCode.PollMs.Duration(), - Stdout: os.Stderr, + Stdout: os.Stderr, } // Analyst (Decider) @@ -266,6 +266,21 @@ func (a *App) handleIncoming(inc chat.Incoming) { return } + // Активная задача есть, но воркер её выполняет (running). Обычный ввод и команды + // редактирования НЕ должны переводить задачу обратно в collecting — это невалидный + // переход S3 (running → collecting). Разрешено лишь терминальное /cancel и /status N. + if task.Status == storage.StatusRunning { + switch { + case cmdName(text) == "/cancel": + // переходим на терминальный статус + case cmdName(text) == "/status" && hasArg(text): + // запрос статуса конкретной задачи — безопасно, не трогает машину состояний + default: + a.send(ctx, uid, "⏳ Задача ещё выполняется воркером. Дождитесь результата, или /cancel чтобы остановить.") + return + } + } + // Активная задача есть — обработка result, err := a.CoreCtx.ProcessTurn(ctx, task.ID, text) if err != nil { @@ -475,4 +490,4 @@ func ensureAgentsDir(cfg *config.Config) error { } log.Printf("app: agents ensured in %s", cfg.OpenCode.ConfigDir) return nil -} \ No newline at end of file +}