package agent import ( "context" "log/slog" "time" ) type Scheduler struct { agent *Agent interval time.Duration diaryHour int stopCh chan struct{} } func NewScheduler(agent *Agent, interval time.Duration, diaryHour int) *Scheduler { return &Scheduler{ agent: agent, interval: interval, diaryHour: diaryHour, stopCh: make(chan struct{}), } } func (s *Scheduler) Start(ctx context.Context) { slog.Info("scheduler started", "interval", s.interval) ticker := time.NewTicker(s.interval) defer ticker.Stop() for { select { case <-ctx.Done(): slog.Info("scheduler stopped via context") return case <-s.stopCh: slog.Info("scheduler stopped via signal") return case <-ticker.C: s.tick(ctx) } } } func (s *Scheduler) Stop() { close(s.stopCh) } func (s *Scheduler) tick(ctx context.Context) { mood := s.agent.companion.Mood() lastContact := s.agent.companion.LastContactDuration() trust := s.agent.companion.Trust() slog.Debug("scheduler tick", "mood", mood, "lastContact", lastContact, "trust", trust) if lastContact > 48*time.Hour && trust > 0.6 { s.agent.companion.QueueAutonomousMessage( "Haven't heard from you in a while. Everything okay?", ) } if s.agent.cfg.AutoDiary { hour := time.Now().Hour() if hour >= s.diaryHour || hour < 1 { if err := s.agent.companion.WriteDiary(ctx); err != nil { slog.Warn("diary write failed", "error", err) } } } }