feat: import agents_and_robots platform as unibots (Matrix-out, unibus transport)
Reemplaza el scaffold del echobot por la plataforma completa de bots traida desde ~/DataProyects/Github/agents_and_robots tras la operacion Matrix-out: los bots ya no hablan por Matrix sino por el bus unibus (modelo todo-rooms + E2E via shell/transportunibus sobre github.com/enmanuel/unibus/pkg/client). - go.mod: replace de unibus -> ../unibus y de fn-registry -> ../../../.. (paths relativos reajustados a la nueva ubicacion dentro de fn_registry). - app.md: bump a 0.2.0, descripcion + arquitectura + comandos + gotchas reales. - modulo Go conservado como github.com/enmanuel/agents (sin reescribir imports). agents_and_robots queda archivado como museo de la era Matrix.
This commit is contained in:
@@ -0,0 +1,110 @@
|
||||
// Package cron provides a scheduler for autonomous bot activity.
|
||||
// It is part of the impure shell: it reads files, calls LLMs, and sends messages
|
||||
// over the bot's transport (unibus).
|
||||
package cron
|
||||
|
||||
import (
|
||||
"context"
|
||||
"log/slog"
|
||||
|
||||
"github.com/robfig/cron/v3"
|
||||
|
||||
"github.com/enmanuel/agents/internal/config"
|
||||
coretypes "github.com/enmanuel/agents/pkg/llm"
|
||||
)
|
||||
|
||||
// Sender is the subset of the bot's transport sender needed by the scheduler.
|
||||
type Sender interface {
|
||||
SendMarkdown(ctx context.Context, roomID, markdown string) error
|
||||
}
|
||||
|
||||
// Scheduler fires configured schedules and executes send_message or llm_prompt actions.
|
||||
type Scheduler struct {
|
||||
cfg []config.ScheduleCfg
|
||||
sender Sender
|
||||
llm coretypes.CompleteFunc // nil when agent has no LLM
|
||||
model string
|
||||
logger *slog.Logger
|
||||
cron *cron.Cron
|
||||
}
|
||||
|
||||
// New creates a Scheduler. llm and model are optional (nil/empty for agents without LLM).
|
||||
func New(
|
||||
cfg []config.ScheduleCfg,
|
||||
sender Sender,
|
||||
llm coretypes.CompleteFunc,
|
||||
model string,
|
||||
logger *slog.Logger,
|
||||
) *Scheduler {
|
||||
return &Scheduler{
|
||||
cfg: cfg,
|
||||
sender: sender,
|
||||
llm: llm,
|
||||
model: model,
|
||||
logger: logger.With("component", "cron"),
|
||||
cron: cron.New(),
|
||||
}
|
||||
}
|
||||
|
||||
// Fire immediately executes the action for the given schedule, bypassing the cron timer.
|
||||
// Useful for tests and manual triggering from CLI.
|
||||
func (s *Scheduler) Fire(ctx context.Context, sc config.ScheduleCfg) {
|
||||
room := sc.OutputRoom
|
||||
if room == "" {
|
||||
s.logger.Warn("Fire: schedule has no output_room, skipping", "name", sc.Name)
|
||||
return
|
||||
}
|
||||
handler := s.buildHandler(sc)
|
||||
if handler == nil {
|
||||
s.logger.Warn("Fire: unsupported action kind", "name", sc.Name, "kind", sc.Action.Kind)
|
||||
return
|
||||
}
|
||||
handler(ctx, room)
|
||||
}
|
||||
|
||||
// Start registers all schedules and starts the cron loop.
|
||||
// It returns when ctx is cancelled, stopping the cron runner.
|
||||
func (s *Scheduler) Start(ctx context.Context) {
|
||||
for _, sc := range s.cfg {
|
||||
sc := sc // capture range var
|
||||
if sc.Cron == "" || sc.Action.Kind == "" {
|
||||
s.logger.Warn("skipping invalid schedule", "name", sc.Name, "cron", sc.Cron, "kind", sc.Action.Kind)
|
||||
continue
|
||||
}
|
||||
|
||||
room := sc.OutputRoom
|
||||
if room == "" {
|
||||
s.logger.Warn("schedule has no output_room, skipping", "name", sc.Name)
|
||||
continue
|
||||
}
|
||||
|
||||
handler := s.buildHandler(sc)
|
||||
if handler == nil {
|
||||
s.logger.Warn("unsupported action kind, skipping", "name", sc.Name, "kind", sc.Action.Kind)
|
||||
continue
|
||||
}
|
||||
|
||||
_, err := s.cron.AddFunc(sc.Cron, func() {
|
||||
handler(ctx, room)
|
||||
})
|
||||
if err != nil {
|
||||
s.logger.Error("failed to register schedule",
|
||||
"name", sc.Name,
|
||||
"cron", sc.Cron,
|
||||
"err", err,
|
||||
)
|
||||
continue
|
||||
}
|
||||
|
||||
s.logger.Info("schedule registered", "name", sc.Name, "cron", sc.Cron, "kind", sc.Action.Kind, "room", room)
|
||||
}
|
||||
|
||||
s.cron.Start()
|
||||
s.logger.Info("cron scheduler started", "schedules", len(s.cfg))
|
||||
|
||||
<-ctx.Done()
|
||||
s.logger.Info("cron scheduler stopping")
|
||||
cronCtx := s.cron.Stop()
|
||||
<-cronCtx.Done()
|
||||
s.logger.Info("cron scheduler stopped")
|
||||
}
|
||||
Reference in New Issue
Block a user