feat: add cron tool integration with agent

- Add adhocore/gronx dependency for cron expression parsing
- Fix CronService race conditions and add cron expression support
- Add CronTool with add/list/remove/enable/disable actions
- Add ContextualTool interface for tools needing channel/chatID context
- Add ProcessDirectWithChannel to AgentLoop for cron job execution
- Register CronTool in gateway and wire up onJob handler
- Fix slice bounds panic in addJob for short messages

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
yinwm
2026-02-11 12:28:37 +08:00
parent 3e902abb5c
commit 6d4d2bc61e
8 changed files with 401 additions and 37 deletions

View File

@@ -27,6 +27,7 @@ import (
"github.com/sipeed/picoclaw/pkg/logger"
"github.com/sipeed/picoclaw/pkg/providers"
"github.com/sipeed/picoclaw/pkg/skills"
"github.com/sipeed/picoclaw/pkg/tools"
"github.com/sipeed/picoclaw/pkg/voice"
)
@@ -551,8 +552,20 @@ func gatewayCmd() {
})
cronStorePath := filepath.Join(filepath.Dir(getConfigPath()), "cron", "jobs.json")
// Create cron service first (onJob handler set after CronTool creation)
cronService := cron.NewCronService(cronStorePath, nil)
// Create and register CronTool
cronTool := tools.NewCronTool(cronService, agentLoop)
agentLoop.RegisterTool(cronTool)
// Now set the onJob handler for cron service
cronService.SetOnJob(func(job *cron.CronJob) (string, error) {
result := cronTool.ExecuteJob(context.Background(), job)
return result, nil
})
heartbeatService := heartbeat.NewHeartbeatService(
cfg.WorkspacePath(),
nil,
@@ -745,7 +758,7 @@ func cronHelp() {
func cronListCmd(storePath string) {
cs := cron.NewCronService(storePath, nil)
jobs := cs.ListJobs(false)
jobs := cs.ListJobs(true) // Show all jobs, including disabled
if len(jobs) == 0 {
fmt.Println("No scheduled jobs.")