Add scheduled tasks (one-off and cron) run by the agent #2

Merged
jacensekai merged 1 commit from scheduled-tasks into master 2026-10-13 14:06:23 -04:00
Owner

The agent can now act without a user message. A schedule is either a
one-off (run_at) or recurring (a 5-field cron expression evaluated in
the server's TZ), and runs in a chosen conversation or in a new
conversation per run. They're stored in a new schedules table; deleting
a schedule's conversation sends later runs to new conversations.

The scheduler (server/scheduler.ts) ticks every 15s and fires due
schedules by adding the prompt as a user message with meta.scheduled.
startAgent moved into agent/loop.ts and can emit that message as a run
event, so open tabs see the turn appear. toChatMessages() prefixes it
with a <scheduled_task> note so the model knows nobody typed it just
now. A run missed while the server was down fires once, late; one-offs
are deleted after firing; a schedule whose conversation is busy stays
due until the run there ends. Recurring schedules may not fire more
often than every 5 minutes.

server/cron.ts is a small parser with no new dependency: lists,
ranges, steps, names, @daily-style aliases, and Vixie's either-day
rule. When clocks go back, fixed-time jobs run once in the repeated
hour and hourly jobs run in both passes.

The agent gets schedule_create/_list/_update/_delete tools, and the
system prompt states the time zone. Settings → Schedules lists, creates,
edits, pauses, deletes and runs schedules now. A finished scheduled run
sends a new scheduled notification kind, with its own toggle so
reminders arrive even when finished-run notifications are off.

Co-Authored-By: Claude Opus 5.5 noreply@anthropic.com

The agent can now act without a user message. A schedule is either a one-off (run_at) or recurring (a 5-field cron expression evaluated in the server's TZ), and runs in a chosen conversation or in a new conversation per run. They're stored in a new schedules table; deleting a schedule's conversation sends later runs to new conversations. The scheduler (server/scheduler.ts) ticks every 15s and fires due schedules by adding the prompt as a user message with meta.scheduled. startAgent moved into agent/loop.ts and can emit that message as a run event, so open tabs see the turn appear. toChatMessages() prefixes it with a <scheduled_task> note so the model knows nobody typed it just now. A run missed while the server was down fires once, late; one-offs are deleted after firing; a schedule whose conversation is busy stays due until the run there ends. Recurring schedules may not fire more often than every 5 minutes. server/cron.ts is a small parser with no new dependency: lists, ranges, steps, names, @daily-style aliases, and Vixie's either-day rule. When clocks go back, fixed-time jobs run once in the repeated hour and hourly jobs run in both passes. The agent gets schedule_create/_list/_update/_delete tools, and the system prompt states the time zone. Settings → Schedules lists, creates, edits, pauses, deletes and runs schedules now. A finished scheduled run sends a new `scheduled` notification kind, with its own toggle so reminders arrive even when finished-run notifications are off. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Add scheduled tasks (one-off and cron) run by the agent
Some checks failed
CI / Typecheck, build and test (pull_request) Successful in 18s
CI / End-to-end (Playwright) (pull_request) Successful in 51s
CI / Docker images and sandbox (pull_request) Failing after 11s
CI / Compose stack smoke test (pull_request) Failing after 6s
919d05b63a
The agent can now act without a user message. A schedule is either a
one-off (run_at) or recurring (a 5-field cron expression evaluated in
the server's TZ), and runs in a chosen conversation or in a new
conversation per run. They're stored in a new schedules table; deleting
a schedule's conversation sends later runs to new conversations.

The scheduler (server/scheduler.ts) ticks every 15s and fires due
schedules by adding the prompt as a user message with meta.scheduled.
startAgent moved into agent/loop.ts and can emit that message as a run
event, so open tabs see the turn appear. toChatMessages() prefixes it
with a <scheduled_task> note so the model knows nobody typed it just
now. A run missed while the server was down fires once, late; one-offs
are deleted after firing; a schedule whose conversation is busy stays
due until the run there ends. Recurring schedules may not fire more
often than every 5 minutes.

server/cron.ts is a small parser with no new dependency: lists,
ranges, steps, names, @daily-style aliases, and Vixie's either-day
rule. When clocks go back, fixed-time jobs run once in the repeated
hour and hourly jobs run in both passes.

The agent gets schedule_create/_list/_update/_delete tools, and the
system prompt states the time zone. Settings → Schedules lists, creates,
edits, pauses, deletes and runs schedules now. A finished scheduled run
sends a new `scheduled` notification kind, with its own toggle so
reminders arrive even when finished-run notifications are off.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
jacensekai/lumina!2
No description provided.