mirror of
https://github.com/YspCoder/clawgo.git
synced 2026-05-17 09:27:28 +08:00
add autonomy waiting-resume debounce config and status visibility
This commit is contained in:
@@ -384,6 +384,9 @@ func summarizeAutonomyChanges(oldCfg, newCfg *config.Config) []string {
|
|||||||
if o.UserIdleResumeSec != n.UserIdleResumeSec {
|
if o.UserIdleResumeSec != n.UserIdleResumeSec {
|
||||||
changes = append(changes, "user_idle_resume_sec")
|
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) {
|
if strings.TrimSpace(o.QuietHours) != strings.TrimSpace(n.QuietHours) {
|
||||||
changes = append(changes, "quiet_hours")
|
changes = append(changes, "quiet_hours")
|
||||||
}
|
}
|
||||||
@@ -750,6 +753,7 @@ func buildAutonomyEngine(cfg *config.Config, msgBus *bus.MessageBus) *autonomy.E
|
|||||||
NotifyCooldownSec: a.NotifyCooldownSec,
|
NotifyCooldownSec: a.NotifyCooldownSec,
|
||||||
QuietHours: a.QuietHours,
|
QuietHours: a.QuietHours,
|
||||||
UserIdleResumeSec: a.UserIdleResumeSec,
|
UserIdleResumeSec: a.UserIdleResumeSec,
|
||||||
|
WaitingResumeDebounceSec: a.WaitingResumeDebounceSec,
|
||||||
Workspace: cfg.WorkspacePath(),
|
Workspace: cfg.WorkspacePath(),
|
||||||
DefaultNotifyChannel: a.NotifyChannel,
|
DefaultNotifyChannel: a.NotifyChannel,
|
||||||
DefaultNotifyChatID: a.NotifyChatID,
|
DefaultNotifyChatID: a.NotifyChatID,
|
||||||
|
|||||||
@@ -132,6 +132,7 @@ func statusCmd() {
|
|||||||
fmt.Printf(" - %s\n", key)
|
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 {
|
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 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"])
|
fmt.Printf("Autonomy Priority: high=%d normal=%d low=%d\n", prio["high"], prio["normal"], prio["low"])
|
||||||
|
|||||||
@@ -23,6 +23,7 @@
|
|||||||
"notify_cooldown_sec": 300,
|
"notify_cooldown_sec": 300,
|
||||||
"quiet_hours": "23:00-08:00",
|
"quiet_hours": "23:00-08:00",
|
||||||
"user_idle_resume_sec": 20,
|
"user_idle_resume_sec": 20,
|
||||||
|
"waiting_resume_debounce_sec": 5,
|
||||||
"notify_channel": "",
|
"notify_channel": "",
|
||||||
"notify_chat_id": ""
|
"notify_chat_id": ""
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -20,18 +20,19 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type Options struct {
|
type Options struct {
|
||||||
Enabled bool
|
Enabled bool
|
||||||
TickIntervalSec int
|
TickIntervalSec int
|
||||||
MinRunIntervalSec int
|
MinRunIntervalSec int
|
||||||
MaxPendingDurationSec int
|
MaxPendingDurationSec int
|
||||||
MaxConsecutiveStalls int
|
MaxConsecutiveStalls int
|
||||||
MaxDispatchPerTick int
|
MaxDispatchPerTick int
|
||||||
Workspace string
|
Workspace string
|
||||||
DefaultNotifyChannel string
|
DefaultNotifyChannel string
|
||||||
DefaultNotifyChatID string
|
DefaultNotifyChatID string
|
||||||
NotifyCooldownSec int
|
NotifyCooldownSec int
|
||||||
QuietHours string
|
QuietHours string
|
||||||
UserIdleResumeSec int
|
UserIdleResumeSec int
|
||||||
|
WaitingResumeDebounceSec int
|
||||||
}
|
}
|
||||||
|
|
||||||
type taskState struct {
|
type taskState struct {
|
||||||
@@ -82,6 +83,9 @@ func NewEngine(opts Options, msgBus *bus.MessageBus) *Engine {
|
|||||||
if opts.UserIdleResumeSec <= 0 {
|
if opts.UserIdleResumeSec <= 0 {
|
||||||
opts.UserIdleResumeSec = 20
|
opts.UserIdleResumeSec = 20
|
||||||
}
|
}
|
||||||
|
if opts.WaitingResumeDebounceSec <= 0 {
|
||||||
|
opts.WaitingResumeDebounceSec = 5
|
||||||
|
}
|
||||||
return &Engine{
|
return &Engine{
|
||||||
opts: opts,
|
opts: opts,
|
||||||
bus: msgBus,
|
bus: msgBus,
|
||||||
@@ -227,7 +231,7 @@ func (e *Engine) tick() {
|
|||||||
}
|
}
|
||||||
if st.Status == "waiting" {
|
if st.Status == "waiting" {
|
||||||
// Debounce waiting/resume flapping
|
// 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
|
continue
|
||||||
}
|
}
|
||||||
reason := st.BlockReason
|
reason := st.BlockReason
|
||||||
|
|||||||
@@ -45,17 +45,18 @@ type AgentDefaults struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type AutonomyConfig struct {
|
type AutonomyConfig struct {
|
||||||
Enabled bool `json:"enabled" env:"CLAWGO_AGENTS_DEFAULTS_AUTONOMY_ENABLED"`
|
Enabled bool `json:"enabled" env:"CLAWGO_AGENTS_DEFAULTS_AUTONOMY_ENABLED"`
|
||||||
TickIntervalSec int `json:"tick_interval_sec" env:"CLAWGO_AGENTS_DEFAULTS_AUTONOMY_TICK_INTERVAL_SEC"`
|
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"`
|
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"`
|
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"`
|
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"`
|
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"`
|
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"`
|
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"`
|
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"`
|
WaitingResumeDebounceSec int `json:"waiting_resume_debounce_sec" env:"CLAWGO_AGENTS_DEFAULTS_AUTONOMY_WAITING_RESUME_DEBOUNCE_SEC"`
|
||||||
NotifyChatID string `json:"notify_chat_id" env:"CLAWGO_AGENTS_DEFAULTS_AUTONOMY_NOTIFY_CHAT_ID"`
|
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 {
|
type AgentTextConfig struct {
|
||||||
@@ -309,6 +310,7 @@ func DefaultConfig() *Config {
|
|||||||
NotifyCooldownSec: 300,
|
NotifyCooldownSec: 300,
|
||||||
QuietHours: "23:00-08:00",
|
QuietHours: "23:00-08:00",
|
||||||
UserIdleResumeSec: 20,
|
UserIdleResumeSec: 20,
|
||||||
|
WaitingResumeDebounceSec: 5,
|
||||||
NotifyChannel: "",
|
NotifyChannel: "",
|
||||||
NotifyChatID: "",
|
NotifyChatID: "",
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -111,6 +111,9 @@ func Validate(cfg *Config) []error {
|
|||||||
if aut.UserIdleResumeSec <= 0 {
|
if aut.UserIdleResumeSec <= 0 {
|
||||||
errs = append(errs, fmt.Errorf("agents.defaults.autonomy.user_idle_resume_sec must be > 0 when enabled=true"))
|
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
|
texts := cfg.Agents.Defaults.Texts
|
||||||
if strings.TrimSpace(texts.NoResponseFallback) == "" {
|
if strings.TrimSpace(texts.NoResponseFallback) == "" {
|
||||||
|
|||||||
Reference in New Issue
Block a user