add autonomy waiting-resume debounce config and status visibility

This commit is contained in:
DBT
2026-02-24 03:51:14 +00:00
parent 357a826319
commit ee91d6e479
6 changed files with 39 additions and 24 deletions

View File

@@ -384,6 +384,9 @@ func summarizeAutonomyChanges(oldCfg, newCfg *config.Config) []string {
if o.UserIdleResumeSec != n.UserIdleResumeSec {
changes = append(changes, "user_idle_resume_sec")
}
if o.WaitingResumeDebounceSec != n.WaitingResumeDebounceSec {
changes = append(changes, "waiting_resume_debounce_sec")
}
if strings.TrimSpace(o.QuietHours) != strings.TrimSpace(n.QuietHours) {
changes = append(changes, "quiet_hours")
}
@@ -750,6 +753,7 @@ func buildAutonomyEngine(cfg *config.Config, msgBus *bus.MessageBus) *autonomy.E
NotifyCooldownSec: a.NotifyCooldownSec,
QuietHours: a.QuietHours,
UserIdleResumeSec: a.UserIdleResumeSec,
WaitingResumeDebounceSec: a.WaitingResumeDebounceSec,
Workspace: cfg.WorkspacePath(),
DefaultNotifyChannel: a.NotifyChannel,
DefaultNotifyChatID: a.NotifyChatID,

View File

@@ -132,6 +132,7 @@ func statusCmd() {
fmt.Printf(" - %s\n", key)
}
}
fmt.Printf("Autonomy Config: idle_resume=%ds waiting_debounce=%ds\n", cfg.Agents.Defaults.Autonomy.UserIdleResumeSec, cfg.Agents.Defaults.Autonomy.WaitingResumeDebounceSec)
if summary, prio, reasons, nextRetry, dedupeHits, err := collectAutonomyTaskSummary(filepath.Join(workspace, "memory", "tasks.json")); err == nil {
fmt.Printf("Autonomy Tasks: todo=%d doing=%d waiting=%d blocked=%d done=%d dedupe_hits=%d\n", summary["todo"], summary["doing"], summary["waiting"], summary["blocked"], summary["done"], dedupeHits)
fmt.Printf("Autonomy Priority: high=%d normal=%d low=%d\n", prio["high"], prio["normal"], prio["low"])

View File

@@ -23,6 +23,7 @@
"notify_cooldown_sec": 300,
"quiet_hours": "23:00-08:00",
"user_idle_resume_sec": 20,
"waiting_resume_debounce_sec": 5,
"notify_channel": "",
"notify_chat_id": ""
},

View File

