Documentation
¶
Overview ¶
Package cron provides a lightweight cron-like scheduler for agent jobs. It supports both the simple Roger crons.json format and the full OpenClaw jobs.json format (schedule.kind:"every", sessionTarget, wakeMode, delivery, payload model/timeout overrides, and state persistence).
Package cron — runlog.go implements persistent cron run logging (REQ-430).
After each cron job completes, a structured entry is appended to a per-job JSONL file at <agent>/cron/runs/<jobId>.jsonl. Supports paginated reads with filtering, sorting, and auto-pruning when files exceed 2MB / 2000 lines.
Index ¶
- Constants
- Variables
- func AppendRunLog(logger *zap.SugaredLogger, dir string, entry RunLogEntry) error
- func PruneIfNeeded(path string, maxBytes int64, keepLines int) error
- type Deliverer
- type Delivery
- type Job
- func (j *Job) DisplayName() string
- func (j *Job) DisplaySchedule() string
- func (j *Job) EffectiveInstruction() string
- func (j *Job) EffectiveInterval() (time.Duration, error)
- func (j *Job) EffectiveModel() string
- func (j *Job) EffectiveSessionKey() string
- func (j *Job) EffectiveTimeout() time.Duration
- func (j *Job) WantsDelivery() bool
- type JobState
- type Manager
- func (m *Manager) Add(spec, instruction string) (*Job, error)
- func (m *Manager) AddDeliverer(d Deliverer)
- func (m *Manager) Dir() string
- func (m *Manager) List() []*Job
- func (m *Manager) LoadJobsFile(path string) error
- func (m *Manager) Remove(id string) error
- func (m *Manager) RunLogDir() string
- func (m *Manager) RunNow(ctx context.Context, id string) error
- func (m *Manager) SetEnabled(id string, enabled bool) error
- func (m *Manager) Start(ctx context.Context) error
- type Payload
- type RunFunc
- type RunLogEntry
- type RunLogPage
- type RunLogPageOpts
- type RunResult
- type Schedule
Constants ¶
const DefaultStaggerMs = 5 * 60 * 1000 // 5 minutes
DefaultStaggerMs is the default stagger window for intervals >= 1 hour.
Variables ¶
var ErrJobNotFound = errors.New("job not found")
ErrJobNotFound is returned when a job ID does not match any known job.
Functions ¶
func AppendRunLog ¶
func AppendRunLog(logger *zap.SugaredLogger, dir string, entry RunLogEntry) error
AppendRunLog appends a single entry to the job's run log file.
Types ¶
type Delivery ¶
type Delivery struct {
Mode string `json:"mode,omitempty"` // "announce" or "none"
Channel string `json:"channel,omitempty"` // "last" (currently only option)
}
Delivery defines how results are delivered. Mode: "announce" = send to all paired users; "none" = suppress delivery.
type Job ¶
type Job struct {
ID string `json:"id"`
Name string `json:"name,omitempty"`
Description string `json:"description,omitempty"`
Enabled bool `json:"enabled"`
// Legacy simple format fields (crons.json)
Spec string `json:"spec,omitempty"` // @daily, @hourly, @every 1h, HH:MM
Instruction string `json:"instruction,omitempty"` // text sent to agent
SessionKey string `json:"sessionKey,omitempty"` // empty = "cron:<id>"
// Full OpenClaw jobs.json fields
CreatedAtMs int64 `json:"createdAtMs,omitempty"`
UpdatedAtMs int64 `json:"updatedAtMs,omitempty"`
Schedule *Schedule `json:"schedule,omitempty"`
// "isolated" = fresh session per run; "persistent" = reuse same key
SessionTarget string `json:"sessionTarget,omitempty"`
// "now" = run missed runs immediately on startup; "skip" = skip missed
WakeMode string `json:"wakeMode,omitempty"`
Payload *Payload `json:"payload,omitempty"`
Delivery *Delivery `json:"delivery,omitempty"`
LightContext bool `json:"lightContext,omitempty"` // if true, use minimal bootstrap context (HEARTBEAT.md only)
State *JobState `json:"state,omitempty"`
}
Job represents a scheduled agent task.
func (*Job) DisplayName ¶
DisplayName returns the best available name for display.
func (*Job) DisplaySchedule ¶
DisplaySchedule returns a human-readable schedule string.
func (*Job) EffectiveInstruction ¶
EffectiveInstruction returns the message to send (supports both formats).
func (*Job) EffectiveInterval ¶
EffectiveInterval returns the repeat interval (supports both formats).
func (*Job) EffectiveModel ¶
EffectiveModel returns the per-job model override, or "" if none.
func (*Job) EffectiveSessionKey ¶
EffectiveSessionKey returns the session key for this run. isolated: fresh key per run; persistent: reuse "cron:<id>".
func (*Job) EffectiveTimeout ¶
EffectiveTimeout returns the per-job timeout, or 0 if none.
func (*Job) WantsDelivery ¶
WantsDelivery returns true if the job wants results announced.
type JobState ¶
type JobState struct {
NextRunAtMs int64 `json:"nextRunAtMs,omitempty"`
LastRunAtMs int64 `json:"lastRunAtMs,omitempty"`
LastRunStatus string `json:"lastRunStatus,omitempty"`
LastStatus string `json:"lastStatus,omitempty"`
LastDurationMs int64 `json:"lastDurationMs,omitempty"`
LastDeliveryStatus string `json:"lastDeliveryStatus,omitempty"`
ConsecutiveErrors int `json:"consecutiveErrors"`
LastDelivered bool `json:"lastDelivered,omitempty"`
}
JobState tracks runtime state; persisted back to jobs.json.
type Manager ¶
type Manager struct {
// contains filtered or unexported fields
}
Manager schedules and manages cron jobs.
func New ¶
func New(logger *zap.SugaredLogger, dir string, runFunc RunFunc) *Manager
New creates a Manager that stores state in dir/crons.json. runFunc is called for each job execution.
func (*Manager) Add ¶
Add creates a new enabled job (simple format). If Start() has already been called, the job is scheduled immediately.
func (*Manager) AddDeliverer ¶
AddDeliverer registers a channel deliverer for job result delivery.
func (*Manager) LoadJobsFile ¶
LoadJobsFile loads the full-format jobs.json from the given path, merging into any already-loaded simple jobs (deduped by ID).
func (*Manager) SetEnabled ¶
SetEnabled enables or disables a job by ID. Re-enabling a job schedules it immediately if Start() has been called.
type Payload ¶
type Payload struct {
Kind string `json:"kind"` // "agentTurn"
Message string `json:"message"` // instruction text
Model string `json:"model,omitempty"` // per-job model override
TimeoutSeconds int `json:"timeoutSeconds,omitempty"` // per-job timeout
}
Payload defines what runs when the job fires.
type RunFunc ¶
RunFunc is the function called when a job fires. It receives the job so it can use model/timeout overrides.
type RunLogEntry ¶
type RunLogEntry struct {
TS int64 `json:"ts"`
JobID string `json:"jobId"`
Action string `json:"action"` // "finished"
Status string `json:"status"` // "ok", "error", "skipped"
Error string `json:"error,omitempty"`
Summary string `json:"summary,omitempty"`
Delivered bool `json:"delivered,omitempty"`
DeliveryStatus string `json:"deliveryStatus,omitempty"`
DeliveryError string `json:"deliveryError,omitempty"`
SessionID string `json:"sessionId,omitempty"`
SessionKey string `json:"sessionKey,omitempty"`
RunAtMs int64 `json:"runAtMs"`
DurationMs int64 `json:"durationMs"`
NextRunAtMs int64 `json:"nextRunAtMs,omitempty"`
Model string `json:"model,omitempty"`
Provider string `json:"provider,omitempty"`
InputTokens int `json:"inputTokens,omitempty"`
OutputTokens int `json:"outputTokens,omitempty"`
}
RunLogEntry is a single run history record.
type RunLogPage ¶
type RunLogPage struct {
Entries []RunLogEntry `json:"entries"`
Total int `json:"total"` // total matching entries
HasMore bool `json:"hasMore"`
}
RunLogPage is a paginated result.
func ReadRunLogPage ¶
func ReadRunLogPage(dir, jobID string, opts RunLogPageOpts) (RunLogPage, error)
ReadRunLogPage reads paginated run log entries from a job's JSONL file.
type RunLogPageOpts ¶
type RunLogPageOpts struct {
Limit int // 1-200, default 50
Offset int // default 0
Status string // "all", "ok", "error", "skipped"
DeliveryStatus string // "" = all
SortDir string // "asc" or "desc" (default "desc")
Query string // text search in summary/error
}
RunLogPageOpts controls paginated reads.
type Schedule ¶
type Schedule struct {
Kind string `json:"kind"` // "every"
EveryMs int64 `json:"everyMs,omitempty"` // interval in milliseconds
AnchorMs int64 `json:"anchorMs,omitempty"` // epoch ms reference point
StaggerMs int64 `json:"staggerMs,omitempty"` // max stagger window (0 = auto for hourly+)
}
Schedule defines when a job runs (OpenClaw format).