From 17d8b7f605789ea63f7b761515da640f6d14758d Mon Sep 17 00:00:00 2001 From: DBT Date: Sat, 28 Feb 2026 05:32:00 +0000 Subject: [PATCH] autonomy M1: add idle-safe task policy whitelist and fix active-user detection path --- cmd/clawgo/cmd_gateway.go | 1 + pkg/autonomy/engine.go | 28 ++++++++++++++++++++++++++-- pkg/config/config.go | 3 ++- 3 files changed, 29 insertions(+), 3 deletions(-) diff --git a/cmd/clawgo/cmd_gateway.go b/cmd/clawgo/cmd_gateway.go index 71b3d07..b011aa4 100644 --- a/cmd/clawgo/cmd_gateway.go +++ b/cmd/clawgo/cmd_gateway.go @@ -950,6 +950,7 @@ func buildAutonomyEngine(cfg *config.Config, msgBus *bus.MessageBus) *autonomy.E QuietHours: a.QuietHours, UserIdleResumeSec: a.UserIdleResumeSec, WaitingResumeDebounceSec: a.WaitingResumeDebounceSec, + AllowedTaskKeywords: a.AllowedTaskKeywords, ImportantKeywords: cfg.Agents.Defaults.Texts.AutonomyImportantKeywords, CompletionTemplate: cfg.Agents.Defaults.Texts.AutonomyCompletionTemplate, BlockedTemplate: cfg.Agents.Defaults.Texts.AutonomyBlockedTemplate, diff --git a/pkg/autonomy/engine.go b/pkg/autonomy/engine.go index 4a284ec..ebbb54b 100644 --- a/pkg/autonomy/engine.go +++ b/pkg/autonomy/engine.go @@ -34,6 +34,7 @@ type Options struct { QuietHours string UserIdleResumeSec int WaitingResumeDebounceSec int + AllowedTaskKeywords []string ImportantKeywords []string CompletionTemplate string BlockedTemplate string @@ -273,6 +274,9 @@ func (e *Engine) tick() { if !st.LastRunAt.IsZero() && now.Sub(st.LastRunAt) < time.Duration(e.opts.MinRunIntervalSec)*time.Second { continue } + if !e.allowTaskByPolicy(st.Content) { + continue + } if st.Status == "running" && now.Sub(st.LastRunAt) > time.Duration(e.opts.MaxPendingDurationSec)*time.Second { st.ConsecutiveStall++ if st.ConsecutiveStall > e.opts.MaxConsecutiveStalls { @@ -839,10 +843,14 @@ func (e *Engine) hasRecentUserActivity(now time.Time) bool { if e.opts.UserIdleResumeSec <= 0 || strings.TrimSpace(e.opts.Workspace) == "" { return false } - sessionsPath := filepath.Join(filepath.Dir(e.opts.Workspace), "sessions", "sessions.json") + sessionsPath := filepath.Join(filepath.Dir(e.opts.Workspace), "agents", "main", "sessions", "sessions.json") data, err := os.ReadFile(sessionsPath) if err != nil { - return false + legacy := filepath.Join(filepath.Dir(e.opts.Workspace), "sessions", "sessions.json") + data, err = os.ReadFile(legacy) + if err != nil { + return false + } } var index map[string]struct { Kind string `json:"kind"` @@ -866,6 +874,22 @@ func (e *Engine) hasRecentUserActivity(now time.Time) bool { return false } +func (e *Engine) allowTaskByPolicy(content string) bool { + if len(e.opts.AllowedTaskKeywords) == 0 { + return true + } + v := strings.ToLower(content) + for _, kw := range e.opts.AllowedTaskKeywords { + if kw == "" { + continue + } + if strings.Contains(v, strings.ToLower(kw)) { + return true + } + } + return false +} + func latestUserMessageTime(path string) time.Time { f, err := os.Open(path) if err != nil { diff --git a/pkg/config/config.go b/pkg/config/config.go index eb8f851..cabb9c8 100644 --- a/pkg/config/config.go +++ b/pkg/config/config.go @@ -55,7 +55,8 @@ type AutonomyConfig struct { NotifySameReasonCooldownSec int `json:"notify_same_reason_cooldown_sec" env:"CLAWGO_AGENTS_DEFAULTS_AUTONOMY_NOTIFY_SAME_REASON_COOLDOWN_SEC"` QuietHours string `json:"quiet_hours" env:"CLAWGO_AGENTS_DEFAULTS_AUTONOMY_QUIET_HOURS"` UserIdleResumeSec int `json:"user_idle_resume_sec" env:"CLAWGO_AGENTS_DEFAULTS_AUTONOMY_USER_IDLE_RESUME_SEC"` - WaitingResumeDebounceSec int `json:"waiting_resume_debounce_sec" env:"CLAWGO_AGENTS_DEFAULTS_AUTONOMY_WAITING_RESUME_DEBOUNCE_SEC"` + WaitingResumeDebounceSec int `json:"waiting_resume_debounce_sec" env:"CLAWGO_AGENTS_DEFAULTS_AUTONOMY_WAITING_RESUME_DEBOUNCE_SEC"` + AllowedTaskKeywords []string `json:"allowed_task_keywords" env:"CLAWGO_AGENTS_DEFAULTS_AUTONOMY_ALLOWED_TASK_KEYWORDS"` NotifyChannel string `json:"notify_channel" env:"CLAWGO_AGENTS_DEFAULTS_AUTONOMY_NOTIFY_CHANNEL"` NotifyChatID string `json:"notify_chat_id" env:"CLAWGO_AGENTS_DEFAULTS_AUTONOMY_NOTIFY_CHAT_ID"` }