@@ -20,18 +20,19 @@ import (
)
type Options struct {
Enabled bool
TickIntervalSec int
MinRunIntervalSec int
MaxPendingDurationSec int
MaxConsecutiveStalls int
MaxDispatchPerTick int
Workspace string
DefaultNotifyChannel string
DefaultNotifyChatID string
NotifyCooldownSec int
QuietHours string
UserIdleResumeSec int
Enabled bool
TickIntervalSec int
MinRunIntervalSec int
MaxPendingDurationSec int
MaxConsecutiveStalls int
MaxDispatchPerTick int
Workspace string
DefaultNotifyChannel string
DefaultNotifyChatID string
NotifyCooldownSec int
QuietHours string
UserIdleResumeSec int
WaitingResumeDebounceSec int
}
type taskState struct {
@@ -82,6 +83,9 @@ func NewEngine(opts Options, msgBus *bus.MessageBus) *Engine {
if opts.UserIdleResumeSec <= 0 {
opts.UserIdleResumeSec = 20
}
if opts.WaitingResumeDebounceSec <= 0 {
opts.WaitingResumeDebounceSec = 5
}
return &Engine{
opts: opts,
bus: msgBus,
@@ -227,7 +231,7 @@ func (e *Engine) tick() {
}
if st.Status == "waiting" {
// Debounce waiting/resume flapping
if !st.WaitingSince.IsZero() && now.Sub(st.WaitingSince) < 5*time.Second {
if !st.WaitingSince.IsZero() && now.Sub(st.WaitingSince) < time.Duration(e.opts.WaitingResumeDebounceSec)*time.Second {
continue
}
reason := st.BlockReason

View File

@@ -45,17 +45,18 @@ type AgentDefaults struct {
}
type AutonomyConfig struct {
Enabled bool `json:"enabled" env:"CLAWGO_AGENTS_DEFAULTS_AUTONOMY_ENABLED"`
TickIntervalSec int `json:"tick_interval_sec" env:"CLAWGO_AGENTS_DEFAULTS_AUTONOMY_TICK_INTERVAL_SEC"`
MinRunIntervalSec int `json:"min_run_interval_sec" env:"CLAWGO_AGENTS_DEFAULTS_AUTONOMY_MIN_RUN_INTERVAL_SEC"`
MaxPendingDurationSec int `json:"max_pending_duration_sec" env:"CLAWGO_AGENTS_DEFAULTS_AUTONOMY_MAX_PENDING_DURATION_SEC"`
MaxConsecutiveStalls int `json:"max_consecutive_stalls" env:"CLAWGO_AGENTS_DEFAULTS_AUTONOMY_MAX_CONSECUTIVE_STALLS"`
MaxDispatchPerTick int `json:"max_dispatch_per_tick" env:"CLAWGO_AGENTS_DEFAULTS_AUTONOMY_MAX_DISPATCH_PER_TICK"`
NotifyCooldownSec int `json:"notify_cooldown_sec" env:"CLAWGO_AGENTS_DEFAULTS_AUTONOMY_NOTIFY_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"`
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"`
Enabled bool `json:"enabled" env:"CLAWGO_AGENTS_DEFAULTS_AUTONOMY_ENABLED"`
TickIntervalSec int `json:"tick_interval_sec" env:"CLAWGO_AGENTS_DEFAULTS_AUTONOMY_TICK_INTERVAL_SEC"`
MinRunIntervalSec int `json:"min_run_interval_sec" env:"CLAWGO_AGENTS_DEFAULTS_AUTONOMY_MIN_RUN_INTERVAL_SEC"`
MaxPendingDurationSec int `json:"max_pending_duration_sec" env:"CLAWGO_AGENTS_DEFAULTS_AUTONOMY_MAX_PENDING_DURATION_SEC"`
MaxConsecutiveStalls int `json:"max_consecutive_stalls" env:"CLAWGO_AGENTS_DEFAULTS_AUTONOMY_MAX_CONSECUTIVE_STALLS"`
MaxDispatchPerTick int `json:"max_dispatch_per_tick" env:"CLAWGO_AGENTS_DEFAULTS_AUTONOMY_MAX_DISPATCH_PER_TICK"`
NotifyCooldownSec int `json:"notify_cooldown_sec" env:"CLAWGO_AGENTS_DEFAULTS_AUTONOMY_NOTIFY_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"`
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"`
}
type AgentTextConfig struct {
@@ -309,6 +310,7 @@ func DefaultConfig() *Config {
NotifyCooldownSec: 300,
QuietHours: "23:00-08:00",
UserIdleResumeSec: 20,
WaitingResumeDebounceSec: 5,
NotifyChannel: "",
NotifyChatID: "",
},

View File

@@ -111,6 +111,9 @@ func Validate(cfg *Config) []error {
if aut.UserIdleResumeSec <= 0 {
errs = append(errs, fmt.Errorf("agents.defaults.autonomy.user_idle_resume_sec must be > 0 when enabled=true"))
}
if aut.WaitingResumeDebounceSec <= 0 {
errs = append(errs, fmt.Errorf("agents.defaults.autonomy.waiting_resume_debounce_sec must be > 0 when enabled=true"))
}
}
texts := cfg.Agents.Defaults.Texts
if strings.TrimSpace(texts.NoResponseFallback) == "" {