mirror of
https://github.com/YspCoder/clawgo.git
synced 2026-04-13 16:47:34 +08:00
89 lines
2.4 KiB
Go
89 lines
2.4 KiB
Go
package autonomy
|
|
|
|
import (
|
|
"encoding/json"
|
|
"os"
|
|
"path/filepath"
|
|
"sort"
|
|
"strings"
|
|
"time"
|
|
)
|
|
|
|
type TaskAttempt struct {
|
|
Time string `json:"time"`
|
|
Status string `json:"status"`
|
|
Session string `json:"session,omitempty"`
|
|
Note string `json:"note,omitempty"`
|
|
}
|
|
|
|
type TaskItem struct {
|
|
ID string `json:"id"`
|
|
ParentTaskID string `json:"parent_task_id,omitempty"`
|
|
Content string `json:"content"`
|
|
Priority string `json:"priority"`
|
|
DueAt string `json:"due_at,omitempty"`
|
|
Status string `json:"status"` // todo|doing|waiting|blocked|done|paused|canceled
|
|
BlockReason string `json:"block_reason,omitempty"`
|
|
RetryAfter string `json:"retry_after,omitempty"`
|
|
Source string `json:"source"`
|
|
DedupeHits int `json:"dedupe_hits,omitempty"`
|
|
ResourceKeys []string `json:"resource_keys,omitempty"`
|
|
LastPauseReason string `json:"last_pause_reason,omitempty"`
|
|
LastPauseAt string `json:"last_pause_at,omitempty"`
|
|
MemoryRefs []string `json:"memory_refs,omitempty"`
|
|
AuditRefs []string `json:"audit_refs,omitempty"`
|
|
Attempts []TaskAttempt `json:"attempts,omitempty"`
|
|
UpdatedAt string `json:"updated_at"`
|
|
}
|
|
|
|
type TaskStore struct {
|
|
workspace string
|
|
}
|
|
|
|
func NewTaskStore(workspace string) *TaskStore {
|
|
return &TaskStore{workspace: workspace}
|
|
}
|
|
|
|
func (s *TaskStore) path() string {
|
|
return filepath.Join(s.workspace, "memory", "tasks.json")
|
|
}
|
|
|
|
func (s *TaskStore) Load() ([]TaskItem, error) {
|
|
data, err := os.ReadFile(s.path())
|
|
if err != nil {
|
|
if os.IsNotExist(err) {
|
|
return []TaskItem{}, nil
|
|
}
|
|
return nil, err
|
|
}
|
|
var items []TaskItem
|
|
if err := json.Unmarshal(data, &items); err != nil {
|
|
return nil, err
|
|
}
|
|
return items, nil
|
|
}
|
|
|
|
func (s *TaskStore) Save(items []TaskItem) error {
|
|
_ = os.MkdirAll(filepath.Dir(s.path()), 0755)
|
|
sort.Slice(items, func(i, j int) bool { return items[i].UpdatedAt > items[j].UpdatedAt })
|
|
data, err := json.MarshalIndent(items, "", " ")
|
|
if err != nil {
|
|
return err
|
|
}
|
|
return os.WriteFile(s.path(), data, 0644)
|
|
}
|
|
|
|
func normalizeStatus(v string) string {
|
|
s := strings.ToLower(strings.TrimSpace(v))
|
|
switch s {
|
|
case "todo", "doing", "waiting", "blocked", "done", "paused", "canceled":
|
|
return s
|
|
default:
|
|
return "todo"
|
|
}
|
|
}
|
|
|
|
func nowRFC3339() string {
|
|
return time.Now().UTC().Format(time.RFC3339)
|
|
}
|