The YAML parser's outer loop was exiting the tasks block when it
encountered 'interval:' or 'prompt:' lines, causing only the first
task to be parsed. Added isTaskField check to skip those lines.
Fixes: #3034790131
- Fix: Pass startedAt into resolveHeartbeatRunPrompt
- Fix: Return proper object instead of null for no-tasks-due
- Fix: Add early return when prompt is null
- Fix: Persist timestamps on successful exits
- Fix YAML parsing to capture interval:/prompt: before breaking
- Record task timestamps AFTER successful execution (not before)
- Initialize task state on first run (handle undefined session)
- Skip API call when no tasks due (return null)
- Use startedAt consistently for due-task filtering
Fixes: #3030568439, #3033833124, #3030570872, #3030568408, #3030570872, #3035434022, #3035434368
The heartbeat task batching feature uses heartbeatTaskState to track
last run times for periodic tasks, but this property was missing
from the SessionEntry type, causing TypeScript compilation errors.
- Add parseHeartbeatTasks() to parse YAML-like task definitions
- Add isTaskDue() to check if task interval has elapsed
- Add heartbeatTaskState to session store for tracking last run times
- Modify resolveHeartbeatRunPrompt to build batched prompts for due tasks
- Update task last run times after successful heartbeat execution
Implements openclaw#29570
* fix(cron): prevent agent default model from overriding cron payload model (#58065)
When a cron job specifies a model override via the Advanced settings,
runWithModelFallback could silently fall back to the agent's configured
primary model. This happened because fallbacksOverride was undefined
when neither payload.fallbacks nor per-agent fallbacks were configured,
causing resolveFallbackCandidates to append the agent primary as a
last-resort candidate. A transient failure on the cron-selected model
(rate limit, model-not-found, etc.) would then succeed on the agent
default, making it appear as if the override was ignored entirely.
Fix: when the cron payload carries an explicit model override, ensure
fallbacksOverride is always a defined array (empty when no fallbacks
are configured) so the agent primary is never silently appended.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* test: use stricter toEqual([]) assertion for fallbacksOverride
Replace toBeDefined() + toBeInstanceOf(Array) with toEqual([])
to catch regressions where the array unexpectedly gains entries.
Addresses review feedback.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* fix: preserve cron override fallback semantics (#58294)
---------
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-authored-by: Peter Steinberger <steipete@gmail.com>