mirror of
https://github.com/tiennm99/goclaw.git
synced 2026-10-20 02:17:24 +00:00
refactor(cron): normalize payload columns into dedicated DB fields (#33)
Extract wake_heartbeat and stateless from JSON payload into first-class columns on cron_jobs. Adds migration 000033 with backfill from existing payload data. Updates PG + SQLite stores, RPC handlers, and UI i18n.
This commit is contained in:
1 parent
d10236241e
commit
24717b0f51
28 files changed
+268
-131
No files matched your search
+16
-13
@@ -49,7 +49,7 @@ func makeCronJobHandler(sched *scheduler.Scheduler, msgBus *bus.MessageBus, cfg
|
||||
}
|
||||
|
||||
sessionKey := sessions.BuildCronSessionKey(agentID, job.ID)
|
||||
channel := job.Payload.Channel
|
||||
channel := job.DeliverChannel
|
||||
if channel == "" {
|
||||
channel = "cron"
|
||||
}
|
||||
@@ -63,12 +63,12 @@ func makeCronJobHandler(sched *scheduler.Scheduler, msgBus *bus.MessageBus, cfg
|
||||
|
||||
// Build cron context so the agent knows delivery target and requester.
|
||||
var extraPrompt string
|
||||
if job.Payload.Deliver && job.Payload.Channel != "" && job.Payload.To != "" {
|
||||
if job.Deliver && job.DeliverChannel != "" && job.DeliverTo != "" {
|
||||
extraPrompt = fmt.Sprintf(
|
||||
"[Cron Job]\nThis is scheduled job \"%s\" (ID: %s).\n"+
|
||||
"Requester: user %s on channel \"%s\" (chat %s).\n"+
|
||||
"Your response will be automatically delivered to that chat — just produce the content directly.",
|
||||
job.Name, job.ID, job.UserID, job.Payload.Channel, job.Payload.To,
|
||||
job.Name, job.ID, job.UserID, job.DeliverChannel, job.DeliverTo,
|
||||
)
|
||||
} else {
|
||||
extraPrompt = fmt.Sprintf(
|
||||
@@ -84,8 +84,11 @@ func makeCronJobHandler(sched *scheduler.Scheduler, msgBus *bus.MessageBus, cfg
|
||||
// Reset session before each cron run to prevent tool errors from previous
|
||||
// runs from polluting the context and blocking future executions (#294).
|
||||
// Save() persists the empty session to DB so stale data won't reload after restart.
|
||||
sessionMgr.Reset(cronCtx, sessionKey)
|
||||
sessionMgr.Save(cronCtx, sessionKey)
|
||||
// Stateless jobs skip this — they intentionally carry no session history.
|
||||
if !job.Stateless {
|
||||
sessionMgr.Reset(cronCtx, sessionKey)
|
||||
sessionMgr.Save(cronCtx, sessionKey)
|
||||
}
|
||||
|
||||
// Schedule through cron lane — scheduler handles agent resolution and concurrency
|
||||
outCh := sched.Schedule(cronCtx, scheduler.LaneCron, agent.RunRequest{
|
||||
@@ -93,7 +96,7 @@ func makeCronJobHandler(sched *scheduler.Scheduler, msgBus *bus.MessageBus, cfg
|
||||
Message: job.Payload.Message,
|
||||
Channel: channel,
|
||||
ChannelType: channelType,
|
||||
ChatID: job.Payload.To,
|
||||
ChatID: job.DeliverTo,
|
||||
PeerKind: peerKind,
|
||||
UserID: job.UserID,
|
||||
RunID: fmt.Sprintf("cron:%s", job.ID),
|
||||
@@ -112,20 +115,20 @@ func makeCronJobHandler(sched *scheduler.Scheduler, msgBus *bus.MessageBus, cfg
|
||||
result := outcome.Result
|
||||
|
||||
// If job wants delivery to a channel, send the agent response to the target chat.
|
||||
if job.Payload.Deliver && job.Payload.Channel != "" && job.Payload.To != "" {
|
||||
if job.Deliver && job.DeliverChannel != "" && job.DeliverTo != "" {
|
||||
outMsg := bus.OutboundMessage{
|
||||
Channel: job.Payload.Channel,
|
||||
ChatID: job.Payload.To,
|
||||
Channel: job.DeliverChannel,
|
||||
ChatID: job.DeliverTo,
|
||||
Content: result.Content,
|
||||
}
|
||||
if peerKind == "group" {
|
||||
outMsg.Metadata = map[string]string{"group_id": job.Payload.To}
|
||||
outMsg.Metadata = map[string]string{"group_id": job.DeliverTo}
|
||||
}
|
||||
appendMediaToOutbound(&outMsg, result.Media)
|
||||
msgBus.PublishOutbound(outMsg)
|
||||
} else if job.Payload.Deliver {
|
||||
} else if job.Deliver {
|
||||
slog.Warn("cron: delivery configured but channel/chatID missing — output discarded",
|
||||
"job_id", job.ID, "job_name", job.Name, "channel", job.Payload.Channel, "to", job.Payload.To)
|
||||
"job_id", job.ID, "job_name", job.Name, "channel", job.DeliverChannel, "to", job.DeliverTo)
|
||||
}
|
||||
|
||||
cronResult := &store.CronJobResult{
|
||||
@@ -138,7 +141,7 @@ func makeCronJobHandler(sched *scheduler.Scheduler, msgBus *bus.MessageBus, cfg
|
||||
|
||||
// wakeMode: trigger heartbeat after cron job completes.
|
||||
// Use original job.AgentID (UUID) — cronHeartbeatWakeFn expects UUID for ticker.Wake().
|
||||
if job.Payload.WakeHeartbeat && cronHeartbeatWakeFn != nil {
|
||||
if job.WakeHeartbeat && cronHeartbeatWakeFn != nil {
|
||||
cronHeartbeatWakeFn(job.AgentID)
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user