From 44c7773e195b3af7b59c767ab10c36f169c4372f Mon Sep 17 00:00:00 2001 From: DBT Date: Tue, 24 Feb 2026 04:16:05 +0000 Subject: [PATCH] enhance autonomy operational telemetry and control status details --- cmd/clawgo/cmd_gateway.go | 32 +++++++++++++++++++++++++++++--- cmd/clawgo/cmd_status.go | 7 +++++++ pkg/autonomy/engine.go | 6 ++++++ 3 files changed, 42 insertions(+), 3 deletions(-) diff --git a/cmd/clawgo/cmd_gateway.go b/cmd/clawgo/cmd_gateway.go index 7236f37..16c43ef 100644 --- a/cmd/clawgo/cmd_gateway.go +++ b/cmd/clawgo/cmd_gateway.go @@ -323,16 +323,31 @@ func gatewayAutonomyControlCmd(args []string) error { pausePath := filepath.Join(memDir, "autonomy.pause") ctrlPath := filepath.Join(memDir, "autonomy.control.json") + type autonomyControl struct { + Enabled bool `json:"enabled"` + UpdatedAt string `json:"updated_at"` + Source string `json:"source"` + } + + writeControl := func(enabled bool) error { + c := autonomyControl{Enabled: enabled, UpdatedAt: time.Now().UTC().Format(time.RFC3339), Source: "manual_cli"} + data, err := json.MarshalIndent(c, "", " ") + if err != nil { + return err + } + return os.WriteFile(ctrlPath, append(data, '\n'), 0644) + } + switch strings.ToLower(strings.TrimSpace(args[0])) { case "on": _ = os.Remove(pausePath) - if err := os.WriteFile(ctrlPath, []byte("{\n \"enabled\": true\n}\n"), 0644); err != nil { + if err := writeControl(true); err != nil { return err } fmt.Println("✓ Autonomy enabled") return nil case "off": - if err := os.WriteFile(ctrlPath, []byte("{\n \"enabled\": false\n}\n"), 0644); err != nil { + if err := writeControl(false); err != nil { return err } if err := os.WriteFile(pausePath, []byte(time.Now().UTC().Format(time.RFC3339)+"\n"), 0644); err != nil { @@ -343,10 +358,14 @@ func gatewayAutonomyControlCmd(args []string) error { case "status": enabled := true reason := "default" + updatedAt := "" + source := "" if data, err := os.ReadFile(ctrlPath); err == nil { - var c struct{ Enabled bool `json:"enabled"` } + var c autonomyControl if json.Unmarshal(data, &c) == nil { enabled = c.Enabled + updatedAt = c.UpdatedAt + source = c.Source if !c.Enabled { reason = "control_file" } @@ -357,6 +376,13 @@ func gatewayAutonomyControlCmd(args []string) error { reason = "pause_file" } fmt.Printf("Autonomy status: %v (%s)\n", enabled, reason) + if strings.TrimSpace(updatedAt) != "" { + fmt.Printf("Last switch: %s", updatedAt) + if strings.TrimSpace(source) != "" { + fmt.Printf(" via %s", source) + } + fmt.Println() + } fmt.Printf("Control file: %s\n", ctrlPath) fmt.Printf("Pause file: %s\n", pausePath) return nil diff --git a/cmd/clawgo/cmd_status.go b/cmd/clawgo/cmd_status.go index 85b501e..9b658da 100644 --- a/cmd/clawgo/cmd_status.go +++ b/cmd/clawgo/cmd_status.go @@ -191,6 +191,13 @@ func summarizeAutonomyActions(statsJSON []byte) string { b := payload.Counts["autonomy:blocked"] parts = append(parts, fmt.Sprintf("ratios(dispatch/waiting/blocked)=%.2f/%.2f/%.2f", float64(d)/float64(total), float64(w)/float64(total), float64(b)/float64(total))) } + wa := payload.Counts["autonomy:waiting:active_user"] + wm := payload.Counts["autonomy:waiting:manual_pause"] + ra := payload.Counts["autonomy:resume:active_user"] + rm := payload.Counts["autonomy:resume:manual_pause"] + if wa+wm+ra+rm > 0 { + parts = append(parts, fmt.Sprintf("wait_resume(active_user=%d/%d manual_pause=%d/%d)", wa, ra, wm, rm)) + } return strings.Join(parts, " ") } diff --git a/pkg/autonomy/engine.go b/pkg/autonomy/engine.go index 4619e10..f0e6f99 100644 --- a/pkg/autonomy/engine.go +++ b/pkg/autonomy/engine.go @@ -464,6 +464,12 @@ func (e *Engine) writeTriggerAudit(action string, st *taskState, errText string) act := strings.ToLower(strings.TrimSpace(action)) if act != "" { stats.Counts["autonomy:"+act]++ + reason := strings.ToLower(strings.TrimSpace(errText)) + if reason != "" { + reason = strings.ReplaceAll(reason, " ", "_") + reason = strings.ReplaceAll(reason, ":", "_") + stats.Counts["autonomy:"+act+":"+reason]++ + } } stats.UpdatedAt = time.Now().UTC().Format(time.RFC3339) if raw, mErr := json.MarshalIndent(stats, "", " "); mErr == nil {