feat: integrar Scheduler en agents/runtime.go

Se instancia shellcron.Scheduler en agents.New() cuando cfg.Schedules tiene
entradas (scheduler queda nil en agentes sin schedules, sin overhead).

En agents.Run() se arranca el scheduler en una goroutine independiente que
termina cuando el ctx del agente es cancelado — el shutdown es limpio gracias
a cron.Stop() que devuelve un contexto que se espera.

La integración no rompe agentes existentes: el campo scheduler es nil por
defecto y todo el código nuevo está tras if a.scheduler != nil.
This commit is contained in:
2026-03-08 19:00:38 +00:00
parent 4dfc6cf0b9
commit 9d1ab2d28e
+15
View File
@@ -24,6 +24,7 @@ import (
"github.com/enmanuel/agents/pkg/personality"
"github.com/enmanuel/agents/pkg/sanitize"
"github.com/enmanuel/agents/shell/bus"
shellcron "github.com/enmanuel/agents/shell/cron"
"github.com/enmanuel/agents/shell/effects"
shellknowledge "github.com/enmanuel/agents/shell/knowledge"
shelllm "github.com/enmanuel/agents/shell/llm"
@@ -93,6 +94,9 @@ type Agent struct {
// Bus — set via SetBus() when running under the unified launcher
agentBus *bus.Bus
// Scheduler — nil when no schedules are configured
scheduler *shellcron.Scheduler
}
// ClearWindow resets the conversation window for a room and deletes persisted
@@ -308,6 +312,12 @@ func New(cfg *config.AgentConfig, rules []decision.Rule, logger *slog.Logger) (*
toolReg.Register(toolmemory.NewMemoryClearContext(a, roomCtx))
}
// Cron scheduler — only when schedules are configured
if len(cfg.Schedules) > 0 {
a.scheduler = shellcron.New(cfg.Schedules, matrixClient, llmFunc, cfg.LLM.Primary.Model, logger)
logger.Info("cron scheduler configured", "schedules", len(cfg.Schedules))
}
// Matrix event listener
a.listener = matrix.NewListener(matrixClient, cfg.Matrix, a.handleEvent, logger)
@@ -420,6 +430,11 @@ func (a *Agent) Run(ctx context.Context) error {
a.logger.Info("bus listener started")
}
// Start cron scheduler in background goroutine (blocks until ctx cancelled)
if a.scheduler != nil {
go a.scheduler.Start(ctx)
}
return a.listener.Run(ctx)
}